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);
4883 Ext.isReady = initExtCss();
4886 Ext.onReady(initExtCss);
4892 var supports = Ext.apply(Ext.supports, {
4894 correctRightMargin: true,
4897 correctTransparentColor: true,
4903 var supportTests = function(){
4904 var div = document.createElement('div'),
4909 div.innerHTML = '<div style="height:30px;width:50px;"><div style="height:20px;width:20px;"></div></div><div style="float:left;background-color:transparent;">';
4910 doc.body.appendChild(div);
4911 last = div.lastChild;
4913 if((view = doc.defaultView)){
4914 if(view.getComputedStyle(div.firstChild.firstChild, null).marginRight != '0px'){
4915 supports.correctRightMargin = false;
4917 if(view.getComputedStyle(last, null).backgroundColor != 'transparent'){
4918 supports.correctTransparentColor = false;
4921 supports.cssFloat = !!last.style.cssFloat;
4922 doc.body.removeChild(div);
4928 Ext.onReady(supportTests);
4934 Ext.EventObject = function(){
4935 var E = Ext.lib.Event,
4936 clickRe = /(dbl)?click/,
4951 btnMap = Ext.isIE ? {1:0,4:1,2:2} : {0:0,1:1,2:2};
4953 Ext.EventObjectImpl = function(e){
4955 this.setEvent(e.browserEvent || e);
4959 Ext.EventObjectImpl.prototype = {
4961 setEvent : function(e){
4963 if(e == me || (e && e.browserEvent)){
4966 me.browserEvent = e;
4969 me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
4970 if(clickRe.test(e.type) && me.button == -1){
4974 me.shiftKey = e.shiftKey;
4976 me.ctrlKey = e.ctrlKey || e.metaKey || false;
4977 me.altKey = e.altKey;
4979 me.keyCode = e.keyCode;
4980 me.charCode = e.charCode;
4982 me.target = E.getTarget(e);
4987 me.shiftKey = false;
4999 stopEvent : function(){
5001 if(me.browserEvent){
5002 if(me.browserEvent.type == 'mousedown'){
5003 Ext.EventManager.stoppedMouseDownEvent.fire(me);
5005 E.stopEvent(me.browserEvent);
5010 preventDefault : function(){
5011 if(this.browserEvent){
5012 E.preventDefault(this.browserEvent);
5017 stopPropagation : function(){
5019 if(me.browserEvent){
5020 if(me.browserEvent.type == 'mousedown'){
5021 Ext.EventManager.stoppedMouseDownEvent.fire(me);
5023 E.stopPropagation(me.browserEvent);
5028 getCharCode : function(){
5029 return this.charCode || this.keyCode;
5033 getKey : function(){
5034 return this.normalizeKey(this.keyCode || this.charCode);
5038 normalizeKey: function(k){
5039 return Ext.isSafari ? (safariKeys[k] || k) : k;
5043 getPageX : function(){
5048 getPageY : function(){
5058 getTarget : function(selector, maxDepth, returnEl){
5059 return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
5063 getRelatedTarget : function(){
5064 return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
5068 getWheelDelta : function(){
5069 var e = this.browserEvent;
5072 delta = e.wheelDelta/120;
5074 delta = -e.detail/3;
5080 within : function(el, related, allowEl){
5082 var t = this[related ? "getRelatedTarget" : "getTarget"]();
5083 return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
5089 return new Ext.EventObjectImpl();
5093 Ext.ns("Ext.grid", "Ext.list", "Ext.dd", "Ext.tree", "Ext.form", "Ext.menu",
5094 "Ext.state", "Ext.layout", "Ext.app", "Ext.ux", "Ext.chart", "Ext.direct");
5097 Ext.apply(Ext, function(){
5104 emptyFn : function(){},
5107 BLANK_IMAGE_URL : Ext.isIE6 || Ext.isIE7 || Ext.isAir ?
5108 'http:/' + '/www.extjs.com/s.gif' :
5109 'data:image/gif;base64,R0lGODlhAQABAID/AMDAwAAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==',
5111 extendX : function(supr, fn){
5112 return Ext.extend(supr, fn(supr.prototype));
5116 getDoc : function(){
5117 return Ext.get(document);
5121 num : function(v, defaultValue){
5122 v = Number(Ext.isEmpty(v) || Ext.isArray(v) || typeof v == 'boolean' || (typeof v == 'string' && v.trim().length == 0) ? NaN : v);
5123 return isNaN(v) ? defaultValue : v;
5127 value : function(v, defaultValue, allowBlank){
5128 return Ext.isEmpty(v, allowBlank) ? defaultValue : v;
5132 escapeRe : function(s) {
5133 return s.replace(/([-.*+?^${}()|[\]\/\\])/g, "\\$1");
5136 sequence : function(o, name, fn, scope){
5137 o[name] = o[name].createSequence(fn, scope);
5141 addBehaviors : function(o){
5143 Ext.onReady(function(){
5144 Ext.addBehaviors(o);
5152 if ((parts = b.split('@'))[1]) {
5155 cache[s] = Ext.select(s);
5157 cache[s].on(parts[1], o[b]);
5165 getScrollBarWidth: function(force){
5170 if(force === true || scrollWidth === null){
5172 var div = Ext.getBody().createChild('<div class="x-hide-offsets" style="width:100px;height:50px;overflow:hidden;"><div style="height:200px;"></div></div>'),
5173 child = div.child('div', true);
5174 var w1 = child.offsetWidth;
5175 div.setStyle('overflow', (Ext.isWebKit || Ext.isGecko) ? 'auto' : 'scroll');
5176 var w2 = child.offsetWidth;
5179 scrollWidth = w1 - w2 + 2;
5186 combine : function(){
5187 var as = arguments, l = as.length, r = [];
5188 for(var i = 0; i < l; i++){
5192 }else if(a.length !== undefined && !a.substr){
5193 r = r.concat(Array.prototype.slice.call(a, 0));
5202 copyTo : function(dest, source, names){
5203 if(typeof names == 'string'){
5204 names = names.split(/[,;\s]/);
5206 Ext.each(names, function(name){
5207 if(source.hasOwnProperty(name)){
5208 dest[name] = source[name];
5215 destroy : function(){
5216 Ext.each(arguments, function(arg){
5218 if(Ext.isArray(arg)){
5219 this.destroy.apply(this, arg);
5220 }else if(typeof arg.destroy == 'function'){
5230 destroyMembers : function(o, arg1, arg2, etc){
5231 for(var i = 1, a = arguments, len = a.length; i < len; i++) {
5232 Ext.destroy(o[a[i]]);
5238 clean : function(arr){
5240 Ext.each(arr, function(v){
5249 unique : function(arr){
5253 Ext.each(arr, function(v) {
5263 flatten : function(arr){
5265 function rFlatten(a) {
5266 Ext.each(a, function(v) {
5275 return rFlatten(arr);
5279 min : function(arr, comp){
5281 comp = comp || function(a,b){ return a < b ? -1 : 1; };
5282 Ext.each(arr, function(v) {
5283 ret = comp(ret, v) == -1 ? ret : v;
5289 max : function(arr, comp){
5291 comp = comp || function(a,b){ return a > b ? 1 : -1; };
5292 Ext.each(arr, function(v) {
5293 ret = comp(ret, v) == 1 ? ret : v;
5299 mean : function(arr){
5300 return arr.length > 0 ? Ext.sum(arr) / arr.length : undefined;
5304 sum : function(arr){
5306 Ext.each(arr, function(v) {
5313 partition : function(arr, truth){
5315 Ext.each(arr, function(v, i, a) {
5316 ret[ (truth && truth(v, i, a)) || (!truth && v) ? 0 : 1].push(v);
5322 invoke : function(arr, methodName){
5324 args = Array.prototype.slice.call(arguments, 2);
5325 Ext.each(arr, function(v,i) {
5326 if (v && typeof v[methodName] == 'function') {
5327 ret.push(v[methodName].apply(v, args));
5329 ret.push(undefined);
5336 pluck : function(arr, prop){
5338 Ext.each(arr, function(v) {
5339 ret.push( v[prop] );
5346 var parts = Ext.partition(arguments, function( val ){ return typeof val != 'function'; }),
5349 len = Ext.max(Ext.pluck(arrs, "length")),
5352 for (var i = 0; i < len; i++) {
5355 ret[i] = fn.apply(fn, Ext.pluck(arrs, i));
5357 for (var j = 0, aLen = arrs.length; j < aLen; j++){
5358 ret[i].push( arrs[j][i] );
5366 getCmp : function(id){
5367 return Ext.ComponentMgr.get(id);
5371 useShims: E.isIE6 || (E.isMac && E.isGecko2),
5376 if(o === undefined || o === null){
5383 if(t == 'object' && o.nodeName) {
5384 switch(o.nodeType) {
5385 case 1: return 'element';
5386 case 3: return (/\S/).test(o.nodeValue) ? 'textnode' : 'whitespace';
5389 if(t == 'object' || t == 'function') {
5390 switch(o.constructor) {
5391 case Array: return 'array';
5392 case RegExp: return 'regexp';
5393 case Date: return 'date';
5395 if(typeof o.length == 'number' && typeof o.item == 'function') {
5402 intercept : function(o, name, fn, scope){
5403 o[name] = o[name].createInterceptor(fn, scope);
5407 callback : function(cb, scope, args, delay){
5408 if(typeof cb == 'function'){
5410 cb.defer(delay, scope, args || []);
5412 cb.apply(scope, args || []);
5420 Ext.apply(Function.prototype, {
5422 createSequence : function(fcn, scope){
5424 return (typeof fcn != 'function') ?
5427 var retval = method.apply(this || window, arguments);
5428 fcn.apply(scope || this || window, arguments);
5436 Ext.applyIf(String, {
5439 escape : function(string) {
5440 return string.replace(/('|\\)/g, "\\$1");
5444 leftPad : function (val, size, ch) {
5445 var result = String(val);
5449 while (result.length < size) {
5450 result = ch + result;
5457 String.prototype.toggle = function(value, other){
5458 return this == value ? other : value;
5462 String.prototype.trim = function(){
5463 var re = /^\s+|\s+$/g;
5464 return function(){ return this.replace(re, ""); };
5469 Date.prototype.getElapsed = function(date) {
5470 return Math.abs((date || new Date()).getTime()-this.getTime());
5475 Ext.applyIf(Number.prototype, {
5477 constrain : function(min, max){
5478 return Math.min(Math.max(this, min), max);
5481 Ext.lib.Dom.getRegion = function(el) {
5482 return Ext.lib.Region.getRegion(el);
5483 }; Ext.lib.Region = function(t, r, b, l) {
5493 Ext.lib.Region.prototype = {
5494 contains : function(region) {
5496 return ( region.left >= me.left &&
5497 region.right <= me.right &&
5498 region.top >= me.top &&
5499 region.bottom <= me.bottom );
5503 getArea : function() {
5505 return ( (me.bottom - me.top) * (me.right - me.left) );
5508 intersect : function(region) {
5510 t = Math.max(me.top, region.top),
5511 r = Math.min(me.right, region.right),
5512 b = Math.min(me.bottom, region.bottom),
5513 l = Math.max(me.left, region.left);
5515 if (b >= t && r >= l) {
5516 return new Ext.lib.Region(t, r, b, l);
5520 union : function(region) {
5522 t = Math.min(me.top, region.top),
5523 r = Math.max(me.right, region.right),
5524 b = Math.max(me.bottom, region.bottom),
5525 l = Math.min(me.left, region.left);
5527 return new Ext.lib.Region(t, r, b, l);
5530 constrainTo : function(r) {
5532 me.top = me.top.constrain(r.top, r.bottom);
5533 me.bottom = me.bottom.constrain(r.top, r.bottom);
5534 me.left = me.left.constrain(r.left, r.right);
5535 me.right = me.right.constrain(r.left, r.right);
5539 adjust : function(t, l, b, r) {
5549 Ext.lib.Region.getRegion = function(el) {
5550 var p = Ext.lib.Dom.getXY(el),
5552 r = p[0] + el.offsetWidth,
5553 b = p[1] + el.offsetHeight,
5556 return new Ext.lib.Region(t, r, b, l);
5557 }; Ext.lib.Point = function(x, y) {
5558 if (Ext.isArray(x)) {
5563 me.x = me.right = me.left = me[0] = x;
5564 me.y = me.top = me.bottom = me[1] = y;
5567 Ext.lib.Point.prototype = new Ext.lib.Region();
5569 Ext.apply(Ext.DomHelper,
5572 afterbegin = 'afterbegin',
5573 afterend = 'afterend',
5574 beforebegin = 'beforebegin',
5575 beforeend = 'beforeend',
5576 confRe = /tag|children|cn|html$/i;
5579 function doInsert(el, o, returnElement, pos, sibling, append){
5580 el = Ext.getDom(el);
5583 newNode = createDom(o, null);
5585 el.appendChild(newNode);
5587 (sibling == 'firstChild' ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
5590 newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
5592 return returnElement ? Ext.get(newNode, true) : newNode;
5597 function createDom(o, parentNode){
5605 if (Ext.isArray(o)) {
5606 el = doc.createDocumentFragment();
5607 for (var i = 0, l = o.length; i < l; i++) {
5608 createDom(o[i], el);
5610 } else if (typeof o == 'string') {
5611 el = doc.createTextNode(o);
5613 el = doc.createElement( o.tag || 'div' );
5614 useSet = !!el.setAttribute;
5615 for (var attr in o) {
5616 if(!confRe.test(attr)){
5622 el.setAttribute(attr, val);
5629 Ext.DomHelper.applyStyles(el, o.style);
5631 if ((cn = o.children || o.cn)) {
5633 } else if (o.html) {
5634 el.innerHTML = o.html;
5638 parentNode.appendChild(el);
5645 createTemplate : function(o){
5646 var html = Ext.DomHelper.createHtml(o);
5647 return new Ext.Template(html);
5654 insertBefore : function(el, o, returnElement){
5655 return doInsert(el, o, returnElement, beforebegin);
5659 insertAfter : function(el, o, returnElement){
5660 return doInsert(el, o, returnElement, afterend, 'nextSibling');
5664 insertFirst : function(el, o, returnElement){
5665 return doInsert(el, o, returnElement, afterbegin, 'firstChild');
5669 append: function(el, o, returnElement){
5670 return doInsert(el, o, returnElement, beforeend, '', true);
5674 createDom: createDom
5679 Ext.apply(Ext.Template.prototype, {
5681 disableFormats : false,
5685 re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
5686 argsRe : /^\s*['"](.*)["']\s*$/,
5688 compileBRe : /(\r\n|\n)/g,
5692 * Returns an HTML fragment of this template with the specified values applied.
5693 * @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'})
5694 * @return {String} The HTML fragment
5697 applyTemplate : function(values){
5699 useF = me.disableFormats !== true,
5700 fm = Ext.util.Format,
5704 return me.compiled(values);
5706 function fn(m, name, format, args){
5707 if (format && useF) {
5708 if (format.substr(0, 5) == "this.") {
5709 return tpl.call(format.substr(5), values[name], values);
5712 // quoted values are required for strings in compiled templates,
5713 // but for non compiled we need to strip them
5714 // quoted reversed for jsmin
5716 args = args.split(',');
5717 for(var i = 0, len = args.length; i < len; i++){
5718 args[i] = args[i].replace(re, "$1");
5720 args = [values[name]].concat(args);
5722 args = [values[name]];
5724 return fm[format].apply(fm, args);
5727 return values[name] !== undefined ? values[name] : "";
5730 return me.html.replace(me.re, fn);
5734 * Compiles the template into an internal function, eliminating the RegEx overhead.
5735 * @return {Ext.Template} this
5738 compile : function(){
5740 fm = Ext.util.Format,
5741 useF = me.disableFormats !== true,
5742 sep = Ext.isGecko ? "+" : ",",
5745 function fn(m, name, format, args){
5747 args = args ? ',' + args : "";
5748 if(format.substr(0, 5) != "this."){
5749 format = "fm." + format + '(';
5751 format = 'this.call("'+ format.substr(5) + '", ';
5755 args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
5757 return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
5760 // branched to use + in gecko and [].join() in others
5762 body = "this.compiled = function(values){ return '" +
5763 me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn) +
5766 body = ["this.compiled = function(values){ return ['"];
5767 body.push(me.html.replace(me.compileARe, '\\\\').replace(me.compileBRe, '\\n').replace(me.compileCRe, "\\'").replace(me.re, fn));
5768 body.push("'].join('');};");
5769 body = body.join('');
5775 // private function used to call members
5776 call : function(fnName, value, allValues){
5777 return this[fnName](value, allValues);
5780 Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
5782 * @class Ext.util.Functions
5785 Ext.util.Functions = {
5787 * Creates an interceptor function. The passed function is called before the original one. If it returns false,
5788 * the original one is not called. The resulting function returns the results of the original function.
5789 * The passed function is called with the parameters of the original function. Example usage:
5791 var sayHi = function(name){
5792 alert('Hi, ' + name);
5795 sayHi('Fred'); // alerts "Hi, Fred"
5797 // create a new function that validates input without
5798 // directly modifying the original function:
5799 var sayHiToFriend = Ext.createInterceptor(sayHi, function(name){
5800 return name == 'Brian';
5803 sayHiToFriend('Fred'); // no alert
5804 sayHiToFriend('Brian'); // alerts "Hi, Brian"
5806 * @param {Function} origFn The original function.
5807 * @param {Function} newFn The function to call before the original
5808 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
5809 * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
5810 * @return {Function} The new function
5812 createInterceptor: function(origFn, newFn, scope) {
5813 var method = origFn;
5814 if (!Ext.isFunction(newFn)) {
5822 newFn.method = origFn;
5823 return (newFn.apply(scope || me || window, args) !== false) ?
5824 origFn.apply(me || window, args) :
5831 * Creates a delegate (callback) that sets the scope to obj.
5832 * Call directly on any function. Example: <code>Ext.createDelegate(this.myFunction, this, [arg1, arg2])</code>
5833 * Will create a function that is automatically scoped to obj so that the <tt>this</tt> variable inside the
5834 * callback points to obj. Example usage:
5836 var sayHi = function(name){
5837 // Note this use of "this.text" here. This function expects to
5838 // execute within a scope that contains a text property. In this
5839 // example, the "this" variable is pointing to the btn object that
5840 // was passed in createDelegate below.
5841 alert('Hi, ' + name + '. You clicked the "' + this.text + '" button.');
5844 var btn = new Ext.Button({
5846 renderTo: Ext.getBody()
5849 // This callback will execute in the scope of the
5850 // button instance. Clicking the button alerts
5851 // "Hi, Fred. You clicked the "Say Hi" button."
5852 btn.on('click', Ext.createDelegate(sayHi, btn, ['Fred']));
5854 * @param {Function} fn The function to delegate.
5855 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
5856 * <b>If omitted, defaults to the browser window.</b>
5857 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
5858 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
5859 * if a number the args are inserted at the specified position
5860 * @return {Function} The new function
5862 createDelegate: function(fn, obj, args, appendArgs) {
5863 if (!Ext.isFunction(fn)) {
5867 var callArgs = args || arguments;
5868 if (appendArgs === true) {
5869 callArgs = Array.prototype.slice.call(arguments, 0);
5870 callArgs = callArgs.concat(args);
5872 else if (Ext.isNumber(appendArgs)) {
5873 callArgs = Array.prototype.slice.call(arguments, 0);
5874 // copy arguments first
5875 var applyArgs = [appendArgs, 0].concat(args);
5876 // create method call params
5877 Array.prototype.splice.apply(callArgs, applyArgs);
5880 return fn.apply(obj || window, callArgs);
5885 * Calls this function after the number of millseconds specified, optionally in a specific scope. Example usage:
5887 var sayHi = function(name){
5888 alert('Hi, ' + name);
5891 // executes immediately:
5894 // executes after 2 seconds:
5895 Ext.defer(sayHi, 2000, this, ['Fred']);
5897 // this syntax is sometimes useful for deferring
5898 // execution of an anonymous function:
5899 Ext.defer(function(){
5903 * @param {Function} fn The function to defer.
5904 * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
5905 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
5906 * <b>If omitted, defaults to the browser window.</b>
5907 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
5908 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
5909 * if a number the args are inserted at the specified position
5910 * @return {Number} The timeout id that can be used with clearTimeout
5912 defer: function(fn, millis, obj, args, appendArgs) {
5913 fn = Ext.util.Functions.createDelegate(fn, obj, args, appendArgs);
5915 return setTimeout(fn, millis);
5923 * Create a combined function call sequence of the original function + the passed function.
5924 * The resulting function returns the results of the original function.
5925 * The passed fcn is called with the parameters of the original function. Example usage:
5928 var sayHi = function(name){
5929 alert('Hi, ' + name);
5932 sayHi('Fred'); // alerts "Hi, Fred"
5934 var sayGoodbye = Ext.createSequence(sayHi, function(name){
5935 alert('Bye, ' + name);
5938 sayGoodbye('Fred'); // both alerts show
5940 * @param {Function} origFn The original function.
5941 * @param {Function} newFn The function to sequence
5942 * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
5943 * If omitted, defaults to the scope in which the original function is called or the browser window.
5944 * @return {Function} The new function
5946 createSequence: function(origFn, newFn, scope) {
5947 if (!Ext.isFunction(newFn)) {
5952 var retval = origFn.apply(this || window, arguments);
5953 newFn.apply(scope || this || window, arguments);
5961 * Shorthand for {@link Ext.util.Functions#defer}
5962 * @param {Function} fn The function to defer.
5963 * @param {Number} millis The number of milliseconds for the setTimeout call (if less than or equal to 0 the function is executed immediately)
5964 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
5965 * <b>If omitted, defaults to the browser window.</b>
5966 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
5967 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
5968 * if a number the args are inserted at the specified position
5969 * @return {Number} The timeout id that can be used with clearTimeout
5974 Ext.defer = Ext.util.Functions.defer;
5977 * Shorthand for {@link Ext.util.Functions#createInterceptor}
5978 * @param {Function} origFn The original function.
5979 * @param {Function} newFn The function to call before the original
5980 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the passed function is executed.
5981 * <b>If omitted, defaults to the scope in which the original function is called or the browser window.</b>
5982 * @return {Function} The new function
5987 Ext.createInterceptor = Ext.util.Functions.createInterceptor;
5990 * Shorthand for {@link Ext.util.Functions#createSequence}
5991 * @param {Function} origFn The original function.
5992 * @param {Function} newFn The function to sequence
5993 * @param {Object} scope (optional) The scope (this reference) in which the passed function is executed.
5994 * If omitted, defaults to the scope in which the original function is called or the browser window.
5995 * @return {Function} The new function
6000 Ext.createSequence = Ext.util.Functions.createSequence;
6003 * Shorthand for {@link Ext.util.Functions#createDelegate}
6004 * @param {Function} fn The function to delegate.
6005 * @param {Object} scope (optional) The scope (<code><b>this</b></code> reference) in which the function is executed.
6006 * <b>If omitted, defaults to the browser window.</b>
6007 * @param {Array} args (optional) Overrides arguments for the call. (Defaults to the arguments passed by the caller)
6008 * @param {Boolean/Number} appendArgs (optional) if True args are appended to call args instead of overriding,
6009 * if a number the args are inserted at the specified position
6010 * @return {Function} The new function
6014 Ext.createDelegate = Ext.util.Functions.createDelegate;
6016 * @class Ext.util.Observable
6018 Ext.apply(Ext.util.Observable.prototype, function(){
6019 // this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?)
6020 // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
6022 function getMethodEvent(method){
6023 var e = (this.methodEvents = this.methodEvents ||
6024 {})[method], returnValue, v, cancel, obj = this;
6027 this.methodEvents[method] = e = {};
6028 e.originalFn = this[method];
6029 e.methodName = method;
6033 var makeCall = function(fn, scope, args){
6034 if((v = fn.apply(scope || obj, args)) !== undefined){
6035 if (typeof v == 'object') {
6036 if(v.returnValue !== undefined){
6037 returnValue = v.returnValue;
6041 cancel = !!v.cancel;
6053 this[method] = function(){
6054 var args = Array.prototype.slice.call(arguments, 0),
6056 returnValue = v = undefined;
6059 for(var i = 0, len = e.before.length; i < len; i++){
6061 makeCall(b.fn, b.scope, args);
6067 if((v = e.originalFn.apply(obj, args)) !== undefined){
6071 for(var i = 0, len = e.after.length; i < len; i++){
6073 makeCall(b.fn, b.scope, args);
6085 // these are considered experimental
6086 // allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
6087 // adds an 'interceptor' called before the original method
6088 beforeMethod : function(method, fn, scope){
6089 getMethodEvent.call(this, method).before.push({
6095 // adds a 'sequence' called after the original method
6096 afterMethod : function(method, fn, scope){
6097 getMethodEvent.call(this, method).after.push({
6103 removeMethodListener: function(method, fn, scope){
6104 var e = this.getMethodEvent(method);
6105 for(var i = 0, len = e.before.length; i < len; i++){
6106 if(e.before[i].fn == fn && e.before[i].scope == scope){
6107 e.before.splice(i, 1);
6111 for(var i = 0, len = e.after.length; i < len; i++){
6112 if(e.after[i].fn == fn && e.after[i].scope == scope){
6113 e.after.splice(i, 1);
6120 * Relays selected events from the specified Observable as if the events were fired by <tt><b>this</b></tt>.
6121 * @param {Object} o The Observable whose events this object is to relay.
6122 * @param {Array} events Array of event names to relay.
6124 relayEvents : function(o, events){
6126 function createHandler(ename){
6128 return me.fireEvent.apply(me, [ename].concat(Array.prototype.slice.call(arguments, 0)));
6131 for(var i = 0, len = events.length; i < len; i++){
6132 var ename = events[i];
6133 me.events[ename] = me.events[ename] || true;
6134 o.on(ename, createHandler(ename), me);
6139 * <p>Enables events fired by this Observable to bubble up an owner hierarchy by calling
6140 * <code>this.getBubbleTarget()</code> if present. There is no implementation in the Observable base class.</p>
6141 * <p>This is commonly used by Ext.Components to bubble events to owner Containers. See {@link Ext.Component.getBubbleTarget}. The default
6142 * implementation in Ext.Component returns the Component's immediate owner. But if a known target is required, this can be overridden to
6143 * access the required target more quickly.</p>
6144 * <p>Example:</p><pre><code>
6145 Ext.override(Ext.form.Field, {
6147 initComponent : Ext.form.Field.prototype.initComponent.createSequence(function() {
6148 this.enableBubble('change');
6152 getBubbleTarget : function() {
6153 if (!this.formPanel) {
6154 this.formPanel = this.findParentByType('form');
6156 return this.formPanel;
6160 var myForm = new Ext.formPanel({
6161 title: 'User Details',
6166 change: function() {
6168 myForm.header.setStyle('color', 'red');
6173 * @param {String/Array} events The event name to bubble, or an Array of event names.
6175 enableBubble : function(events){
6177 if(!Ext.isEmpty(events)){
6178 events = Ext.isArray(events) ? events : Array.prototype.slice.call(arguments, 0);
6179 for(var i = 0, len = events.length; i < len; i++){
6180 var ename = events[i];
6181 ename = ename.toLowerCase();
6182 var ce = me.events[ename] || true;
6183 if (typeof ce == 'boolean') {
6184 ce = new Ext.util.Event(me, ename);
6185 me.events[ename] = ce;
6196 Ext.util.Observable.capture = function(o, fn, scope){
6197 o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
6202 Ext.util.Observable.observeClass = function(c, listeners){
6205 Ext.apply(c, new Ext.util.Observable());
6206 Ext.util.Observable.capture(c.prototype, c.fireEvent, c);
6208 if(typeof listeners == 'object'){
6215 Ext.apply(Ext.EventManager, function(){
6221 propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/,
6227 useKeydown = Ext.isWebKit ?
6228 Ext.num(navigator.userAgent.match(/AppleWebKit\/(\d+)/)[1]) >= 525 :
6229 !((Ext.isGecko && !Ext.isWindows) || Ext.isOpera);
6233 doResizeEvent: function(){
6234 var h = D.getViewHeight(),
6235 w = D.getViewWidth();
6238 if(curHeight != h || curWidth != w){
6239 resizeEvent.fire(curWidth = w, curHeight = h);
6244 onWindowResize : function(fn, scope, options){
6246 resizeEvent = new Ext.util.Event();
6247 resizeTask = new Ext.util.DelayedTask(this.doResizeEvent);
6248 Ext.EventManager.on(window, "resize", this.fireWindowResize, this);
6250 resizeEvent.addListener(fn, scope, options);
6254 fireWindowResize : function(){
6256 resizeTask.delay(100);
6261 onTextResize : function(fn, scope, options){
6263 textEvent = new Ext.util.Event();
6264 var textEl = new Ext.Element(document.createElement('div'));
6265 textEl.dom.className = 'x-text-resize';
6266 textEl.dom.innerHTML = 'X';
6267 textEl.appendTo(document.body);
6268 textSize = textEl.dom.offsetHeight;
6269 setInterval(function(){
6270 if(textEl.dom.offsetHeight != textSize){
6271 textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
6273 }, this.textResizeInterval);
6275 textEvent.addListener(fn, scope, options);
6279 removeResizeListener : function(fn, scope){
6281 resizeEvent.removeListener(fn, scope);
6286 fireResize : function(){
6288 resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
6293 textResizeInterval : 50,
6299 getKeyEvent : function(){
6300 return useKeydown ? 'keydown' : 'keypress';
6305 useKeydown: useKeydown
6309 Ext.EventManager.on = Ext.EventManager.addListener;
6312 Ext.apply(Ext.EventObjectImpl.prototype, {
6492 isNavKeyPress : function(){
6494 k = this.normalizeKey(me.keyCode);
6495 return (k >= 33 && k <= 40) ||
6501 isSpecialKey : function(){
6502 var k = this.normalizeKey(this.keyCode);
6503 return (this.type == 'keypress' && this.ctrlKey) ||
6504 this.isNavKeyPress() ||
6505 (k == this.BACKSPACE) ||
6506 (k >= 16 && k <= 20) ||
6507 (k >= 44 && k <= 46);
6510 getPoint : function(){
6511 return new Ext.lib.Point(this.xy[0], this.xy[1]);
6515 hasModifier : function(){
6516 return ((this.ctrlKey || this.altKey) || this.shiftKey);
6519 Ext.Element.addMethods({
6521 swallowEvent : function(eventName, preventDefault) {
6524 e.stopPropagation();
6525 if (preventDefault) {
6530 if (Ext.isArray(eventName)) {
6531 Ext.each(eventName, function(e) {
6536 me.on(eventName, fn);
6541 relayEvent : function(eventName, observable) {
6542 this.on(eventName, function(e) {
6543 observable.fireEvent(eventName, e);
6548 clean : function(forceReclean) {
6554 if (Ext.Element.data(dom, 'isCleaned') && forceReclean !== true) {
6559 var nx = n.nextSibling;
6560 if (n.nodeType == 3 && !(/\S/.test(n.nodeValue))) {
6568 Ext.Element.data(dom, 'isCleaned', true);
6574 var updateManager = this.getUpdater();
6575 updateManager.update.apply(updateManager, arguments);
6581 getUpdater : function() {
6582 return this.updateManager || (this.updateManager = new Ext.Updater(this));
6586 update : function(html, loadScripts, callback) {
6592 if (loadScripts !== true) {
6593 this.dom.innerHTML = html;
6594 if (typeof callback == 'function') {
6603 html += '<span id="' + id + '"></span>';
6605 Ext.lib.Event.onAvailable(id, function() {
6607 hd = DOC.getElementsByTagName("head")[0],
6608 re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
6609 srcRe = /\ssrc=([\'\"])(.*?)\1/i,
6610 typeRe = /\stype=([\'\"])(.*?)\1/i,
6618 while ((match = re.exec(html))) {
6620 srcMatch = attrs ? attrs.match(srcRe) : false;
6621 if (srcMatch && srcMatch[2]) {
6622 s = DOC.createElement("script");
6623 s.src = srcMatch[2];
6624 typeMatch = attrs.match(typeRe);
6625 if (typeMatch && typeMatch[2]) {
6626 s.type = typeMatch[2];
6629 } else if (match[2] && match[2].length > 0) {
6630 if (window.execScript) {
6631 window.execScript(match[2]);
6633 window.eval(match[2]);
6638 el = DOC.getElementById(id);
6643 if (typeof callback == 'function') {
6647 dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
6652 removeAllListeners : function() {
6653 this.removeAnchor();
6654 Ext.EventManager.removeAll(this.dom);
6659 createProxy : function(config, renderTo, matchBox) {
6660 config = (typeof config == 'object') ? config : {tag : "div", cls: config};
6663 proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
6664 Ext.DomHelper.insertBefore(me.dom, config, true);
6666 if (matchBox && me.setBox && me.getBox) {
6667 proxy.setBox(me.getBox());
6673 Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater;
6675 Ext.Element.addMethods({
6677 getAnchorXY : function(anchor, local, s){
6680 anchor = (anchor || "tl").toLowerCase();
6684 vp = me.dom == document.body || me.dom == document,
6685 w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
6686 h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),
6690 scroll = me.getScroll(),
6691 extraX = vp ? scroll.left : !local ? o[0] : 0,
6692 extraY = vp ? scroll.top : !local ? o[1] : 0,
6694 c : [r(w * 0.5), r(h * 0.5)],
6695 t : [r(w * 0.5), 0],
6696 l : [0, r(h * 0.5)],
6697 r : [w, r(h * 0.5)],
6698 b : [r(w * 0.5), h],
6706 return [xy[0] + extraX, xy[1] + extraY];
6710 anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){
6713 scroll = !Ext.isEmpty(monitorScroll),
6714 action = function(){
6715 Ext.fly(dom).alignTo(el, alignment, offsets, animate);
6716 Ext.callback(callback, Ext.fly(dom));
6718 anchor = this.getAnchor();
6721 this.removeAnchor();
6727 Ext.EventManager.onWindowResize(action, null);
6730 Ext.EventManager.on(window, 'scroll', action, null,
6731 {buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
6738 removeAnchor : function(){
6740 anchor = this.getAnchor();
6742 if(anchor && anchor.fn){
6743 Ext.EventManager.removeResizeListener(anchor.fn);
6745 Ext.EventManager.un(window, 'scroll', anchor.fn);
6753 getAnchor : function(){
6754 var data = Ext.Element.data,
6759 var anchor = data(dom, '_anchor');
6762 anchor = data(dom, '_anchor', {});
6768 getAlignToXY : function(el, p, o){
6772 throw "Element.alignToXY with an element that doesn't exist";
6776 p = (!p || p == "?" ? "tl-bl?" : (!(/-/).test(p) && p !== "" ? "tl-" + p : p || "tl-bl")).toLowerCase();
6788 dw = Ext.lib.Dom.getViewWidth() -10,
6789 dh = Ext.lib.Dom.getViewHeight()-10,
6797 docElement = doc.documentElement,
6799 scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
6800 scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
6804 m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/);
6807 throw "Element.alignTo with an invalid alignment " + p;
6816 a1 = me.getAnchorXY(p1, true);
6817 a2 = el.getAnchorXY(p2, false);
6819 x = a2[0] - a1[0] + o[0];
6820 y = a2[1] - a1[1] + o[1];
6830 p1x = p1.charAt(p1.length-1);
6832 p2x = p2.charAt(p2.length-1);
6833 swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
6834 swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));
6837 if (x + w > dw + scrollX) {
6838 x = swapX ? r.left-w : dw+scrollX-w;
6841 x = swapX ? r.right : scrollX;
6843 if (y + h > dh + scrollY) {
6844 y = swapY ? r.top-h : dh+scrollY-h;
6847 y = swapY ? r.bottom : scrollY;
6854 alignTo : function(element, position, offsets, animate){
6856 return me.setXY(me.getAlignToXY(element, position, offsets),
6857 me.preanim && !!animate ? me.preanim(arguments, 3) : false);
6861 adjustForConstraints : function(xy, parent, offsets){
6862 return this.getConstrainToXY(parent || document, false, offsets, xy) || xy;
6866 getConstrainToXY : function(el, local, offsets, proposedXY){
6867 var os = {top:0, left:0, bottom:0, right: 0};
6869 return function(el, local, offsets, proposedXY){
6871 offsets = offsets ? Ext.applyIf(offsets, os) : os;
6873 var vw, vh, vx = 0, vy = 0;
6874 if(el.dom == document.body || el.dom == document){
6875 vw =Ext.lib.Dom.getViewWidth();
6876 vh = Ext.lib.Dom.getViewHeight();
6878 vw = el.dom.clientWidth;
6879 vh = el.dom.clientHeight;
6881 var vxy = el.getXY();
6887 var s = el.getScroll();
6889 vx += offsets.left + s.left;
6890 vy += offsets.top + s.top;
6892 vw -= offsets.right;
6893 vh -= offsets.bottom;
6897 xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]),
6898 x = xy[0], y = xy[1],
6899 offset = this.getConstrainOffset(),
6900 w = this.dom.offsetWidth + offset,
6901 h = this.dom.offsetHeight + offset;
6924 return moved ? [x, y] : false;
6984 getConstrainOffset : function(){
6989 getCenterXY : function(){
6990 return this.getAlignToXY(document, 'c-c');
6994 center : function(centerIn){
6995 return this.alignTo(centerIn || document, 'c-c');
6999 Ext.Element.addMethods({
7001 select : function(selector, unique){
7002 return Ext.Element.select(selector, unique, this.dom);
7005 Ext.apply(Ext.Element.prototype, function() {
7006 var GETDOM = Ext.getDom,
7012 insertSibling: function(el, where, returnDom){
7015 isAfter = (where || 'before').toLowerCase() == 'after',
7018 if(Ext.isArray(el)){
7020 Ext.each(el, function(e) {
7021 rt = Ext.fly(insertEl, '_internal').insertSibling(e, where, returnDom);
7031 if(el.nodeType || el.dom){
7032 rt = me.dom.parentNode.insertBefore(GETDOM(el), isAfter ? me.dom.nextSibling : me.dom);
7037 if (isAfter && !me.dom.nextSibling) {
7038 rt = DH.append(me.dom.parentNode, el, !returnDom);
7040 rt = DH[isAfter ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
7049 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>';
7051 Ext.Element.addMethods(function(){
7052 var INTERNAL = "_internal",
7053 pxMatch = /(\d+\.?\d+)px/;
7056 applyStyles : function(style){
7057 Ext.DomHelper.applyStyles(this.dom, style);
7062 getStyles : function(){
7064 Ext.each(arguments, function(v) {
7065 ret[v] = this.getStyle(v);
7072 setOverflow : function(v){
7074 if(v=='auto' && Ext.isMac && Ext.isGecko2){
7075 dom.style.overflow = 'hidden';
7076 (function(){dom.style.overflow = 'auto';}).defer(1);
7078 dom.style.overflow = v;
7083 boxWrap : function(cls){
7084 cls = cls || 'x-box';
7085 var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>"));
7086 Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
7091 setSize : function(width, height, animate){
7093 if(typeof width == 'object'){
7094 height = width.height;
7095 width = width.width;
7097 width = me.adjustWidth(width);
7098 height = me.adjustHeight(height);
7099 if(!animate || !me.anim){
7100 me.dom.style.width = me.addUnits(width);
7101 me.dom.style.height = me.addUnits(height);
7103 me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));
7109 getComputedHeight : function(){
7111 h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
7113 h = parseFloat(me.getStyle('height')) || 0;
7114 if(!me.isBorderBox()){
7115 h += me.getFrameWidth('tb');
7122 getComputedWidth : function(){
7123 var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
7125 w = parseFloat(this.getStyle('width')) || 0;
7126 if(!this.isBorderBox()){
7127 w += this.getFrameWidth('lr');
7134 getFrameWidth : function(sides, onlyContentBox){
7135 return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
7139 addClassOnOver : function(className){
7142 Ext.fly(this, INTERNAL).addClass(className);
7145 Ext.fly(this, INTERNAL).removeClass(className);
7152 addClassOnFocus : function(className){
7153 this.on("focus", function(){
7154 Ext.fly(this, INTERNAL).addClass(className);
7156 this.on("blur", function(){
7157 Ext.fly(this, INTERNAL).removeClass(className);
7163 addClassOnClick : function(className){
7165 this.on("mousedown", function(){
7166 Ext.fly(dom, INTERNAL).addClass(className);
7167 var d = Ext.getDoc(),
7169 Ext.fly(dom, INTERNAL).removeClass(className);
7170 d.removeListener("mouseup", fn);
7172 d.on("mouseup", fn);
7179 getViewSize : function(){
7182 isDoc = (d == doc || d == doc.body);
7186 var extdom = Ext.lib.Dom;
7188 width : extdom.getViewWidth(),
7189 height : extdom.getViewHeight()
7195 width : d.clientWidth,
7196 height : d.clientHeight
7203 getStyleSize : function(){
7208 isDoc = (d == doc || d == doc.body),
7213 var extdom = Ext.lib.Dom;
7215 width : extdom.getViewWidth(),
7216 height : extdom.getViewHeight()
7220 if(s.width && s.width != 'auto'){
7221 w = parseFloat(s.width);
7222 if(me.isBorderBox()){
7223 w -= me.getFrameWidth('lr');
7227 if(s.height && s.height != 'auto'){
7228 h = parseFloat(s.height);
7229 if(me.isBorderBox()){
7230 h -= me.getFrameWidth('tb');
7234 return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
7238 getSize : function(contentSize){
7239 return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
7243 repaint : function(){
7245 this.addClass("x-repaint");
7246 setTimeout(function(){
7247 Ext.fly(dom).removeClass("x-repaint");
7253 unselectable : function(){
7254 this.dom.unselectable = "on";
7255 return this.swallowEvent("selectstart", true).
7256 applyStyles("-moz-user-select:none;-khtml-user-select:none;").
7257 addClass("x-unselectable");
7261 getMargins : function(side){
7264 hash = {t:"top", l:"left", r:"right", b: "bottom"},
7268 for (key in me.margins){
7269 o[hash[key]] = parseFloat(me.getStyle(me.margins[key])) || 0;
7273 return me.addStyles.call(me, side, me.margins);
7279 Ext.Element.addMethods({
7281 setBox : function(box, adjust, animate){
7285 if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){
7286 w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
7287 h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
7289 me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));
7294 getBox : function(contentBox, local) {
7299 getBorderWidth = me.getBorderWidth,
7300 getPadding = me.getPadding,
7308 left = parseInt(me.getStyle("left"), 10) || 0;
7309 top = parseInt(me.getStyle("top"), 10) || 0;
7312 var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
7314 bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
7316 l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
7317 r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
7318 t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
7319 b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
7320 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)};
7322 bx.right = bx.x + bx.width;
7323 bx.bottom = bx.y + bx.height;
7328 move : function(direction, distance, animate){
7333 left = [x - distance, y],
7334 right = [x + distance, y],
7335 top = [x, y - distance],
7336 bottom = [x, y + distance],
7350 direction = direction.toLowerCase();
7351 me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));
7355 setLeftTop : function(left, top){
7357 style = me.dom.style;
7358 style.left = me.addUnits(left);
7359 style.top = me.addUnits(top);
7364 getRegion : function(){
7365 return Ext.lib.Dom.getRegion(this.dom);
7369 setBounds : function(x, y, width, height, animate){
7371 if (!animate || !me.anim) {
7372 me.setSize(width, height);
7373 me.setLocation(x, y);
7375 me.anim({points: {to: [x, y]},
7376 width: {to: me.adjustWidth(width)},
7377 height: {to: me.adjustHeight(height)}},
7378 me.preanim(arguments, 4),
7385 setRegion : function(region, animate) {
7386 return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));
7389 Ext.Element.addMethods({
7391 scrollTo : function(side, value, animate) {
7393 var top = /top/i.test(side),
7397 if (!animate || !me.anim) {
7399 prop = 'scroll' + (top ? 'Top' : 'Left');
7404 prop = 'scroll' + (top ? 'Left' : 'Top');
7405 me.anim({scroll: {to: top ? [dom[prop], value] : [value, dom[prop]]}}, me.preanim(arguments, 2), 'scroll');
7411 scrollIntoView : function(container, hscroll) {
7412 var c = Ext.getDom(container) || Ext.getBody().dom,
7414 o = this.getOffsetsTo(c),
7415 l = o[0] + c.scrollLeft,
7416 t = o[1] + c.scrollTop,
7417 b = t + el.offsetHeight,
7418 r = l + el.offsetWidth,
7419 ch = c.clientHeight,
7420 ct = parseInt(c.scrollTop, 10),
7421 cl = parseInt(c.scrollLeft, 10),
7423 cr = cl + c.clientWidth;
7425 if (el.offsetHeight > ch || t < ct) {
7432 c.scrollTop = c.scrollTop;
7434 if (hscroll !== false) {
7435 if (el.offsetWidth > c.clientWidth || l < cl) {
7439 c.scrollLeft = r - c.clientWidth;
7441 c.scrollLeft = c.scrollLeft;
7447 scrollChildIntoView : function(child, hscroll) {
7448 Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
7452 scroll : function(direction, distance, animate) {
7453 if (!this.isScrollable()) {
7457 l = el.scrollLeft, t = el.scrollTop,
7458 w = el.scrollWidth, h = el.scrollHeight,
7459 cw = el.clientWidth, ch = el.clientHeight,
7460 scrolled = false, v,
7462 l: Math.min(l + distance, w-cw),
7463 r: v = Math.max(l - distance, 0),
7464 t: Math.max(t - distance, 0),
7465 b: Math.min(t + distance, h-ch)
7470 direction = direction.substr(0, 1);
7471 if ((v = hash[direction]) > -1) {
7473 this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2));
7478 Ext.Element.addMethods(
7480 var VISIBILITY = "visibility",
7481 DISPLAY = "display",
7484 XMASKED = "x-masked",
7485 XMASKEDRELATIVE = "x-masked-relative",
7486 data = Ext.Element.data;
7490 isVisible : function(deep) {
7491 var vis = !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE),
7492 p = this.dom.parentNode;
7494 if (deep !== true || !vis) {
7498 while (p && !(/^body/i.test(p.tagName))) {
7499 if (!Ext.fly(p, '_isVisible').isVisible()) {
7508 isDisplayed : function() {
7509 return !this.isStyle(DISPLAY, NONE);
7513 enableDisplayMode : function(display) {
7514 this.setVisibilityMode(Ext.Element.DISPLAY);
7516 if (!Ext.isEmpty(display)) {
7517 data(this.dom, 'originalDisplay', display);
7524 mask : function(msg, msgCls) {
7528 EXTELMASKMSG = "ext-el-mask-msg",
7532 if (!(/^body/i.test(dom.tagName) && me.getStyle('position') == 'static')) {
7533 me.addClass(XMASKEDRELATIVE);
7535 if (el = data(dom, 'maskMsg')) {
7538 if (el = data(dom, 'mask')) {
7542 mask = dh.append(dom, {cls : "ext-el-mask"}, true);
7543 data(dom, 'mask', mask);
7545 me.addClass(XMASKED);
7546 mask.setDisplayed(true);
7548 if (typeof msg == 'string') {
7549 var mm = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);
7550 data(dom, 'maskMsg', mm);
7551 mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;
7552 mm.dom.firstChild.innerHTML = msg;
7553 mm.setDisplayed(true);
7558 if (Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto') {
7559 mask.setSize(undefined, me.getHeight());
7566 unmask : function() {
7569 mask = data(dom, 'mask'),
7570 maskMsg = data(dom, 'maskMsg');
7575 data(dom, 'maskMsg', undefined);
7579 data(dom, 'mask', undefined);
7580 me.removeClass([XMASKED, XMASKEDRELATIVE]);
7585 isMasked : function() {
7586 var m = data(this.dom, 'mask');
7587 return m && m.isVisible();
7591 createShim : function() {
7592 var el = document.createElement('iframe'),
7595 el.frameBorder = '0';
7596 el.className = 'ext-shim';
7597 el.src = Ext.SSL_SECURE_URL;
7598 shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
7599 shim.autoBoxAdjust = false;
7605 Ext.Element.addMethods({
7607 addKeyListener : function(key, fn, scope){
7609 if(typeof key != 'object' || Ext.isArray(key)){
7625 return new Ext.KeyMap(this, config);
7629 addKeyMap : function(config){
7630 return new Ext.KeyMap(this, config);
7636 Ext.CompositeElementLite.importElementMethods();
7637 Ext.apply(Ext.CompositeElementLite.prototype, {
7638 addElements : function(els, root){
7642 if(typeof els == "string"){
7643 els = Ext.Element.selectorFunction(els, root);
7645 var yels = this.elements;
7646 Ext.each(els, function(e) {
7647 yels.push(Ext.get(e));
7654 return this.item(0);
7659 return this.item(this.getCount()-1);
7663 contains : function(el){
7664 return this.indexOf(el) != -1;
7668 removeElement : function(keys, removeDom){
7670 els = this.elements,
7672 Ext.each(keys, function(val){
7673 if ((el = (els[val] || els[val = me.indexOf(val)]))) {
7688 Ext.CompositeElement = Ext.extend(Ext.CompositeElementLite, {
7690 constructor : function(els, root){
7692 this.add(els, root);
7696 getElement : function(el){
7702 transformElement : function(el){
7714 Ext.Element.select = function(selector, unique, root){
7716 if(typeof selector == "string"){
7717 els = Ext.Element.selectorFunction(selector, root);
7718 }else if(selector.length !== undefined){
7721 throw "Invalid selector";
7724 return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
7728 Ext.select = Ext.Element.select;
7729 Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable,
7731 var BEFOREUPDATE = "beforeupdate",
7733 FAILURE = "failure";
7736 function processSuccess(response){
7738 me.transaction = null;
7739 if (response.argument.form && response.argument.reset) {
7741 response.argument.form.reset();
7744 if (me.loadScripts) {
7745 me.renderer.render(me.el, response, me,
7746 updateComplete.createDelegate(me, [response]));
7748 me.renderer.render(me.el, response, me);
7749 updateComplete.call(me, response);
7754 function updateComplete(response, type, success){
7755 this.fireEvent(type || UPDATE, this.el, response);
7756 if(Ext.isFunction(response.argument.callback)){
7757 response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);
7762 function processFailure(response){
7763 updateComplete.call(this, response, FAILURE, !!(this.transaction = null));
7767 constructor: function(el, forceNew){
7770 if(!forceNew && el.updateManager){
7771 return el.updateManager;
7776 me.defaultUrl = null;
7787 Ext.apply(me, Ext.Updater.defaults);
7796 me.transaction = null;
7798 me.refreshDelegate = me.refresh.createDelegate(me);
7800 me.updateDelegate = me.update.createDelegate(me);
7802 me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);
7805 me.renderer = me.renderer || me.getDefaultRenderer();
7807 Ext.Updater.superclass.constructor.call(me);
7811 setRenderer : function(renderer){
7812 this.renderer = renderer;
7816 getRenderer : function(){
7817 return this.renderer;
7821 getDefaultRenderer: function() {
7822 return new Ext.Updater.BasicRenderer();
7826 setDefaultUrl : function(defaultUrl){
7827 this.defaultUrl = defaultUrl;
7836 update : function(url, params, callback, discardUrl){
7841 if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){
7842 if(Ext.isObject(url)){
7845 params = params || cfg.params;
7846 callback = callback || cfg.callback;
7847 discardUrl = discardUrl || cfg.discardUrl;
7848 callerScope = cfg.scope;
7849 if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};
7850 if(!Ext.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
7851 if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};
7852 if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};
7857 me.defaultUrl = url;
7859 if(Ext.isFunction(url)){
7863 var o = Ext.apply({}, {
7865 params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,
7866 success: processSuccess,
7867 failure: processFailure,
7869 callback: undefined,
7870 timeout: (me.timeout*1000),
7871 disableCaching: me.disableCaching,
7876 "callback": callback,
7877 "scope": callerScope || window,
7882 me.transaction = Ext.Ajax.request(o);
7887 formUpdate : function(form, url, reset, callback){
7889 if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
7890 if(Ext.isFunction(url)){
7893 form = Ext.getDom(form);
7894 me.transaction = Ext.Ajax.request({
7897 success: processSuccess,
7898 failure: processFailure,
7900 timeout: (me.timeout*1000),
7904 "callback": callback,
7908 me.showLoading.defer(1, me);
7913 startAutoRefresh : function(interval, url, params, callback, refreshNow){
7916 me.update(url || me.defaultUrl, params, callback, true);
7918 if(me.autoRefreshProcId){
7919 clearInterval(me.autoRefreshProcId);
7921 me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);
7925 stopAutoRefresh : function(){
7926 if(this.autoRefreshProcId){
7927 clearInterval(this.autoRefreshProcId);
7928 delete this.autoRefreshProcId;
7933 isAutoRefreshing : function(){
7934 return !!this.autoRefreshProcId;
7938 showLoading : function(){
7939 if(this.showLoadIndicator){
7940 this.el.dom.innerHTML = this.indicatorText;
7946 if(this.transaction){
7947 Ext.Ajax.abort(this.transaction);
7952 isUpdating : function(){
7953 return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;
7957 refresh : function(callback){
7958 if(this.defaultUrl){
7959 this.update(this.defaultUrl, null, callback, true);
7966 Ext.Updater.defaults = {
7970 disableCaching : false,
7972 showLoadIndicator : true,
7974 indicatorText : '<div class="loading-indicator">Loading...</div>',
7976 loadScripts : false,
7978 sslBlankUrl : Ext.SSL_SECURE_URL
7983 Ext.Updater.updateElement = function(el, url, params, options){
7984 var um = Ext.get(el).getUpdater();
7985 Ext.apply(um, options);
7986 um.update(url, params, options ? options.callback : null);
7990 Ext.Updater.BasicRenderer = function(){};
7992 Ext.Updater.BasicRenderer.prototype = {
7994 render : function(el, response, updateManager, callback){
7995 el.update(response.responseText, updateManager.loadScripts, callback);
8004 Date.useStrict = false;
8010 function xf(format) {
8011 var args = Array.prototype.slice.call(arguments, 1);
8012 return format.replace(/\{(\d+)\}/g, function(m, i) {
8019 Date.formatCodeToRegex = function(character, currentGroup) {
8021 var p = Date.parseCodes[character];
8024 p = typeof p == 'function'? p() : p;
8025 Date.parseCodes[character] = p;
8028 return p ? Ext.applyIf({
8029 c: p.c ? xf(p.c, currentGroup || "{0}") : p.c
8033 s:Ext.escapeRe(character)
8038 var $f = Date.formatCodeToRegex;
8043 "M$": function(input, strict) {
8046 var re = new RegExp('\\/Date\\(([-+])?(\\d+)(?:[+-]\\d{4})?\\)\\/');
8047 var r = (input || '').match(re);
8048 return r? new Date(((r[1] || '') + r[2]) * 1) : null;
8057 return '\\/Date(' + this.getTime() + ')\\/';
8131 getShortMonthName : function(month) {
8132 return Date.monthNames[month].substring(0, 3);
8136 getShortDayName : function(day) {
8137 return Date.dayNames[day].substring(0, 3);
8141 getMonthNumber : function(name) {
8143 return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
8148 d: "String.leftPad(this.getDate(), 2, '0')",
8149 D: "Date.getShortDayName(this.getDay())",
8150 j: "this.getDate()",
8151 l: "Date.dayNames[this.getDay()]",
8152 N: "(this.getDay() ? this.getDay() : 7)",
8153 S: "this.getSuffix()",
8155 z: "this.getDayOfYear()",
8156 W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
8157 F: "Date.monthNames[this.getMonth()]",
8158 m: "String.leftPad(this.getMonth() + 1, 2, '0')",
8159 M: "Date.getShortMonthName(this.getMonth())",
8160 n: "(this.getMonth() + 1)",
8161 t: "this.getDaysInMonth()",
8162 L: "(this.isLeapYear() ? 1 : 0)",
8163 o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
8164 Y: "String.leftPad(this.getFullYear(), 4, '0')",
8165 y: "('' + this.getFullYear()).substring(2, 4)",
8166 a: "(this.getHours() < 12 ? 'am' : 'pm')",
8167 A: "(this.getHours() < 12 ? 'AM' : 'PM')",
8168 g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
8169 G: "this.getHours()",
8170 h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
8171 H: "String.leftPad(this.getHours(), 2, '0')",
8172 i: "String.leftPad(this.getMinutes(), 2, '0')",
8173 s: "String.leftPad(this.getSeconds(), 2, '0')",
8174 u: "String.leftPad(this.getMilliseconds(), 3, '0')",
8175 O: "this.getGMTOffset()",
8176 P: "this.getGMTOffset(true)",
8177 T: "this.getTimezone()",
8178 Z: "(this.getTimezoneOffset() * -60)",
8181 for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
8182 var e = c.charAt(i);
8183 code.push(e == "T" ? "'T'" : Date.getFormatCode(e));
8185 return code.join(" + ");
8189 U: "Math.round(this.getTime() / 1000)"
8193 isValid : function(y, m, d, h, i, s, ms) {
8201 var dt = new Date(y < 100 ? 100 : y, m - 1, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);
8203 return y == dt.getFullYear() &&
8204 m == dt.getMonth() + 1 &&
8205 d == dt.getDate() &&
8206 h == dt.getHours() &&
8207 i == dt.getMinutes() &&
8208 s == dt.getSeconds() &&
8209 ms == dt.getMilliseconds();
8213 parseDate : function(input, format, strict) {
8214 var p = Date.parseFunctions;
8215 if (p[format] == null) {
8216 Date.createParser(format);
8218 return p[format](input, Ext.isDefined(strict) ? strict : Date.useStrict);
8222 getFormatCode : function(character) {
8223 var f = Date.formatCodes[character];
8226 f = typeof f == 'function'? f() : f;
8227 Date.formatCodes[character] = f;
8231 return f || ("'" + String.escape(character) + "'");
8235 createFormat : function(format) {
8240 for (var i = 0; i < format.length; ++i) {
8241 ch = format.charAt(i);
8242 if (!special && ch == "\\") {
8244 } else if (special) {
8246 code.push("'" + String.escape(ch) + "'");
8248 code.push(Date.getFormatCode(ch));
8251 Date.formatFunctions[format] = new Function("return " + code.join('+'));
8255 createParser : function() {
8257 "var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",
8258 "def = Date.defaults,",
8259 "results = String(input).match(Date.parseRegexes[{0}]);",
8265 "v = new Date(u * 1000);",
8270 "dt = (new Date()).clearTime();",
8273 "y = Ext.num(y, Ext.num(def.y, dt.getFullYear()));",
8274 "m = Ext.num(m, Ext.num(def.m - 1, dt.getMonth()));",
8275 "d = Ext.num(d, Ext.num(def.d, dt.getDate()));",
8278 "h = Ext.num(h, Ext.num(def.h, dt.getHours()));",
8279 "i = Ext.num(i, Ext.num(def.i, dt.getMinutes()));",
8280 "s = Ext.num(s, Ext.num(def.s, dt.getSeconds()));",
8281 "ms = Ext.num(ms, Ext.num(def.ms, dt.getMilliseconds()));",
8283 "if(z >= 0 && y >= 0){",
8289 "v = new Date(y < 100 ? 100 : y, 0, 1, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",
8292 "v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",
8293 "}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){",
8298 "v = new Date(y < 100 ? 100 : y, m, d, h, i, s, ms).add(Date.YEAR, y < 100 ? y - 100 : 0);",
8307 "v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",
8310 "v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
8317 return function(format) {
8318 var regexNum = Date.parseRegexes.length,
8325 for (var i = 0; i < format.length; ++i) {
8326 ch = format.charAt(i);
8327 if (!special && ch == "\\") {
8329 } else if (special) {
8331 regex.push(String.escape(ch));
8333 var obj = $f(ch, currentGroup);
8334 currentGroup += obj.g;
8336 if (obj.g && obj.c) {
8342 Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", 'i');
8343 Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
8352 c:"d = parseInt(results[{0}], 10);\n",
8357 c:"d = parseInt(results[{0}], 10);\n",
8361 for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i);
8365 s:"(?:" + a.join("|") +")"
8372 s:"(?:" + Date.dayNames.join("|") + ")"
8392 c:"z = parseInt(results[{0}], 10);\n",
8403 c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n",
8404 s:"(" + Date.monthNames.join("|") + ")"
8408 for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i);
8409 return Ext.applyIf({
8410 s:"(" + a.join("|") + ")"
8415 c:"m = parseInt(results[{0}], 10) - 1;\n",
8420 c:"m = parseInt(results[{0}], 10) - 1;\n",
8438 c:"y = parseInt(results[{0}], 10);\n",
8443 c:"var ty = parseInt(results[{0}], 10);\n"
8444 + "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n",
8450 c:"if (/(am)/i.test(results[{0}])) {\n"
8451 + "if (!h || h == 12) { h = 0; }\n"
8452 + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
8457 c:"if (/(am)/i.test(results[{0}])) {\n"
8458 + "if (!h || h == 12) { h = 0; }\n"
8459 + "} else { if (!h || h < 12) { h = (h || 0) + 12; }}",
8467 c:"h = parseInt(results[{0}], 10);\n",
8475 c:"h = parseInt(results[{0}], 10);\n",
8480 c:"i = parseInt(results[{0}], 10);\n",
8485 c:"s = parseInt(results[{0}], 10);\n",
8490 c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
8496 "o = results[{0}];",
8497 "var sn = o.substring(0,1),",
8498 "hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),",
8499 "mn = o.substring(3,5) % 60;",
8500 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
8507 "o = results[{0}];",
8508 "var sn = o.substring(0,1),",
8509 "hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),",
8510 "mn = o.substring(4,6) % 60;",
8511 "o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n"
8513 s: "([+\-]\\d{2}:\\d{2})"
8522 c:"zz = results[{0}] * 1;\n"
8523 + "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
8524 s:"([+\-]?\\d{1,5})"
8535 {c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"},
8538 "if(results[8] == 'Z'){",
8540 "}else if (results[8].indexOf(':') > -1){",
8549 for (var i = 0, l = arr.length; i < l; ++i) {
8550 calc.push(arr[i].c);
8558 "(?:", "-", arr[1].s,
8559 "(?:", "-", arr[2].s,
8562 arr[3].s, ":", arr[4].s,
8563 "(?::", arr[5].s, ")?",
8564 "(?:(?:\\.|,)(\\d+))?",
8565 "(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?",
8574 c:"u = parseInt(results[{0}], 10);\n",
8582 Ext.apply(Date.prototype, {
8584 dateFormat : function(format) {
8585 if (Date.formatFunctions[format] == null) {
8586 Date.createFormat(format);
8588 return Date.formatFunctions[format].call(this);
8592 getTimezone : function() {
8605 return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
8609 getGMTOffset : function(colon) {
8610 return (this.getTimezoneOffset() > 0 ? "-" : "+")
8611 + String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")
8612 + (colon ? ":" : "")
8613 + String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
8617 getDayOfYear: function() {
8620 m = this.getMonth(),
8623 for (i = 0, d.setDate(1), d.setMonth(0); i < m; d.setMonth(++i)) {
8624 num += d.getDaysInMonth();
8626 return num + this.getDate() - 1;
8630 getWeekOfYear : function() {
8636 var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d,
8637 AWN = Math.floor(DC3 / 7),
8638 Wyr = new Date(AWN * ms7d).getUTCFullYear();
8640 return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
8645 isLeapYear : function() {
8646 var year = this.getFullYear();
8647 return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
8651 getFirstDayOfMonth : function() {
8652 var day = (this.getDay() - (this.getDate() - 1)) % 7;
8653 return (day < 0) ? (day + 7) : day;
8657 getLastDayOfMonth : function() {
8658 return this.getLastDateOfMonth().getDay();
8663 getFirstDateOfMonth : function() {
8664 return new Date(this.getFullYear(), this.getMonth(), 1);
8668 getLastDateOfMonth : function() {
8669 return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
8673 getDaysInMonth: function() {
8674 var daysInMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
8677 var m = this.getMonth();
8679 return m == 1 && this.isLeapYear() ? 29 : daysInMonth[m];
8684 getSuffix : function() {
8685 switch (this.getDate()) {
8702 clone : function() {
8703 return new Date(this.getTime());
8707 isDST : function() {
8710 return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
8714 clearTime : function(clone) {
8716 return this.clone().clearTime();
8720 var d = this.getDate();
8726 this.setMilliseconds(0);
8728 if (this.getDate() != d) {
8733 for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));
8736 this.setHours(c.getHours());
8743 add : function(interval, value) {
8744 var d = this.clone();
8745 if (!interval || value === 0) return d;
8747 switch(interval.toLowerCase()) {
8749 d.setMilliseconds(this.getMilliseconds() + value);
8752 d.setSeconds(this.getSeconds() + value);
8755 d.setMinutes(this.getMinutes() + value);
8758 d.setHours(this.getHours() + value);
8761 d.setDate(this.getDate() + value);
8764 var day = this.getDate();
8766 day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
8769 d.setMonth(this.getMonth() + value);
8772 d.setFullYear(this.getFullYear() + value);
8779 between : function(start, end) {
8780 var t = this.getTime();
8781 return start.getTime() <= t && t <= end.getTime();
8787 Date.prototype.format = Date.prototype.dateFormat;
8791 if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
8792 Ext.apply(Date.prototype, {
8793 _xMonth : Date.prototype.setMonth,
8794 _xDate : Date.prototype.setDate,
8798 setMonth : function(num) {
8800 var n = Math.ceil(-num),
8801 back_year = Math.ceil(n / 12),
8802 month = (n % 12) ? 12 - n % 12 : 0;
8804 this.setFullYear(this.getFullYear() - back_year);
8806 return this._xMonth(month);
8808 return this._xMonth(num);
8815 setDate : function(d) {
8818 return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
8827 Ext.util.MixedCollection = function(allowFunctions, keyFn){
8843 this.allowFunctions = allowFunctions === true;
8845 this.getKey = keyFn;
8847 Ext.util.MixedCollection.superclass.constructor.call(this);
8850 Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
8853 allowFunctions : false,
8856 add : function(key, o){
8857 if(arguments.length == 1){
8859 key = this.getKey(o);
8861 if(typeof key != 'undefined' && key !== null){
8862 var old = this.map[key];
8863 if(typeof old != 'undefined'){
8864 return this.replace(key, o);
8870 this.keys.push(key);
8871 this.fireEvent('add', this.length-1, o, key);
8876 getKey : function(o){
8881 replace : function(key, o){
8882 if(arguments.length == 1){
8884 key = this.getKey(o);
8886 var old = this.map[key];
8887 if(typeof key == 'undefined' || key === null || typeof old == 'undefined'){
8888 return this.add(key, o);
8890 var index = this.indexOfKey(key);
8891 this.items[index] = o;
8893 this.fireEvent('replace', key, old, o);
8898 addAll : function(objs){
8899 if(arguments.length > 1 || Ext.isArray(objs)){
8900 var args = arguments.length > 1 ? arguments : objs;
8901 for(var i = 0, len = args.length; i < len; i++){
8905 for(var key in objs){
8906 if(this.allowFunctions || typeof objs[key] != 'function'){
8907 this.add(key, objs[key]);
8914 each : function(fn, scope){
8915 var items = [].concat(this.items);
8916 for(var i = 0, len = items.length; i < len; i++){
8917 if(fn.call(scope || items[i], items[i], i, len) === false){
8924 eachKey : function(fn, scope){
8925 for(var i = 0, len = this.keys.length; i < len; i++){
8926 fn.call(scope || window, this.keys[i], this.items[i], i, len);
8931 find : function(fn, scope){
8932 for(var i = 0, len = this.items.length; i < len; i++){
8933 if(fn.call(scope || window, this.items[i], this.keys[i])){
8934 return this.items[i];
8941 insert : function(index, key, o){
8942 if(arguments.length == 2){
8944 key = this.getKey(o);
8946 if(this.containsKey(key)){
8947 this.suspendEvents();
8948 this.removeKey(key);
8949 this.resumeEvents();
8951 if(index >= this.length){
8952 return this.add(key, o);
8955 this.items.splice(index, 0, o);
8956 if(typeof key != 'undefined' && key !== null){
8959 this.keys.splice(index, 0, key);
8960 this.fireEvent('add', index, o, key);
8965 remove : function(o){
8966 return this.removeAt(this.indexOf(o));
8970 removeAt : function(index){
8971 if(index < this.length && index >= 0){
8973 var o = this.items[index];
8974 this.items.splice(index, 1);
8975 var key = this.keys[index];
8976 if(typeof key != 'undefined'){
8977 delete this.map[key];
8979 this.keys.splice(index, 1);
8980 this.fireEvent('remove', o, key);
8987 removeKey : function(key){
8988 return this.removeAt(this.indexOfKey(key));
8992 getCount : function(){
8997 indexOf : function(o){
8998 return this.items.indexOf(o);
9002 indexOfKey : function(key){
9003 return this.keys.indexOf(key);
9007 item : function(key){
9008 var mk = this.map[key],
9009 item = mk !== undefined ? mk : (typeof key == 'number') ? this.items[key] : undefined;
9010 return typeof item != 'function' || this.allowFunctions ? item : null;
9014 itemAt : function(index){
9015 return this.items[index];
9019 key : function(key){
9020 return this.map[key];
9024 contains : function(o){
9025 return this.indexOf(o) != -1;
9029 containsKey : function(key){
9030 return typeof this.map[key] != 'undefined';
9039 this.fireEvent('clear');
9044 return this.items[0];
9049 return this.items[this.length-1];
9053 _sort : function(property, dir, fn){
9055 dsc = String(dir).toUpperCase() == 'DESC' ? -1 : 1,
9063 fn = fn || function(a, b) {
9068 for(i = 0, len = items.length; i < len; i++){
9077 c.sort(function(a, b){
9078 var v = fn(a[property], b[property]) * dsc;
9080 v = (a.index < b.index ? -1 : 1);
9086 for(i = 0, len = c.length; i < len; i++){
9087 items[i] = c[i].value;
9091 this.fireEvent('sort', this);
9095 sort : function(dir, fn){
9096 this._sort('value', dir, fn);
9100 reorder: function(mapping) {
9101 this.suspendEvents();
9103 var items = this.items,
9105 length = items.length,
9111 for (oldIndex in mapping) {
9112 order[mapping[oldIndex]] = items[oldIndex];
9115 for (index = 0; index < length; index++) {
9116 if (mapping[index] == undefined) {
9117 remaining.push(items[index]);
9121 for (index = 0; index < length; index++) {
9122 if (order[index] == undefined) {
9123 order[index] = remaining.shift();
9130 this.resumeEvents();
9131 this.fireEvent('sort', this);
9135 keySort : function(dir, fn){
9136 this._sort('key', dir, fn || function(a, b){
9137 var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
9138 return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
9143 getRange : function(start, end){
9144 var items = this.items;
9145 if(items.length < 1){
9149 end = Math.min(typeof end == 'undefined' ? this.length-1 : end, this.length-1);
9152 for(i = start; i <= end; i++) {
9153 r[r.length] = items[i];
9156 for(i = start; i >= end; i--) {
9157 r[r.length] = items[i];
9164 filter : function(property, value, anyMatch, caseSensitive){
9165 if(Ext.isEmpty(value, false)){
9166 return this.clone();
9168 value = this.createValueMatcher(value, anyMatch, caseSensitive);
9169 return this.filterBy(function(o){
9170 return o && value.test(o[property]);
9175 filterBy : function(fn, scope){
9176 var r = new Ext.util.MixedCollection();
9177 r.getKey = this.getKey;
9178 var k = this.keys, it = this.items;
9179 for(var i = 0, len = it.length; i < len; i++){
9180 if(fn.call(scope||this, it[i], k[i])){
9188 findIndex : function(property, value, start, anyMatch, caseSensitive){
9189 if(Ext.isEmpty(value, false)){
9192 value = this.createValueMatcher(value, anyMatch, caseSensitive);
9193 return this.findIndexBy(function(o){
9194 return o && value.test(o[property]);
9199 findIndexBy : function(fn, scope, start){
9200 var k = this.keys, it = this.items;
9201 for(var i = (start||0), len = it.length; i < len; i++){
9202 if(fn.call(scope||this, it[i], k[i])){
9210 createValueMatcher : function(value, anyMatch, caseSensitive, exactMatch) {
9212 var er = Ext.escapeRe;
9213 value = String(value);
9215 if (anyMatch === true) {
9218 value = '^' + er(value);
9219 if (exactMatch === true) {
9223 value = new RegExp(value, caseSensitive ? '' : 'i');
9230 var r = new Ext.util.MixedCollection();
9231 var k = this.keys, it = this.items;
9232 for(var i = 0, len = it.length; i < len; i++){
9235 r.getKey = this.getKey;
9240 Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
9242 Ext.AbstractManager = Ext.extend(Object, {
9245 constructor: function(config) {
9246 Ext.apply(this, config || {});
9249 this.all = new Ext.util.MixedCollection();
9256 return this.all.get(id);
9260 register: function(item) {
9265 unregister: function(item) {
9266 this.all.remove(item);
9270 registerType : function(type, cls){
9271 this.types[type] = cls;
9272 cls[this.typeName] = type;
9276 isRegistered : function(type){
9277 return this.types[type] !== undefined;
9281 create: function(config, defaultType) {
9282 var type = config[this.typeName] || config.type || defaultType,
9283 Constructor = this.types[type];
9285 if (Constructor == undefined) {
9286 throw new Error(String.format("The '{0}' type has not been registered with this manager", type));
9289 return new Constructor(config);
9293 onAvailable : function(id, fn, scope){
9296 all.on("add", function(index, o){
9298 fn.call(scope || o, o);
9299 all.un("add", fn, scope);
9304 Ext.util.Format = function() {
9305 var trimRe = /^\s+|\s+$/g,
9306 stripTagsRE = /<\/?[^>]+>/gi,
9307 stripScriptsRe = /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
9312 ellipsis : function(value, len, word) {
9313 if (value && value.length > len) {
9315 var vs = value.substr(0, len - 2),
9316 index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
9317 if (index == -1 || index < (len - 15)) {
9318 return value.substr(0, len - 3) + "...";
9320 return vs.substr(0, index) + "...";
9323 return value.substr(0, len - 3) + "...";
9330 undef : function(value) {
9331 return value !== undefined ? value : "";
9335 defaultValue : function(value, defaultValue) {
9336 return value !== undefined && value !== '' ? value : defaultValue;
9340 htmlEncode : function(value) {
9341 return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, """);
9345 htmlDecode : function(value) {
9346 return !value ? value : String(value).replace(/>/g, ">").replace(/</g, "<").replace(/"/g, '"').replace(/&/g, "&");
9350 trim : function(value) {
9351 return String(value).replace(trimRe, "");
9355 substr : function(value, start, length) {
9356 return String(value).substr(start, length);
9360 lowercase : function(value) {
9361 return String(value).toLowerCase();
9365 uppercase : function(value) {
9366 return String(value).toUpperCase();
9370 capitalize : function(value) {
9371 return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
9375 call : function(value, fn) {
9376 if (arguments.length > 2) {
9377 var args = Array.prototype.slice.call(arguments, 2);
9378 args.unshift(value);
9379 return eval(fn).apply(window, args);
9381 return eval(fn).call(window, value);
9386 usMoney : function(v) {
9387 v = (Math.round((v-0)*100))/100;
9388 v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
9390 var ps = v.split('.'),
9392 sub = ps[1] ? '.'+ ps[1] : '.00',
9394 while (r.test(whole)) {
9395 whole = whole.replace(r, '$1' + ',' + '$2');
9398 if (v.charAt(0) == '-') {
9399 return '-$' + v.substr(1);
9405 date : function(v, format) {
9409 if (!Ext.isDate(v)) {
9410 v = new Date(Date.parse(v));
9412 return v.dateFormat(format || "m/d/Y");
9416 dateRenderer : function(format) {
9417 return function(v) {
9418 return Ext.util.Format.date(v, format);
9423 stripTags : function(v) {
9424 return !v ? v : String(v).replace(stripTagsRE, "");
9428 stripScripts : function(v) {
9429 return !v ? v : String(v).replace(stripScriptsRe, "");
9433 fileSize : function(size) {
9435 return size + " bytes";
9436 } else if (size < 1048576) {
9437 return (Math.round(((size*10) / 1024))/10) + " KB";
9439 return (Math.round(((size*10) / 1048576))/10) + " MB";
9447 return function(v, a){
9449 fns[a] = new Function('v', 'return v ' + a + ';');
9456 round : function(value, precision) {
9457 var result = Number(value);
9458 if (typeof precision == 'number') {
9459 precision = Math.pow(10, precision);
9460 result = Math.round(value * precision) / precision;
9466 number: function(v, format) {
9470 v = Ext.num(v, NaN);
9480 if (format.substr(format.length - 2) == '/i') {
9481 format = format.substr(0, format.length - 2);
9487 var hasComma = format.indexOf(comma) != -1,
9488 psplit = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec);
9490 if (1 < psplit.length) {
9491 v = v.toFixed(psplit[1].length);
9492 } else if(2 < psplit.length) {
9493 throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
9498 var fnum = v.toString();
9500 psplit = fnum.split('.');
9503 var cnum = psplit[0],
9506 m = Math.floor(j / 3),
9507 n = cnum.length % 3 || 3,
9510 for (i = 0; i < j; i += n) {
9515 parr[parr.length] = cnum.substr(i, n);
9518 fnum = parr.join(comma);
9520 fnum += dec + psplit[1];
9524 fnum = psplit[0] + dec + psplit[1];
9528 return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum);
9532 numberRenderer : function(format) {
9533 return function(v) {
9534 return Ext.util.Format.number(v, format);
9539 plural : function(v, s, p) {
9540 return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
9544 nl2br : function(v) {
9545 return Ext.isEmpty(v) ? '' : v.replace(nl2brRe, '<br/>');
9550 Ext.XTemplate = function(){
9551 Ext.XTemplate.superclass.constructor.apply(this, arguments);
9555 re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
9556 nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
9557 ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
9558 execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
9567 WITHVALUES = 'with(values){ ';
9569 s = ['<tpl>', s, '</tpl>'].join('');
9571 while((m = s.match(re))){
9572 var m2 = m[0].match(nameRe),
9573 m3 = m[0].match(ifRe),
9574 m4 = m[0].match(execRe),
9578 name = m2 && m2[1] ? m2[1] : '';
9581 exp = m3 && m3[1] ? m3[1] : null;
9583 fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');
9587 exp = m4 && m4[1] ? m4[1] : null;
9589 exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');
9594 case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break;
9595 case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break;
9596 default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');
9606 s = s.replace(m[0], '{xtpl'+ id + '}');
9609 for(var i = tpls.length-1; i >= 0; --i){
9610 me.compileTpl(tpls[i]);
9612 me.master = tpls[tpls.length-1];
9615 Ext.extend(Ext.XTemplate, Ext.Template, {
9617 re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
9619 codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
9622 applySubTemplate : function(id, values, parent, xindex, xcount){
9628 if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||
9629 (t.exec && t.exec.call(me, values, parent, xindex, xcount))) {
9632 vs = t.target ? t.target.call(me, values, parent) : values;
9634 parent = t.target ? values : parent;
9635 if(t.target && Ext.isArray(vs)){
9636 for(var i = 0, len = vs.length; i < len; i++){
9637 buf[buf.length] = t.compiled.call(me, vs[i], parent, i+1, len);
9639 return buf.join('');
9641 return t.compiled.call(me, vs, parent, xindex, xcount);
9645 compileTpl : function(tpl){
9646 var fm = Ext.util.Format,
9647 useF = this.disableFormats !== true,
9648 sep = Ext.isGecko ? "+" : ",",
9651 function fn(m, name, format, args, math){
9652 if(name.substr(0, 4) == 'xtpl'){
9653 return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
9658 }else if(name === '#'){
9660 }else if(name.indexOf('.') != -1){
9663 v = "values['" + name + "']";
9666 v = '(' + v + math + ')';
9668 if (format && useF) {
9669 args = args ? ',' + args : "";
9670 if(format.substr(0, 5) != "this."){
9671 format = "fm." + format + '(';
9673 format = 'this.call("'+ format.substr(5) + '", ';
9677 args= ''; format = "("+v+" === undefined ? '' : ";
9679 return "'"+ sep + format + v + args + ")"+sep+"'";
9682 function codeFn(m, code){
9684 return "'" + sep + '(' + code.replace(/\\'/g, "'") + ')' + sep + "'";
9689 body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
9690 tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
9693 body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
9694 body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
9695 body.push("'].join('');};");
9696 body = body.join('');
9703 applyTemplate : function(values){
9704 return this.master.compiled.call(this, values, {}, 1, 1);
9708 compile : function(){return this;}
9716 Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;
9719 Ext.XTemplate.from = function(el){
9720 el = Ext.getDom(el);
9721 return new Ext.XTemplate(el.value || el.innerHTML);
9724 Ext.util.CSS = function(){
9728 var camelRe = /(-[a-z])/gi;
9729 var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
9733 createStyleSheet : function(cssText, id){
9735 var head = doc.getElementsByTagName("head")[0];
9736 var rules = doc.createElement("style");
9737 rules.setAttribute("type", "text/css");
9739 rules.setAttribute("id", id);
9742 head.appendChild(rules);
9743 ss = rules.styleSheet;
9744 ss.cssText = cssText;
9747 rules.appendChild(doc.createTextNode(cssText));
9749 rules.cssText = cssText;
9751 head.appendChild(rules);
9752 ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
9754 this.cacheStyleSheet(ss);
9759 removeStyleSheet : function(id){
9760 var existing = doc.getElementById(id);
9762 existing.parentNode.removeChild(existing);
9767 swapStyleSheet : function(id, url){
9768 this.removeStyleSheet(id);
9769 var ss = doc.createElement("link");
9770 ss.setAttribute("rel", "stylesheet");
9771 ss.setAttribute("type", "text/css");
9772 ss.setAttribute("id", id);
9773 ss.setAttribute("href", url);
9774 doc.getElementsByTagName("head")[0].appendChild(ss);
9778 refreshCache : function(){
9779 return this.getRules(true);
9783 cacheStyleSheet : function(ss){
9788 var ssRules = ss.cssRules || ss.rules;
9789 for(var j = ssRules.length-1; j >= 0; --j){
9790 rules[ssRules[j].selectorText.toLowerCase()] = ssRules[j];
9796 getRules : function(refreshCache){
9797 if(rules === null || refreshCache){
9799 var ds = doc.styleSheets;
9800 for(var i =0, len = ds.length; i < len; i++){
9802 this.cacheStyleSheet(ds[i]);
9810 getRule : function(selector, refreshCache){
9811 var rs = this.getRules(refreshCache);
9812 if(!Ext.isArray(selector)){
9813 return rs[selector.toLowerCase()];
9815 for(var i = 0; i < selector.length; i++){
9816 if(rs[selector[i]]){
9817 return rs[selector[i].toLowerCase()];
9825 updateRule : function(selector, property, value){
9826 if(!Ext.isArray(selector)){
9827 var rule = this.getRule(selector);
9829 rule.style[property.replace(camelRe, camelFn)] = value;
9833 for(var i = 0; i < selector.length; i++){
9834 if(this.updateRule(selector[i], property, value)){
9843 Ext.util.ClickRepeater = Ext.extend(Ext.util.Observable, {
9845 constructor : function(el, config){
9846 this.el = Ext.get(el);
9847 this.el.unselectable();
9849 Ext.apply(this, config);
9861 this.disabled = true;
9867 this.on("click", this.handler, this.scope || this);
9870 Ext.util.ClickRepeater.superclass.constructor.call(this);
9875 preventDefault : true,
9876 stopDefault : false,
9882 this.el.on('mousedown', this.handleMouseDown, this);
9884 this.el.on('dblclick', this.handleDblClick, this);
9886 if(this.preventDefault || this.stopDefault){
9887 this.el.on('click', this.eventOptions, this);
9890 this.disabled = false;
9894 disable: function( force){
9895 if(force || !this.disabled){
9896 clearTimeout(this.timer);
9897 if(this.pressClass){
9898 this.el.removeClass(this.pressClass);
9900 Ext.getDoc().un('mouseup', this.handleMouseUp, this);
9901 this.el.removeAllListeners();
9903 this.disabled = true;
9907 setDisabled: function(disabled){
9908 this[disabled ? 'disable' : 'enable']();
9911 eventOptions: function(e){
9912 if(this.preventDefault){
9915 if(this.stopDefault){
9921 destroy : function() {
9923 Ext.destroy(this.el);
9924 this.purgeListeners();
9927 handleDblClick : function(e){
9928 clearTimeout(this.timer);
9931 this.fireEvent("mousedown", this, e);
9932 this.fireEvent("click", this, e);
9936 handleMouseDown : function(e){
9937 clearTimeout(this.timer);
9939 if(this.pressClass){
9940 this.el.addClass(this.pressClass);
9942 this.mousedownTime = new Date();
9944 Ext.getDoc().on("mouseup", this.handleMouseUp, this);
9945 this.el.on("mouseout", this.handleMouseOut, this);
9947 this.fireEvent("mousedown", this, e);
9948 this.fireEvent("click", this, e);
9951 if (this.accelerate) {
9954 this.timer = this.click.defer(this.delay || this.interval, this, [e]);
9958 click : function(e){
9959 this.fireEvent("click", this, e);
9960 this.timer = this.click.defer(this.accelerate ?
9961 this.easeOutExpo(this.mousedownTime.getElapsed(),
9965 this.interval, this, [e]);
9968 easeOutExpo : function (t, b, c, d) {
9969 return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
9973 handleMouseOut : function(){
9974 clearTimeout(this.timer);
9975 if(this.pressClass){
9976 this.el.removeClass(this.pressClass);
9978 this.el.on("mouseover", this.handleMouseReturn, this);
9982 handleMouseReturn : function(){
9983 this.el.un("mouseover", this.handleMouseReturn, this);
9984 if(this.pressClass){
9985 this.el.addClass(this.pressClass);
9991 handleMouseUp : function(e){
9992 clearTimeout(this.timer);
9993 this.el.un("mouseover", this.handleMouseReturn, this);
9994 this.el.un("mouseout", this.handleMouseOut, this);
9995 Ext.getDoc().un("mouseup", this.handleMouseUp, this);
9996 this.el.removeClass(this.pressClass);
9997 this.fireEvent("mouseup", this, e);
10000 Ext.KeyNav = function(el, config){
10001 this.el = Ext.get(el);
10002 Ext.apply(this, config);
10003 if(!this.disabled){
10004 this.disabled = true;
10009 Ext.KeyNav.prototype = {
10013 defaultEventAction: "stopEvent",
10015 forceKeyDown : false,
10018 relay : function(e){
10019 var k = e.getKey(),
10020 h = this.keyToHandler[k];
10022 if(this.doRelay(e, this[h], h) !== true){
10023 e[this.defaultEventAction]();
10029 doRelay : function(e, h, hname){
10030 return h.call(this.scope || this, e, hname);
10063 stopKeyUp: function(e) {
10064 var k = e.getKey();
10066 if (k >= 37 && k <= 40) {
10074 destroy: function(){
10079 enable: function() {
10080 if (this.disabled) {
10081 if (Ext.isSafari2) {
10083 this.el.on('keyup', this.stopKeyUp, this);
10086 this.el.on(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
10087 this.disabled = false;
10092 disable: function() {
10093 if (!this.disabled) {
10094 if (Ext.isSafari2) {
10096 this.el.un('keyup', this.stopKeyUp, this);
10099 this.el.un(this.isKeydown()? 'keydown' : 'keypress', this.relay, this);
10100 this.disabled = true;
10105 setDisabled : function(disabled){
10106 this[disabled ? "disable" : "enable"]();
10110 isKeydown: function(){
10111 return this.forceKeyDown || Ext.EventManager.useKeydown;
10115 Ext.KeyMap = function(el, config, eventName){
10116 this.el = Ext.get(el);
10117 this.eventName = eventName || "keydown";
10118 this.bindings = [];
10120 this.addBinding(config);
10125 Ext.KeyMap.prototype = {
10130 addBinding : function(config){
10131 if(Ext.isArray(config)){
10132 Ext.each(config, function(c){
10133 this.addBinding(c);
10137 var keyCode = config.key,
10138 fn = config.fn || config.handler,
10139 scope = config.scope;
10141 if (config.stopEvent) {
10142 this.stopEvent = config.stopEvent;
10145 if(typeof keyCode == "string"){
10147 var keyString = keyCode.toUpperCase();
10148 for(var j = 0, len = keyString.length; j < len; j++){
10149 ks.push(keyString.charCodeAt(j));
10153 var keyArray = Ext.isArray(keyCode);
10155 var handler = function(e){
10156 if(this.checkModifiers(config, e)){
10157 var k = e.getKey();
10159 for(var i = 0, len = keyCode.length; i < len; i++){
10160 if(keyCode[i] == k){
10161 if(this.stopEvent){
10164 fn.call(scope || window, k, e);
10170 if(this.stopEvent){
10173 fn.call(scope || window, k, e);
10178 this.bindings.push(handler);
10182 checkModifiers: function(config, e){
10183 var val, key, keys = ['shift', 'ctrl', 'alt'];
10184 for (var i = 0, len = keys.length; i < len; ++i){
10187 if(!(val === undefined || (val === e[key + 'Key']))){
10195 on : function(key, fn, scope){
10196 var keyCode, shift, ctrl, alt;
10197 if(typeof key == "object" && !Ext.isArray(key)){
10216 handleKeyDown : function(e){
10218 var b = this.bindings;
10219 for(var i = 0, len = b.length; i < len; i++){
10220 b[i].call(this, e);
10226 isEnabled : function(){
10227 return this.enabled;
10231 enable: function(){
10233 this.el.on(this.eventName, this.handleKeyDown, this);
10234 this.enabled = true;
10239 disable: function(){
10241 this.el.removeListener(this.eventName, this.handleKeyDown, this);
10242 this.enabled = false;
10247 setDisabled : function(disabled){
10248 this[disabled ? "disable" : "enable"]();
10251 Ext.util.TextMetrics = function(){
10255 measure : function(el, text, fixedWidth){
10257 shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
10260 shared.setFixedWidth(fixedWidth || 'auto');
10261 return shared.getSize(text);
10265 createInstance : function(el, fixedWidth){
10266 return Ext.util.TextMetrics.Instance(el, fixedWidth);
10271 Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
10272 var ml = new Ext.Element(document.createElement('div'));
10273 document.body.appendChild(ml.dom);
10274 ml.position('absolute');
10275 ml.setLeftTop(-1000, -1000);
10279 ml.setWidth(fixedWidth);
10284 getSize : function(text){
10286 var s = ml.getSize();
10292 bind : function(el){
10294 Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
10299 setFixedWidth : function(width){
10300 ml.setWidth(width);
10304 getWidth : function(text){
10305 ml.dom.style.width = 'auto';
10306 return this.getSize(text).width;
10310 getHeight : function(text){
10311 return this.getSize(text).height;
10315 instance.bind(bindTo);
10320 Ext.Element.addMethods({
10322 getTextWidth : function(text, min, max){
10323 return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
10327 Ext.util.Cookies = {
10329 set : function(name, value){
10330 var argv = arguments;
10331 var argc = arguments.length;
10332 var expires = (argc > 2) ? argv[2] : null;
10333 var path = (argc > 3) ? argv[3] : '/';
10334 var domain = (argc > 4) ? argv[4] : null;
10335 var secure = (argc > 5) ? argv[5] : false;
10336 document.cookie = name + "=" + escape(value) + ((expires === null) ? "" : ("; expires=" + expires.toGMTString())) + ((path === null) ? "" : ("; path=" + path)) + ((domain === null) ? "" : ("; domain=" + domain)) + ((secure === true) ? "; secure" : "");
10340 get : function(name){
10341 var arg = name + "=";
10342 var alen = arg.length;
10343 var clen = document.cookie.length;
10348 if(document.cookie.substring(i, j) == arg){
10349 return Ext.util.Cookies.getCookieVal(j);
10351 i = document.cookie.indexOf(" ", i) + 1;
10360 clear : function(name){
10361 if(Ext.util.Cookies.get(name)){
10362 document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
10366 getCookieVal : function(offset){
10367 var endstr = document.cookie.indexOf(";", offset);
10369 endstr = document.cookie.length;
10371 return unescape(document.cookie.substring(offset, endstr));
10374 Ext.handleError = function(e) {
10379 Ext.Error = function(message) {
10381 this.message = (this.lang[message]) ? this.lang[message] : message;
10384 Ext.Error.prototype = new Error();
10385 Ext.apply(Ext.Error.prototype, {
10391 getName : function() {
10395 getMessage : function() {
10396 return this.message;
10399 toJson : function() {
10400 return Ext.encode(this);
10404 Ext.ComponentMgr = function(){
10405 var all = new Ext.util.MixedCollection();
10411 register : function(c){
10416 unregister : function(c){
10421 get : function(id){
10422 return all.get(id);
10426 onAvailable : function(id, fn, scope){
10427 all.on("add", function(index, o){
10429 fn.call(scope || o, o);
10430 all.un("add", fn, scope);
10445 isRegistered : function(xtype){
10446 return types[xtype] !== undefined;
10450 isPluginRegistered : function(ptype){
10451 return ptypes[ptype] !== undefined;
10455 registerType : function(xtype, cls){
10456 types[xtype] = cls;
10461 create : function(config, defaultType){
10462 return config.render ? config : new types[config.xtype || defaultType](config);
10466 registerPlugin : function(ptype, cls){
10467 ptypes[ptype] = cls;
10472 createPlugin : function(config, defaultType){
10473 var PluginCls = ptypes[config.ptype || defaultType];
10474 if (PluginCls.init) {
10477 return new PluginCls(config);
10484 Ext.reg = Ext.ComponentMgr.registerType;
10486 Ext.preg = Ext.ComponentMgr.registerPlugin;
10488 Ext.create = Ext.ComponentMgr.create;
10489 Ext.Component = function(config){
10490 config = config || {};
10491 if(config.initialConfig){
10492 if(config.isAction){
10493 this.baseAction = config;
10495 config = config.initialConfig;
10496 }else if(config.tagName || config.dom || Ext.isString(config)){
10497 config = {applyTo: config, id: config.id || config};
10501 this.initialConfig = config;
10503 Ext.apply(this, config);
10532 'beforestaterestore',
10541 Ext.ComponentMgr.register(this);
10542 Ext.Component.superclass.constructor.call(this);
10544 if(this.baseAction){
10545 this.baseAction.addComponent(this);
10548 this.initComponent();
10551 if(Ext.isArray(this.plugins)){
10552 for(var i = 0, len = this.plugins.length; i < len; i++){
10553 this.plugins[i] = this.initPlugin(this.plugins[i]);
10556 this.plugins = this.initPlugin(this.plugins);
10560 if(this.stateful !== false){
10565 this.applyToMarkup(this.applyTo);
10566 delete this.applyTo;
10567 }else if(this.renderTo){
10568 this.render(this.renderTo);
10569 delete this.renderTo;
10574 Ext.Component.AUTO_ID = 1000;
10576 Ext.extend(Ext.Component, Ext.util.Observable, {
10607 disabledClass : 'x-item-disabled',
10609 allowDomMove : true,
10613 hideMode : 'display',
10615 hideParent : false,
10629 tplWriteMode : 'overwrite',
10638 ctype : 'Ext.Component',
10644 getActionEl : function(){
10645 return this[this.actionMode];
10648 initPlugin : function(p){
10649 if(p.ptype && !Ext.isFunction(p.init)){
10650 p = Ext.ComponentMgr.createPlugin(p);
10651 }else if(Ext.isString(p)){
10652 p = Ext.ComponentMgr.createPlugin({
10661 initComponent : function(){
10663 if(this.listeners){
10664 this.on(this.listeners);
10665 delete this.listeners;
10667 this.enableBubble(this.bubbleEvents);
10671 render : function(container, position){
10672 if(!this.rendered && this.fireEvent('beforerender', this) !== false){
10673 if(!container && this.el){
10674 this.el = Ext.get(this.el);
10675 container = this.el.dom.parentNode;
10676 this.allowDomMove = false;
10678 this.container = Ext.get(container);
10680 this.container.addClass(this.ctCls);
10682 this.rendered = true;
10683 if(position !== undefined){
10684 if(Ext.isNumber(position)){
10685 position = this.container.dom.childNodes[position];
10687 position = Ext.getDom(position);
10690 this.onRender(this.container, position || null);
10692 this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
10695 this.el.addClass(this.cls);
10699 this.el.applyStyles(this.style);
10703 this.el.addClassOnOver(this.overCls);
10705 this.fireEvent('render', this);
10710 var contentTarget = this.getContentTarget();
10712 contentTarget.update(Ext.DomHelper.markup(this.html));
10715 if (this.contentEl){
10716 var ce = Ext.getDom(this.contentEl);
10717 Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
10718 contentTarget.appendChild(ce);
10721 if (!this.tpl.compile) {
10722 this.tpl = new Ext.XTemplate(this.tpl);
10725 this.tpl[this.tplWriteMode](contentTarget, this.data);
10729 this.afterRender(this.container);
10738 this.disable(true);
10741 if(this.stateful !== false){
10742 this.initStateEvents();
10744 this.fireEvent('afterrender', this);
10751 update: function(htmlOrData, loadScripts, cb) {
10752 var contentTarget = this.getContentTarget();
10753 if (this.tpl && typeof htmlOrData !== "string") {
10754 this.tpl[this.tplWriteMode](contentTarget, htmlOrData || {});
10756 var html = Ext.isObject(htmlOrData) ? Ext.DomHelper.markup(htmlOrData) : htmlOrData;
10757 contentTarget.update(html, loadScripts, cb);
10763 onAdded : function(container, pos) {
10764 this.ownerCt = container;
10766 this.fireEvent('added', this, container, pos);
10770 onRemoved : function() {
10772 this.fireEvent('removed', this, this.ownerCt);
10773 delete this.ownerCt;
10777 initRef : function() {
10779 if(this.ref && !this.refOwner){
10780 var levels = this.ref.split('/'),
10781 last = levels.length,
10785 while(t && i < last){
10790 t[this.refName = levels[--i]] = this;
10797 removeRef : function() {
10798 if (this.refOwner && this.refName) {
10799 delete this.refOwner[this.refName];
10800 delete this.refOwner;
10805 initState : function(){
10806 if(Ext.state.Manager){
10807 var id = this.getStateId();
10809 var state = Ext.state.Manager.get(id);
10811 if(this.fireEvent('beforestaterestore', this, state) !== false){
10812 this.applyState(Ext.apply({}, state));
10813 this.fireEvent('staterestore', this, state);
10821 getStateId : function(){
10822 return this.stateId || ((/^(ext-comp-|ext-gen)/).test(String(this.id)) ? null : this.id);
10826 initStateEvents : function(){
10827 if(this.stateEvents){
10828 for(var i = 0, e; e = this.stateEvents[i]; i++){
10829 this.on(e, this.saveState, this, {delay:100});
10835 applyState : function(state){
10837 Ext.apply(this, state);
10842 getState : function(){
10847 saveState : function(){
10848 if(Ext.state.Manager && this.stateful !== false){
10849 var id = this.getStateId();
10851 var state = this.getState();
10852 if(this.fireEvent('beforestatesave', this, state) !== false){
10853 Ext.state.Manager.set(id, state);
10854 this.fireEvent('statesave', this, state);
10861 applyToMarkup : function(el){
10862 this.allowDomMove = false;
10863 this.el = Ext.get(el);
10864 this.render(this.el.dom.parentNode);
10868 addClass : function(cls){
10870 this.el.addClass(cls);
10872 this.cls = this.cls ? this.cls + ' ' + cls : cls;
10878 removeClass : function(cls){
10880 this.el.removeClass(cls);
10881 }else if(this.cls){
10882 this.cls = this.cls.split(' ').remove(cls).join(' ');
10889 onRender : function(ct, position){
10890 if(!this.el && this.autoEl){
10891 if(Ext.isString(this.autoEl)){
10892 this.el = document.createElement(this.autoEl);
10894 var div = document.createElement('div');
10895 Ext.DomHelper.overwrite(div, this.autoEl);
10896 this.el = div.firstChild;
10899 this.el.id = this.getId();
10903 this.el = Ext.get(this.el);
10904 if(this.allowDomMove !== false){
10905 ct.dom.insertBefore(this.el.dom, position);
10907 Ext.removeNode(div);
10915 getAutoCreate : function(){
10916 var cfg = Ext.isObject(this.autoCreate) ?
10917 this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
10918 if(this.id && !cfg.id){
10925 afterRender : Ext.emptyFn,
10928 destroy : function(){
10929 if(!this.isDestroyed){
10930 if(this.fireEvent('beforedestroy', this) !== false){
10931 this.destroying = true;
10932 this.beforeDestroy();
10933 if(this.ownerCt && this.ownerCt.remove){
10934 this.ownerCt.remove(this, false);
10938 if(this.actionMode == 'container' || this.removeMode == 'container'){
10939 this.container.remove();
10943 if(this.focusTask && this.focusTask.cancel){
10944 this.focusTask.cancel();
10947 Ext.ComponentMgr.unregister(this);
10948 this.fireEvent('destroy', this);
10949 this.purgeListeners();
10950 this.destroying = false;
10951 this.isDestroyed = true;
10956 deleteMembers : function(){
10957 var args = arguments;
10958 for(var i = 0, len = args.length; i < len; ++i){
10959 delete this[args[i]];
10964 beforeDestroy : Ext.emptyFn,
10967 onDestroy : Ext.emptyFn,
10970 getEl : function(){
10975 getContentTarget : function(){
10980 getId : function(){
10981 return this.id || (this.id = 'ext-comp-' + (++Ext.Component.AUTO_ID));
10985 getItemId : function(){
10986 return this.itemId || this.getId();
10990 focus : function(selectText, delay){
10992 this.focusTask = new Ext.util.DelayedTask(this.focus, this, [selectText, false]);
10993 this.focusTask.delay(Ext.isNumber(delay) ? delay : 10);
10996 if(this.rendered && !this.isDestroyed){
10998 if(selectText === true){
10999 this.el.dom.select();
11014 disable : function( silent){
11018 this.disabled = true;
11019 if(silent !== true){
11020 this.fireEvent('disable', this);
11026 onDisable : function(){
11027 this.getActionEl().addClass(this.disabledClass);
11028 this.el.dom.disabled = true;
11032 enable : function(){
11036 this.disabled = false;
11037 this.fireEvent('enable', this);
11042 onEnable : function(){
11043 this.getActionEl().removeClass(this.disabledClass);
11044 this.el.dom.disabled = false;
11048 setDisabled : function(disabled){
11049 return this[disabled ? 'disable' : 'enable']();
11054 if(this.fireEvent('beforeshow', this) !== false){
11055 this.hidden = false;
11056 if(this.autoRender){
11057 this.render(Ext.isBoolean(this.autoRender) ? Ext.getBody() : this.autoRender);
11062 this.fireEvent('show', this);
11068 onShow : function(){
11069 this.getVisibilityEl().removeClass('x-hide-' + this.hideMode);
11074 if(this.fireEvent('beforehide', this) !== false){
11076 this.fireEvent('hide', this);
11082 doHide: function(){
11083 this.hidden = true;
11090 onHide : function(){
11091 this.getVisibilityEl().addClass('x-hide-' + this.hideMode);
11095 getVisibilityEl : function(){
11096 return this.hideParent ? this.container : this.getActionEl();
11100 setVisible : function(visible){
11101 return this[visible ? 'show' : 'hide']();
11105 isVisible : function(){
11106 return this.rendered && this.getVisibilityEl().isVisible();
11110 cloneConfig : function(overrides){
11111 overrides = overrides || {};
11112 var id = overrides.id || Ext.id();
11113 var cfg = Ext.applyIf(overrides, this.initialConfig);
11115 return new this.constructor(cfg);
11119 getXType : function(){
11120 return this.constructor.xtype;
11124 isXType : function(xtype, shallow){
11126 if (Ext.isFunction(xtype)){
11127 xtype = xtype.xtype;
11128 }else if (Ext.isObject(xtype)){
11129 xtype = xtype.constructor.xtype;
11132 return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
11136 getXTypes : function(){
11137 var tc = this.constructor;
11139 var c = [], sc = this;
11140 while(sc && sc.constructor.xtype){
11141 c.unshift(sc.constructor.xtype);
11142 sc = sc.constructor.superclass;
11145 tc.xtypes = c.join('/');
11151 findParentBy : function(fn) {
11152 for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
11157 findParentByType : function(xtype, shallow){
11158 return this.findParentBy(function(c){
11159 return c.isXType(xtype, shallow);
11164 bubble : function(fn, scope, args){
11167 if(fn.apply(scope || p, args || [p]) === false){
11176 getPositionEl : function(){
11177 return this.positionEl || this.el;
11181 purgeListeners : function(){
11182 Ext.Component.superclass.purgeListeners.call(this);
11184 this.on('beforedestroy', this.clearMons, this, {single: true});
11189 clearMons : function(){
11190 Ext.each(this.mons, function(m){
11191 m.item.un(m.ename, m.fn, m.scope);
11197 createMons: function(){
11200 this.on('beforedestroy', this.clearMons, this, {single: true});
11205 mon : function(item, ename, fn, scope, opt){
11207 if(Ext.isObject(ename)){
11208 var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
11212 if(propRe.test(e)){
11215 if(Ext.isFunction(o[e])){
11218 item: item, ename: e, fn: o[e], scope: o.scope
11220 item.on(e, o[e], o.scope, o);
11224 item: item, ename: e, fn: o[e], scope: o.scope
11233 item: item, ename: ename, fn: fn, scope: scope
11235 item.on(ename, fn, scope, opt);
11239 mun : function(item, ename, fn, scope){
11242 for(var i = 0, len = this.mons.length; i < len; ++i){
11243 mon = this.mons[i];
11244 if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
11245 this.mons.splice(i, 1);
11246 item.un(ename, fn, scope);
11255 nextSibling : function(){
11257 var index = this.ownerCt.items.indexOf(this);
11258 if(index != -1 && index+1 < this.ownerCt.items.getCount()){
11259 return this.ownerCt.items.itemAt(index+1);
11266 previousSibling : function(){
11268 var index = this.ownerCt.items.indexOf(this);
11270 return this.ownerCt.items.itemAt(index-1);
11277 getBubbleTarget : function(){
11278 return this.ownerCt;
11282 Ext.reg('component', Ext.Component);
11284 Ext.Action = Ext.extend(Object, {
11293 constructor : function(config){
11294 this.initialConfig = config;
11295 this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
11303 setText : function(text){
11304 this.initialConfig.text = text;
11305 this.callEach('setText', [text]);
11309 getText : function(){
11310 return this.initialConfig.text;
11314 setIconClass : function(cls){
11315 this.initialConfig.iconCls = cls;
11316 this.callEach('setIconClass', [cls]);
11320 getIconClass : function(){
11321 return this.initialConfig.iconCls;
11325 setDisabled : function(v){
11326 this.initialConfig.disabled = v;
11327 this.callEach('setDisabled', [v]);
11331 enable : function(){
11332 this.setDisabled(false);
11336 disable : function(){
11337 this.setDisabled(true);
11341 isDisabled : function(){
11342 return this.initialConfig.disabled;
11346 setHidden : function(v){
11347 this.initialConfig.hidden = v;
11348 this.callEach('setVisible', [!v]);
11353 this.setHidden(false);
11358 this.setHidden(true);
11362 isHidden : function(){
11363 return this.initialConfig.hidden;
11367 setHandler : function(fn, scope){
11368 this.initialConfig.handler = fn;
11369 this.initialConfig.scope = scope;
11370 this.callEach('setHandler', [fn, scope]);
11374 each : function(fn, scope){
11375 Ext.each(this.items, fn, scope);
11379 callEach : function(fnName, args){
11380 var cs = this.items;
11381 for(var i = 0, len = cs.length; i < len; i++){
11382 cs[i][fnName].apply(cs[i], args);
11387 addComponent : function(comp){
11388 this.items.push(comp);
11389 comp.on('destroy', this.removeComponent, this);
11393 removeComponent : function(comp){
11394 this.items.remove(comp);
11398 execute : function(){
11399 this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
11404 Ext.Layer = function(config, existingEl){
11405 config = config || {};
11406 var dh = Ext.DomHelper,
11407 cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
11410 this.dom = Ext.getDom(existingEl);
11413 var o = config.dh || {tag: 'div', cls: 'x-layer'};
11414 this.dom = dh.append(pel, o);
11417 this.addClass(config.cls);
11419 this.constrain = config.constrain !== false;
11420 this.setVisibilityMode(Ext.Element.VISIBILITY);
11422 this.id = this.dom.id = config.id;
11424 this.id = Ext.id(this.dom);
11426 this.zindex = config.zindex || this.getZIndex();
11427 this.position('absolute', this.zindex);
11429 this.shadowOffset = config.shadowOffset || 4;
11430 this.shadow = new Ext.Shadow({
11431 offset : this.shadowOffset,
11432 mode : config.shadow
11435 this.shadowOffset = 0;
11437 this.useShim = config.shim !== false && Ext.useShims;
11438 this.useDisplay = config.useDisplay;
11442 var supr = Ext.Element.prototype;
11447 Ext.extend(Ext.Layer, Ext.Element, {
11449 getZIndex : function(){
11450 return this.zindex || parseInt((this.getShim() || this).getStyle('z-index'), 10) || 11000;
11453 getShim : function(){
11460 var shim = shims.shift();
11462 shim = this.createShim();
11463 shim.enableDisplayMode('block');
11464 shim.dom.style.display = 'none';
11465 shim.dom.style.visibility = 'visible';
11467 var pn = this.dom.parentNode;
11468 if(shim.dom.parentNode != pn){
11469 pn.insertBefore(shim.dom, this.dom);
11471 shim.setStyle('z-index', this.getZIndex()-2);
11476 hideShim : function(){
11478 this.shim.setDisplayed(false);
11479 shims.push(this.shim);
11484 disableShadow : function(){
11486 this.shadowDisabled = true;
11487 this.shadow.hide();
11488 this.lastShadowOffset = this.shadowOffset;
11489 this.shadowOffset = 0;
11493 enableShadow : function(show){
11495 this.shadowDisabled = false;
11496 this.shadowOffset = this.lastShadowOffset;
11497 delete this.lastShadowOffset;
11507 sync : function(doShow){
11508 var shadow = this.shadow;
11509 if(!this.updating && this.isVisible() && (shadow || this.useShim)){
11510 var shim = this.getShim(),
11511 w = this.getWidth(),
11512 h = this.getHeight(),
11513 l = this.getLeft(true),
11514 t = this.getTop(true);
11516 if(shadow && !this.shadowDisabled){
11517 if(doShow && !shadow.isVisible()){
11520 shadow.realign(l, t, w, h);
11527 var shadowAdj = shadow.el.getXY(), shimStyle = shim.dom.style,
11528 shadowSize = shadow.el.getSize();
11529 shimStyle.left = (shadowAdj[0])+'px';
11530 shimStyle.top = (shadowAdj[1])+'px';
11531 shimStyle.width = (shadowSize.width)+'px';
11532 shimStyle.height = (shadowSize.height)+'px';
11538 shim.setSize(w, h);
11539 shim.setLeftTop(l, t);
11545 destroy : function(){
11548 this.shadow.hide();
11550 this.removeAllListeners();
11551 Ext.removeNode(this.dom);
11555 remove : function(){
11560 beginUpdate : function(){
11561 this.updating = true;
11565 endUpdate : function(){
11566 this.updating = false;
11571 hideUnders : function(negOffset){
11573 this.shadow.hide();
11579 constrainXY : function(){
11580 if(this.constrain){
11581 var vw = Ext.lib.Dom.getViewWidth(),
11582 vh = Ext.lib.Dom.getViewHeight();
11583 var s = Ext.getDoc().getScroll();
11585 var xy = this.getXY();
11586 var x = xy[0], y = xy[1];
11587 var so = this.shadowOffset;
11588 var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
11592 if((x + w) > vw+s.left){
11596 if((y + h) > vh+s.top){
11611 var ay = this.avoidY;
11612 if(y <= ay && (y+h) >= ay){
11618 supr.setXY.call(this, xy);
11625 getConstrainOffset : function(){
11626 return this.shadowOffset;
11629 isVisible : function(){
11630 return this.visible;
11634 showAction : function(){
11635 this.visible = true;
11636 if(this.useDisplay === true){
11637 this.setDisplayed('');
11638 }else if(this.lastXY){
11639 supr.setXY.call(this, this.lastXY);
11640 }else if(this.lastLT){
11641 supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
11646 hideAction : function(){
11647 this.visible = false;
11648 if(this.useDisplay === true){
11649 this.setDisplayed(false);
11651 this.setLeftTop(-10000,-10000);
11656 setVisible : function(v, a, d, c, e){
11661 var cb = function(){
11666 }.createDelegate(this);
11667 supr.setVisible.call(this, true, true, d, cb, e);
11670 this.hideUnders(true);
11679 }.createDelegate(this);
11681 supr.setVisible.call(this, v, a, d, cb, e);
11691 storeXY : function(xy){
11692 delete this.lastLT;
11696 storeLeftTop : function(left, top){
11697 delete this.lastXY;
11698 this.lastLT = [left, top];
11702 beforeFx : function(){
11703 this.beforeAction();
11704 return Ext.Layer.superclass.beforeFx.apply(this, arguments);
11708 afterFx : function(){
11709 Ext.Layer.superclass.afterFx.apply(this, arguments);
11710 this.sync(this.isVisible());
11714 beforeAction : function(){
11715 if(!this.updating && this.shadow){
11716 this.shadow.hide();
11721 setLeft : function(left){
11722 this.storeLeftTop(left, this.getTop(true));
11723 supr.setLeft.apply(this, arguments);
11728 setTop : function(top){
11729 this.storeLeftTop(this.getLeft(true), top);
11730 supr.setTop.apply(this, arguments);
11735 setLeftTop : function(left, top){
11736 this.storeLeftTop(left, top);
11737 supr.setLeftTop.apply(this, arguments);
11742 setXY : function(xy, a, d, c, e){
11744 this.beforeAction();
11746 var cb = this.createCB(c);
11747 supr.setXY.call(this, xy, a, d, cb, e);
11755 createCB : function(c){
11767 setX : function(x, a, d, c, e){
11768 this.setXY([x, this.getY()], a, d, c, e);
11773 setY : function(y, a, d, c, e){
11774 this.setXY([this.getX(), y], a, d, c, e);
11779 setSize : function(w, h, a, d, c, e){
11780 this.beforeAction();
11781 var cb = this.createCB(c);
11782 supr.setSize.call(this, w, h, a, d, cb, e);
11790 setWidth : function(w, a, d, c, e){
11791 this.beforeAction();
11792 var cb = this.createCB(c);
11793 supr.setWidth.call(this, w, a, d, cb, e);
11801 setHeight : function(h, a, d, c, e){
11802 this.beforeAction();
11803 var cb = this.createCB(c);
11804 supr.setHeight.call(this, h, a, d, cb, e);
11812 setBounds : function(x, y, w, h, a, d, c, e){
11813 this.beforeAction();
11814 var cb = this.createCB(c);
11816 this.storeXY([x, y]);
11817 supr.setXY.call(this, [x, y]);
11818 supr.setSize.call(this, w, h, a, d, cb, e);
11821 supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
11827 setZIndex : function(zindex){
11828 this.zindex = zindex;
11829 this.setStyle('z-index', zindex + 2);
11831 this.shadow.setZIndex(zindex + 1);
11834 this.shim.setStyle('z-index', zindex);
11841 Ext.Shadow = function(config) {
11842 Ext.apply(this, config);
11843 if (typeof this.mode != "string") {
11844 this.mode = this.defaultMode;
11846 var o = this.offset,
11850 rad = Math.floor(this.offset / 2);
11851 switch (this.mode.toLowerCase()) {
11858 a.l -= this.offset + rad;
11859 a.t -= this.offset + rad;
11870 a.l -= (this.offset - rad);
11871 a.t -= this.offset + rad;
11873 a.w -= (this.offset - rad) * 2;
11879 a.w = a.h = (o * 2);
11884 a.l -= (this.offset - rad);
11885 a.t -= (this.offset - rad);
11887 a.w -= (this.offset + rad + 1);
11888 a.h -= (this.offset + rad);
11897 Ext.Shadow.prototype = {
11903 defaultMode: "drop",
11906 show: function(target) {
11907 target = Ext.get(target);
11909 this.el = Ext.Shadow.Pool.pull();
11910 if (this.el.dom.nextSibling != target.dom) {
11911 this.el.insertBefore(target);
11914 this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10) - 1);
11916 this.el.dom.style.filter = "progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + (this.offset) + ")";
11919 target.getLeft(true),
11920 target.getTop(true),
11924 this.el.dom.style.display = "block";
11928 isVisible: function() {
11929 return this.el ? true: false;
11933 realign: function(l, t, w, h) {
11937 var a = this.adjusts,
11947 s.left = (l + a.l) + "px";
11948 s.top = (t + a.t) + "px";
11949 if (s.width != sws || s.height != shs) {
11954 sww = Math.max(0, (sw - 12)) + "px";
11955 cn[0].childNodes[1].style.width = sww;
11956 cn[1].childNodes[1].style.width = sww;
11957 cn[2].childNodes[1].style.width = sww;
11958 cn[1].style.height = Math.max(0, (sh - 12)) + "px";
11966 this.el.dom.style.display = "none";
11967 Ext.Shadow.Pool.push(this.el);
11973 setZIndex: function(z) {
11976 this.el.setStyle("z-index", z);
11982 Ext.Shadow.Pool = function() {
11984 markup = Ext.isIE ?
11985 '<div class="x-ie-shadow"></div>':
11986 '<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>';
11989 var sh = p.shift();
11991 sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
11992 sh.autoBoxAdjust = false;
11997 push: function(sh) {
12002 Ext.BoxComponent = Ext.extend(Ext.Component, {
12031 initComponent : function(){
12032 Ext.BoxComponent.superclass.initComponent.call(this);
12044 deferHeight: false,
12047 setSize : function(w, h){
12050 if(typeof w == 'object'){
12054 if (Ext.isDefined(w) && Ext.isDefined(this.boxMinWidth) && (w < this.boxMinWidth)) {
12055 w = this.boxMinWidth;
12057 if (Ext.isDefined(h) && Ext.isDefined(this.boxMinHeight) && (h < this.boxMinHeight)) {
12058 h = this.boxMinHeight;
12060 if (Ext.isDefined(w) && Ext.isDefined(this.boxMaxWidth) && (w > this.boxMaxWidth)) {
12061 w = this.boxMaxWidth;
12063 if (Ext.isDefined(h) && Ext.isDefined(this.boxMaxHeight) && (h > this.boxMaxHeight)) {
12064 h = this.boxMaxHeight;
12067 if(!this.boxReady){
12074 if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
12077 this.lastSize = {width: w, height: h};
12078 var adj = this.adjustSize(w, h),
12082 if(aw !== undefined || ah !== undefined){
12083 rz = this.getResizeEl();
12084 if(!this.deferHeight && aw !== undefined && ah !== undefined){
12085 rz.setSize(aw, ah);
12086 }else if(!this.deferHeight && ah !== undefined){
12088 }else if(aw !== undefined){
12091 this.onResize(aw, ah, w, h);
12092 this.fireEvent('resize', this, aw, ah, w, h);
12098 setWidth : function(width){
12099 return this.setSize(width);
12103 setHeight : function(height){
12104 return this.setSize(undefined, height);
12108 getSize : function(){
12109 return this.getResizeEl().getSize();
12113 getWidth : function(){
12114 return this.getResizeEl().getWidth();
12118 getHeight : function(){
12119 return this.getResizeEl().getHeight();
12123 getOuterSize : function(){
12124 var el = this.getResizeEl();
12125 return {width: el.getWidth() + el.getMargins('lr'),
12126 height: el.getHeight() + el.getMargins('tb')};
12130 getPosition : function(local){
12131 var el = this.getPositionEl();
12132 if(local === true){
12133 return [el.getLeft(true), el.getTop(true)];
12135 return this.xy || el.getXY();
12139 getBox : function(local){
12140 var pos = this.getPosition(local);
12141 var s = this.getSize();
12148 updateBox : function(box){
12149 this.setSize(box.width, box.height);
12150 this.setPagePosition(box.x, box.y);
12155 getResizeEl : function(){
12156 return this.resizeEl || this.el;
12160 setAutoScroll : function(scroll){
12162 this.getContentTarget().setOverflow(scroll ? 'auto' : '');
12164 this.autoScroll = scroll;
12169 setPosition : function(x, y){
12170 if(x && typeof x[1] == 'number'){
12176 if(!this.boxReady){
12179 var adj = this.adjustPosition(x, y);
12180 var ax = adj.x, ay = adj.y;
12182 var el = this.getPositionEl();
12183 if(ax !== undefined || ay !== undefined){
12184 if(ax !== undefined && ay !== undefined){
12185 el.setLeftTop(ax, ay);
12186 }else if(ax !== undefined){
12188 }else if(ay !== undefined){
12191 this.onPosition(ax, ay);
12192 this.fireEvent('move', this, ax, ay);
12198 setPagePosition : function(x, y){
12199 if(x && typeof x[1] == 'number'){
12205 if(!this.boxReady){
12208 if(x === undefined || y === undefined){
12211 var p = this.getPositionEl().translatePoints(x, y);
12212 this.setPosition(p.left, p.top);
12217 afterRender : function(){
12218 Ext.BoxComponent.superclass.afterRender.call(this);
12220 this.resizeEl = Ext.get(this.resizeEl);
12222 if(this.positionEl){
12223 this.positionEl = Ext.get(this.positionEl);
12225 this.boxReady = true;
12226 Ext.isDefined(this.autoScroll) && this.setAutoScroll(this.autoScroll);
12227 this.setSize(this.width, this.height);
12228 if(this.x || this.y){
12229 this.setPosition(this.x, this.y);
12230 }else if(this.pageX || this.pageY){
12231 this.setPagePosition(this.pageX, this.pageY);
12236 syncSize : function(){
12237 delete this.lastSize;
12238 this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());
12243 onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
12247 onPosition : function(x, y){
12252 adjustSize : function(w, h){
12253 if(this.autoWidth){
12256 if(this.autoHeight){
12259 return {width : w, height: h};
12263 adjustPosition : function(x, y){
12264 return {x : x, y: y};
12267 Ext.reg('box', Ext.BoxComponent);
12271 Ext.Spacer = Ext.extend(Ext.BoxComponent, {
12274 Ext.reg('spacer', Ext.Spacer);
12275 Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
12278 this.el = Ext.get(dragElement, true);
12279 this.el.dom.unselectable = "on";
12281 this.resizingEl = Ext.get(resizingElement, true);
12284 this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
12291 this.maxSize = 2000;
12294 this.animate = false;
12297 this.useShim = false;
12302 if(!existingProxy){
12304 this.proxy = Ext.SplitBar.createProxy(this.orientation);
12306 this.proxy = Ext.get(existingProxy).dom;
12309 this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
12312 this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
12315 this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
12318 this.dragSpecs = {};
12321 this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
12322 this.adapter.init(this);
12324 if(this.orientation == Ext.SplitBar.HORIZONTAL){
12326 this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
12327 this.el.addClass("x-splitbar-h");
12330 this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
12331 this.el.addClass("x-splitbar-v");
12345 Ext.SplitBar.superclass.constructor.call(this);
12348 Ext.extend(Ext.SplitBar, Ext.util.Observable, {
12349 onStartProxyDrag : function(x, y){
12350 this.fireEvent("beforeresize", this);
12351 this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: " "}, true);
12352 this.overlay.unselectable();
12353 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
12354 this.overlay.show();
12355 Ext.get(this.proxy).setDisplayed("block");
12356 var size = this.adapter.getElementSize(this);
12357 this.activeMinSize = this.getMinimumSize();
12358 this.activeMaxSize = this.getMaximumSize();
12359 var c1 = size - this.activeMinSize;
12360 var c2 = Math.max(this.activeMaxSize - size, 0);
12361 if(this.orientation == Ext.SplitBar.HORIZONTAL){
12362 this.dd.resetConstraints();
12363 this.dd.setXConstraint(
12364 this.placement == Ext.SplitBar.LEFT ? c1 : c2,
12365 this.placement == Ext.SplitBar.LEFT ? c2 : c1,
12368 this.dd.setYConstraint(0, 0);
12370 this.dd.resetConstraints();
12371 this.dd.setXConstraint(0, 0);
12372 this.dd.setYConstraint(
12373 this.placement == Ext.SplitBar.TOP ? c1 : c2,
12374 this.placement == Ext.SplitBar.TOP ? c2 : c1,
12378 this.dragSpecs.startSize = size;
12379 this.dragSpecs.startPoint = [x, y];
12380 Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
12384 onEndProxyDrag : function(e){
12385 Ext.get(this.proxy).setDisplayed(false);
12386 var endPoint = Ext.lib.Event.getXY(e);
12388 Ext.destroy(this.overlay);
12389 delete this.overlay;
12392 if(this.orientation == Ext.SplitBar.HORIZONTAL){
12393 newSize = this.dragSpecs.startSize +
12394 (this.placement == Ext.SplitBar.LEFT ?
12395 endPoint[0] - this.dragSpecs.startPoint[0] :
12396 this.dragSpecs.startPoint[0] - endPoint[0]
12399 newSize = this.dragSpecs.startSize +
12400 (this.placement == Ext.SplitBar.TOP ?
12401 endPoint[1] - this.dragSpecs.startPoint[1] :
12402 this.dragSpecs.startPoint[1] - endPoint[1]
12405 newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
12406 if(newSize != this.dragSpecs.startSize){
12407 if(this.fireEvent('beforeapply', this, newSize) !== false){
12408 this.adapter.setElementSize(this, newSize);
12409 this.fireEvent("moved", this, newSize);
12410 this.fireEvent("resize", this, newSize);
12416 getAdapter : function(){
12417 return this.adapter;
12421 setAdapter : function(adapter){
12422 this.adapter = adapter;
12423 this.adapter.init(this);
12427 getMinimumSize : function(){
12428 return this.minSize;
12432 setMinimumSize : function(minSize){
12433 this.minSize = minSize;
12437 getMaximumSize : function(){
12438 return this.maxSize;
12442 setMaximumSize : function(maxSize){
12443 this.maxSize = maxSize;
12447 setCurrentSize : function(size){
12448 var oldAnimate = this.animate;
12449 this.animate = false;
12450 this.adapter.setElementSize(this, size);
12451 this.animate = oldAnimate;
12455 destroy : function(removeEl){
12456 Ext.destroy(this.shim, Ext.get(this.proxy));
12461 this.purgeListeners();
12466 Ext.SplitBar.createProxy = function(dir){
12467 var proxy = new Ext.Element(document.createElement("div"));
12468 document.body.appendChild(proxy.dom);
12469 proxy.unselectable();
12470 var cls = 'x-splitbar-proxy';
12471 proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
12476 Ext.SplitBar.BasicLayoutAdapter = function(){
12479 Ext.SplitBar.BasicLayoutAdapter.prototype = {
12481 init : function(s){
12485 getElementSize : function(s){
12486 if(s.orientation == Ext.SplitBar.HORIZONTAL){
12487 return s.resizingEl.getWidth();
12489 return s.resizingEl.getHeight();
12494 setElementSize : function(s, newSize, onComplete){
12495 if(s.orientation == Ext.SplitBar.HORIZONTAL){
12497 s.resizingEl.setWidth(newSize);
12499 onComplete(s, newSize);
12502 s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
12507 s.resizingEl.setHeight(newSize);
12509 onComplete(s, newSize);
12512 s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
12519 Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
12520 this.basic = new Ext.SplitBar.BasicLayoutAdapter();
12521 this.container = Ext.get(container);
12524 Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
12525 init : function(s){
12526 this.basic.init(s);
12529 getElementSize : function(s){
12530 return this.basic.getElementSize(s);
12533 setElementSize : function(s, newSize, onComplete){
12534 this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
12537 moveSplitter : function(s){
12538 var yes = Ext.SplitBar;
12539 switch(s.placement){
12541 s.el.setX(s.resizingEl.getRight());
12544 s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
12547 s.el.setY(s.resizingEl.getBottom());
12550 s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
12557 Ext.SplitBar.VERTICAL = 1;
12560 Ext.SplitBar.HORIZONTAL = 2;
12563 Ext.SplitBar.LEFT = 1;
12566 Ext.SplitBar.RIGHT = 2;
12569 Ext.SplitBar.TOP = 3;
12572 Ext.SplitBar.BOTTOM = 4;
12574 Ext.Container = Ext.extend(Ext.BoxComponent, {
12587 autoDestroy : true,
12590 forceLayout: false,
12594 defaultType : 'panel',
12597 resizeEvent: 'resize',
12600 bubbleEvents: ['add', 'remove'],
12603 initComponent : function(){
12604 Ext.Container.superclass.initComponent.call(this);
12620 var items = this.items;
12628 initItems : function(){
12630 this.items = new Ext.util.MixedCollection(false, this.getComponentId);
12636 setLayout : function(layout){
12637 if(this.layout && this.layout != layout){
12638 this.layout.setContainer(null);
12640 this.layout = layout;
12642 layout.setContainer(this);
12645 afterRender: function(){
12648 Ext.Container.superclass.afterRender.call(this);
12650 this.layout = 'auto';
12652 if(Ext.isObject(this.layout) && !this.layout.layout){
12653 this.layoutConfig = this.layout;
12654 this.layout = this.layoutConfig.type;
12656 if(Ext.isString(this.layout)){
12657 this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
12659 this.setLayout(this.layout);
12662 if(this.activeItem !== undefined && this.layout.setActiveItem){
12663 var item = this.activeItem;
12664 delete this.activeItem;
12665 this.layout.setActiveItem(item);
12670 this.doLayout(false, true);
12675 if(this.monitorResize === true){
12676 Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
12681 getLayoutTarget : function(){
12686 getComponentId : function(comp){
12687 return comp.getItemId();
12691 add : function(comp){
12693 var args = arguments.length > 1;
12694 if(args || Ext.isArray(comp)){
12696 Ext.each(args ? arguments : comp, function(c){
12697 result.push(this.add(c));
12701 var c = this.lookupComponent(this.applyDefaults(comp));
12702 var index = this.items.length;
12703 if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
12706 c.onAdded(this, index);
12708 this.fireEvent('add', this, c, index);
12713 onAdd : function(c){
12718 onAdded : function(container, pos) {
12720 this.ownerCt = container;
12723 this.cascade(function(c){
12726 this.fireEvent('added', this, container, pos);
12730 insert : function(index, comp) {
12731 var args = arguments,
12732 length = args.length,
12739 for (i = length - 1; i >= 1; --i) {
12740 result.push(this.insert(index, args[i]));
12745 c = this.lookupComponent(this.applyDefaults(comp));
12746 index = Math.min(index, this.items.length);
12748 if (this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false) {
12749 if (c.ownerCt == this) {
12750 this.items.remove(c);
12752 this.items.insert(index, c);
12753 c.onAdded(this, index);
12755 this.fireEvent('add', this, c, index);
12762 applyDefaults : function(c){
12763 var d = this.defaults;
12765 if(Ext.isFunction(d)){
12766 d = d.call(this, c);
12768 if(Ext.isString(c)){
12769 c = Ext.ComponentMgr.get(c);
12771 }else if(!c.events){
12781 onBeforeAdd : function(item){
12783 item.ownerCt.remove(item, false);
12785 if(this.hideBorders === true){
12786 item.border = (item.border === true);
12791 remove : function(comp, autoDestroy){
12793 var c = this.getComponent(comp);
12794 if(c && this.fireEvent('beforeremove', this, c) !== false){
12795 this.doRemove(c, autoDestroy);
12796 this.fireEvent('remove', this, c);
12801 onRemove: function(c){
12806 doRemove: function(c, autoDestroy){
12807 var l = this.layout,
12808 hasLayout = l && this.rendered;
12813 this.items.remove(c);
12816 if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
12825 removeAll: function(autoDestroy){
12827 var item, rem = [], items = [];
12828 this.items.each(function(i){
12831 for (var i = 0, len = rem.length; i < len; ++i){
12833 this.remove(item, autoDestroy);
12834 if(item.ownerCt !== this){
12842 getComponent : function(comp){
12843 if(Ext.isObject(comp)){
12844 comp = comp.getItemId();
12846 return this.items.get(comp);
12850 lookupComponent : function(comp){
12851 if(Ext.isString(comp)){
12852 return Ext.ComponentMgr.get(comp);
12853 }else if(!comp.events){
12854 return this.createComponent(comp);
12860 createComponent : function(config, defaultType){
12861 if (config.render) {
12866 var c = Ext.create(Ext.apply({
12868 }, config), defaultType || this.defaultType);
12869 delete c.initialConfig.ownerCt;
12875 canLayout : function() {
12876 var el = this.getVisibilityEl();
12877 return el && el.dom && !el.isStyle("display", "none");
12882 doLayout : function(shallow, force){
12883 var rendered = this.rendered,
12884 forceLayout = force || this.forceLayout;
12886 if(this.collapsed || !this.canLayout()){
12887 this.deferLayout = this.deferLayout || !shallow;
12891 shallow = shallow && !this.deferLayout;
12893 delete this.deferLayout;
12895 if(rendered && this.layout){
12896 this.layout.layout();
12898 if(shallow !== true && this.items){
12899 var cs = this.items.items;
12900 for(var i = 0, len = cs.length; i < len; i++){
12903 c.doLayout(false, forceLayout);
12908 this.onLayout(shallow, forceLayout);
12911 this.hasLayout = true;
12912 delete this.forceLayout;
12915 onLayout : Ext.emptyFn,
12918 shouldBufferLayout: function(){
12920 var hl = this.hasLayout;
12923 return hl ? !this.hasLayoutPending() : false;
12930 hasLayoutPending: function(){
12932 var pending = false;
12933 this.ownerCt.bubble(function(c){
12934 if(c.layoutPending){
12942 onShow : function(){
12944 Ext.Container.superclass.onShow.call(this);
12946 if(Ext.isDefined(this.deferLayout)){
12947 delete this.deferLayout;
12948 this.doLayout(true);
12953 getLayout : function(){
12955 var layout = new Ext.layout.AutoLayout(this.layoutConfig);
12956 this.setLayout(layout);
12958 return this.layout;
12962 beforeDestroy : function(){
12965 while(c = this.items.first()){
12966 this.doRemove(c, true);
12969 if(this.monitorResize){
12970 Ext.EventManager.removeResizeListener(this.doLayout, this);
12972 Ext.destroy(this.layout);
12973 Ext.Container.superclass.beforeDestroy.call(this);
12977 cascade : function(fn, scope, args){
12978 if(fn.apply(scope || this, args || [this]) !== false){
12980 var cs = this.items.items;
12981 for(var i = 0, len = cs.length; i < len; i++){
12983 cs[i].cascade(fn, scope, args);
12985 fn.apply(scope || cs[i], args || [cs[i]]);
12994 findById : function(id){
12997 this.cascade(function(c){
12998 if(ct != c && c.id === id){
13007 findByType : function(xtype, shallow){
13008 return this.findBy(function(c){
13009 return c.isXType(xtype, shallow);
13014 find : function(prop, value){
13015 return this.findBy(function(c){
13016 return c[prop] === value;
13021 findBy : function(fn, scope){
13022 var m = [], ct = this;
13023 this.cascade(function(c){
13024 if(ct != c && fn.call(scope || c, c, ct) === true){
13032 get : function(key){
13033 return this.getComponent(key);
13037 Ext.Container.LAYOUTS = {};
13038 Ext.reg('container', Ext.Container);
13040 Ext.layout.ContainerLayout = Ext.extend(Object, {
13047 monitorResize:false,
13051 constructor : function(config){
13052 this.id = Ext.id(null, 'ext-layout-');
13053 Ext.apply(this, config);
13059 IEMeasureHack : function(target, viewFlag) {
13060 var tChildren = target.dom.childNodes, tLen = tChildren.length, c, d = [], e, i, ret;
13061 for (i = 0 ; i < tLen ; i++) {
13065 d[i] = e.getStyle('display');
13066 e.setStyle({display: 'none'});
13069 ret = target ? target.getViewSize(viewFlag) : {};
13070 for (i = 0 ; i < tLen ; i++) {
13074 e.setStyle({display: d[i]});
13081 getLayoutTargetSize : Ext.EmptyFn,
13084 layout : function(){
13085 var ct = this.container, target = ct.getLayoutTarget();
13086 if(!(this.hasLayout || Ext.isEmpty(this.targetCls))){
13087 target.addClass(this.targetCls);
13089 this.onLayout(ct, target);
13090 ct.fireEvent('afterlayout', ct, this);
13094 onLayout : function(ct, target){
13095 this.renderAll(ct, target);
13099 isValidParent : function(c, target){
13100 return target && c.getPositionEl().dom.parentNode == (target.dom || target);
13104 renderAll : function(ct, target){
13105 var items = ct.items.items, i, c, len = items.length;
13106 for(i = 0; i < len; i++) {
13108 if(c && (!c.rendered || !this.isValidParent(c, target))){
13109 this.renderItem(c, i, target);
13115 renderItem : function(c, position, target){
13118 c.render(target, position);
13119 this.configureItem(c);
13120 } else if (!this.isValidParent(c, target)) {
13121 if (Ext.isNumber(position)) {
13122 position = target.dom.childNodes[position];
13125 target.dom.insertBefore(c.getPositionEl().dom, position || null);
13126 c.container = target;
13127 this.configureItem(c);
13134 getRenderedItems: function(ct){
13135 var t = ct.getLayoutTarget(), cti = ct.items.items, len = cti.length, i, c, items = [];
13136 for (i = 0; i < len; i++) {
13137 if((c = cti[i]).rendered && this.isValidParent(c, t) && c.shouldLayout !== false){
13145 configureItem: function(c){
13146 if (this.extraCls) {
13147 var t = c.getPositionEl ? c.getPositionEl() : c;
13148 t.addClass(this.extraCls);
13152 if (c.doLayout && this.forceLayout) {
13155 if (this.renderHidden && c != this.activeItem) {
13160 onRemove: function(c){
13161 if(this.activeItem == c){
13162 delete this.activeItem;
13164 if(c.rendered && this.extraCls){
13165 var t = c.getPositionEl ? c.getPositionEl() : c;
13166 t.removeClass(this.extraCls);
13170 afterRemove: function(c){
13171 if(c.removeRestore){
13172 c.removeMode = 'container';
13173 delete c.removeRestore;
13178 onResize: function(){
13179 var ct = this.container,
13184 if(b = ct.bufferResize && ct.shouldBufferLayout()){
13185 if(!this.resizeTask){
13186 this.resizeTask = new Ext.util.DelayedTask(this.runLayout, this);
13187 this.resizeBuffer = Ext.isNumber(b) ? b : 50;
13189 ct.layoutPending = true;
13190 this.resizeTask.delay(this.resizeBuffer);
13196 runLayout: function(){
13197 var ct = this.container;
13200 delete ct.layoutPending;
13204 setContainer : function(ct){
13206 if(this.monitorResize && ct != this.container){
13207 var old = this.container;
13209 old.un(old.resizeEvent, this.onResize, this);
13212 ct.on(ct.resizeEvent, this.onResize, this);
13215 this.container = ct;
13219 parseMargins : function(v){
13220 if (Ext.isNumber(v)) {
13223 var ms = v.split(' '),
13227 ms[1] = ms[2] = ms[3] = ms[0];
13228 } else if(len == 2) {
13231 } else if(len == 3) {
13236 top :parseInt(ms[0], 10) || 0,
13237 right :parseInt(ms[1], 10) || 0,
13238 bottom:parseInt(ms[2], 10) || 0,
13239 left :parseInt(ms[3], 10) || 0
13244 fieldTpl: (function() {
13245 var t = new Ext.Template(
13246 '<div class="x-form-item {itemCls}" tabIndex="-1">',
13247 '<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
13248 '<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
13249 '</div><div class="{clearCls}"></div>',
13252 t.disableFormats = true;
13253 return t.compile();
13257 destroy : function(){
13259 if(this.resizeTask && this.resizeTask.cancel){
13260 this.resizeTask.cancel();
13262 if(!Ext.isEmpty(this.targetCls)){
13263 var target = this.container.getLayoutTarget();
13265 target.removeClass(this.targetCls);
13270 Ext.layout.AutoLayout = Ext.extend(Ext.layout.ContainerLayout, {
13273 monitorResize: true,
13275 onLayout : function(ct, target){
13276 Ext.layout.AutoLayout.superclass.onLayout.call(this, ct, target);
13277 var cs = this.getRenderedItems(ct), len = cs.length, i, c;
13278 for(i = 0; i < len; i++){
13288 Ext.Container.LAYOUTS['auto'] = Ext.layout.AutoLayout;
13290 Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
13292 monitorResize:true,
13296 getLayoutTargetSize : function() {
13297 var target = this.container.getLayoutTarget();
13302 return target.getStyleSize();
13306 onLayout : function(ct, target){
13307 Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
13309 this.setItemSize(this.activeItem || ct.items.itemAt(0), this.getLayoutTargetSize());
13314 setItemSize : function(item, size){
13315 if(item && size.height > 0){
13316 item.setSize(size);
13320 Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
13321 Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
13323 deferredRender : false,
13326 layoutOnCardChange : false,
13330 renderHidden : true,
13335 setActiveItem : function(item){
13336 var ai = this.activeItem,
13337 ct = this.container;
13338 item = ct.getComponent(item);
13341 if(item && ai != item){
13346 if (ai.hidden !== true) {
13349 ai.fireEvent('deactivate', ai);
13352 var layout = item.doLayout && (this.layoutOnCardChange || !item.rendered);
13355 this.activeItem = item;
13359 delete item.deferLayout;
13369 item.fireEvent('activate', item);
13374 renderAll : function(ct, target){
13375 if(this.deferredRender){
13376 this.renderItem(this.activeItem, undefined, target);
13378 Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
13382 Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
13384 Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
13388 monitorResize : true,
13393 defaultAnchor : '100%',
13395 parseAnchorRE : /^(r|right|b|bottom)$/i,
13398 getLayoutTargetSize : function() {
13399 var target = this.container.getLayoutTarget(), ret = {};
13401 ret = target.getViewSize();
13406 if (Ext.isIE && Ext.isStrict && ret.width == 0){
13407 ret = target.getStyleSize();
13409 ret.width -= target.getPadding('lr');
13410 ret.height -= target.getPadding('tb');
13416 onLayout : function(container, target) {
13417 Ext.layout.AnchorLayout.superclass.onLayout.call(this, container, target);
13419 var size = this.getLayoutTargetSize(),
13420 containerWidth = size.width,
13421 containerHeight = size.height,
13422 overflow = target.getStyle('overflow'),
13423 components = this.getRenderedItems(container),
13424 len = components.length,
13438 if(containerWidth < 20 && containerHeight < 20){
13443 if(container.anchorSize) {
13444 if(typeof container.anchorSize == 'number') {
13445 anchorWidth = container.anchorSize;
13447 anchorWidth = container.anchorSize.width;
13448 anchorHeight = container.anchorSize.height;
13451 anchorWidth = container.initialConfig.width;
13452 anchorHeight = container.initialConfig.height;
13455 for(i = 0; i < len; i++) {
13456 component = components[i];
13457 el = component.getPositionEl();
13460 if (!component.anchor && component.items && !Ext.isNumber(component.width) && !(Ext.isIE6 && Ext.isStrict)){
13461 component.anchor = this.defaultAnchor;
13464 if(component.anchor) {
13465 anchorSpec = component.anchorSpec;
13468 anchorsArray = component.anchor.split(' ');
13469 component.anchorSpec = anchorSpec = {
13470 right: this.parseAnchor(anchorsArray[0], component.initialConfig.width, anchorWidth),
13471 bottom: this.parseAnchor(anchorsArray[1], component.initialConfig.height, anchorHeight)
13474 calcWidth = anchorSpec.right ? this.adjustWidthAnchor(anchorSpec.right(containerWidth) - el.getMargins('lr'), component) : undefined;
13475 calcHeight = anchorSpec.bottom ? this.adjustHeightAnchor(anchorSpec.bottom(containerHeight) - el.getMargins('tb'), component) : undefined;
13477 if(calcWidth || calcHeight) {
13479 component: component,
13480 width: calcWidth || undefined,
13481 height: calcHeight || undefined
13486 for (i = 0, len = boxes.length; i < len; i++) {
13488 box.component.setSize(box.width, box.height);
13491 if (overflow && overflow != 'hidden' && !this.adjustmentPass) {
13492 var newTargetSize = this.getLayoutTargetSize();
13493 if (newTargetSize.width != size.width || newTargetSize.height != size.height){
13494 this.adjustmentPass = true;
13495 this.onLayout(container, target);
13499 delete this.adjustmentPass;
13503 parseAnchor : function(a, start, cstart) {
13504 if (a && a != 'none') {
13507 if (this.parseAnchorRE.test(a)) {
13508 var diff = cstart - start;
13509 return function(v){
13516 } else if(a.indexOf('%') != -1) {
13517 var ratio = parseFloat(a.replace('%', ''))*.01;
13518 return function(v){
13521 return Math.floor(v*ratio);
13526 a = parseInt(a, 10);
13528 return function(v) {
13541 adjustWidthAnchor : function(value, comp){
13546 adjustHeightAnchor : function(value, comp){
13552 Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
13554 Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
13556 monitorResize:true,
13560 extraCls: 'x-column',
13566 targetCls: 'x-column-layout-ct',
13568 isValidParent : function(c, target){
13569 return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
13572 getLayoutTargetSize : function() {
13573 var target = this.container.getLayoutTarget(), ret;
13575 ret = target.getViewSize();
13580 if (Ext.isIE && Ext.isStrict && ret.width == 0){
13581 ret = target.getStyleSize();
13584 ret.width -= target.getPadding('lr');
13585 ret.height -= target.getPadding('tb');
13590 renderAll : function(ct, target) {
13594 this.innerCt = target.createChild({cls:'x-column-inner'});
13595 this.innerCt.createChild({cls:'x-clear'});
13597 Ext.layout.ColumnLayout.superclass.renderAll.call(this, ct, this.innerCt);
13601 onLayout : function(ct, target){
13602 var cs = ct.items.items,
13609 this.renderAll(ct, target);
13611 var size = this.getLayoutTargetSize();
13613 if(size.width < 1 && size.height < 1){
13617 var w = size.width - this.scrollOffset,
13621 this.innerCt.setWidth(w);
13626 for(i = 0; i < len; i++){
13628 m = c.getPositionEl().getMargins('lr');
13630 if(!c.columnWidth){
13631 pw -= (c.getWidth() + m);
13635 pw = pw < 0 ? 0 : pw;
13637 for(i = 0; i < len; i++){
13641 c.setSize(Math.floor(c.columnWidth * pw) - m);
13648 if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
13649 var ts = this.getLayoutTargetSize();
13650 if (ts.width != size.width){
13651 this.adjustmentPass = true;
13652 this.onLayout(ct, target);
13656 delete this.adjustmentPass;
13662 Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
13664 Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
13666 monitorResize:true,
13672 targetCls: 'x-border-layout-ct',
13674 getLayoutTargetSize : function() {
13675 var target = this.container.getLayoutTarget();
13676 return target ? target.getViewSize() : {};
13680 onLayout : function(ct, target){
13681 var collapsed, i, c, pos, items = ct.items.items, len = items.length;
13682 if(!this.rendered){
13684 for(i = 0; i < len; i++) {
13690 c.collapsed = false;
13692 c.render(target, i);
13693 c.getPositionEl().addClass('x-border-panel');
13695 this[pos] = pos != 'center' && c.split ?
13696 new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
13697 new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
13698 this[pos].render(target, c);
13700 this.rendered = true;
13703 var size = this.getLayoutTargetSize();
13704 if(size.width < 20 || size.height < 20){
13706 this.restoreCollapsed = collapsed;
13709 }else if(this.restoreCollapsed){
13710 collapsed = this.restoreCollapsed;
13711 delete this.restoreCollapsed;
13714 var w = size.width, h = size.height,
13715 centerW = w, centerH = h, centerY = 0, centerX = 0,
13716 n = this.north, s = this.south, west = this.west, e = this.east, c = this.center,
13717 b, m, totalWidth, totalHeight;
13718 if(!c && Ext.layout.BorderLayout.WARN !== false){
13719 throw 'No center region defined in BorderLayout ' + ct.id;
13722 if(n && n.isVisible()){
13724 m = n.getMargins();
13725 b.width = w - (m.left+m.right);
13728 centerY = b.height + b.y + m.bottom;
13729 centerH -= centerY;
13732 if(s && s.isVisible()){
13734 m = s.getMargins();
13735 b.width = w - (m.left+m.right);
13737 totalHeight = (b.height + m.top + m.bottom);
13738 b.y = h - totalHeight + m.top;
13739 centerH -= totalHeight;
13742 if(west && west.isVisible()){
13743 b = west.getSize();
13744 m = west.getMargins();
13745 b.height = centerH - (m.top+m.bottom);
13747 b.y = centerY + m.top;
13748 totalWidth = (b.width + m.left + m.right);
13749 centerX += totalWidth;
13750 centerW -= totalWidth;
13751 west.applyLayout(b);
13753 if(e && e.isVisible()){
13755 m = e.getMargins();
13756 b.height = centerH - (m.top+m.bottom);
13757 totalWidth = (b.width + m.left + m.right);
13758 b.x = w - totalWidth + m.left;
13759 b.y = centerY + m.top;
13760 centerW -= totalWidth;
13764 m = c.getMargins();
13766 x: centerX + m.left,
13767 y: centerY + m.top,
13768 width: centerW - (m.left+m.right),
13769 height: centerH - (m.top+m.bottom)
13771 c.applyLayout(centerBox);
13774 for(i = 0, len = collapsed.length; i < len; i++){
13775 collapsed[i].collapse(false);
13778 if(Ext.isIE && Ext.isStrict){
13782 if (i = target.getStyle('overflow') && i != 'hidden' && !this.adjustmentPass) {
13783 var ts = this.getLayoutTargetSize();
13784 if (ts.width != size.width || ts.height != size.height){
13785 this.adjustmentPass = true;
13786 this.onLayout(ct, target);
13789 delete this.adjustmentPass;
13792 destroy: function() {
13793 var r = ['north', 'south', 'east', 'west'], i, region;
13794 for (i = 0; i < r.length; i++) {
13795 region = this[r[i]];
13797 if(region.destroy){
13799 }else if (region.split){
13800 region.split.destroy(true);
13804 Ext.layout.BorderLayout.superclass.destroy.call(this);
13811 Ext.layout.BorderLayout.Region = function(layout, config, pos){
13812 Ext.apply(this, config);
13813 this.layout = layout;
13814 this.position = pos;
13816 if(typeof this.margins == 'string'){
13817 this.margins = this.layout.parseMargins(this.margins);
13819 this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
13820 if(this.collapsible){
13821 if(typeof this.cmargins == 'string'){
13822 this.cmargins = this.layout.parseMargins(this.cmargins);
13824 if(this.collapseMode == 'mini' && !this.cmargins){
13825 this.cmargins = {left:0,top:0,right:0,bottom:0};
13827 this.cmargins = Ext.applyIf(this.cmargins || {},
13828 pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
13833 Ext.layout.BorderLayout.Region.prototype = {
13840 collapsible : false,
13851 defaultMargins : {left:0,top:0,right:0,bottom:0},
13853 defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
13855 defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
13856 floatingZIndex: 100,
13859 isCollapsed : false,
13866 render : function(ct, p){
13868 p.el.enableDisplayMode();
13869 this.targetEl = ct;
13872 var gs = p.getState, ps = this.position;
13873 p.getState = function(){
13874 return Ext.apply(gs.call(p) || {}, this.state);
13875 }.createDelegate(this);
13877 if(ps != 'center'){
13878 p.allowQueuedExpand = false;
13880 beforecollapse: this.beforeCollapse,
13881 collapse: this.onCollapse,
13882 beforeexpand: this.beforeExpand,
13883 expand: this.onExpand,
13888 if(this.collapsible || this.floatable){
13889 p.collapseEl = 'el';
13890 p.slideAnchor = this.getSlideAnchor();
13892 if(p.tools && p.tools.toggle){
13893 p.tools.toggle.addClass('x-tool-collapse-'+ps);
13894 p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
13900 getCollapsedEl : function(){
13901 if(!this.collapsedEl){
13902 if(!this.toolTemplate){
13903 var tt = new Ext.Template(
13904 '<div class="x-tool x-tool-{id}"> </div>'
13906 tt.disableFormats = true;
13908 Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
13910 this.collapsedEl = this.targetEl.createChild({
13911 cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
13912 id: this.panel.id + '-xcollapsed'
13914 this.collapsedEl.enableDisplayMode('block');
13916 if(this.collapseMode == 'mini'){
13917 this.collapsedEl.addClass('x-layout-cmini-'+this.position);
13918 this.miniCollapsedEl = this.collapsedEl.createChild({
13919 cls: "x-layout-mini x-layout-mini-"+this.position, html: " "
13921 this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
13922 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
13923 this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
13925 if(this.collapsible !== false && !this.hideCollapseTool) {
13926 var t = this.expandToolEl = this.toolTemplate.append(
13927 this.collapsedEl.dom,
13928 {id:'expand-'+this.position}, true);
13929 t.addClassOnOver('x-tool-expand-'+this.position+'-over');
13930 t.on('click', this.onExpandClick, this, {stopEvent:true});
13932 if(this.floatable !== false || this.titleCollapse){
13933 this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
13934 this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this);
13938 return this.collapsedEl;
13942 onExpandClick : function(e){
13944 this.panel.expand(false);
13946 this.panel.expand();
13951 onCollapseClick : function(e){
13952 this.panel.collapse();
13956 beforeCollapse : function(p, animate){
13957 this.lastAnim = animate;
13959 this.splitEl.hide();
13961 this.getCollapsedEl().show();
13962 var el = this.panel.getEl();
13963 this.originalZIndex = el.getStyle('z-index');
13964 el.setStyle('z-index', 100);
13965 this.isCollapsed = true;
13966 this.layout.layout();
13970 onCollapse : function(animate){
13971 this.panel.el.setStyle('z-index', 1);
13972 if(this.lastAnim === false || this.panel.animCollapse === false){
13973 this.getCollapsedEl().dom.style.visibility = 'visible';
13975 this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
13977 this.state.collapsed = true;
13978 this.panel.saveState();
13982 beforeExpand : function(animate){
13984 this.afterSlideIn();
13986 var c = this.getCollapsedEl();
13988 if(this.position == 'east' || this.position == 'west'){
13989 this.panel.setSize(undefined, c.getHeight());
13991 this.panel.setSize(c.getWidth(), undefined);
13994 c.dom.style.visibility = 'hidden';
13995 this.panel.el.setStyle('z-index', this.floatingZIndex);
13999 onExpand : function(){
14000 this.isCollapsed = false;
14002 this.splitEl.show();
14004 this.layout.layout();
14005 this.panel.el.setStyle('z-index', this.originalZIndex);
14006 this.state.collapsed = false;
14007 this.panel.saveState();
14011 collapseClick : function(e){
14013 e.stopPropagation();
14016 e.stopPropagation();
14022 onHide : function(){
14023 if(this.isCollapsed){
14024 this.getCollapsedEl().hide();
14025 }else if(this.splitEl){
14026 this.splitEl.hide();
14031 onShow : function(){
14032 if(this.isCollapsed){
14033 this.getCollapsedEl().show();
14034 }else if(this.splitEl){
14035 this.splitEl.show();
14040 isVisible : function(){
14041 return !this.panel.hidden;
14045 getMargins : function(){
14046 return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
14050 getSize : function(){
14051 return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
14055 setPanel : function(panel){
14056 this.panel = panel;
14060 getMinWidth: function(){
14061 return this.minWidth;
14065 getMinHeight: function(){
14066 return this.minHeight;
14070 applyLayoutCollapsed : function(box){
14071 var ce = this.getCollapsedEl();
14072 ce.setLeftTop(box.x, box.y);
14073 ce.setSize(box.width, box.height);
14077 applyLayout : function(box){
14078 if(this.isCollapsed){
14079 this.applyLayoutCollapsed(box);
14081 this.panel.setPosition(box.x, box.y);
14082 this.panel.setSize(box.width, box.height);
14087 beforeSlide: function(){
14088 this.panel.beforeEffect();
14092 afterSlide : function(){
14093 this.panel.afterEffect();
14097 initAutoHide : function(){
14098 if(this.autoHide !== false){
14099 if(!this.autoHideHd){
14100 this.autoHideSlideTask = new Ext.util.DelayedTask(this.slideIn, this);
14101 this.autoHideHd = {
14102 "mouseout": function(e){
14103 if(!e.within(this.el, true)){
14104 this.autoHideSlideTask.delay(500);
14107 "mouseover" : function(e){
14108 this.autoHideSlideTask.cancel();
14113 this.el.on(this.autoHideHd);
14114 this.collapsedEl.on(this.autoHideHd);
14119 clearAutoHide : function(){
14120 if(this.autoHide !== false){
14121 this.el.un("mouseout", this.autoHideHd.mouseout);
14122 this.el.un("mouseover", this.autoHideHd.mouseover);
14123 this.collapsedEl.un("mouseout", this.autoHideHd.mouseout);
14124 this.collapsedEl.un("mouseover", this.autoHideHd.mouseover);
14129 clearMonitor : function(){
14130 Ext.getDoc().un("click", this.slideInIf, this);
14134 slideOut : function(){
14135 if(this.isSlid || this.el.hasActiveFx()){
14138 this.isSlid = true;
14139 var ts = this.panel.tools, dh, pc;
14140 if(ts && ts.toggle){
14146 pc = this.panel.collapsed;
14147 this.panel.collapsed = false;
14149 if(this.position == 'east' || this.position == 'west'){
14151 dh = this.panel.deferHeight;
14152 this.panel.deferHeight = false;
14154 this.panel.setSize(undefined, this.collapsedEl.getHeight());
14157 this.panel.deferHeight = dh;
14159 this.panel.setSize(this.collapsedEl.getWidth(), undefined);
14163 this.panel.collapsed = pc;
14165 this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
14166 this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
14167 this.el.setStyle("z-index", this.floatingZIndex+2);
14168 this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
14169 if(this.animFloat !== false){
14170 this.beforeSlide();
14171 this.el.slideIn(this.getSlideAnchor(), {
14172 callback: function(){
14174 this.initAutoHide();
14175 Ext.getDoc().on("click", this.slideInIf, this);
14181 this.initAutoHide();
14182 Ext.getDoc().on("click", this.slideInIf, this);
14187 afterSlideIn : function(){
14188 this.clearAutoHide();
14189 this.isSlid = false;
14190 this.clearMonitor();
14191 this.el.setStyle("z-index", "");
14192 this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
14193 this.el.dom.style.left = this.restoreLT[0];
14194 this.el.dom.style.top = this.restoreLT[1];
14196 var ts = this.panel.tools;
14197 if(ts && ts.toggle){
14203 slideIn : function(cb){
14204 if(!this.isSlid || this.el.hasActiveFx()){
14208 this.isSlid = false;
14209 if(this.animFloat !== false){
14210 this.beforeSlide();
14211 this.el.slideOut(this.getSlideAnchor(), {
14212 callback: function(){
14215 this.afterSlideIn();
14223 this.afterSlideIn();
14228 slideInIf : function(e){
14229 if(!e.within(this.el)){
14259 getAnchor : function(){
14260 return this.anchors[this.position];
14264 getCollapseAnchor : function(){
14265 return this.canchors[this.position];
14269 getSlideAnchor : function(){
14270 return this.sanchors[this.position];
14274 getAlignAdj : function(){
14275 var cm = this.cmargins;
14276 switch(this.position){
14293 getExpandAdj : function(){
14294 var c = this.collapsedEl, cm = this.cmargins;
14295 switch(this.position){
14297 return [-(cm.right+c.getWidth()+cm.left), 0];
14300 return [cm.right+c.getWidth()+cm.left, 0];
14303 return [0, -(cm.top+cm.bottom+c.getHeight())];
14306 return [0, cm.top+cm.bottom+c.getHeight()];
14311 destroy : function(){
14312 if (this.autoHideSlideTask && this.autoHideSlideTask.cancel){
14313 this.autoHideSlideTask.cancel();
14315 Ext.destroyMembers(this, 'miniCollapsedEl', 'collapsedEl', 'expandToolEl');
14320 Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
14321 Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
14323 this.applyLayout = this.applyFns[pos];
14326 Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
14329 splitTip : "Drag to resize.",
14331 collapsibleSplitTip : "Drag to resize. Double click to hide.",
14333 useSplitTips : false,
14338 orientation: Ext.SplitBar.VERTICAL,
14339 placement: Ext.SplitBar.TOP,
14340 maxFn : 'getVMaxSize',
14341 minProp: 'minHeight',
14342 maxProp: 'maxHeight'
14345 orientation: Ext.SplitBar.VERTICAL,
14346 placement: Ext.SplitBar.BOTTOM,
14347 maxFn : 'getVMaxSize',
14348 minProp: 'minHeight',
14349 maxProp: 'maxHeight'
14352 orientation: Ext.SplitBar.HORIZONTAL,
14353 placement: Ext.SplitBar.RIGHT,
14354 maxFn : 'getHMaxSize',
14355 minProp: 'minWidth',
14356 maxProp: 'maxWidth'
14359 orientation: Ext.SplitBar.HORIZONTAL,
14360 placement: Ext.SplitBar.LEFT,
14361 maxFn : 'getHMaxSize',
14362 minProp: 'minWidth',
14363 maxProp: 'maxWidth'
14369 west : function(box){
14370 if(this.isCollapsed){
14371 return this.applyLayoutCollapsed(box);
14373 var sd = this.splitEl.dom, s = sd.style;
14374 this.panel.setPosition(box.x, box.y);
14375 var sw = sd.offsetWidth;
14376 s.left = (box.x+box.width-sw)+'px';
14377 s.top = (box.y)+'px';
14378 s.height = Math.max(0, box.height)+'px';
14379 this.panel.setSize(box.width-sw, box.height);
14381 east : function(box){
14382 if(this.isCollapsed){
14383 return this.applyLayoutCollapsed(box);
14385 var sd = this.splitEl.dom, s = sd.style;
14386 var sw = sd.offsetWidth;
14387 this.panel.setPosition(box.x+sw, box.y);
14388 s.left = (box.x)+'px';
14389 s.top = (box.y)+'px';
14390 s.height = Math.max(0, box.height)+'px';
14391 this.panel.setSize(box.width-sw, box.height);
14393 north : function(box){
14394 if(this.isCollapsed){
14395 return this.applyLayoutCollapsed(box);
14397 var sd = this.splitEl.dom, s = sd.style;
14398 var sh = sd.offsetHeight;
14399 this.panel.setPosition(box.x, box.y);
14400 s.left = (box.x)+'px';
14401 s.top = (box.y+box.height-sh)+'px';
14402 s.width = Math.max(0, box.width)+'px';
14403 this.panel.setSize(box.width, box.height-sh);
14405 south : function(box){
14406 if(this.isCollapsed){
14407 return this.applyLayoutCollapsed(box);
14409 var sd = this.splitEl.dom, s = sd.style;
14410 var sh = sd.offsetHeight;
14411 this.panel.setPosition(box.x, box.y+sh);
14412 s.left = (box.x)+'px';
14413 s.top = (box.y)+'px';
14414 s.width = Math.max(0, box.width)+'px';
14415 this.panel.setSize(box.width, box.height-sh);
14420 render : function(ct, p){
14421 Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
14423 var ps = this.position;
14425 this.splitEl = ct.createChild({
14426 cls: "x-layout-split x-layout-split-"+ps, html: " ",
14427 id: this.panel.id + '-xsplit'
14430 if(this.collapseMode == 'mini'){
14431 this.miniSplitEl = this.splitEl.createChild({
14432 cls: "x-layout-mini x-layout-mini-"+ps, html: " "
14434 this.miniSplitEl.addClassOnOver('x-layout-mini-over');
14435 this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
14438 var s = this.splitSettings[ps];
14440 this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
14441 this.split.tickSize = this.tickSize;
14442 this.split.placement = s.placement;
14443 this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
14444 this.split.minSize = this.minSize || this[s.minProp];
14445 this.split.on("beforeapply", this.onSplitMove, this);
14446 this.split.useShim = this.useShim === true;
14447 this.maxSize = this.maxSize || this[s.maxProp];
14450 this.splitEl.hide();
14453 if(this.useSplitTips){
14454 this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
14456 if(this.collapsible){
14457 this.splitEl.on("dblclick", this.onCollapseClick, this);
14462 getSize : function(){
14463 if(this.isCollapsed){
14464 return this.collapsedEl.getSize();
14466 var s = this.panel.getSize();
14467 if(this.position == 'north' || this.position == 'south'){
14468 s.height += this.splitEl.dom.offsetHeight;
14470 s.width += this.splitEl.dom.offsetWidth;
14476 getHMaxSize : function(){
14477 var cmax = this.maxSize || 10000;
14478 var center = this.layout.center;
14479 return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
14483 getVMaxSize : function(){
14484 var cmax = this.maxSize || 10000;
14485 var center = this.layout.center;
14486 return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
14490 onSplitMove : function(split, newSize){
14491 var s = this.panel.getSize();
14492 this.lastSplitSize = newSize;
14493 if(this.position == 'north' || this.position == 'south'){
14494 this.panel.setSize(s.width, newSize);
14495 this.state.height = newSize;
14497 this.panel.setSize(newSize, s.height);
14498 this.state.width = newSize;
14500 this.layout.layout();
14501 this.panel.saveState();
14506 getSplitBar : function(){
14511 destroy : function() {
14512 Ext.destroy(this.miniSplitEl, this.split, this.splitEl);
14513 Ext.layout.BorderLayout.SplitRegion.superclass.destroy.call(this);
14517 Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
14519 Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
14522 labelSeparator : ':',
14531 onRemove: function(c){
14532 Ext.layout.FormLayout.superclass.onRemove.call(this, c);
14533 if(this.trackLabels){
14534 c.un('show', this.onFieldShow, this);
14535 c.un('hide', this.onFieldHide, this);
14538 var el = c.getPositionEl(),
14539 ct = c.getItemCt && c.getItemCt();
14540 if (c.rendered && ct) {
14541 if (el && el.dom) {
14542 el.insertAfter(ct);
14545 Ext.destroyMembers(c, 'label', 'itemCt');
14546 if (c.customItemCt) {
14547 Ext.destroyMembers(c, 'getItemCt', 'customItemCt');
14553 setContainer : function(ct){
14554 Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
14556 ct.addClass('x-form-label-'+ct.labelAlign);
14561 labelStyle: 'display:none',
14562 elementStyle: 'padding-left:0;',
14566 this.labelSeparator = Ext.isDefined(ct.labelSeparator) ? ct.labelSeparator : this.labelSeparator;
14567 ct.labelWidth = ct.labelWidth || 100;
14568 if(Ext.isNumber(ct.labelWidth)){
14569 var pad = Ext.isNumber(ct.labelPad) ? ct.labelPad : 5;
14571 labelAdjust: ct.labelWidth + pad,
14572 labelStyle: 'width:' + ct.labelWidth + 'px;',
14573 elementStyle: 'padding-left:' + (ct.labelWidth + pad) + 'px'
14576 if(ct.labelAlign == 'top'){
14578 labelStyle: 'width:auto;',
14580 elementStyle: 'padding-left:0;'
14587 isHide: function(c){
14588 return c.hideLabel || this.container.hideLabels;
14591 onFieldShow: function(c){
14592 c.getItemCt().removeClass('x-hide-' + c.hideMode);
14595 if (c.isComposite) {
14600 onFieldHide: function(c){
14601 c.getItemCt().addClass('x-hide-' + c.hideMode);
14605 getLabelStyle: function(s){
14606 var ls = '', items = [this.labelStyle, s];
14607 for (var i = 0, len = items.length; i < len; ++i){
14610 if (ls.substr(-1, 1) != ';'){
14621 renderItem : function(c, position, target){
14622 if(c && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
14623 var args = this.getTemplateArgs(c);
14624 if(Ext.isNumber(position)){
14625 position = target.dom.childNodes[position] || null;
14628 c.itemCt = this.fieldTpl.insertBefore(position, args, true);
14630 c.itemCt = this.fieldTpl.append(target, args, true);
14636 getItemCt: function(){
14642 c.label = c.getItemCt().child('label.x-form-item-label');
14644 c.render('x-form-el-' + c.id);
14645 }else if(!this.isValidParent(c, target)){
14646 Ext.fly('x-form-el-' + c.id).appendChild(c.getPositionEl());
14648 if(this.trackLabels){
14650 this.onFieldHide(c);
14654 show: this.onFieldShow,
14655 hide: this.onFieldHide
14658 this.configureItem(c);
14660 Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
14665 getTemplateArgs: function(field) {
14666 var noLabelSep = !field.fieldLabel || field.hideLabel;
14670 label : field.fieldLabel,
14671 itemCls : (field.itemCls || this.container.itemCls || '') + (field.hideLabel ? ' x-hide-label' : ''),
14672 clearCls : field.clearCls || 'x-form-clear-left',
14673 labelStyle : this.getLabelStyle(field.labelStyle),
14674 elementStyle : this.elementStyle || '',
14675 labelSeparator: noLabelSep ? '' : (Ext.isDefined(field.labelSeparator) ? field.labelSeparator : this.labelSeparator)
14680 adjustWidthAnchor: function(value, c){
14681 if(c.label && !this.isHide(c) && (this.container.labelAlign != 'top')){
14682 var adjust = Ext.isIE6 || (Ext.isIE && !Ext.isStrict);
14683 return value - this.labelAdjust + (adjust ? -3 : 0);
14688 adjustHeightAnchor : function(value, c){
14689 if(c.label && !this.isHide(c) && (this.container.labelAlign == 'top')){
14690 return value - c.label.getHeight();
14696 isValidParent : function(c, target){
14697 return target && this.container.getEl().contains(c.getPositionEl());
14703 Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
14705 Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {
14711 titleCollapse : true,
14713 hideCollapseTool : false,
14715 collapseFirst : false,
14721 activeOnTop : false,
14725 renderItem : function(c){
14726 if(this.animate === false){
14727 c.animCollapse = false;
14729 c.collapsible = true;
14730 if(this.autoWidth){
14731 c.autoWidth = true;
14733 if(this.titleCollapse){
14734 c.titleCollapse = true;
14736 if(this.hideCollapseTool){
14737 c.hideCollapseTool = true;
14739 if(this.collapseFirst !== undefined){
14740 c.collapseFirst = this.collapseFirst;
14742 if(!this.activeItem && !c.collapsed){
14743 this.setActiveItem(c, true);
14744 }else if(this.activeItem && this.activeItem != c){
14745 c.collapsed = true;
14747 Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
14748 c.header.addClass('x-accordion-hd');
14749 c.on('beforeexpand', this.beforeExpand, this);
14752 onRemove: function(c){
14753 Ext.layout.AccordionLayout.superclass.onRemove.call(this, c);
14755 c.header.removeClass('x-accordion-hd');
14757 c.un('beforeexpand', this.beforeExpand, this);
14761 beforeExpand : function(p, anim){
14762 var ai = this.activeItem;
14765 delete this.activeItem;
14766 if (!ai.collapsed){
14767 ai.collapse({callback:function(){
14768 p.expand(anim || true);
14773 ai.collapse(this.animate);
14777 if(this.activeOnTop){
14778 p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
14785 setItemSize : function(item, size){
14786 if(this.fill && item){
14787 var hh = 0, i, ct = this.getRenderedItems(this.container), len = ct.length, p;
14789 for (i = 0; i < len; i++) {
14790 if((p = ct[i]) != item && !p.hidden){
14791 hh += p.header.getHeight();
14798 item.setSize(size);
14803 setActiveItem : function(item){
14804 this.setActive(item, true);
14808 setActive : function(item, expand){
14809 var ai = this.activeItem;
14810 item = this.container.getComponent(item);
14812 if(item.rendered && item.collapsed && expand){
14816 ai.fireEvent('deactivate', ai);
14818 this.activeItem = item;
14819 item.fireEvent('activate', item);
14824 Ext.Container.LAYOUTS.accordion = Ext.layout.AccordionLayout;
14827 Ext.layout.Accordion = Ext.layout.AccordionLayout;
14828 Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
14832 monitorResize:false,
14836 targetCls: 'x-table-layout-ct',
14842 setContainer : function(ct){
14843 Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
14845 this.currentRow = 0;
14846 this.currentColumn = 0;
14851 onLayout : function(ct, target){
14852 var cs = ct.items.items, len = cs.length, c, i;
14855 target.addClass('x-table-layout-ct');
14857 this.table = target.createChild(
14858 Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
14860 this.renderAll(ct, target);
14864 getRow : function(index){
14865 var row = this.table.tBodies[0].childNodes[index];
14867 row = document.createElement('tr');
14868 this.table.tBodies[0].appendChild(row);
14874 getNextCell : function(c){
14875 var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
14876 var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
14877 for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
14878 if(!this.cells[rowIndex]){
14879 this.cells[rowIndex] = [];
14881 for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
14882 this.cells[rowIndex][colIndex] = true;
14885 var td = document.createElement('td');
14889 var cls = 'x-table-layout-cell';
14891 cls += ' ' + c.cellCls;
14893 td.className = cls;
14895 td.colSpan = c.colspan;
14898 td.rowSpan = c.rowspan;
14900 this.getRow(curRow).appendChild(td);
14905 getNextNonSpan: function(colIndex, rowIndex){
14906 var cols = this.columns;
14907 while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
14908 if(cols && colIndex >= cols){
14915 return [colIndex, rowIndex];
14919 renderItem : function(c, position, target){
14922 this.table = target.createChild(
14923 Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
14925 if(c && !c.rendered){
14926 c.render(this.getNextCell(c));
14927 this.configureItem(c);
14928 }else if(c && !this.isValidParent(c, target)){
14929 var container = this.getNextCell(c);
14930 container.insertBefore(c.getPositionEl().dom, null);
14931 c.container = Ext.get(container);
14932 this.configureItem(c);
14937 isValidParent : function(c, target){
14938 return c.getPositionEl().up('table', 5).dom.parentNode === (target.dom || target);
14941 destroy: function(){
14943 Ext.layout.TableLayout.superclass.destroy.call(this);
14949 Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
14950 Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
14952 extraCls: 'x-abs-layout-item',
14956 onLayout : function(ct, target){
14958 this.paddingLeft = target.getPadding('l');
14959 this.paddingTop = target.getPadding('t');
14960 Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
14964 adjustWidthAnchor : function(value, comp){
14965 return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
14969 adjustHeightAnchor : function(value, comp){
14970 return value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
14974 Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
14976 Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
14978 defaultMargins : {left:0,top:0,right:0,bottom:0},
14985 monitorResize : true,
14988 extraCls : 'x-box-item',
14989 targetCls : 'x-box-layout-ct',
14990 innerCls : 'x-box-inner',
14992 constructor : function(config){
14993 Ext.layout.BoxLayout.superclass.constructor.call(this, config);
14995 if (Ext.isString(this.defaultMargins)) {
14996 this.defaultMargins = this.parseMargins(this.defaultMargins);
14999 var handler = this.overflowHandler;
15001 if (typeof handler == 'string') {
15007 var handlerType = 'none';
15008 if (handler && handler.type != undefined) {
15009 handlerType = handler.type;
15012 var constructor = Ext.layout.boxOverflow[handlerType];
15013 if (constructor[this.type]) {
15014 constructor = constructor[this.type];
15017 this.overflowHandler = new constructor(this, handler);
15021 onLayout: function(container, target) {
15022 Ext.layout.BoxLayout.superclass.onLayout.call(this, container, target);
15024 var tSize = this.getLayoutTargetSize(),
15025 items = this.getVisibleItems(container),
15026 calcs = this.calculateChildBoxes(items, tSize),
15027 boxes = calcs.boxes,
15031 if (tSize.width > 0) {
15032 var handler = this.overflowHandler,
15033 method = meta.tooNarrow ? 'handleOverflow' : 'clearOverflow';
15035 var results = handler[method](calcs, tSize);
15038 if (results.targetSize) {
15039 tSize = results.targetSize;
15042 if (results.recalculate) {
15043 items = this.getVisibleItems(container);
15044 calcs = this.calculateChildBoxes(items, tSize);
15045 boxes = calcs.boxes;
15051 this.layoutTargetLastSize = tSize;
15054 this.childBoxCache = calcs;
15056 this.updateInnerCtSize(tSize, calcs);
15057 this.updateChildBoxes(boxes);
15060 this.handleTargetOverflow(tSize, container, target);
15064 updateChildBoxes: function(boxes) {
15065 for (var i = 0, length = boxes.length; i < length; i++) {
15066 var box = boxes[i],
15067 comp = box.component;
15069 if (box.dirtySize) {
15070 comp.setSize(box.width, box.height);
15073 if (isNaN(box.left) || isNaN(box.top)) {
15077 comp.setPosition(box.left, box.top);
15082 updateInnerCtSize: function(tSize, calcs) {
15083 var align = this.align,
15084 padding = this.padding,
15085 width = tSize.width,
15086 height = tSize.height;
15088 if (this.type == 'hbox') {
15089 var innerCtWidth = width,
15090 innerCtHeight = calcs.meta.maxHeight + padding.top + padding.bottom;
15092 if (align == 'stretch') {
15093 innerCtHeight = height;
15094 } else if (align == 'middle') {
15095 innerCtHeight = Math.max(height, innerCtHeight);
15098 var innerCtHeight = height,
15099 innerCtWidth = calcs.meta.maxWidth + padding.left + padding.right;
15101 if (align == 'stretch') {
15102 innerCtWidth = width;
15103 } else if (align == 'center') {
15104 innerCtWidth = Math.max(width, innerCtWidth);
15108 this.innerCt.setSize(innerCtWidth || undefined, innerCtHeight || undefined);
15112 handleTargetOverflow: function(previousTargetSize, container, target) {
15113 var overflow = target.getStyle('overflow');
15115 if (overflow && overflow != 'hidden' &&!this.adjustmentPass) {
15116 var newTargetSize = this.getLayoutTargetSize();
15117 if (newTargetSize.width != previousTargetSize.width || newTargetSize.height != previousTargetSize.height){
15118 this.adjustmentPass = true;
15119 this.onLayout(container, target);
15123 delete this.adjustmentPass;
15127 isValidParent : function(c, target) {
15128 return this.innerCt && c.getPositionEl().dom.parentNode == this.innerCt.dom;
15132 getVisibleItems: function(ct) {
15133 var ct = ct || this.container,
15134 t = ct.getLayoutTarget(),
15135 cti = ct.items.items,
15140 for (i = 0; i < len; i++) {
15141 if((c = cti[i]).rendered && this.isValidParent(c, t) && c.hidden !== true && c.collapsed !== true && c.shouldLayout !== false){
15150 renderAll : function(ct, target) {
15151 if (!this.innerCt) {
15153 this.innerCt = target.createChild({cls:this.innerCls});
15154 this.padding = this.parseMargins(this.padding);
15156 Ext.layout.BoxLayout.superclass.renderAll.call(this, ct, this.innerCt);
15159 getLayoutTargetSize : function() {
15160 var target = this.container.getLayoutTarget(), ret;
15163 ret = target.getViewSize();
15168 if (Ext.isIE && Ext.isStrict && ret.width == 0){
15169 ret = target.getStyleSize();
15172 ret.width -= target.getPadding('lr');
15173 ret.height -= target.getPadding('tb');
15180 renderItem : function(c) {
15181 if(Ext.isString(c.margins)){
15182 c.margins = this.parseMargins(c.margins);
15183 }else if(!c.margins){
15184 c.margins = this.defaultMargins;
15186 Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
15190 destroy: function() {
15191 Ext.destroy(this.overflowHandler);
15193 Ext.layout.BoxLayout.superclass.destroy.apply(this, arguments);
15199 Ext.ns('Ext.layout.boxOverflow');
15203 Ext.layout.boxOverflow.None = Ext.extend(Object, {
15204 constructor: function(layout, config) {
15205 this.layout = layout;
15207 Ext.apply(this, config || {});
15210 handleOverflow: Ext.emptyFn,
15212 clearOverflow: Ext.emptyFn
15216 Ext.layout.boxOverflow.none = Ext.layout.boxOverflow.None;
15218 Ext.layout.boxOverflow.Menu = Ext.extend(Ext.layout.boxOverflow.None, {
15220 afterCls: 'x-strip-right',
15223 noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
15225 constructor: function(layout) {
15226 Ext.layout.boxOverflow.Menu.superclass.constructor.apply(this, arguments);
15229 this.menuItems = [];
15233 createInnerElements: function() {
15234 if (!this.afterCt) {
15235 this.afterCt = this.layout.innerCt.insertSibling({cls: this.afterCls}, 'before');
15240 clearOverflow: function(calculations, targetSize) {
15241 var newWidth = targetSize.width + (this.afterCt ? this.afterCt.getWidth() : 0),
15242 items = this.menuItems;
15244 this.hideTrigger();
15246 for (var index = 0, length = items.length; index < length; index++) {
15247 items.pop().component.show();
15252 height: targetSize.height,
15259 showTrigger: function() {
15261 this.menuTrigger.show();
15265 hideTrigger: function() {
15266 if (this.menuTrigger != undefined) {
15267 this.menuTrigger.hide();
15272 beforeMenuShow: function(menu) {
15273 var items = this.menuItems,
15274 len = items.length,
15278 var needsSep = function(group, item){
15279 return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
15285 for (var i = 0; i < len; i++) {
15286 item = items[i].component;
15288 if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
15292 this.addComponentToMenu(menu, item);
15297 if (menu.items.length < 1) {
15298 menu.add(this.noItemsMenuText);
15303 createMenuConfig : function(component, hideOnClick){
15304 var config = Ext.apply({}, component.initialConfig),
15305 group = component.toggleGroup;
15307 Ext.copyTo(config, component, [
15308 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
15311 Ext.apply(config, {
15312 text : component.overflowText || component.text,
15313 hideOnClick: hideOnClick
15316 if (group || component.enableToggle) {
15317 Ext.apply(config, {
15319 checked: component.pressed,
15321 checkchange: function(item, checked){
15322 component.toggle(checked);
15328 delete config.ownerCt;
15329 delete config.xtype;
15336 addComponentToMenu : function(menu, component) {
15337 if (component instanceof Ext.Toolbar.Separator) {
15340 } else if (Ext.isFunction(component.isXType)) {
15341 if (component.isXType('splitbutton')) {
15342 menu.add(this.createMenuConfig(component, true));
15344 } else if (component.isXType('button')) {
15345 menu.add(this.createMenuConfig(component, !component.menu));
15347 } else if (component.isXType('buttongroup')) {
15348 component.items.each(function(item){
15349 this.addComponentToMenu(menu, item);
15356 clearMenu : function(){
15357 var menu = this.moreMenu;
15358 if (menu && menu.items) {
15359 menu.items.each(function(item){
15366 createMenu: function() {
15367 if (!this.menuTrigger) {
15368 this.createInnerElements();
15371 this.menu = new Ext.menu.Menu({
15372 ownerCt : this.layout.container,
15375 beforeshow: this.beforeMenuShow
15380 this.menuTrigger = new Ext.Button({
15381 iconCls : 'x-toolbar-more-icon',
15382 cls : 'x-toolbar-more',
15384 renderTo: this.afterCt
15390 destroy: function() {
15391 Ext.destroy(this.menu, this.menuTrigger);
15395 Ext.layout.boxOverflow.menu = Ext.layout.boxOverflow.Menu;
15399 Ext.layout.boxOverflow.HorizontalMenu = Ext.extend(Ext.layout.boxOverflow.Menu, {
15401 constructor: function() {
15402 Ext.layout.boxOverflow.HorizontalMenu.superclass.constructor.apply(this, arguments);
15405 layout = me.layout,
15406 origFunction = layout.calculateChildBoxes;
15408 layout.calculateChildBoxes = function(visibleItems, targetSize) {
15409 var calcs = origFunction.apply(layout, arguments),
15411 items = me.menuItems;
15415 var hiddenWidth = 0;
15416 for (var index = 0, length = items.length; index < length; index++) {
15417 hiddenWidth += items[index].width;
15420 meta.minimumWidth += hiddenWidth;
15421 meta.tooNarrow = meta.minimumWidth > targetSize.width;
15427 handleOverflow: function(calculations, targetSize) {
15428 this.showTrigger();
15430 var newWidth = targetSize.width - this.afterCt.getWidth(),
15431 boxes = calculations.boxes,
15433 recalculate = false;
15436 for (var index = 0, length = boxes.length; index < length; index++) {
15437 usedWidth += boxes[index].width;
15440 var spareWidth = newWidth - usedWidth,
15444 for (var index = 0, length = this.menuItems.length; index < length; index++) {
15445 var hidden = this.menuItems[index],
15446 comp = hidden.component,
15447 width = hidden.width;
15449 if (width < spareWidth) {
15452 spareWidth -= width;
15454 recalculate = true;
15461 this.menuItems = this.menuItems.slice(showCount);
15463 for (var i = boxes.length - 1; i >= 0; i--) {
15464 var item = boxes[i].component,
15465 right = boxes[i].left + boxes[i].width;
15467 if (right >= newWidth) {
15468 this.menuItems.unshift({
15470 width : boxes[i].width
15480 if (this.menuItems.length == 0) {
15481 this.hideTrigger();
15486 height: targetSize.height,
15489 recalculate: recalculate
15494 Ext.layout.boxOverflow.menu.hbox = Ext.layout.boxOverflow.HorizontalMenu;
15495 Ext.layout.boxOverflow.Scroller = Ext.extend(Ext.layout.boxOverflow.None, {
15497 animateScroll: true,
15500 scrollIncrement: 100,
15506 scrollRepeatInterval: 400,
15509 scrollDuration: 0.4,
15512 beforeCls: 'x-strip-left',
15515 afterCls: 'x-strip-right',
15518 scrollerCls: 'x-strip-scroller',
15521 beforeScrollerCls: 'x-strip-scroller-left',
15524 afterScrollerCls: 'x-strip-scroller-right',
15527 createWheelListener: function() {
15528 this.layout.innerCt.on({
15530 mousewheel: function(e) {
15533 this.scrollBy(e.getWheelDelta() * this.wheelIncrement * -1, false);
15539 handleOverflow: function(calculations, targetSize) {
15540 this.createInnerElements();
15541 this.showScrollers();
15545 clearOverflow: function() {
15546 this.hideScrollers();
15550 showScrollers: function() {
15551 this.createScrollers();
15553 this.beforeScroller.show();
15554 this.afterScroller.show();
15556 this.updateScrollButtons();
15560 hideScrollers: function() {
15561 if (this.beforeScroller != undefined) {
15562 this.beforeScroller.hide();
15563 this.afterScroller.hide();
15568 createScrollers: function() {
15569 if (!this.beforeScroller && !this.afterScroller) {
15570 var before = this.beforeCt.createChild({
15571 cls: String.format("{0} {1} ", this.scrollerCls, this.beforeScrollerCls)
15574 var after = this.afterCt.createChild({
15575 cls: String.format("{0} {1}", this.scrollerCls, this.afterScrollerCls)
15578 before.addClassOnOver(this.beforeScrollerCls + '-hover');
15579 after.addClassOnOver(this.afterScrollerCls + '-hover');
15581 before.setVisibilityMode(Ext.Element.DISPLAY);
15582 after.setVisibilityMode(Ext.Element.DISPLAY);
15584 this.beforeRepeater = new Ext.util.ClickRepeater(before, {
15585 interval: this.scrollRepeatInterval,
15586 handler : this.scrollLeft,
15590 this.afterRepeater = new Ext.util.ClickRepeater(after, {
15591 interval: this.scrollRepeatInterval,
15592 handler : this.scrollRight,
15597 this.beforeScroller = before;
15600 this.afterScroller = after;
15605 destroy: function() {
15606 Ext.destroy(this.beforeScroller, this.afterScroller, this.beforeRepeater, this.afterRepeater, this.beforeCt, this.afterCt);
15610 scrollBy: function(delta, animate) {
15611 this.scrollTo(this.getScrollPosition() + delta, animate);
15615 getItem: function(item) {
15616 if (Ext.isString(item)) {
15617 item = Ext.getCmp(item);
15618 } else if (Ext.isNumber(item)) {
15619 item = this.items[item];
15626 getScrollAnim: function() {
15628 duration: this.scrollDuration,
15629 callback: this.updateScrollButtons,
15635 updateScrollButtons: function() {
15636 if (this.beforeScroller == undefined || this.afterScroller == undefined) {
15640 var beforeMeth = this.atExtremeBefore() ? 'addClass' : 'removeClass',
15641 afterMeth = this.atExtremeAfter() ? 'addClass' : 'removeClass',
15642 beforeCls = this.beforeScrollerCls + '-disabled',
15643 afterCls = this.afterScrollerCls + '-disabled';
15645 this.beforeScroller[beforeMeth](beforeCls);
15646 this.afterScroller[afterMeth](afterCls);
15647 this.scrolling = false;
15651 atExtremeBefore: function() {
15652 return this.getScrollPosition() === 0;
15656 scrollLeft: function(animate) {
15657 this.scrollBy(-this.scrollIncrement, animate);
15661 scrollRight: function(animate) {
15662 this.scrollBy(this.scrollIncrement, animate);
15666 scrollToItem: function(item, animate) {
15667 item = this.getItem(item);
15669 if (item != undefined) {
15670 var visibility = this.getItemVisibility(item);
15672 if (!visibility.fullyVisible) {
15673 var box = item.getBox(true, true),
15676 if (visibility.hiddenRight) {
15677 newX -= (this.layout.innerCt.getWidth() - box.width);
15680 this.scrollTo(newX, animate);
15686 getItemVisibility: function(item) {
15687 var box = this.getItem(item).getBox(true, true),
15689 itemRight = box.x + box.width,
15690 scrollLeft = this.getScrollPosition(),
15691 scrollRight = this.layout.innerCt.getWidth() + scrollLeft;
15694 hiddenLeft : itemLeft < scrollLeft,
15695 hiddenRight : itemRight > scrollRight,
15696 fullyVisible: itemLeft > scrollLeft && itemRight < scrollRight
15701 Ext.layout.boxOverflow.scroller = Ext.layout.boxOverflow.Scroller;
15705 Ext.layout.boxOverflow.VerticalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
15706 scrollIncrement: 75,
15707 wheelIncrement : 2,
15709 handleOverflow: function(calculations, targetSize) {
15710 Ext.layout.boxOverflow.VerticalScroller.superclass.handleOverflow.apply(this, arguments);
15714 height: targetSize.height - (this.beforeCt.getHeight() + this.afterCt.getHeight()),
15715 width : targetSize.width
15721 createInnerElements: function() {
15722 var target = this.layout.innerCt;
15726 if (!this.beforeCt) {
15727 this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
15728 this.afterCt = target.insertSibling({cls: this.afterCls}, 'after');
15730 this.createWheelListener();
15735 scrollTo: function(position, animate) {
15736 var oldPosition = this.getScrollPosition(),
15737 newPosition = position.constrain(0, this.getMaxScrollBottom());
15739 if (newPosition != oldPosition && !this.scrolling) {
15740 if (animate == undefined) {
15741 animate = this.animateScroll;
15744 this.layout.innerCt.scrollTo('top', newPosition, animate ? this.getScrollAnim() : false);
15747 this.scrolling = true;
15749 this.scrolling = false;
15750 this.updateScrollButtons();
15756 getScrollPosition: function(){
15757 return parseInt(this.layout.innerCt.dom.scrollTop, 10) || 0;
15761 getMaxScrollBottom: function() {
15762 return this.layout.innerCt.dom.scrollHeight - this.layout.innerCt.getHeight();
15766 atExtremeAfter: function() {
15767 return this.getScrollPosition() >= this.getMaxScrollBottom();
15771 Ext.layout.boxOverflow.scroller.vbox = Ext.layout.boxOverflow.VerticalScroller;
15775 Ext.layout.boxOverflow.HorizontalScroller = Ext.extend(Ext.layout.boxOverflow.Scroller, {
15776 handleOverflow: function(calculations, targetSize) {
15777 Ext.layout.boxOverflow.HorizontalScroller.superclass.handleOverflow.apply(this, arguments);
15781 height: targetSize.height,
15782 width : targetSize.width - (this.beforeCt.getWidth() + this.afterCt.getWidth())
15788 createInnerElements: function() {
15789 var target = this.layout.innerCt;
15793 if (!this.beforeCt) {
15794 this.afterCt = target.insertSibling({cls: this.afterCls}, 'before');
15795 this.beforeCt = target.insertSibling({cls: this.beforeCls}, 'before');
15797 this.createWheelListener();
15802 scrollTo: function(position, animate) {
15803 var oldPosition = this.getScrollPosition(),
15804 newPosition = position.constrain(0, this.getMaxScrollRight());
15806 if (newPosition != oldPosition && !this.scrolling) {
15807 if (animate == undefined) {
15808 animate = this.animateScroll;
15811 this.layout.innerCt.scrollTo('left', newPosition, animate ? this.getScrollAnim() : false);
15814 this.scrolling = true;
15816 this.scrolling = false;
15817 this.updateScrollButtons();
15823 getScrollPosition: function(){
15824 return parseInt(this.layout.innerCt.dom.scrollLeft, 10) || 0;
15828 getMaxScrollRight: function() {
15829 return this.layout.innerCt.dom.scrollWidth - this.layout.innerCt.getWidth();
15833 atExtremeAfter: function() {
15834 return this.getScrollPosition() >= this.getMaxScrollRight();
15838 Ext.layout.boxOverflow.scroller.hbox = Ext.layout.boxOverflow.HorizontalScroller;
15839 Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
15849 calculateChildBoxes: function(visibleItems, targetSize) {
15850 var visibleCount = visibleItems.length,
15852 padding = this.padding,
15853 topOffset = padding.top,
15854 leftOffset = padding.left,
15855 paddingVert = topOffset + padding.bottom,
15856 paddingHoriz = leftOffset + padding.right,
15858 width = targetSize.width - this.scrollOffset,
15859 height = targetSize.height,
15860 availHeight = Math.max(0, height - paddingVert),
15862 isStart = this.pack == 'start',
15863 isCenter = this.pack == 'center',
15864 isEnd = this.pack == 'end',
15876 child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth,
15877 horizMargins, vertMargins, stretchHeight;
15880 for (i = 0; i < visibleCount; i++) {
15881 child = visibleItems[i];
15882 childHeight = child.height;
15883 childWidth = child.width;
15884 canLayout = !child.hasLayout && typeof child.doLayout == 'function';
15887 if (typeof childWidth != 'number') {
15890 if (child.flex && !childWidth) {
15891 totalFlex += child.flex;
15897 if (!childWidth && canLayout) {
15901 childSize = child.getSize();
15902 childWidth = childSize.width;
15903 childHeight = childSize.height;
15907 childMargins = child.margins;
15908 horizMargins = childMargins.left + childMargins.right;
15910 nonFlexWidth += horizMargins + (childWidth || 0);
15911 desiredWidth += horizMargins + (child.flex ? child.minWidth || 0 : childWidth);
15912 minimumWidth += horizMargins + (child.minWidth || childWidth || 0);
15915 if (typeof childHeight != 'number') {
15919 childHeight = child.getHeight();
15922 maxHeight = Math.max(maxHeight, childHeight + childMargins.top + childMargins.bottom);
15927 height : childHeight || undefined,
15928 width : childWidth || undefined
15932 var shortfall = desiredWidth - width,
15933 tooNarrow = minimumWidth > width;
15936 var availableWidth = Math.max(0, width - nonFlexWidth - paddingHoriz);
15939 for (i = 0; i < visibleCount; i++) {
15940 boxes[i].width = visibleItems[i].minWidth || visibleItems[i].width || boxes[i].width;
15945 if (shortfall > 0) {
15946 var minWidths = [];
15949 for (var index = 0, length = visibleCount; index < length; index++) {
15950 var item = visibleItems[index],
15951 minWidth = item.minWidth || 0;
15956 boxes[index].width = minWidth;
15959 minWidth : minWidth,
15960 available: boxes[index].width - minWidth,
15967 minWidths.sort(function(a, b) {
15968 return a.available > b.available ? 1 : -1;
15972 for (var i = 0, length = minWidths.length; i < length; i++) {
15973 var itemIndex = minWidths[i].index;
15975 if (itemIndex == undefined) {
15979 var item = visibleItems[itemIndex],
15980 box = boxes[itemIndex],
15981 oldWidth = box.width,
15982 minWidth = item.minWidth,
15983 newWidth = Math.max(minWidth, oldWidth - Math.ceil(shortfall / (length - i))),
15984 reduction = oldWidth - newWidth;
15986 boxes[itemIndex].width = newWidth;
15987 shortfall -= reduction;
15991 var remainingWidth = availableWidth,
15992 remainingFlex = totalFlex;
15995 for (i = 0; i < visibleCount; i++) {
15996 child = visibleItems[i];
15999 childMargins = child.margins;
16000 vertMargins = childMargins.top + childMargins.bottom;
16002 if (isStart && child.flex && !child.width) {
16003 flexedWidth = Math.ceil((child.flex / remainingFlex) * remainingWidth);
16004 remainingWidth -= flexedWidth;
16005 remainingFlex -= child.flex;
16007 calcs.width = flexedWidth;
16008 calcs.dirtySize = true;
16015 leftOffset += availableWidth / 2;
16016 } else if (isEnd) {
16017 leftOffset += availableWidth;
16021 for (i = 0; i < visibleCount; i++) {
16022 child = visibleItems[i];
16025 childMargins = child.margins;
16026 leftOffset += childMargins.left;
16027 vertMargins = childMargins.top + childMargins.bottom;
16029 calcs.left = leftOffset;
16030 calcs.top = topOffset + childMargins.top;
16032 switch (this.align) {
16034 stretchHeight = availHeight - vertMargins;
16035 calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
16036 calcs.dirtySize = true;
16039 stretchHeight = maxHeight - vertMargins;
16040 calcs.height = stretchHeight.constrain(child.minHeight || 0, child.maxHeight || 1000000);
16041 calcs.dirtySize = true;
16044 var diff = availHeight - calcs.height - vertMargins;
16046 calcs.top = topOffset + vertMargins + (diff / 2);
16050 leftOffset += calcs.width + childMargins.right;
16056 maxHeight : maxHeight,
16057 nonFlexWidth: nonFlexWidth,
16058 desiredWidth: desiredWidth,
16059 minimumWidth: minimumWidth,
16060 shortfall : desiredWidth - width,
16061 tooNarrow : tooNarrow
16067 Ext.Container.LAYOUTS.hbox = Ext.layout.HBoxLayout;
16068 Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
16078 calculateChildBoxes: function(visibleItems, targetSize) {
16079 var visibleCount = visibleItems.length,
16081 padding = this.padding,
16082 topOffset = padding.top,
16083 leftOffset = padding.left,
16084 paddingVert = topOffset + padding.bottom,
16085 paddingHoriz = leftOffset + padding.right,
16087 width = targetSize.width - this.scrollOffset,
16088 height = targetSize.height,
16089 availWidth = Math.max(0, width - paddingHoriz),
16091 isStart = this.pack == 'start',
16092 isCenter = this.pack == 'center',
16093 isEnd = this.pack == 'end',
16105 child, childWidth, childHeight, childSize, childMargins, canLayout, i, calcs, flexedWidth,
16106 horizMargins, vertMargins, stretchWidth;
16109 for (i = 0; i < visibleCount; i++) {
16110 child = visibleItems[i];
16111 childHeight = child.height;
16112 childWidth = child.width;
16113 canLayout = !child.hasLayout && typeof child.doLayout == 'function';
16116 if (typeof childHeight != 'number') {
16119 if (child.flex && !childHeight) {
16120 totalFlex += child.flex;
16126 if (!childHeight && canLayout) {
16130 childSize = child.getSize();
16131 childWidth = childSize.width;
16132 childHeight = childSize.height;
16136 childMargins = child.margins;
16137 vertMargins = childMargins.top + childMargins.bottom;
16139 nonFlexHeight += vertMargins + (childHeight || 0);
16140 desiredHeight += vertMargins + (child.flex ? child.minHeight || 0 : childHeight);
16141 minimumHeight += vertMargins + (child.minHeight || childHeight || 0);
16144 if (typeof childWidth != 'number') {
16148 childWidth = child.getWidth();
16151 maxWidth = Math.max(maxWidth, childWidth + childMargins.left + childMargins.right);
16156 height : childHeight || undefined,
16157 width : childWidth || undefined
16161 var shortfall = desiredHeight - height,
16162 tooNarrow = minimumHeight > height;
16165 var availableHeight = Math.max(0, (height - nonFlexHeight - paddingVert));
16168 for (i = 0, length = visibleCount; i < length; i++) {
16169 boxes[i].height = visibleItems[i].minHeight || visibleItems[i].height || boxes[i].height;
16174 if (shortfall > 0) {
16175 var minHeights = [];
16178 for (var index = 0, length = visibleCount; index < length; index++) {
16179 var item = visibleItems[index],
16180 minHeight = item.minHeight || 0;
16185 boxes[index].height = minHeight;
16188 minHeight: minHeight,
16189 available: boxes[index].height - minHeight,
16196 minHeights.sort(function(a, b) {
16197 return a.available > b.available ? 1 : -1;
16201 for (var i = 0, length = minHeights.length; i < length; i++) {
16202 var itemIndex = minHeights[i].index;
16204 if (itemIndex == undefined) {
16208 var item = visibleItems[itemIndex],
16209 box = boxes[itemIndex],
16210 oldHeight = box.height,
16211 minHeight = item.minHeight,
16212 newHeight = Math.max(minHeight, oldHeight - Math.ceil(shortfall / (length - i))),
16213 reduction = oldHeight - newHeight;
16215 boxes[itemIndex].height = newHeight;
16216 shortfall -= reduction;
16220 var remainingHeight = availableHeight,
16221 remainingFlex = totalFlex;
16224 for (i = 0; i < visibleCount; i++) {
16225 child = visibleItems[i];
16228 childMargins = child.margins;
16229 horizMargins = childMargins.left + childMargins.right;
16231 if (isStart && child.flex && !child.height) {
16232 flexedHeight = Math.ceil((child.flex / remainingFlex) * remainingHeight);
16233 remainingHeight -= flexedHeight;
16234 remainingFlex -= child.flex;
16236 calcs.height = flexedHeight;
16237 calcs.dirtySize = true;
16244 topOffset += availableHeight / 2;
16245 } else if (isEnd) {
16246 topOffset += availableHeight;
16250 for (i = 0; i < visibleCount; i++) {
16251 child = visibleItems[i];
16254 childMargins = child.margins;
16255 topOffset += childMargins.top;
16256 horizMargins = childMargins.left + childMargins.right;
16259 calcs.left = leftOffset + childMargins.left;
16260 calcs.top = topOffset;
16262 switch (this.align) {
16264 stretchWidth = availWidth - horizMargins;
16265 calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
16266 calcs.dirtySize = true;
16269 stretchWidth = maxWidth - horizMargins;
16270 calcs.width = stretchWidth.constrain(child.minWidth || 0, child.maxWidth || 1000000);
16271 calcs.dirtySize = true;
16274 var diff = availWidth - calcs.width - horizMargins;
16276 calcs.left = leftOffset + horizMargins + (diff / 2);
16280 topOffset += calcs.height + childMargins.bottom;
16286 maxWidth : maxWidth,
16287 nonFlexHeight: nonFlexHeight,
16288 desiredHeight: desiredHeight,
16289 minimumHeight: minimumHeight,
16290 shortfall : desiredHeight - height,
16291 tooNarrow : tooNarrow
16297 Ext.Container.LAYOUTS.vbox = Ext.layout.VBoxLayout;
16299 Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
16300 monitorResize : true,
16308 noItemsMenuText : '<div class="x-toolbar-no-items">(None)</div>',
16311 lastOverflow: false,
16315 '<table cellspacing="0" class="x-toolbar-ct">',
16318 '<td class="x-toolbar-left" align="{0}">',
16319 '<table cellspacing="0">',
16321 '<tr class="x-toolbar-left-row"></tr>',
16325 '<td class="x-toolbar-right" align="right">',
16326 '<table cellspacing="0" class="x-toolbar-right-ct">',
16330 '<table cellspacing="0">',
16332 '<tr class="x-toolbar-right-row"></tr>',
16337 '<table cellspacing="0">',
16339 '<tr class="x-toolbar-extras-row"></tr>',
16353 onLayout : function(ct, target) {
16355 if (!this.leftTr) {
16356 var align = ct.buttonAlign == 'center' ? 'center' : 'left';
16358 target.addClass('x-toolbar-layout-ct');
16359 target.insertHtml('beforeEnd', String.format(this.tableHTML, align));
16361 this.leftTr = target.child('tr.x-toolbar-left-row', true);
16362 this.rightTr = target.child('tr.x-toolbar-right-row', true);
16363 this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
16365 if (this.hiddenItem == undefined) {
16367 this.hiddenItems = [];
16371 var side = ct.buttonAlign == 'right' ? this.rightTr : this.leftTr,
16372 items = ct.items.items,
16376 for (var i = 0, len = items.length, c; i < len; i++, position++) {
16380 side = this.rightTr;
16382 } else if (!c.rendered) {
16383 c.render(this.insertCell(c, side, position));
16384 this.configureItem(c);
16386 if (!c.xtbHidden && !this.isValidParent(c, side.childNodes[position])) {
16387 var td = this.insertCell(c, side, position);
16388 td.appendChild(c.getPositionEl().dom);
16389 c.container = Ext.get(td);
16395 this.cleanup(this.leftTr);
16396 this.cleanup(this.rightTr);
16397 this.cleanup(this.extrasTr);
16398 this.fitToSize(target);
16402 cleanup : function(el) {
16403 var cn = el.childNodes, i, c;
16405 for (i = cn.length-1; i >= 0 && (c = cn[i]); i--) {
16406 if (!c.firstChild) {
16413 insertCell : function(c, target, position) {
16414 var td = document.createElement('td');
16415 td.className = 'x-toolbar-cell';
16417 target.insertBefore(td, target.childNodes[position] || null);
16423 hideItem : function(item) {
16424 this.hiddenItems.push(item);
16426 item.xtbHidden = true;
16427 item.xtbWidth = item.getPositionEl().dom.parentNode.offsetWidth;
16432 unhideItem : function(item) {
16434 item.xtbHidden = false;
16435 this.hiddenItems.remove(item);
16439 getItemWidth : function(c) {
16440 return c.hidden ? (c.xtbWidth || 0) : c.getPositionEl().dom.parentNode.offsetWidth;
16444 fitToSize : function(target) {
16445 if (this.container.enableOverflow === false) {
16449 var width = target.dom.clientWidth,
16450 tableWidth = target.dom.firstChild.offsetWidth,
16451 clipWidth = width - this.triggerWidth,
16452 lastWidth = this.lastWidth || 0,
16454 hiddenItems = this.hiddenItems,
16455 hasHiddens = hiddenItems.length != 0,
16456 isLarger = width >= lastWidth;
16458 this.lastWidth = width;
16460 if (tableWidth > width || (hasHiddens && isLarger)) {
16461 var items = this.container.items.items,
16462 len = items.length,
16466 for (var i = 0; i < len; i++) {
16469 if (!item.isFill) {
16470 loopWidth += this.getItemWidth(item);
16471 if (loopWidth > clipWidth) {
16472 if (!(item.hidden || item.xtbHidden)) {
16473 this.hideItem(item);
16475 } else if (item.xtbHidden) {
16476 this.unhideItem(item);
16483 hasHiddens = hiddenItems.length != 0;
16488 if (!this.lastOverflow) {
16489 this.container.fireEvent('overflowchange', this.container, true);
16490 this.lastOverflow = true;
16492 } else if (this.more) {
16494 this.more.destroy();
16497 if (this.lastOverflow) {
16498 this.container.fireEvent('overflowchange', this.container, false);
16499 this.lastOverflow = false;
16505 createMenuConfig : function(component, hideOnClick){
16506 var config = Ext.apply({}, component.initialConfig),
16507 group = component.toggleGroup;
16509 Ext.copyTo(config, component, [
16510 'iconCls', 'icon', 'itemId', 'disabled', 'handler', 'scope', 'menu'
16513 Ext.apply(config, {
16514 text : component.overflowText || component.text,
16515 hideOnClick: hideOnClick
16518 if (group || component.enableToggle) {
16519 Ext.apply(config, {
16521 checked: component.pressed,
16523 checkchange: function(item, checked){
16524 component.toggle(checked);
16530 delete config.ownerCt;
16531 delete config.xtype;
16538 addComponentToMenu : function(menu, component) {
16539 if (component instanceof Ext.Toolbar.Separator) {
16542 } else if (Ext.isFunction(component.isXType)) {
16543 if (component.isXType('splitbutton')) {
16544 menu.add(this.createMenuConfig(component, true));
16546 } else if (component.isXType('button')) {
16547 menu.add(this.createMenuConfig(component, !component.menu));
16549 } else if (component.isXType('buttongroup')) {
16550 component.items.each(function(item){
16551 this.addComponentToMenu(menu, item);
16558 clearMenu : function(){
16559 var menu = this.moreMenu;
16560 if (menu && menu.items) {
16561 menu.items.each(function(item){
16568 beforeMoreShow : function(menu) {
16569 var items = this.container.items.items,
16570 len = items.length,
16574 var needsSep = function(group, item){
16575 return group.isXType('buttongroup') && !(item instanceof Ext.Toolbar.Separator);
16580 for (var i = 0; i < len; i++) {
16582 if (item.xtbHidden) {
16583 if (prev && (needsSep(item, prev) || needsSep(prev, item))) {
16586 this.addComponentToMenu(menu, item);
16592 if (menu.items.length < 1) {
16593 menu.add(this.noItemsMenuText);
16598 initMore : function(){
16601 this.moreMenu = new Ext.menu.Menu({
16602 ownerCt : this.container,
16604 beforeshow: this.beforeMoreShow,
16610 this.more = new Ext.Button({
16611 iconCls: 'x-toolbar-more-icon',
16612 cls : 'x-toolbar-more',
16613 menu : this.moreMenu,
16614 ownerCt: this.container
16617 var td = this.insertCell(this.more, this.extrasTr, 100);
16618 this.more.render(td);
16622 destroy : function(){
16623 Ext.destroy(this.more, this.moreMenu);
16624 delete this.leftTr;
16625 delete this.rightTr;
16626 delete this.extrasTr;
16627 Ext.layout.ToolbarLayout.superclass.destroy.call(this);
16631 Ext.Container.LAYOUTS.toolbar = Ext.layout.ToolbarLayout;
16633 Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, {
16634 monitorResize : true,
16638 setContainer : function(ct){
16639 this.monitorResize = !ct.floating;
16642 ct.on('autosize', this.doAutoSize, this);
16643 Ext.layout.MenuLayout.superclass.setContainer.call(this, ct);
16646 renderItem : function(c, position, target){
16647 if (!this.itemTpl) {
16648 this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate(
16649 '<li id="{itemId}" class="{itemCls}">',
16650 '<tpl if="needsIcon">',
16651 '<img alt="{altText}" src="{icon}" class="{iconCls}"/>',
16657 if(c && !c.rendered){
16658 if(Ext.isNumber(position)){
16659 position = target.dom.childNodes[position];
16661 var a = this.getItemArgs(c);
16664 c.render(c.positionEl = position ?
16665 this.itemTpl.insertBefore(position, a, true) :
16666 this.itemTpl.append(target, a, true));
16669 c.positionEl.menuItemId = c.getItemId();
16673 if (!a.isMenuItem && a.needsIcon) {
16674 c.positionEl.addClass('x-menu-list-item-indent');
16676 this.configureItem(c);
16677 }else if(c && !this.isValidParent(c, target)){
16678 if(Ext.isNumber(position)){
16679 position = target.dom.childNodes[position];
16681 target.dom.insertBefore(c.getActionEl().dom, position || null);
16685 getItemArgs : function(c) {
16686 var isMenuItem = c instanceof Ext.menu.Item,
16687 canHaveIcon = !(isMenuItem || c instanceof Ext.menu.Separator);
16690 isMenuItem: isMenuItem,
16691 needsIcon: canHaveIcon && (c.icon || c.iconCls),
16692 icon: c.icon || Ext.BLANK_IMAGE_URL,
16693 iconCls: 'x-menu-item-icon ' + (c.iconCls || ''),
16694 itemId: 'x-menu-el-' + c.id,
16695 itemCls: 'x-menu-list-item ',
16696 altText: c.altText || ''
16701 isValidParent : function(c, target) {
16702 return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target);
16705 onLayout : function(ct, target){
16706 Ext.layout.MenuLayout.superclass.onLayout.call(this, ct, target);
16710 doAutoSize : function(){
16711 var ct = this.container, w = ct.width;
16715 }else if(Ext.isIE){
16716 ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8) ? 'auto' : ct.minWidth);
16717 var el = ct.getEl(), t = el.dom.offsetWidth;
16718 ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr'));
16723 Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout;
16725 Ext.Viewport = Ext.extend(Ext.Container, {
16739 initComponent : function() {
16740 Ext.Viewport.superclass.initComponent.call(this);
16741 document.getElementsByTagName('html')[0].className += ' x-viewport';
16742 this.el = Ext.getBody();
16743 this.el.setHeight = Ext.emptyFn;
16744 this.el.setWidth = Ext.emptyFn;
16745 this.el.setSize = Ext.emptyFn;
16746 this.el.dom.scroll = 'no';
16747 this.allowDomMove = false;
16748 this.autoWidth = true;
16749 this.autoHeight = true;
16750 Ext.EventManager.onWindowResize(this.fireResize, this);
16751 this.renderTo = this.el;
16754 fireResize : function(w, h){
16755 this.fireEvent('resize', this, w, h, w, h);
16758 Ext.reg('viewport', Ext.Viewport);
16760 Ext.Panel = Ext.extend(Ext.Container, {
16805 baseCls : 'x-panel',
16807 collapsedCls : 'x-panel-collapsed',
16809 maskDisabled : true,
16811 animCollapse : Ext.enableFx,
16813 headerAsText : true,
16815 buttonAlign : 'right',
16819 collapseFirst : true,
16821 minButtonWidth : 75,
16826 preventBodyReset : false,
16829 padding: undefined,
16832 resizeEvent: 'bodyresize',
16837 toolTarget : 'header',
16838 collapseEl : 'bwrap',
16840 disabledClass : '',
16843 deferHeight : true,
16849 collapseDefaults : {
16854 initComponent : function(){
16855 Ext.Panel.superclass.initComponent.call(this);
16883 this.baseCls = 'x-plain';
16887 this.toolbars = [];
16890 this.elements += ',tbar';
16891 this.topToolbar = this.createToolbar(this.tbar);
16896 this.elements += ',bbar';
16897 this.bottomToolbar = this.createToolbar(this.bbar);
16901 if(this.header === true){
16902 this.elements += ',header';
16903 this.header = null;
16904 }else if(this.headerCfg || (this.title && this.header !== false)){
16905 this.elements += ',header';
16908 if(this.footerCfg || this.footer === true){
16909 this.elements += ',footer';
16910 this.footer = null;
16914 this.fbar = this.buttons;
16915 this.buttons = null;
16918 this.createFbar(this.fbar);
16921 this.on('render', this.doAutoLoad, this, {delay:10});
16926 createFbar : function(fbar){
16927 var min = this.minButtonWidth;
16928 this.elements += ',footer';
16929 this.fbar = this.createToolbar(fbar, {
16930 buttonAlign: this.buttonAlign,
16931 toolbarCls: 'x-panel-fbar',
16932 enableOverflow: false,
16933 defaults: function(c){
16935 minWidth: c.minWidth || min
16942 this.fbar.items.each(function(c){
16943 c.minWidth = c.minWidth || this.minButtonWidth;
16945 this.buttons = this.fbar.items.items;
16949 createToolbar: function(tb, options){
16952 if(Ext.isArray(tb)){
16957 result = tb.events ? Ext.apply(tb, options) : this.createComponent(Ext.apply({}, tb, options), 'toolbar');
16958 this.toolbars.push(result);
16963 createElement : function(name, pnode){
16965 pnode.appendChild(this[name].dom);
16969 if(name === 'bwrap' || this.elements.indexOf(name) != -1){
16970 if(this[name+'Cfg']){
16971 this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
16973 var el = document.createElement('div');
16974 el.className = this[name+'Cls'];
16975 this[name] = Ext.get(pnode.appendChild(el));
16977 if(this[name+'CssClass']){
16978 this[name].addClass(this[name+'CssClass']);
16980 if(this[name+'Style']){
16981 this[name].applyStyles(this[name+'Style']);
16987 onRender : function(ct, position){
16988 Ext.Panel.superclass.onRender.call(this, ct, position);
16989 this.createClasses();
16997 if(this.collapsible && !this.hideCollapseTool){
16998 this.tools = this.tools ? this.tools.slice(0) : [];
16999 this.tools[this.collapseFirst?'unshift':'push']({
17001 handler : this.toggleCollapse,
17008 this.elements += (this.header !== false) ? ',header' : '';
17012 el.addClass(this.baseCls);
17014 this.header = el.down('.'+this.headerCls);
17015 this.bwrap = el.down('.'+this.bwrapCls);
17016 var cp = this.bwrap ? this.bwrap : el;
17017 this.tbar = cp.down('.'+this.tbarCls);
17018 this.body = cp.down('.'+this.bodyCls);
17019 this.bbar = cp.down('.'+this.bbarCls);
17020 this.footer = cp.down('.'+this.footerCls);
17021 this.fromMarkup = true;
17023 if (this.preventBodyReset === true) {
17024 el.addClass('x-panel-reset');
17027 el.addClass(this.cls);
17031 this.elements += ',footer';
17038 el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
17040 this.createElement('header', d.firstChild.firstChild.firstChild);
17041 this.createElement('bwrap', d);
17044 bw = this.bwrap.dom;
17045 var ml = d.childNodes[1], bl = d.childNodes[2];
17046 bw.appendChild(ml);
17047 bw.appendChild(bl);
17049 var mc = bw.firstChild.firstChild.firstChild;
17050 this.createElement('tbar', mc);
17051 this.createElement('body', mc);
17052 this.createElement('bbar', mc);
17053 this.createElement('footer', bw.lastChild.firstChild.firstChild);
17056 this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
17059 this.ft = Ext.get(this.bwrap.dom.lastChild);
17060 this.mc = Ext.get(mc);
17062 this.createElement('header', d);
17063 this.createElement('bwrap', d);
17066 bw = this.bwrap.dom;
17067 this.createElement('tbar', bw);
17068 this.createElement('body', bw);
17069 this.createElement('bbar', bw);
17070 this.createElement('footer', bw);
17073 this.body.addClass(this.bodyCls + '-noheader');
17075 this.tbar.addClass(this.tbarCls + '-noheader');
17080 if(Ext.isDefined(this.padding)){
17081 this.body.setStyle('padding', this.body.addUnits(this.padding));
17084 if(this.border === false){
17085 this.el.addClass(this.baseCls + '-noborder');
17086 this.body.addClass(this.bodyCls + '-noborder');
17088 this.header.addClass(this.headerCls + '-noborder');
17091 this.footer.addClass(this.footerCls + '-noborder');
17094 this.tbar.addClass(this.tbarCls + '-noborder');
17097 this.bbar.addClass(this.bbarCls + '-noborder');
17101 if(this.bodyBorder === false){
17102 this.body.addClass(this.bodyCls + '-noborder');
17105 this.bwrap.enableDisplayMode('block');
17108 this.header.unselectable();
17111 if(this.headerAsText){
17112 this.header.dom.innerHTML =
17113 '<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
17116 this.setIconClass(this.iconCls);
17122 this.makeFloating(this.floating);
17125 if(this.collapsible && this.titleCollapse && this.header){
17126 this.mon(this.header, 'click', this.toggleCollapse, this);
17127 this.header.setStyle('cursor', 'pointer');
17130 this.addTool.apply(this, ts);
17135 this.footer.addClass('x-panel-btns');
17136 this.fbar.ownerCt = this;
17137 this.fbar.render(this.footer);
17138 this.footer.createChild({cls:'x-clear'});
17140 if(this.tbar && this.topToolbar){
17141 this.topToolbar.ownerCt = this;
17142 this.topToolbar.render(this.tbar);
17144 if(this.bbar && this.bottomToolbar){
17145 this.bottomToolbar.ownerCt = this;
17146 this.bottomToolbar.render(this.bbar);
17151 setIconClass : function(cls){
17152 var old = this.iconCls;
17153 this.iconCls = cls;
17154 if(this.rendered && this.header){
17156 this.header.addClass('x-panel-icon');
17157 this.header.replaceClass(old, this.iconCls);
17159 var hd = this.header,
17160 img = hd.child('img.x-panel-inline-icon');
17162 Ext.fly(img).replaceClass(old, this.iconCls);
17164 var hdspan = hd.child('span.' + this.headerTextCls);
17166 Ext.DomHelper.insertBefore(hdspan.dom, {
17167 tag:'img', alt: '', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
17173 this.fireEvent('iconchange', this, cls, old);
17177 makeFloating : function(cfg){
17178 this.floating = true;
17179 this.el = new Ext.Layer(Ext.apply({}, cfg, {
17180 shadow: Ext.isDefined(this.shadow) ? this.shadow : 'sides',
17181 shadowOffset: this.shadowOffset,
17183 shim: this.shim === false ? false : undefined
17188 getTopToolbar : function(){
17189 return this.topToolbar;
17193 getBottomToolbar : function(){
17194 return this.bottomToolbar;
17198 getFooterToolbar : function() {
17203 addButton : function(config, handler, scope){
17205 this.createFbar([]);
17208 if(Ext.isString(config)){
17209 config = {text: config};
17211 config = Ext.apply({
17216 return this.fbar.add(config);
17220 addTool : function(){
17221 if(!this.rendered){
17225 Ext.each(arguments, function(arg){
17226 this.tools.push(arg);
17231 if(!this[this.toolTarget]){
17234 if(!this.toolTemplate){
17236 var tt = new Ext.Template(
17237 '<div class="x-tool x-tool-{id}"> </div>'
17239 tt.disableFormats = true;
17241 Ext.Panel.prototype.toolTemplate = tt;
17243 for(var i = 0, a = arguments, len = a.length; i < len; i++) {
17245 if(!this.tools[tc.id]){
17246 var overCls = 'x-tool-'+tc.id+'-over';
17247 var t = this.toolTemplate.insertFirst(this[this.toolTarget], tc, true);
17248 this.tools[tc.id] = t;
17249 t.enableDisplayMode('block');
17250 this.mon(t, 'click', this.createToolHandler(t, tc, overCls, this));
17252 this.mon(t, tc.on);
17258 if(Ext.isObject(tc.qtip)){
17259 Ext.QuickTips.register(Ext.apply({
17263 t.dom.qtip = tc.qtip;
17266 t.addClassOnOver(overCls);
17271 onLayout : function(shallow, force){
17272 Ext.Panel.superclass.onLayout.apply(this, arguments);
17273 if(this.hasLayout && this.toolbars.length > 0){
17274 Ext.each(this.toolbars, function(tb){
17275 tb.doLayout(undefined, force);
17281 syncHeight : function(){
17282 var h = this.toolbarHeight,
17284 lsh = this.lastSize.height,
17287 if(this.autoHeight || !Ext.isDefined(lsh) || lsh == 'auto'){
17292 if(h != this.getToolbarHeight()){
17293 h = Math.max(0, lsh - this.getFrameHeight());
17296 this.toolbarHeight = this.getToolbarHeight();
17297 this.onBodyResize(sz.width, sz.height);
17302 onShow : function(){
17304 return this.el.show();
17306 Ext.Panel.superclass.onShow.call(this);
17310 onHide : function(){
17312 return this.el.hide();
17314 Ext.Panel.superclass.onHide.call(this);
17318 createToolHandler : function(t, tc, overCls, panel){
17319 return function(e){
17320 t.removeClass(overCls);
17321 if(tc.stopEvent !== false){
17325 tc.handler.call(tc.scope || t, e, t, panel, tc);
17331 afterRender : function(){
17332 if(this.floating && !this.hidden){
17336 this.setTitle(this.title);
17338 Ext.Panel.superclass.afterRender.call(this);
17339 if (this.collapsed) {
17340 this.collapsed = false;
17341 this.collapse(false);
17347 getKeyMap : function(){
17349 this.keyMap = new Ext.KeyMap(this.el, this.keys);
17351 return this.keyMap;
17355 initEvents : function(){
17359 if(this.draggable){
17360 this.initDraggable();
17362 if(this.toolbars.length > 0){
17363 Ext.each(this.toolbars, function(tb){
17367 afterlayout: this.syncHeight,
17368 remove: this.syncHeight
17377 initDraggable : function(){
17379 this.dd = new Ext.Panel.DD(this, Ext.isBoolean(this.draggable) ? null : this.draggable);
17383 beforeEffect : function(anim){
17385 this.el.beforeAction();
17387 if(anim !== false){
17388 this.el.addClass('x-panel-animated');
17393 afterEffect : function(anim){
17395 this.el.removeClass('x-panel-animated');
17399 createEffect : function(a, cb, scope){
17407 }else if(!a.callback){
17410 o.callback = function(){
17412 Ext.callback(a.callback, a.scope);
17415 return Ext.applyIf(o, a);
17419 collapse : function(animate){
17420 if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
17423 var doAnim = animate === true || (animate !== false && this.animCollapse);
17424 this.beforeEffect(doAnim);
17425 this.onCollapse(doAnim, animate);
17430 onCollapse : function(doAnim, animArg){
17432 this[this.collapseEl].slideOut(this.slideAnchor,
17433 Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
17434 this.collapseDefaults));
17436 this[this.collapseEl].hide(this.hideMode);
17437 this.afterCollapse(false);
17442 afterCollapse : function(anim){
17443 this.collapsed = true;
17444 this.el.addClass(this.collapsedCls);
17445 if(anim !== false){
17446 this[this.collapseEl].hide(this.hideMode);
17448 this.afterEffect(anim);
17451 this.cascade(function(c) {
17453 c.lastSize = { width: undefined, height: undefined };
17456 this.fireEvent('collapse', this);
17460 expand : function(animate){
17461 if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
17464 var doAnim = animate === true || (animate !== false && this.animCollapse);
17465 this.el.removeClass(this.collapsedCls);
17466 this.beforeEffect(doAnim);
17467 this.onExpand(doAnim, animate);
17472 onExpand : function(doAnim, animArg){
17474 this[this.collapseEl].slideIn(this.slideAnchor,
17475 Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
17476 this.expandDefaults));
17478 this[this.collapseEl].show(this.hideMode);
17479 this.afterExpand(false);
17484 afterExpand : function(anim){
17485 this.collapsed = false;
17486 if(anim !== false){
17487 this[this.collapseEl].show(this.hideMode);
17489 this.afterEffect(anim);
17490 if (this.deferLayout) {
17491 delete this.deferLayout;
17492 this.doLayout(true);
17494 this.fireEvent('expand', this);
17498 toggleCollapse : function(animate){
17499 this[this.collapsed ? 'expand' : 'collapse'](animate);
17504 onDisable : function(){
17505 if(this.rendered && this.maskDisabled){
17508 Ext.Panel.superclass.onDisable.call(this);
17512 onEnable : function(){
17513 if(this.rendered && this.maskDisabled){
17516 Ext.Panel.superclass.onEnable.call(this);
17520 onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
17524 if(Ext.isDefined(w) || Ext.isDefined(h)){
17525 if(!this.collapsed){
17530 if(Ext.isNumber(w)){
17531 this.body.setWidth(w = this.adjustBodyWidth(w - this.getFrameWidth()));
17532 } else if (w == 'auto') {
17533 w = this.body.setWidth('auto').dom.offsetWidth;
17535 w = this.body.dom.offsetWidth;
17539 this.tbar.setWidth(w);
17540 if(this.topToolbar){
17541 this.topToolbar.setSize(w);
17545 this.bbar.setWidth(w);
17546 if(this.bottomToolbar){
17547 this.bottomToolbar.setSize(w);
17550 this.bbar.setStyle('position', 'static');
17551 this.bbar.setStyle('position', '');
17556 this.footer.setWidth(w);
17558 this.fbar.setSize(Ext.isIE ? (w - this.footer.getFrameWidth('lr')) : 'auto');
17563 if(Ext.isNumber(h)){
17564 h = Math.max(0, h - this.getFrameHeight());
17566 this.body.setHeight(h);
17567 }else if(h == 'auto'){
17568 this.body.setHeight(h);
17571 if(this.disabled && this.el._mask){
17572 this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());
17576 this.queuedBodySize = {width: w, height: h};
17577 if(!this.queuedExpand && this.allowQueuedExpand !== false){
17578 this.queuedExpand = true;
17579 this.on('expand', function(){
17580 delete this.queuedExpand;
17581 this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
17582 }, this, {single:true});
17585 this.onBodyResize(w, h);
17588 Ext.Panel.superclass.onResize.call(this, adjWidth, adjHeight, rawWidth, rawHeight);
17593 onBodyResize: function(w, h){
17594 this.fireEvent('bodyresize', this, w, h);
17598 getToolbarHeight: function(){
17601 Ext.each(this.toolbars, function(tb){
17602 h += tb.getHeight();
17609 adjustBodyHeight : function(h){
17614 adjustBodyWidth : function(w){
17619 onPosition : function(){
17624 getFrameWidth : function(){
17625 var w = this.el.getFrameWidth('lr') + this.bwrap.getFrameWidth('lr');
17628 var l = this.bwrap.dom.firstChild;
17629 w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
17630 w += this.mc.getFrameWidth('lr');
17636 getFrameHeight : function() {
17637 var h = this.el.getFrameWidth('tb') + this.bwrap.getFrameWidth('tb');
17638 h += (this.tbar ? this.tbar.getHeight() : 0) +
17639 (this.bbar ? this.bbar.getHeight() : 0);
17642 h += this.el.dom.firstChild.offsetHeight + this.ft.dom.offsetHeight + this.mc.getFrameWidth('tb');
17644 h += (this.header ? this.header.getHeight() : 0) +
17645 (this.footer ? this.footer.getHeight() : 0);
17651 getInnerWidth : function(){
17652 return this.getSize().width - this.getFrameWidth();
17656 getInnerHeight : function(){
17657 return this.body.getHeight();
17662 syncShadow : function(){
17664 this.el.sync(true);
17669 getLayoutTarget : function(){
17674 getContentTarget : function(){
17679 setTitle : function(title, iconCls){
17680 this.title = title;
17681 if(this.header && this.headerAsText){
17682 this.header.child('span').update(title);
17685 this.setIconClass(iconCls);
17687 this.fireEvent('titlechange', this, title);
17692 getUpdater : function(){
17693 return this.body.getUpdater();
17698 var um = this.body.getUpdater();
17699 um.update.apply(um, arguments);
17704 beforeDestroy : function(){
17705 Ext.Panel.superclass.beforeDestroy.call(this);
17707 this.header.removeAllListeners();
17710 for(var k in this.tools){
17711 Ext.destroy(this.tools[k]);
17714 if(this.toolbars.length > 0){
17715 Ext.each(this.toolbars, function(tb){
17716 tb.un('afterlayout', this.syncHeight, this);
17717 tb.un('remove', this.syncHeight, this);
17720 if(Ext.isArray(this.buttons)){
17721 while(this.buttons.length) {
17722 Ext.destroy(this.buttons[0]);
17744 Ext.destroy(this.toolbars);
17748 createClasses : function(){
17749 this.headerCls = this.baseCls + '-header';
17750 this.headerTextCls = this.baseCls + '-header-text';
17751 this.bwrapCls = this.baseCls + '-bwrap';
17752 this.tbarCls = this.baseCls + '-tbar';
17753 this.bodyCls = this.baseCls + '-body';
17754 this.bbarCls = this.baseCls + '-bbar';
17755 this.footerCls = this.baseCls + '-footer';
17759 createGhost : function(cls, useShim, appendTo){
17760 var el = document.createElement('div');
17761 el.className = 'x-panel-ghost ' + (cls ? cls : '');
17763 el.appendChild(this.el.dom.firstChild.cloneNode(true));
17765 Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
17766 el.style.width = this.el.dom.offsetWidth + 'px';;
17768 this.container.dom.appendChild(el);
17770 Ext.getDom(appendTo).appendChild(el);
17772 if(useShim !== false && this.el.useShim !== false){
17773 var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el);
17777 return new Ext.Element(el);
17782 doAutoLoad : function(){
17783 var u = this.body.getUpdater();
17785 u.setRenderer(this.renderer);
17787 u.update(Ext.isObject(this.autoLoad) ? this.autoLoad : {url: this.autoLoad});
17791 getTool : function(id) {
17792 return this.tools[id];
17797 Ext.reg('panel', Ext.Panel);
17799 Ext.Editor = function(field, config){
17801 this.field = Ext.create(field.field, 'textfield');
17802 config = Ext.apply({}, field);
17803 delete config.field;
17805 this.field = field;
17807 Ext.Editor.superclass.constructor.call(this, config);
17810 Ext.extend(Ext.Editor, Ext.Component, {
17829 swallowKeys : true,
17831 completeOnEnter : true,
17833 cancelOnEsc : true,
17837 initComponent : function(){
17838 Ext.Editor.superclass.initComponent.call(this);
17856 onRender : function(ct, position){
17857 this.el = new Ext.Layer({
17858 shadow: this.shadow,
17862 shadowOffset: this.shadowOffset || 4,
17864 constrain: this.constrain
17867 this.el.setZIndex(this.zIndex);
17869 this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
17870 if(this.field.msgTarget != 'title'){
17871 this.field.msgTarget = 'qtip';
17873 this.field.inEditor = true;
17874 this.mon(this.field, {
17877 specialkey: this.onSpecialKey
17879 if(this.field.grow){
17880 this.mon(this.field, "autosize", this.el.sync, this.el, {delay:1});
17882 this.field.render(this.el).show();
17883 this.field.getEl().dom.name = '';
17884 if(this.swallowKeys){
17885 this.field.el.swallowEvent([
17893 onSpecialKey : function(field, e){
17894 var key = e.getKey(),
17895 complete = this.completeOnEnter && key == e.ENTER,
17896 cancel = this.cancelOnEsc && key == e.ESC;
17897 if(complete || cancel){
17900 this.completeEdit();
17904 if(field.triggerBlur){
17905 field.triggerBlur();
17908 this.fireEvent('specialkey', field, e);
17912 startEdit : function(el, value){
17914 this.completeEdit();
17916 this.boundEl = Ext.get(el);
17917 var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
17918 if(!this.rendered){
17919 this.render(this.parentEl || document.body);
17921 if(this.fireEvent("beforestartedit", this, this.boundEl, v) !== false){
17922 this.startValue = v;
17923 this.field.reset();
17924 this.field.setValue(v);
17925 this.realign(true);
17926 this.editing = true;
17932 doAutoSize : function(){
17934 var sz = this.boundEl.getSize(),
17935 fs = this.field.getSize();
17937 switch(this.autoSize){
17939 this.setSize(sz.width, fs.height);
17942 this.setSize(fs.width, sz.height);
17945 this.setSize(fs.width, fs.height);
17948 this.setSize(sz.width, sz.height);
17954 setSize : function(w, h){
17955 delete this.field.lastSize;
17956 this.field.setSize(w, h);
17959 if(Ext.isGecko2 || Ext.isOpera || (Ext.isIE7 && Ext.isStrict)){
17961 this.el.setSize(w, h);
17968 realign : function(autoSize){
17969 if(autoSize === true){
17972 this.el.alignTo(this.boundEl, this.alignment, this.offsets);
17976 completeEdit : function(remainVisible){
17981 if (this.field.assertValue) {
17982 this.field.assertValue();
17984 var v = this.getValue();
17985 if(!this.field.isValid()){
17986 if(this.revertInvalid !== false){
17987 this.cancelEdit(remainVisible);
17991 if(String(v) === String(this.startValue) && this.ignoreNoChange){
17992 this.hideEdit(remainVisible);
17995 if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
17996 v = this.getValue();
17997 if(this.updateEl && this.boundEl){
17998 this.boundEl.update(v);
18000 this.hideEdit(remainVisible);
18001 this.fireEvent("complete", this, v, this.startValue);
18006 onShow : function(){
18008 if(this.hideEl !== false){
18009 this.boundEl.hide();
18011 this.field.show().focus(false, true);
18012 this.fireEvent("startedit", this.boundEl, this.startValue);
18016 cancelEdit : function(remainVisible){
18018 var v = this.getValue();
18019 this.setValue(this.startValue);
18020 this.hideEdit(remainVisible);
18021 this.fireEvent("canceledit", this, v, this.startValue);
18026 hideEdit: function(remainVisible){
18027 if(remainVisible !== true){
18028 this.editing = false;
18034 onBlur : function(){
18036 if(this.allowBlur === true && this.editing && this.selectSameEditor !== true){
18037 this.completeEdit();
18042 onHide : function(){
18044 this.completeEdit();
18048 if(this.field.collapse){
18049 this.field.collapse();
18052 if(this.hideEl !== false){
18053 this.boundEl.show();
18058 setValue : function(v){
18059 this.field.setValue(v);
18063 getValue : function(){
18064 return this.field.getValue();
18067 beforeDestroy : function(){
18068 Ext.destroyMembers(this, 'field');
18070 delete this.parentEl;
18071 delete this.boundEl;
18074 Ext.reg('editor', Ext.Editor);
18076 Ext.ColorPalette = Ext.extend(Ext.Component, {
18079 itemCls : 'x-color-palette',
18083 clickEvent :'click',
18085 ctype : 'Ext.ColorPalette',
18088 allowReselect : false,
18092 '000000', '993300', '333300', '003300', '003366', '000080', '333399', '333333',
18093 '800000', 'FF6600', '808000', '008000', '008080', '0000FF', '666699', '808080',
18094 'FF0000', 'FF9900', '99CC00', '339966', '33CCCC', '3366FF', '800080', '969696',
18095 'FF00FF', 'FFCC00', 'FFFF00', '00FF00', '00FFFF', '00CCFF', '993366', 'C0C0C0',
18096 'FF99CC', 'FFCC99', 'FFFF99', 'CCFFCC', 'CCFFFF', '99CCFF', 'CC99FF', 'FFFFFF'
18103 initComponent : function(){
18104 Ext.ColorPalette.superclass.initComponent.call(this);
18111 this.on('select', this.handler, this.scope, true);
18116 onRender : function(container, position){
18121 Ext.ColorPalette.superclass.onRender.call(this, container, position);
18122 var t = this.tpl || new Ext.XTemplate(
18123 '<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on"> </span></em></a></tpl>'
18125 t.overwrite(this.el, this.colors);
18126 this.mon(this.el, this.clickEvent, this.handleClick, this, {delegate: 'a'});
18127 if(this.clickEvent != 'click'){
18128 this.mon(this.el, 'click', Ext.emptyFn, this, {delegate: 'a', preventDefault: true});
18133 afterRender : function(){
18134 Ext.ColorPalette.superclass.afterRender.call(this);
18136 var s = this.value;
18138 this.select(s, true);
18143 handleClick : function(e, t){
18144 e.preventDefault();
18145 if(!this.disabled){
18146 var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];
18147 this.select(c.toUpperCase());
18152 select : function(color, suppressEvent){
18153 color = color.replace('#', '');
18154 if(color != this.value || this.allowReselect){
18157 el.child('a.color-'+this.value).removeClass('x-color-palette-sel');
18159 el.child('a.color-'+color).addClass('x-color-palette-sel');
18160 this.value = color;
18161 if(suppressEvent !== true){
18162 this.fireEvent('select', this, color);
18169 Ext.reg('colorpalette', Ext.ColorPalette);
18170 Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
18172 todayText : 'Today',
18174 okText : ' OK ',
18176 cancelText : 'Cancel',
18180 todayTip : '{0} (Spacebar)',
18182 minText : 'This date is before the minimum date',
18184 maxText : 'This date is after the maximum date',
18188 disabledDaysText : 'Disabled',
18190 disabledDatesText : 'Disabled',
18192 monthNames : Date.monthNames,
18194 dayNames : Date.dayNames,
18196 nextText : 'Next Month (Control+Right)',
18198 prevText : 'Previous Month (Control+Left)',
18200 monthYearText : 'Choose a month (Control+Up/Down to move years)',
18213 focusOnSelect: true,
18220 initComponent : function(){
18221 Ext.DatePicker.superclass.initComponent.call(this);
18223 this.value = this.value ?
18224 this.value.clearTime(true) : new Date().clearTime();
18232 this.on('select', this.handler, this.scope || this);
18235 this.initDisabledDays();
18239 initDisabledDays : function(){
18240 if(!this.disabledDatesRE && this.disabledDates){
18241 var dd = this.disabledDates,
18242 len = dd.length - 1,
18245 Ext.each(dd, function(d, i){
18246 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
18251 this.disabledDatesRE = new RegExp(re + ')');
18256 setDisabledDates : function(dd){
18257 if(Ext.isArray(dd)){
18258 this.disabledDates = dd;
18259 this.disabledDatesRE = null;
18261 this.disabledDatesRE = dd;
18263 this.initDisabledDays();
18264 this.update(this.value, true);
18268 setDisabledDays : function(dd){
18269 this.disabledDays = dd;
18270 this.update(this.value, true);
18274 setMinDate : function(dt){
18276 this.update(this.value, true);
18280 setMaxDate : function(dt){
18282 this.update(this.value, true);
18286 setValue : function(value){
18287 this.value = value.clearTime(true);
18288 this.update(this.value);
18292 getValue : function(){
18297 focus : function(){
18298 this.update(this.activeDate);
18302 onEnable: function(initial){
18303 Ext.DatePicker.superclass.onEnable.call(this);
18304 this.doDisabled(false);
18305 this.update(initial ? this.value : this.activeDate);
18313 onDisable : function(){
18314 Ext.DatePicker.superclass.onDisable.call(this);
18315 this.doDisabled(true);
18316 if(Ext.isIE && !Ext.isIE8){
18318 Ext.each([].concat(this.textNodes, this.el.query('th span')), function(el){
18319 Ext.fly(el).repaint();
18325 doDisabled : function(disabled){
18326 this.keyNav.setDisabled(disabled);
18327 this.prevRepeater.setDisabled(disabled);
18328 this.nextRepeater.setDisabled(disabled);
18329 if(this.showToday){
18330 this.todayKeyListener.setDisabled(disabled);
18331 this.todayBtn.setDisabled(disabled);
18336 onRender : function(container, position){
18338 '<table cellspacing="0">',
18339 '<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>',
18340 '<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'],
18341 dn = this.dayNames,
18343 for(i = 0; i < 7; i++){
18344 var d = this.startDay+i;
18348 m.push('<th><span>', dn[d].substr(0,1), '</span></th>');
18350 m[m.length] = '</tr></thead><tbody><tr>';
18351 for(i = 0; i < 42; i++) {
18352 if(i % 7 === 0 && i !== 0){
18353 m[m.length] = '</tr><tr>';
18355 m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
18357 m.push('</tr></tbody></table></td></tr>',
18358 this.showToday ? '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>' : '',
18359 '</table><div class="x-date-mp"></div>');
18361 var el = document.createElement('div');
18362 el.className = 'x-date-picker';
18363 el.innerHTML = m.join('');
18365 container.dom.insertBefore(el, position);
18367 this.el = Ext.get(el);
18368 this.eventEl = Ext.get(el.firstChild);
18370 this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), {
18371 handler: this.showPrevMonth,
18373 preventDefault:true,
18377 this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), {
18378 handler: this.showNextMonth,
18380 preventDefault:true,
18384 this.monthPicker = this.el.down('div.x-date-mp');
18385 this.monthPicker.enableDisplayMode('block');
18387 this.keyNav = new Ext.KeyNav(this.eventEl, {
18388 'left' : function(e){
18390 this.showPrevMonth();
18392 this.update(this.activeDate.add('d', -1));
18396 'right' : function(e){
18398 this.showNextMonth();
18400 this.update(this.activeDate.add('d', 1));
18404 'up' : function(e){
18406 this.showNextYear();
18408 this.update(this.activeDate.add('d', -7));
18412 'down' : function(e){
18414 this.showPrevYear();
18416 this.update(this.activeDate.add('d', 7));
18420 'pageUp' : function(e){
18421 this.showNextMonth();
18424 'pageDown' : function(e){
18425 this.showPrevMonth();
18428 'enter' : function(e){
18429 e.stopPropagation();
18436 this.el.unselectable();
18438 this.cells = this.el.select('table.x-date-inner tbody td');
18439 this.textNodes = this.el.query('table.x-date-inner tbody span');
18441 this.mbtn = new Ext.Button({
18443 tooltip: this.monthYearText,
18444 renderTo: this.el.child('td.x-date-middle', true)
18446 this.mbtn.el.child('em').addClass('x-btn-arrow');
18448 if(this.showToday){
18449 this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, this);
18450 var today = (new Date()).dateFormat(this.format);
18451 this.todayBtn = new Ext.Button({
18452 renderTo: this.el.child('td.x-date-bottom', true),
18453 text: String.format(this.todayText, today),
18454 tooltip: String.format(this.todayTip, today),
18455 handler: this.selectToday,
18459 this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this);
18460 this.mon(this.eventEl, 'click', this.handleDateClick, this, {delegate: 'a.x-date-date'});
18461 this.mon(this.mbtn, 'click', this.showMonthPicker, this);
18462 this.onEnable(true);
18466 createMonthPicker : function(){
18467 if(!this.monthPicker.dom.firstChild){
18468 var buf = ['<table border="0" cellspacing="0">'];
18469 for(var i = 0; i < 6; i++){
18471 '<tr><td class="x-date-mp-month"><a href="#">', Date.getShortMonthName(i), '</a></td>',
18472 '<td class="x-date-mp-month x-date-mp-sep"><a href="#">', Date.getShortMonthName(i + 6), '</a></td>',
18474 '<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>' :
18475 '<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
18479 '<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
18481 '</button><button type="button" class="x-date-mp-cancel">',
18483 '</button></td></tr>',
18486 this.monthPicker.update(buf.join(''));
18488 this.mon(this.monthPicker, 'click', this.onMonthClick, this);
18489 this.mon(this.monthPicker, 'dblclick', this.onMonthDblClick, this);
18491 this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
18492 this.mpYears = this.monthPicker.select('td.x-date-mp-year');
18494 this.mpMonths.each(function(m, a, i){
18497 m.dom.xmonth = 5 + Math.round(i * 0.5);
18499 m.dom.xmonth = Math.round((i-1) * 0.5);
18506 showMonthPicker : function(){
18507 if(!this.disabled){
18508 this.createMonthPicker();
18509 var size = this.el.getSize();
18510 this.monthPicker.setSize(size);
18511 this.monthPicker.child('table').setSize(size);
18513 this.mpSelMonth = (this.activeDate || this.value).getMonth();
18514 this.updateMPMonth(this.mpSelMonth);
18515 this.mpSelYear = (this.activeDate || this.value).getFullYear();
18516 this.updateMPYear(this.mpSelYear);
18518 this.monthPicker.slideIn('t', {duration:0.2});
18523 updateMPYear : function(y){
18525 var ys = this.mpYears.elements;
18526 for(var i = 1; i <= 10; i++){
18527 var td = ys[i-1], y2;
18529 y2 = y + Math.round(i * 0.5);
18530 td.firstChild.innerHTML = y2;
18533 y2 = y - (5-Math.round(i * 0.5));
18534 td.firstChild.innerHTML = y2;
18537 this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
18542 updateMPMonth : function(sm){
18543 this.mpMonths.each(function(m, a, i){
18544 m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
18549 selectMPMonth : function(m){
18554 onMonthClick : function(e, t){
18556 var el = new Ext.Element(t), pn;
18557 if(el.is('button.x-date-mp-cancel')){
18558 this.hideMonthPicker();
18560 else if(el.is('button.x-date-mp-ok')){
18561 var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate());
18562 if(d.getMonth() != this.mpSelMonth){
18564 d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth();
18567 this.hideMonthPicker();
18569 else if((pn = el.up('td.x-date-mp-month', 2))){
18570 this.mpMonths.removeClass('x-date-mp-sel');
18571 pn.addClass('x-date-mp-sel');
18572 this.mpSelMonth = pn.dom.xmonth;
18574 else if((pn = el.up('td.x-date-mp-year', 2))){
18575 this.mpYears.removeClass('x-date-mp-sel');
18576 pn.addClass('x-date-mp-sel');
18577 this.mpSelYear = pn.dom.xyear;
18579 else if(el.is('a.x-date-mp-prev')){
18580 this.updateMPYear(this.mpyear-10);
18582 else if(el.is('a.x-date-mp-next')){
18583 this.updateMPYear(this.mpyear+10);
18588 onMonthDblClick : function(e, t){
18590 var el = new Ext.Element(t), pn;
18591 if((pn = el.up('td.x-date-mp-month', 2))){
18592 this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
18593 this.hideMonthPicker();
18595 else if((pn = el.up('td.x-date-mp-year', 2))){
18596 this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
18597 this.hideMonthPicker();
18602 hideMonthPicker : function(disableAnim){
18603 if(this.monthPicker){
18604 if(disableAnim === true){
18605 this.monthPicker.hide();
18607 this.monthPicker.slideOut('t', {duration:0.2});
18613 showPrevMonth : function(e){
18614 this.update(this.activeDate.add('mo', -1));
18618 showNextMonth : function(e){
18619 this.update(this.activeDate.add('mo', 1));
18623 showPrevYear : function(){
18624 this.update(this.activeDate.add('y', -1));
18628 showNextYear : function(){
18629 this.update(this.activeDate.add('y', 1));
18633 handleMouseWheel : function(e){
18635 if(!this.disabled){
18636 var delta = e.getWheelDelta();
18638 this.showPrevMonth();
18639 } else if(delta < 0){
18640 this.showNextMonth();
18646 handleDateClick : function(e, t){
18648 if(!this.disabled && t.dateValue && !Ext.fly(t.parentNode).hasClass('x-date-disabled')){
18649 this.cancelFocus = this.focusOnSelect === false;
18650 this.setValue(new Date(t.dateValue));
18651 delete this.cancelFocus;
18652 this.fireEvent('select', this, this.value);
18657 selectToday : function(){
18658 if(this.todayBtn && !this.todayBtn.disabled){
18659 this.setValue(new Date().clearTime());
18660 this.fireEvent('select', this, this.value);
18665 update : function(date, forceRefresh){
18667 var vd = this.activeDate, vis = this.isVisible();
18668 this.activeDate = date;
18669 if(!forceRefresh && vd && this.el){
18670 var t = date.getTime();
18671 if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
18672 this.cells.removeClass('x-date-selected');
18673 this.cells.each(function(c){
18674 if(c.dom.firstChild.dateValue == t){
18675 c.addClass('x-date-selected');
18676 if(vis && !this.cancelFocus){
18677 Ext.fly(c.dom.firstChild).focus(50);
18685 var days = date.getDaysInMonth(),
18686 firstOfMonth = date.getFirstDateOfMonth(),
18687 startingPos = firstOfMonth.getDay()-this.startDay;
18689 if(startingPos < 0){
18692 days += startingPos;
18694 var pm = date.add('mo', -1),
18695 prevStart = pm.getDaysInMonth()-startingPos,
18696 cells = this.cells.elements,
18697 textEls = this.textNodes,
18699 d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart, this.initHour)),
18700 today = new Date().clearTime().getTime(),
18701 sel = date.clearTime(true).getTime(),
18702 min = this.minDate ? this.minDate.clearTime(true) : Number.NEGATIVE_INFINITY,
18703 max = this.maxDate ? this.maxDate.clearTime(true) : Number.POSITIVE_INFINITY,
18704 ddMatch = this.disabledDatesRE,
18705 ddText = this.disabledDatesText,
18706 ddays = this.disabledDays ? this.disabledDays.join('') : false,
18707 ddaysText = this.disabledDaysText,
18708 format = this.format;
18710 if(this.showToday){
18711 var td = new Date().clearTime(),
18712 disable = (td < min || td > max ||
18713 (ddMatch && format && ddMatch.test(td.dateFormat(format))) ||
18714 (ddays && ddays.indexOf(td.getDay()) != -1));
18716 if(!this.disabled){
18717 this.todayBtn.setDisabled(disable);
18718 this.todayKeyListener[disable ? 'disable' : 'enable']();
18722 var setCellClass = function(cal, cell){
18724 var t = d.clearTime(true).getTime();
18725 cell.firstChild.dateValue = t;
18727 cell.className += ' x-date-today';
18728 cell.title = cal.todayText;
18731 cell.className += ' x-date-selected';
18733 Ext.fly(cell.firstChild).focus(50);
18738 cell.className = ' x-date-disabled';
18739 cell.title = cal.minText;
18743 cell.className = ' x-date-disabled';
18744 cell.title = cal.maxText;
18748 if(ddays.indexOf(d.getDay()) != -1){
18749 cell.title = ddaysText;
18750 cell.className = ' x-date-disabled';
18753 if(ddMatch && format){
18754 var fvalue = d.dateFormat(format);
18755 if(ddMatch.test(fvalue)){
18756 cell.title = ddText.replace('%0', fvalue);
18757 cell.className = ' x-date-disabled';
18763 for(; i < startingPos; i++) {
18764 textEls[i].innerHTML = (++prevStart);
18765 d.setDate(d.getDate()+1);
18766 cells[i].className = 'x-date-prevday';
18767 setCellClass(this, cells[i]);
18769 for(; i < days; i++){
18770 var intDay = i - startingPos + 1;
18771 textEls[i].innerHTML = (intDay);
18772 d.setDate(d.getDate()+1);
18773 cells[i].className = 'x-date-active';
18774 setCellClass(this, cells[i]);
18777 for(; i < 42; i++) {
18778 textEls[i].innerHTML = (++extraDays);
18779 d.setDate(d.getDate()+1);
18780 cells[i].className = 'x-date-nextday';
18781 setCellClass(this, cells[i]);
18784 this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());
18786 if(!this.internalRender){
18787 var main = this.el.dom.firstChild,
18788 w = main.offsetWidth;
18789 this.el.setWidth(w + this.el.getBorderWidth('lr'));
18790 Ext.fly(main).setWidth(w);
18791 this.internalRender = true;
18795 if(Ext.isOpera && !this.secondPass){
18796 main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';
18797 this.secondPass = true;
18798 this.update.defer(10, this, [date]);
18805 beforeDestroy : function() {
18817 delete this.textNodes;
18818 delete this.cells.elements;
18825 Ext.reg('datepicker', Ext.DatePicker);
18827 Ext.LoadMask = function(el, config){
18828 this.el = Ext.get(el);
18829 Ext.apply(this, config);
18833 beforeload: this.onBeforeLoad,
18835 exception: this.onLoad
18837 this.removeMask = Ext.value(this.removeMask, false);
18839 var um = this.el.getUpdater();
18840 um.showLoadIndicator = false;
18843 beforeupdate: this.onBeforeLoad,
18844 update: this.onLoad,
18845 failure: this.onLoad
18847 this.removeMask = Ext.value(this.removeMask, true);
18851 Ext.LoadMask.prototype = {
18855 msg : 'Loading...',
18857 msgCls : 'x-mask-loading',
18863 disable : function(){
18864 this.disabled = true;
18868 enable : function(){
18869 this.disabled = false;
18873 onLoad : function(){
18874 this.el.unmask(this.removeMask);
18878 onBeforeLoad : function(){
18879 if(!this.disabled){
18880 this.el.mask(this.msg, this.msgCls);
18886 this.onBeforeLoad();
18895 destroy : function(){
18897 this.store.un('beforeload', this.onBeforeLoad, this);
18898 this.store.un('load', this.onLoad, this);
18899 this.store.un('exception', this.onLoad, this);
18901 var um = this.el.getUpdater();
18902 um.un('beforeupdate', this.onBeforeLoad, this);
18903 um.un('update', this.onLoad, this);
18904 um.un('failure', this.onLoad, this);
18907 };Ext.ns('Ext.slider');
18910 Ext.slider.Thumb = Ext.extend(Object, {
18916 constructor: function(config) {
18918 Ext.apply(this, config || {}, {
18919 cls: 'x-slider-thumb',
18925 Ext.slider.Thumb.superclass.constructor.call(this, config);
18927 if (this.slider.vertical) {
18928 Ext.apply(this, Ext.slider.Thumb.Vertical);
18933 render: function() {
18934 this.el = this.slider.innerEl.insertFirst({cls: this.cls});
18940 enable: function() {
18941 this.disabled = false;
18942 this.el.removeClass(this.slider.disabledClass);
18946 disable: function() {
18947 this.disabled = true;
18948 this.el.addClass(this.slider.disabledClass);
18952 initEvents: function() {
18955 el.addClassOnOver('x-slider-thumb-over');
18957 this.tracker = new Ext.dd.DragTracker({
18958 onBeforeStart: this.onBeforeDragStart.createDelegate(this),
18959 onStart : this.onDragStart.createDelegate(this),
18960 onDrag : this.onDrag.createDelegate(this),
18961 onEnd : this.onDragEnd.createDelegate(this),
18966 this.tracker.initEl(el);
18970 onBeforeDragStart : function(e) {
18971 if (this.disabled) {
18974 this.slider.promoteThumb(this);
18980 onDragStart: function(e){
18981 this.el.addClass('x-slider-thumb-drag');
18982 this.dragging = true;
18983 this.dragStartValue = this.value;
18985 this.slider.fireEvent('dragstart', this.slider, e, this);
18989 onDrag: function(e) {
18990 var slider = this.slider,
18991 index = this.index,
18992 newValue = this.getNewValue();
18994 if (this.constrain) {
18995 var above = slider.thumbs[index + 1],
18996 below = slider.thumbs[index - 1];
18998 if (below != undefined && newValue <= below.value) newValue = below.value;
18999 if (above != undefined && newValue >= above.value) newValue = above.value;
19002 slider.setValue(index, newValue, false);
19003 slider.fireEvent('drag', slider, e, this);
19006 getNewValue: function() {
19007 var slider = this.slider,
19008 pos = slider.innerEl.translatePoints(this.tracker.getXY());
19010 return Ext.util.Format.round(slider.reverseValue(pos.left), slider.decimalPrecision);
19014 onDragEnd: function(e) {
19015 var slider = this.slider,
19016 value = this.value;
19018 this.el.removeClass('x-slider-thumb-drag');
19020 this.dragging = false;
19021 slider.fireEvent('dragend', slider, e);
19023 if (this.dragStartValue != value) {
19024 slider.fireEvent('changecomplete', slider, value, this);
19029 destroy: function(){
19030 Ext.destroyMembers(this, 'tracker', 'el');
19035 Ext.slider.MultiSlider = Ext.extend(Ext.BoxComponent, {
19044 decimalPrecision: 0,
19051 clickRange: [5,15],
19054 clickToChange : true,
19058 constrainThumbs: true,
19061 topThumbZIndex: 10000,
19064 initComponent : function(){
19065 if(!Ext.isDefined(this.value)){
19066 this.value = this.minValue;
19072 Ext.slider.MultiSlider.superclass.initComponent.call(this);
19074 this.keyIncrement = Math.max(this.increment, this.keyIncrement);
19096 if (this.values == undefined || Ext.isEmpty(this.values)) this.values = [0];
19098 var values = this.values;
19100 for (var i=0; i < values.length; i++) {
19101 this.addThumb(values[i]);
19105 Ext.apply(this, Ext.slider.Vertical);
19110 addThumb: function(value) {
19111 var thumb = new Ext.slider.Thumb({
19114 index : this.thumbs.length,
19115 constrain: this.constrainThumbs
19117 this.thumbs.push(thumb);
19120 if (this.rendered) thumb.render();
19124 promoteThumb: function(topThumb) {
19125 var thumbs = this.thumbs,
19128 for (var i = 0, j = thumbs.length; i < j; i++) {
19131 if (thumb == topThumb) {
19132 zIndex = this.topThumbZIndex;
19137 thumb.el.setStyle('zIndex', zIndex);
19142 onRender : function() {
19144 cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
19146 cls: 'x-slider-end',
19148 cls:'x-slider-inner',
19149 cn : [{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]
19154 Ext.slider.MultiSlider.superclass.onRender.apply(this, arguments);
19156 this.endEl = this.el.first();
19157 this.innerEl = this.endEl.first();
19158 this.focusEl = this.innerEl.child('.x-slider-focus');
19161 for (var i=0; i < this.thumbs.length; i++) {
19162 this.thumbs[i].render();
19166 var thumb = this.innerEl.child('.x-slider-thumb');
19167 this.halfThumb = (this.vertical ? thumb.getHeight() : thumb.getWidth()) / 2;
19173 initEvents : function(){
19174 this.mon(this.el, {
19176 mousedown: this.onMouseDown,
19177 keydown : this.onKeyDown
19180 this.focusEl.swallowEvent("click", true);
19184 onMouseDown : function(e){
19190 var thumbClicked = false;
19191 for (var i=0; i < this.thumbs.length; i++) {
19192 thumbClicked = thumbClicked || e.target == this.thumbs[i].el.dom;
19195 if (this.clickToChange && !thumbClicked) {
19196 var local = this.innerEl.translatePoints(e.getXY());
19197 this.onClickChange(local);
19203 onClickChange : function(local) {
19204 if (local.top > this.clickRange[0] && local.top < this.clickRange[1]) {
19206 var thumb = this.getNearest(local, 'left'),
19207 index = thumb.index;
19209 this.setValue(index, Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
19214 getNearest: function(local, prop) {
19215 var localValue = prop == 'top' ? this.innerEl.getHeight() - local[prop] : local[prop],
19216 clickValue = this.reverseValue(localValue),
19217 nearestDistance = (this.maxValue - this.minValue) + 5,
19221 for (var i=0; i < this.thumbs.length; i++) {
19222 var thumb = this.thumbs[i],
19223 value = thumb.value,
19224 dist = Math.abs(value - clickValue);
19226 if (Math.abs(dist <= nearestDistance)) {
19229 nearestDistance = dist;
19236 onKeyDown : function(e){
19238 if(this.disabled || this.thumbs.length !== 1){
19239 e.preventDefault();
19242 var k = e.getKey(),
19248 val = e.ctrlKey ? this.maxValue : this.getValue(0) + this.keyIncrement;
19249 this.setValue(0, val, undefined, true);
19254 val = e.ctrlKey ? this.minValue : this.getValue(0) - this.keyIncrement;
19255 this.setValue(0, val, undefined, true);
19258 e.preventDefault();
19263 doSnap : function(value){
19264 if (!(this.increment && value)) {
19267 var newValue = value,
19268 inc = this.increment,
19272 if (m * 2 >= inc) {
19274 } else if (m * 2 < -inc) {
19278 return newValue.constrain(this.minValue, this.maxValue);
19282 afterRender : function(){
19283 Ext.slider.MultiSlider.superclass.afterRender.apply(this, arguments);
19285 for (var i=0; i < this.thumbs.length; i++) {
19286 var thumb = this.thumbs[i];
19288 if (thumb.value !== undefined) {
19289 var v = this.normalizeValue(thumb.value);
19291 if (v !== thumb.value) {
19293 this.setValue(i, v, false);
19295 this.moveThumb(i, this.translateValue(v), false);
19302 getRatio : function(){
19303 var w = this.innerEl.getWidth(),
19304 v = this.maxValue - this.minValue;
19305 return v == 0 ? w : (w/v);
19309 normalizeValue : function(v){
19310 v = this.doSnap(v);
19311 v = Ext.util.Format.round(v, this.decimalPrecision);
19312 v = v.constrain(this.minValue, this.maxValue);
19317 setMinValue : function(val){
19318 this.minValue = val;
19320 thumbs = this.thumbs,
19321 len = thumbs.length,
19324 for(; i < len; ++i){
19326 t.value = t.value < val ? val : t.value;
19332 setMaxValue : function(val){
19333 this.maxValue = val;
19335 thumbs = this.thumbs,
19336 len = thumbs.length,
19339 for(; i < len; ++i){
19341 t.value = t.value > val ? val : t.value;
19347 setValue : function(index, v, animate, changeComplete) {
19348 var thumb = this.thumbs[index],
19351 v = this.normalizeValue(v);
19353 if (v !== thumb.value && this.fireEvent('beforechange', this, v, thumb.value, thumb) !== false) {
19356 this.moveThumb(index, this.translateValue(v), animate !== false);
19357 this.fireEvent('change', this, v, thumb);
19358 if(changeComplete){
19359 this.fireEvent('changecomplete', this, v, thumb);
19366 translateValue : function(v) {
19367 var ratio = this.getRatio();
19368 return (v * ratio) - (this.minValue * ratio) - this.halfThumb;
19372 reverseValue : function(pos){
19373 var ratio = this.getRatio();
19374 return (pos + (this.minValue * ratio)) / ratio;
19378 moveThumb: function(index, v, animate){
19379 var thumb = this.thumbs[index].el;
19381 if(!animate || this.animate === false){
19384 thumb.shift({left: v, stopFx: true, duration:.35});
19389 focus : function(){
19390 this.focusEl.focus(10);
19394 onResize : function(w, h){
19395 var thumbs = this.thumbs,
19396 len = thumbs.length,
19400 for(; i < len; ++i){
19401 thumbs[i].el.stopFx();
19404 if(Ext.isNumber(w)){
19405 this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
19408 Ext.slider.MultiSlider.superclass.onResize.apply(this, arguments);
19412 onDisable: function(){
19413 Ext.slider.MultiSlider.superclass.onDisable.call(this);
19415 for (var i=0; i < this.thumbs.length; i++) {
19416 var thumb = this.thumbs[i],
19424 var xy = el.getXY();
19427 this.innerEl.addClass(this.disabledClass).dom.disabled = true;
19429 if (!this.thumbHolder) {
19430 this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});
19433 this.thumbHolder.show().setXY(xy);
19439 onEnable: function(){
19440 Ext.slider.MultiSlider.superclass.onEnable.call(this);
19442 for (var i=0; i < this.thumbs.length; i++) {
19443 var thumb = this.thumbs[i],
19449 this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
19451 if (this.thumbHolder) this.thumbHolder.hide();
19460 syncThumb : function() {
19461 if (this.rendered) {
19462 for (var i=0; i < this.thumbs.length; i++) {
19463 this.moveThumb(i, this.translateValue(this.thumbs[i].value));
19469 getValue : function(index) {
19470 return this.thumbs[index].value;
19474 getValues: function() {
19477 for (var i=0; i < this.thumbs.length; i++) {
19478 values.push(this.thumbs[i].value);
19485 beforeDestroy : function(){
19486 var thumbs = this.thumbs;
19487 for(var i = 0, len = thumbs.length; i < len; ++i){
19488 thumbs[i].destroy();
19491 Ext.destroyMembers(this, 'endEl', 'innerEl', 'focusEl', 'thumbHolder');
19492 Ext.slider.MultiSlider.superclass.beforeDestroy.call(this);
19496 Ext.reg('multislider', Ext.slider.MultiSlider);
19499 Ext.slider.SingleSlider = Ext.extend(Ext.slider.MultiSlider, {
19500 constructor: function(config) {
19501 config = config || {};
19503 Ext.applyIf(config, {
19504 values: [config.value || 0]
19507 Ext.slider.SingleSlider.superclass.constructor.call(this, config);
19511 getValue: function() {
19513 return Ext.slider.SingleSlider.superclass.getValue.call(this, 0);
19517 setValue: function(value, animate) {
19518 var args = Ext.toArray(arguments),
19524 if (len == 1 || (len <= 3 && typeof arguments[1] != 'number')) {
19528 return Ext.slider.SingleSlider.superclass.setValue.apply(this, args);
19532 syncThumb : function() {
19533 return Ext.slider.SingleSlider.superclass.syncThumb.apply(this, [0].concat(arguments));
19537 getNearest : function(){
19539 return this.thumbs[0];
19544 Ext.Slider = Ext.slider.SingleSlider;
19546 Ext.reg('slider', Ext.slider.SingleSlider);
19549 Ext.slider.Vertical = {
19550 onResize : function(w, h){
19551 this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
19555 getRatio : function(){
19556 var h = this.innerEl.getHeight(),
19557 v = this.maxValue - this.minValue;
19561 moveThumb: function(index, v, animate) {
19562 var thumb = this.thumbs[index],
19565 if (!animate || this.animate === false) {
19568 el.shift({bottom: v, stopFx: true, duration:.35});
19572 onClickChange : function(local) {
19573 if (local.left > this.clickRange[0] && local.left < this.clickRange[1]) {
19574 var thumb = this.getNearest(local, 'top'),
19575 index = thumb.index,
19576 value = this.minValue + this.reverseValue(this.innerEl.getHeight() - local.top);
19578 this.setValue(index, Ext.util.Format.round(value, this.decimalPrecision), undefined, true);
19584 Ext.slider.Thumb.Vertical = {
19585 getNewValue: function() {
19586 var slider = this.slider,
19587 innerEl = slider.innerEl,
19588 pos = innerEl.translatePoints(this.tracker.getXY()),
19589 bottom = innerEl.getHeight() - pos.top;
19591 return slider.minValue + Ext.util.Format.round(bottom / slider.getRatio(), slider.decimalPrecision);
19595 Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
19597 baseCls : 'x-progress',
19606 initComponent : function(){
19607 Ext.ProgressBar.superclass.initComponent.call(this);
19615 onRender : function(ct, position){
19616 var tpl = new Ext.Template(
19617 '<div class="{cls}-wrap">',
19618 '<div class="{cls}-inner">',
19619 '<div class="{cls}-bar">',
19620 '<div class="{cls}-text">',
19621 '<div> </div>',
19624 '<div class="{cls}-text {cls}-text-back">',
19625 '<div> </div>',
19631 this.el = position ? tpl.insertBefore(position, {cls: this.baseCls}, true)
19632 : tpl.append(ct, {cls: this.baseCls}, true);
19635 this.el.dom.id = this.id;
19637 var inner = this.el.dom.firstChild;
19638 this.progressBar = Ext.get(inner.firstChild);
19642 this.textEl = Ext.get(this.textEl);
19643 delete this.textTopEl;
19646 this.textTopEl = Ext.get(this.progressBar.dom.firstChild);
19647 var textBackEl = Ext.get(inner.childNodes[1]);
19648 this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');
19649 this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);
19650 this.textEl.setWidth(inner.offsetWidth);
19652 this.progressBar.setHeight(inner.offsetHeight);
19656 afterRender : function(){
19657 Ext.ProgressBar.superclass.afterRender.call(this);
19659 this.updateProgress(this.value, this.text);
19661 this.updateText(this.text);
19666 updateProgress : function(value, text, animate){
19667 this.value = value || 0;
19669 this.updateText(text);
19671 if(this.rendered && !this.isDestroyed){
19672 var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
19673 this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate));
19674 if(this.textTopEl){
19676 this.textTopEl.removeClass('x-hidden').setWidth(w);
19679 this.fireEvent('update', this, value, text);
19684 wait : function(o){
19685 if(!this.waitTimer){
19688 this.updateText(o.text);
19689 this.waitTimer = Ext.TaskMgr.start({
19691 var inc = o.increment || 10;
19693 this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*0.01, null, o.animate);
19695 interval: o.interval || 1000,
19696 duration: o.duration,
19697 onStop: function(){
19699 o.fn.apply(o.scope || this);
19710 isWaiting : function(){
19711 return this.waitTimer !== null;
19715 updateText : function(text){
19716 this.text = text || ' ';
19718 this.textEl.update(this.text);
19724 syncProgressBar : function(){
19726 this.updateProgress(this.value, this.text);
19732 setSize : function(w, h){
19733 Ext.ProgressBar.superclass.setSize.call(this, w, h);
19734 if(this.textTopEl){
19735 var inner = this.el.dom.firstChild;
19736 this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);
19738 this.syncProgressBar();
19743 reset : function(hide){
19744 this.updateProgress(0);
19745 if(this.textTopEl){
19746 this.textTopEl.addClass('x-hidden');
19756 clearTimer : function(){
19757 if(this.waitTimer){
19758 this.waitTimer.onStop = null;
19759 Ext.TaskMgr.stop(this.waitTimer);
19760 this.waitTimer = null;
19764 onDestroy: function(){
19767 if(this.textEl.isComposite){
19768 this.textEl.clear();
19770 Ext.destroyMembers(this, 'textEl', 'progressBar', 'textTopEl');
19772 Ext.ProgressBar.superclass.onDestroy.call(this);
19775 Ext.reg('progress', Ext.ProgressBar);
19779 var Event=Ext.EventManager;
19780 var Dom=Ext.lib.Dom;
19783 Ext.dd.DragDrop = function(id, sGroup, config) {
19785 this.init(id, sGroup, config);
19789 Ext.dd.DragDrop.prototype = {
19806 invalidHandleTypes: null,
19809 invalidHandleIds: null,
19812 invalidHandleClasses: null,
19828 this.locked = true;
19835 unlock: function() {
19836 this.locked = false;
19849 __ygDragDrop: true,
19870 maintainOffset: false,
19879 primaryButtonOnly: true,
19885 hasOuterHandles: false,
19888 b4StartDrag: function(x, y) { },
19891 startDrag: function(x, y) { },
19894 b4Drag: function(e) { },
19897 onDrag: function(e) { },
19900 onDragEnter: function(e, id) { },
19903 b4DragOver: function(e) { },
19906 onDragOver: function(e, id) { },
19909 b4DragOut: function(e) { },
19912 onDragOut: function(e, id) { },
19915 b4DragDrop: function(e) { },
19918 onDragDrop: function(e, id) { },
19921 onInvalidDrop: function(e) { },
19924 b4EndDrag: function(e) { },
19927 endDrag: function(e) { },
19930 b4MouseDown: function(e) { },
19933 onMouseDown: function(e) { },
19936 onMouseUp: function(e) { },
19939 onAvailable: function () {
19943 defaultPadding : {left:0, right:0, top:0, bottom:0},
19946 constrainTo : function(constrainTo, pad, inContent){
19947 if(Ext.isNumber(pad)){
19948 pad = {left: pad, right:pad, top:pad, bottom:pad};
19950 pad = pad || this.defaultPadding;
19951 var b = Ext.get(this.getEl()).getBox(),
19952 ce = Ext.get(constrainTo),
19953 s = ce.getScroll(),
19956 if(cd == document.body){
19957 c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
19959 var xy = ce.getXY();
19960 c = {x : xy[0], y: xy[1], width: cd.clientWidth, height: cd.clientHeight};
19964 var topSpace = b.y - c.y,
19965 leftSpace = b.x - c.x;
19967 this.resetConstraints();
19968 this.setXConstraint(leftSpace - (pad.left||0),
19969 c.width - leftSpace - b.width - (pad.right||0),
19972 this.setYConstraint(topSpace - (pad.top||0),
19973 c.height - topSpace - b.height - (pad.bottom||0),
19979 getEl: function() {
19980 if (!this._domRef) {
19981 this._domRef = Ext.getDom(this.id);
19984 return this._domRef;
19988 getDragEl: function() {
19989 return Ext.getDom(this.dragElId);
19993 init: function(id, sGroup, config) {
19994 this.initTarget(id, sGroup, config);
19995 Event.on(this.id, "mousedown", this.handleMouseDown, this);
20000 initTarget: function(id, sGroup, config) {
20003 this.config = config || {};
20006 this.DDM = Ext.dd.DDM;
20012 if (typeof id !== "string") {
20020 this.addToGroup((sGroup) ? sGroup : "default");
20024 this.handleElId = id;
20027 this.setDragElId(id);
20030 this.invalidHandleTypes = { A: "A" };
20031 this.invalidHandleIds = {};
20032 this.invalidHandleClasses = [];
20034 this.applyConfig();
20036 this.handleOnAvailable();
20040 applyConfig: function() {
20044 this.padding = this.config.padding || [0, 0, 0, 0];
20045 this.isTarget = (this.config.isTarget !== false);
20046 this.maintainOffset = (this.config.maintainOffset);
20047 this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
20052 handleOnAvailable: function() {
20053 this.available = true;
20054 this.resetConstraints();
20055 this.onAvailable();
20059 setPadding: function(iTop, iRight, iBot, iLeft) {
20061 if (!iRight && 0 !== iRight) {
20062 this.padding = [iTop, iTop, iTop, iTop];
20063 } else if (!iBot && 0 !== iBot) {
20064 this.padding = [iTop, iRight, iTop, iRight];
20066 this.padding = [iTop, iRight, iBot, iLeft];
20071 setInitPosition: function(diffX, diffY) {
20072 var el = this.getEl();
20074 if (!this.DDM.verifyEl(el)) {
20078 var dx = diffX || 0;
20079 var dy = diffY || 0;
20081 var p = Dom.getXY( el );
20083 this.initPageX = p[0] - dx;
20084 this.initPageY = p[1] - dy;
20086 this.lastPageX = p[0];
20087 this.lastPageY = p[1];
20089 this.setStartPosition(p);
20093 setStartPosition: function(pos) {
20094 var p = pos || Dom.getXY( this.getEl() );
20095 this.deltaSetXY = null;
20097 this.startPageX = p[0];
20098 this.startPageY = p[1];
20102 addToGroup: function(sGroup) {
20103 this.groups[sGroup] = true;
20104 this.DDM.regDragDrop(this, sGroup);
20108 removeFromGroup: function(sGroup) {
20109 if (this.groups[sGroup]) {
20110 delete this.groups[sGroup];
20113 this.DDM.removeDDFromGroup(this, sGroup);
20117 setDragElId: function(id) {
20118 this.dragElId = id;
20122 setHandleElId: function(id) {
20123 if (typeof id !== "string") {
20126 this.handleElId = id;
20127 this.DDM.regHandle(this.id, id);
20131 setOuterHandleElId: function(id) {
20132 if (typeof id !== "string") {
20135 Event.on(id, "mousedown",
20136 this.handleMouseDown, this);
20137 this.setHandleElId(id);
20139 this.hasOuterHandles = true;
20143 unreg: function() {
20144 Event.un(this.id, "mousedown",
20145 this.handleMouseDown);
20146 this._domRef = null;
20147 this.DDM._remove(this);
20150 destroy : function(){
20155 isLocked: function() {
20156 return (this.DDM.isLocked() || this.locked);
20160 handleMouseDown: function(e, oDD){
20161 if (this.primaryButtonOnly && e.button != 0) {
20165 if (this.isLocked()) {
20169 this.DDM.refreshCache(this.groups);
20171 var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
20172 if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {
20174 if (this.clickValidator(e)) {
20177 this.setStartPosition();
20179 this.b4MouseDown(e);
20180 this.onMouseDown(e);
20182 this.DDM.handleMouseDown(e, this);
20184 this.DDM.stopEvent(e);
20192 clickValidator: function(e) {
20193 var target = e.getTarget();
20194 return ( this.isValidHandleChild(target) &&
20195 (this.id == this.handleElId ||
20196 this.DDM.handleWasClicked(target, this.id)) );
20200 addInvalidHandleType: function(tagName) {
20201 var type = tagName.toUpperCase();
20202 this.invalidHandleTypes[type] = type;
20206 addInvalidHandleId: function(id) {
20207 if (typeof id !== "string") {
20210 this.invalidHandleIds[id] = id;
20214 addInvalidHandleClass: function(cssClass) {
20215 this.invalidHandleClasses.push(cssClass);
20219 removeInvalidHandleType: function(tagName) {
20220 var type = tagName.toUpperCase();
20222 delete this.invalidHandleTypes[type];
20226 removeInvalidHandleId: function(id) {
20227 if (typeof id !== "string") {
20230 delete this.invalidHandleIds[id];
20234 removeInvalidHandleClass: function(cssClass) {
20235 for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
20236 if (this.invalidHandleClasses[i] == cssClass) {
20237 delete this.invalidHandleClasses[i];
20243 isValidHandleChild: function(node) {
20249 nodeName = node.nodeName.toUpperCase();
20251 nodeName = node.nodeName;
20253 valid = valid && !this.invalidHandleTypes[nodeName];
20254 valid = valid && !this.invalidHandleIds[node.id];
20256 for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
20257 valid = !Ext.fly(node).hasClass(this.invalidHandleClasses[i]);
20266 setXTicks: function(iStartX, iTickSize) {
20268 this.xTickSize = iTickSize;
20272 for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
20274 this.xTicks[this.xTicks.length] = i;
20279 for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
20281 this.xTicks[this.xTicks.length] = i;
20286 this.xTicks.sort(this.DDM.numericSort) ;
20290 setYTicks: function(iStartY, iTickSize) {
20292 this.yTickSize = iTickSize;
20296 for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
20298 this.yTicks[this.yTicks.length] = i;
20303 for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
20305 this.yTicks[this.yTicks.length] = i;
20310 this.yTicks.sort(this.DDM.numericSort) ;
20314 setXConstraint: function(iLeft, iRight, iTickSize) {
20315 this.leftConstraint = iLeft;
20316 this.rightConstraint = iRight;
20318 this.minX = this.initPageX - iLeft;
20319 this.maxX = this.initPageX + iRight;
20320 if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
20322 this.constrainX = true;
20326 clearConstraints: function() {
20327 this.constrainX = false;
20328 this.constrainY = false;
20333 clearTicks: function() {
20334 this.xTicks = null;
20335 this.yTicks = null;
20336 this.xTickSize = 0;
20337 this.yTickSize = 0;
20341 setYConstraint: function(iUp, iDown, iTickSize) {
20342 this.topConstraint = iUp;
20343 this.bottomConstraint = iDown;
20345 this.minY = this.initPageY - iUp;
20346 this.maxY = this.initPageY + iDown;
20347 if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
20349 this.constrainY = true;
20354 resetConstraints: function() {
20356 if (this.initPageX || this.initPageX === 0) {
20358 var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
20359 var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
20361 this.setInitPosition(dx, dy);
20365 this.setInitPosition();
20368 if (this.constrainX) {
20369 this.setXConstraint( this.leftConstraint,
20370 this.rightConstraint,
20374 if (this.constrainY) {
20375 this.setYConstraint( this.topConstraint,
20376 this.bottomConstraint,
20382 getTick: function(val, tickArray) {
20387 } else if (tickArray[0] >= val) {
20390 return tickArray[0];
20392 for (var i=0, len=tickArray.length; i<len; ++i) {
20394 if (tickArray[next] && tickArray[next] >= val) {
20395 var diff1 = val - tickArray[i];
20396 var diff2 = tickArray[next] - val;
20397 return (diff2 > diff1) ? tickArray[i] : tickArray[next];
20403 return tickArray[tickArray.length - 1];
20408 toString: function() {
20409 return ("DragDrop " + this.id);
20419 if (!Ext.dd.DragDropMgr) {
20422 Ext.dd.DragDropMgr = function() {
20424 var Event = Ext.EventManager;
20447 preventDefault: true,
20450 stopPropagation: true,
20453 initialized: false,
20460 this.initialized = true;
20473 _execOnAll: function(sMethod, args) {
20474 for (var i in this.ids) {
20475 for (var j in this.ids[i]) {
20476 var oDD = this.ids[i][j];
20477 if (! this.isTypeOfDD(oDD)) {
20480 oDD[sMethod].apply(oDD, args);
20486 _onLoad: function() {
20491 Event.on(document, "mouseup", this.handleMouseUp, this, true);
20492 Event.on(document, "mousemove", this.handleMouseMove, this, true);
20493 Event.on(window, "unload", this._onUnload, this, true);
20494 Event.on(window, "resize", this._onResize, this, true);
20500 _onResize: function(e) {
20501 this._execOnAll("resetConstraints", []);
20505 lock: function() { this.locked = true; },
20508 unlock: function() { this.locked = false; },
20511 isLocked: function() { return this.locked; },
20520 clickPixelThresh: 3,
20523 clickTimeThresh: 350,
20526 dragThreshMet: false,
20529 clickTimeout: null,
20538 regDragDrop: function(oDD, sGroup) {
20539 if (!this.initialized) { this.init(); }
20541 if (!this.ids[sGroup]) {
20542 this.ids[sGroup] = {};
20544 this.ids[sGroup][oDD.id] = oDD;
20548 removeDDFromGroup: function(oDD, sGroup) {
20549 if (!this.ids[sGroup]) {
20550 this.ids[sGroup] = {};
20553 var obj = this.ids[sGroup];
20554 if (obj && obj[oDD.id]) {
20555 delete obj[oDD.id];
20560 _remove: function(oDD) {
20561 for (var g in oDD.groups) {
20562 if (g && this.ids[g] && this.ids[g][oDD.id]) {
20563 delete this.ids[g][oDD.id];
20566 delete this.handleIds[oDD.id];
20570 regHandle: function(sDDId, sHandleId) {
20571 if (!this.handleIds[sDDId]) {
20572 this.handleIds[sDDId] = {};
20574 this.handleIds[sDDId][sHandleId] = sHandleId;
20578 isDragDrop: function(id) {
20579 return ( this.getDDById(id) ) ? true : false;
20583 getRelated: function(p_oDD, bTargetsOnly) {
20585 for (var i in p_oDD.groups) {
20586 for (var j in this.ids[i]) {
20587 var dd = this.ids[i][j];
20588 if (! this.isTypeOfDD(dd)) {
20591 if (!bTargetsOnly || dd.isTarget) {
20592 oDDs[oDDs.length] = dd;
20601 isLegalTarget: function (oDD, oTargetDD) {
20602 var targets = this.getRelated(oDD, true);
20603 for (var i=0, len=targets.length;i<len;++i) {
20604 if (targets[i].id == oTargetDD.id) {
20613 isTypeOfDD: function (oDD) {
20614 return (oDD && oDD.__ygDragDrop);
20618 isHandle: function(sDDId, sHandleId) {
20619 return ( this.handleIds[sDDId] &&
20620 this.handleIds[sDDId][sHandleId] );
20624 getDDById: function(id) {
20625 for (var i in this.ids) {
20626 if (this.ids[i][id]) {
20627 return this.ids[i][id];
20634 handleMouseDown: function(e, oDD) {
20636 Ext.QuickTips.ddDisable();
20638 if(this.dragCurrent){
20641 this.handleMouseUp(e);
20644 this.currentTarget = e.getTarget();
20645 this.dragCurrent = oDD;
20647 var el = oDD.getEl();
20650 this.startX = e.getPageX();
20651 this.startY = e.getPageY();
20653 this.deltaX = this.startX - el.offsetLeft;
20654 this.deltaY = this.startY - el.offsetTop;
20656 this.dragThreshMet = false;
20658 this.clickTimeout = setTimeout(
20660 var DDM = Ext.dd.DDM;
20661 DDM.startDrag(DDM.startX, DDM.startY);
20663 this.clickTimeThresh );
20667 startDrag: function(x, y) {
20668 clearTimeout(this.clickTimeout);
20669 if (this.dragCurrent) {
20670 this.dragCurrent.b4StartDrag(x, y);
20671 this.dragCurrent.startDrag(x, y);
20673 this.dragThreshMet = true;
20677 handleMouseUp: function(e) {
20680 Ext.QuickTips.ddEnable();
20682 if (! this.dragCurrent) {
20686 clearTimeout(this.clickTimeout);
20688 if (this.dragThreshMet) {
20689 this.fireEvents(e, true);
20699 stopEvent: function(e){
20700 if(this.stopPropagation) {
20701 e.stopPropagation();
20704 if (this.preventDefault) {
20705 e.preventDefault();
20710 stopDrag: function(e) {
20712 if (this.dragCurrent) {
20713 if (this.dragThreshMet) {
20714 this.dragCurrent.b4EndDrag(e);
20715 this.dragCurrent.endDrag(e);
20718 this.dragCurrent.onMouseUp(e);
20721 this.dragCurrent = null;
20722 this.dragOvers = {};
20726 handleMouseMove: function(e) {
20727 if (! this.dragCurrent) {
20733 if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
20735 return this.handleMouseUp(e);
20738 if (!this.dragThreshMet) {
20739 var diffX = Math.abs(this.startX - e.getPageX());
20740 var diffY = Math.abs(this.startY - e.getPageY());
20741 if (diffX > this.clickPixelThresh ||
20742 diffY > this.clickPixelThresh) {
20743 this.startDrag(this.startX, this.startY);
20747 if (this.dragThreshMet) {
20748 this.dragCurrent.b4Drag(e);
20749 this.dragCurrent.onDrag(e);
20750 if(!this.dragCurrent.moveOnly){
20751 this.fireEvents(e, false);
20761 fireEvents: function(e, isDrop) {
20762 var dc = this.dragCurrent;
20766 if (!dc || dc.isLocked()) {
20770 var pt = e.getPoint();
20778 var enterEvts = [];
20782 for (var i in this.dragOvers) {
20784 var ddo = this.dragOvers[i];
20786 if (! this.isTypeOfDD(ddo)) {
20790 if (! this.isOverTarget(pt, ddo, this.mode)) {
20791 outEvts.push( ddo );
20794 oldOvers[i] = true;
20795 delete this.dragOvers[i];
20798 for (var sGroup in dc.groups) {
20800 if ("string" != typeof sGroup) {
20804 for (i in this.ids[sGroup]) {
20805 var oDD = this.ids[sGroup][i];
20806 if (! this.isTypeOfDD(oDD)) {
20810 if (oDD.isTarget && !oDD.isLocked() && ((oDD != dc) || (dc.ignoreSelf === false))) {
20811 if (this.isOverTarget(pt, oDD, this.mode)) {
20814 dropEvts.push( oDD );
20819 if (!oldOvers[oDD.id]) {
20820 enterEvts.push( oDD );
20823 overEvts.push( oDD );
20826 this.dragOvers[oDD.id] = oDD;
20834 if (outEvts.length) {
20835 dc.b4DragOut(e, outEvts);
20836 dc.onDragOut(e, outEvts);
20839 if (enterEvts.length) {
20840 dc.onDragEnter(e, enterEvts);
20843 if (overEvts.length) {
20844 dc.b4DragOver(e, overEvts);
20845 dc.onDragOver(e, overEvts);
20848 if (dropEvts.length) {
20849 dc.b4DragDrop(e, dropEvts);
20850 dc.onDragDrop(e, dropEvts);
20856 for (i=0, len=outEvts.length; i<len; ++i) {
20857 dc.b4DragOut(e, outEvts[i].id);
20858 dc.onDragOut(e, outEvts[i].id);
20862 for (i=0,len=enterEvts.length; i<len; ++i) {
20864 dc.onDragEnter(e, enterEvts[i].id);
20868 for (i=0,len=overEvts.length; i<len; ++i) {
20869 dc.b4DragOver(e, overEvts[i].id);
20870 dc.onDragOver(e, overEvts[i].id);
20874 for (i=0, len=dropEvts.length; i<len; ++i) {
20875 dc.b4DragDrop(e, dropEvts[i].id);
20876 dc.onDragDrop(e, dropEvts[i].id);
20882 if (isDrop && !dropEvts.length) {
20883 dc.onInvalidDrop(e);
20889 getBestMatch: function(dds) {
20897 var len = dds.length;
20903 for (var i=0; i<len; ++i) {
20908 if (dd.cursorIsOver) {
20914 winner.overlap.getArea() < dd.overlap.getArea()) {
20925 refreshCache: function(groups) {
20926 for (var sGroup in groups) {
20927 if ("string" != typeof sGroup) {
20930 for (var i in this.ids[sGroup]) {
20931 var oDD = this.ids[sGroup][i];
20933 if (this.isTypeOfDD(oDD)) {
20935 var loc = this.getLocation(oDD);
20937 this.locationCache[oDD.id] = loc;
20939 delete this.locationCache[oDD.id];
20950 verifyEl: function(el) {
20955 parent = el.offsetParent;
20958 parent = el.offsetParent;
20969 getLocation: function(oDD) {
20970 if (! this.isTypeOfDD(oDD)) {
20974 var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
20977 pos= Ext.lib.Dom.getXY(el);
20985 x2 = x1 + el.offsetWidth;
20987 y2 = y1 + el.offsetHeight;
20989 t = y1 - oDD.padding[0];
20990 r = x2 + oDD.padding[1];
20991 b = y2 + oDD.padding[2];
20992 l = x1 - oDD.padding[3];
20994 return new Ext.lib.Region( t, r, b, l );
20998 isOverTarget: function(pt, oTarget, intersect) {
21000 var loc = this.locationCache[oTarget.id];
21001 if (!loc || !this.useCache) {
21002 loc = this.getLocation(oTarget);
21003 this.locationCache[oTarget.id] = loc;
21011 oTarget.cursorIsOver = loc.contains( pt );
21018 var dc = this.dragCurrent;
21019 if (!dc || !dc.getTargetCoord ||
21020 (!intersect && !dc.constrainX && !dc.constrainY)) {
21021 return oTarget.cursorIsOver;
21024 oTarget.overlap = null;
21030 var pos = dc.getTargetCoord(pt.x, pt.y);
21032 var el = dc.getDragEl();
21033 var curRegion = new Ext.lib.Region( pos.y,
21034 pos.x + el.offsetWidth,
21035 pos.y + el.offsetHeight,
21038 var overlap = curRegion.intersect(loc);
21041 oTarget.overlap = overlap;
21042 return (intersect) ? true : oTarget.cursorIsOver;
21049 _onUnload: function(e, me) {
21050 Ext.dd.DragDropMgr.unregAll();
21054 unregAll: function() {
21056 if (this.dragCurrent) {
21058 this.dragCurrent = null;
21061 this._execOnAll("unreg", []);
21063 for (var i in this.elementCache) {
21064 delete this.elementCache[i];
21067 this.elementCache = {};
21075 getElWrapper: function(id) {
21076 var oWrapper = this.elementCache[id];
21077 if (!oWrapper || !oWrapper.el) {
21078 oWrapper = this.elementCache[id] =
21079 new this.ElementWrapper(Ext.getDom(id));
21085 getElement: function(id) {
21086 return Ext.getDom(id);
21090 getCss: function(id) {
21091 var el = Ext.getDom(id);
21092 return (el) ? el.style : null;
21096 ElementWrapper: function(el) {
21098 this.el = el || null;
21100 this.id = this.el && el.id;
21102 this.css = this.el && el.style;
21106 getPosX: function(el) {
21107 return Ext.lib.Dom.getX(el);
21111 getPosY: function(el) {
21112 return Ext.lib.Dom.getY(el);
21116 swapNode: function(n1, n2) {
21120 var p = n2.parentNode;
21121 var s = n2.nextSibling;
21124 p.insertBefore(n1, n2);
21125 } else if (n2 == n1.nextSibling) {
21126 p.insertBefore(n2, n1);
21128 n1.parentNode.replaceChild(n2, n1);
21129 p.insertBefore(n1, s);
21135 getScroll: function () {
21136 var t, l, dde=document.documentElement, db=document.body;
21137 if (dde && (dde.scrollTop || dde.scrollLeft)) {
21139 l = dde.scrollLeft;
21146 return { top: t, left: l };
21150 getStyle: function(el, styleProp) {
21151 return Ext.fly(el).getStyle(styleProp);
21155 getScrollTop: function () {
21156 return this.getScroll().top;
21160 getScrollLeft: function () {
21161 return this.getScroll().left;
21165 moveToEl: function (moveEl, targetEl) {
21166 var aCoord = Ext.lib.Dom.getXY(targetEl);
21167 Ext.lib.Dom.setXY(moveEl, aCoord);
21171 numericSort: function(a, b) {
21179 _addListeners: function() {
21180 var DDM = Ext.dd.DDM;
21181 if ( Ext.lib.Event && document ) {
21184 if (DDM._timeoutCount > 2000) {
21186 setTimeout(DDM._addListeners, 10);
21187 if (document && document.body) {
21188 DDM._timeoutCount += 1;
21195 handleWasClicked: function(node, id) {
21196 if (this.isHandle(id, node.id)) {
21200 var p = node.parentNode;
21203 if (this.isHandle(id, p.id)) {
21219 Ext.dd.DDM = Ext.dd.DragDropMgr;
21220 Ext.dd.DDM._addListeners();
21225 Ext.dd.DD = function(id, sGroup, config) {
21227 this.init(id, sGroup, config);
21231 Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
21237 autoOffset: function(iPageX, iPageY) {
21238 var x = iPageX - this.startPageX;
21239 var y = iPageY - this.startPageY;
21240 this.setDelta(x, y);
21244 setDelta: function(iDeltaX, iDeltaY) {
21245 this.deltaX = iDeltaX;
21246 this.deltaY = iDeltaY;
21250 setDragElPos: function(iPageX, iPageY) {
21254 var el = this.getDragEl();
21255 this.alignElWithMouse(el, iPageX, iPageY);
21259 alignElWithMouse: function(el, iPageX, iPageY) {
21260 var oCoord = this.getTargetCoord(iPageX, iPageY);
21261 var fly = el.dom ? el : Ext.fly(el, '_dd');
21262 if (!this.deltaSetXY) {
21263 var aCoord = [oCoord.x, oCoord.y];
21265 var newLeft = fly.getLeft(true);
21266 var newTop = fly.getTop(true);
21267 this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
21269 fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
21272 this.cachePosition(oCoord.x, oCoord.y);
21273 this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
21278 cachePosition: function(iPageX, iPageY) {
21280 this.lastPageX = iPageX;
21281 this.lastPageY = iPageY;
21283 var aCoord = Ext.lib.Dom.getXY(this.getEl());
21284 this.lastPageX = aCoord[0];
21285 this.lastPageY = aCoord[1];
21290 autoScroll: function(x, y, h, w) {
21294 var clientH = Ext.lib.Dom.getViewHeight();
21297 var clientW = Ext.lib.Dom.getViewWidth();
21300 var st = this.DDM.getScrollTop();
21303 var sl = this.DDM.getScrollLeft();
21314 var toBot = (clientH + st - y - this.deltaY);
21317 var toRight = (clientW + sl - x - this.deltaX);
21327 var scrAmt = (document.all) ? 80 : 30;
21331 if ( bot > clientH && toBot < thresh ) {
21332 window.scrollTo(sl, st + scrAmt);
21337 if ( y < st && st > 0 && y - st < thresh ) {
21338 window.scrollTo(sl, st - scrAmt);
21343 if ( right > clientW && toRight < thresh ) {
21344 window.scrollTo(sl + scrAmt, st);
21349 if ( x < sl && sl > 0 && x - sl < thresh ) {
21350 window.scrollTo(sl - scrAmt, st);
21356 getTargetCoord: function(iPageX, iPageY) {
21357 var x = iPageX - this.deltaX;
21358 var y = iPageY - this.deltaY;
21360 if (this.constrainX) {
21361 if (x < this.minX) { x = this.minX; }
21362 if (x > this.maxX) { x = this.maxX; }
21365 if (this.constrainY) {
21366 if (y < this.minY) { y = this.minY; }
21367 if (y > this.maxY) { y = this.maxY; }
21370 x = this.getTick(x, this.xTicks);
21371 y = this.getTick(y, this.yTicks);
21378 applyConfig: function() {
21379 Ext.dd.DD.superclass.applyConfig.call(this);
21380 this.scroll = (this.config.scroll !== false);
21384 b4MouseDown: function(e) {
21386 this.autoOffset(e.getPageX(),
21391 b4Drag: function(e) {
21392 this.setDragElPos(e.getPageX(),
21396 toString: function() {
21397 return ("DD " + this.id);
21407 Ext.dd.DDProxy = function(id, sGroup, config) {
21409 this.init(id, sGroup, config);
21415 Ext.dd.DDProxy.dragElId = "ygddfdiv";
21417 Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {
21423 centerFrame: false,
21426 createFrame: function() {
21428 var body = document.body;
21430 if (!body || !body.firstChild) {
21431 setTimeout( function() { self.createFrame(); }, 50 );
21435 var div = this.getDragEl();
21438 div = document.createElement("div");
21439 div.id = this.dragElId;
21442 s.position = "absolute";
21443 s.visibility = "hidden";
21445 s.border = "2px solid #aaa";
21451 body.insertBefore(div, body.firstChild);
21456 initFrame: function() {
21457 this.createFrame();
21460 applyConfig: function() {
21461 Ext.dd.DDProxy.superclass.applyConfig.call(this);
21463 this.resizeFrame = (this.config.resizeFrame !== false);
21464 this.centerFrame = (this.config.centerFrame);
21465 this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
21469 showFrame: function(iPageX, iPageY) {
21470 var el = this.getEl();
21471 var dragEl = this.getDragEl();
21472 var s = dragEl.style;
21474 this._resizeProxy();
21476 if (this.centerFrame) {
21477 this.setDelta( Math.round(parseInt(s.width, 10)/2),
21478 Math.round(parseInt(s.height, 10)/2) );
21481 this.setDragElPos(iPageX, iPageY);
21483 Ext.fly(dragEl).show();
21487 _resizeProxy: function() {
21488 if (this.resizeFrame) {
21489 var el = this.getEl();
21490 Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
21495 b4MouseDown: function(e) {
21496 var x = e.getPageX();
21497 var y = e.getPageY();
21498 this.autoOffset(x, y);
21499 this.setDragElPos(x, y);
21503 b4StartDrag: function(x, y) {
21505 this.showFrame(x, y);
21509 b4EndDrag: function(e) {
21510 Ext.fly(this.getDragEl()).hide();
21516 endDrag: function(e) {
21518 var lel = this.getEl();
21519 var del = this.getDragEl();
21522 del.style.visibility = "";
21527 lel.style.visibility = "hidden";
21528 Ext.dd.DDM.moveToEl(lel, del);
21529 del.style.visibility = "hidden";
21530 lel.style.visibility = "";
21535 beforeMove : function(){
21539 afterDrag : function(){
21543 toString: function() {
21544 return ("DDProxy " + this.id);
21549 Ext.dd.DDTarget = function(id, sGroup, config) {
21551 this.initTarget(id, sGroup, config);
21556 Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
21558 getDragEl: Ext.emptyFn,
21560 isValidHandleChild: Ext.emptyFn,
21562 startDrag: Ext.emptyFn,
21564 endDrag: Ext.emptyFn,
21566 onDrag: Ext.emptyFn,
21568 onDragDrop: Ext.emptyFn,
21570 onDragEnter: Ext.emptyFn,
21572 onDragOut: Ext.emptyFn,
21574 onDragOver: Ext.emptyFn,
21576 onInvalidDrop: Ext.emptyFn,
21578 onMouseDown: Ext.emptyFn,
21580 onMouseUp: Ext.emptyFn,
21582 setXConstraint: Ext.emptyFn,
21584 setYConstraint: Ext.emptyFn,
21586 resetConstraints: Ext.emptyFn,
21588 clearConstraints: Ext.emptyFn,
21590 clearTicks: Ext.emptyFn,
21592 setInitPosition: Ext.emptyFn,
21594 setDragElId: Ext.emptyFn,
21596 setHandleElId: Ext.emptyFn,
21598 setOuterHandleElId: Ext.emptyFn,
21600 addInvalidHandleClass: Ext.emptyFn,
21602 addInvalidHandleId: Ext.emptyFn,
21604 addInvalidHandleType: Ext.emptyFn,
21606 removeInvalidHandleClass: Ext.emptyFn,
21608 removeInvalidHandleId: Ext.emptyFn,
21610 removeInvalidHandleType: Ext.emptyFn,
21612 toString: function() {
21613 return ("DDTarget " + this.id);
21616 Ext.dd.DragTracker = Ext.extend(Ext.util.Observable, {
21624 constructor : function(config){
21625 Ext.apply(this, config);
21641 this.dragRegion = new Ext.lib.Region(0,0,0,0);
21644 this.initEl(this.el);
21646 Ext.dd.DragTracker.superclass.constructor.call(this, config);
21649 initEl: function(el){
21650 this.el = Ext.get(el);
21651 el.on('mousedown', this.onMouseDown, this,
21652 this.delegate ? {delegate: this.delegate} : undefined);
21655 destroy : function(){
21656 this.el.un('mousedown', this.onMouseDown, this);
21660 onMouseDown: function(e, target){
21661 if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
21662 this.startXY = this.lastXY = e.getXY();
21663 this.dragTarget = this.delegate ? target : this.el.dom;
21664 if(this.preventDefault !== false){
21665 e.preventDefault();
21669 mouseup: this.onMouseUp,
21670 mousemove: this.onMouseMove,
21671 selectstart: this.stopSelect
21673 if(this.autoStart){
21674 this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this, [e]);
21679 onMouseMove: function(e, target){
21681 if(this.active && Ext.isIE && !e.browserEvent.button){
21682 e.preventDefault();
21687 e.preventDefault();
21688 var xy = e.getXY(), s = this.startXY;
21691 if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
21692 this.triggerStart(e);
21697 this.fireEvent('mousemove', this, e);
21699 this.fireEvent('drag', this, e);
21702 onMouseUp: function(e) {
21703 var doc = Ext.getDoc(),
21704 wasActive = this.active;
21706 doc.un('mousemove', this.onMouseMove, this);
21707 doc.un('mouseup', this.onMouseUp, this);
21708 doc.un('selectstart', this.stopSelect, this);
21709 e.preventDefault();
21711 this.active = false;
21712 delete this.elRegion;
21713 this.fireEvent('mouseup', this, e);
21716 this.fireEvent('dragend', this, e);
21720 triggerStart: function(e) {
21722 this.active = true;
21724 this.fireEvent('dragstart', this, e);
21727 clearStart : function() {
21729 clearTimeout(this.timer);
21734 stopSelect : function(e) {
21740 onBeforeStart : function(e) {
21745 onStart : function(xy) {
21750 onDrag : function(e) {
21755 onEnd : function(e) {
21760 getDragTarget : function(){
21761 return this.dragTarget;
21764 getDragCt : function(){
21768 getXY : function(constrain){
21770 this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
21773 getOffset : function(constrain){
21774 var xy = this.getXY(constrain),
21776 return [s[0]-xy[0], s[1]-xy[1]];
21780 'point' : function(xy){
21782 if(!this.elRegion){
21783 this.elRegion = this.getDragCt().getRegion();
21786 var dr = this.dragRegion;
21793 dr.constrainTo(this.elRegion);
21795 return [dr.left, dr.top];
21799 Ext.dd.ScrollManager = function(){
21800 var ddm = Ext.dd.DragDropMgr;
21805 var onStop = function(e){
21810 var triggerRefresh = function(){
21811 if(ddm.dragCurrent){
21812 ddm.refreshCache(ddm.dragCurrent.groups);
21816 var doScroll = function(){
21817 if(ddm.dragCurrent){
21818 var dds = Ext.dd.ScrollManager;
21819 var inc = proc.el.ddScrollConfig ?
21820 proc.el.ddScrollConfig.increment : dds.increment;
21822 if(proc.el.scroll(proc.dir, inc)){
21826 proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
21831 var clearProc = function(){
21833 clearInterval(proc.id);
21840 var startProc = function(el, dir){
21844 var group = el.ddScrollConfig ? el.ddScrollConfig.ddGroup : undefined,
21845 freq = (el.ddScrollConfig && el.ddScrollConfig.frequency)
21846 ? el.ddScrollConfig.frequency
21847 : Ext.dd.ScrollManager.frequency;
21849 if (group === undefined || ddm.dragCurrent.ddGroup == group) {
21850 proc.id = setInterval(doScroll, freq);
21854 var onFire = function(e, isDrop){
21855 if(isDrop || !ddm.dragCurrent){ return; }
21856 var dds = Ext.dd.ScrollManager;
21857 if(!dragEl || dragEl != ddm.dragCurrent){
21858 dragEl = ddm.dragCurrent;
21860 dds.refreshCache();
21863 var xy = Ext.lib.Event.getXY(e);
21864 var pt = new Ext.lib.Point(xy[0], xy[1]);
21865 for(var id in els){
21866 var el = els[id], r = el._region;
21867 var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
21868 if(r && r.contains(pt) && el.isScrollable()){
21869 if(r.bottom - pt.y <= c.vthresh){
21871 startProc(el, "down");
21874 }else if(r.right - pt.x <= c.hthresh){
21876 startProc(el, "left");
21879 }else if(pt.y - r.top <= c.vthresh){
21881 startProc(el, "up");
21884 }else if(pt.x - r.left <= c.hthresh){
21886 startProc(el, "right");
21895 ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
21896 ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
21900 register : function(el){
21901 if(Ext.isArray(el)){
21902 for(var i = 0, len = el.length; i < len; i++) {
21903 this.register(el[i]);
21912 unregister : function(el){
21913 if(Ext.isArray(el)){
21914 for(var i = 0, len = el.length; i < len; i++) {
21915 this.unregister(el[i]);
21941 ddGroup: undefined,
21944 refreshCache : function(){
21945 for(var id in els){
21946 if(typeof els[id] == 'object'){
21947 els[id]._region = els[id].getRegion();
21953 Ext.dd.Registry = function(){
21956 var autoIdSeed = 0;
21958 var getId = function(el, autogen){
21959 if(typeof el == "string"){
21963 if(!id && autogen !== false){
21964 id = "extdd-" + (++autoIdSeed);
21972 register : function(el, data){
21974 if(typeof el == "string"){
21975 el = document.getElementById(el);
21978 elements[getId(el)] = data;
21979 if(data.isHandle !== false){
21980 handles[data.ddel.id] = data;
21983 var hs = data.handles;
21984 for(var i = 0, len = hs.length; i < len; i++){
21985 handles[getId(hs[i])] = data;
21991 unregister : function(el){
21992 var id = getId(el, false);
21993 var data = elements[id];
21995 delete elements[id];
21997 var hs = data.handles;
21998 for(var i = 0, len = hs.length; i < len; i++){
21999 delete handles[getId(hs[i], false)];
22006 getHandle : function(id){
22007 if(typeof id != "string"){
22010 return handles[id];
22014 getHandleFromEvent : function(e){
22015 var t = Ext.lib.Event.getTarget(e);
22016 return t ? handles[t.id] : null;
22020 getTarget : function(id){
22021 if(typeof id != "string"){
22024 return elements[id];
22028 getTargetFromEvent : function(e){
22029 var t = Ext.lib.Event.getTarget(e);
22030 return t ? elements[t.id] || handles[t.id] : null;
22034 Ext.dd.StatusProxy = function(config){
22035 Ext.apply(this, config);
22036 this.id = this.id || Ext.id();
22037 this.el = new Ext.Layer({
22039 id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [
22040 {tag: "div", cls: "x-dd-drop-icon"},
22041 {tag: "div", cls: "x-dd-drag-ghost"}
22044 shadow: !config || config.shadow !== false
22046 this.ghost = Ext.get(this.el.dom.childNodes[1]);
22047 this.dropStatus = this.dropNotAllowed;
22050 Ext.dd.StatusProxy.prototype = {
22052 dropAllowed : "x-dd-drop-ok",
22054 dropNotAllowed : "x-dd-drop-nodrop",
22057 setStatus : function(cssClass){
22058 cssClass = cssClass || this.dropNotAllowed;
22059 if(this.dropStatus != cssClass){
22060 this.el.replaceClass(this.dropStatus, cssClass);
22061 this.dropStatus = cssClass;
22066 reset : function(clearGhost){
22067 this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
22068 this.dropStatus = this.dropNotAllowed;
22070 this.ghost.update("");
22075 update : function(html){
22076 if(typeof html == "string"){
22077 this.ghost.update(html);
22079 this.ghost.update("");
22080 html.style.margin = "0";
22081 this.ghost.dom.appendChild(html);
22083 var el = this.ghost.dom.firstChild;
22085 Ext.fly(el).setStyle('float', 'none');
22090 getEl : function(){
22095 getGhost : function(){
22100 hide : function(clear){
22109 if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
22125 repair : function(xy, callback, scope){
22126 this.callback = callback;
22127 this.scope = scope;
22128 if(xy && this.animRepair !== false){
22129 this.el.addClass("x-dd-drag-repair");
22130 this.el.hideUnders(true);
22131 this.anim = this.el.shift({
22132 duration: this.repairDuration || .5,
22136 callback: this.afterRepair,
22140 this.afterRepair();
22145 afterRepair : function(){
22147 if(typeof this.callback == "function"){
22148 this.callback.call(this.scope || this);
22150 this.callback = null;
22154 destroy: function(){
22155 Ext.destroy(this.ghost, this.el);
22158 Ext.dd.DragSource = function(el, config){
22159 this.el = Ext.get(el);
22160 if(!this.dragData){
22161 this.dragData = {};
22164 Ext.apply(this, config);
22167 this.proxy = new Ext.dd.StatusProxy();
22169 Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
22170 {dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});
22172 this.dragging = false;
22175 Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {
22178 dropAllowed : "x-dd-drop-ok",
22180 dropNotAllowed : "x-dd-drop-nodrop",
22183 getDragData : function(e){
22184 return this.dragData;
22188 onDragEnter : function(e, id){
22189 var target = Ext.dd.DragDropMgr.getDDById(id);
22190 this.cachedTarget = target;
22191 if(this.beforeDragEnter(target, e, id) !== false){
22192 if(target.isNotifyTarget){
22193 var status = target.notifyEnter(this, e, this.dragData);
22194 this.proxy.setStatus(status);
22196 this.proxy.setStatus(this.dropAllowed);
22199 if(this.afterDragEnter){
22201 this.afterDragEnter(target, e, id);
22207 beforeDragEnter : function(target, e, id){
22212 alignElWithMouse: function() {
22213 Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
22218 onDragOver : function(e, id){
22219 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
22220 if(this.beforeDragOver(target, e, id) !== false){
22221 if(target.isNotifyTarget){
22222 var status = target.notifyOver(this, e, this.dragData);
22223 this.proxy.setStatus(status);
22226 if(this.afterDragOver){
22228 this.afterDragOver(target, e, id);
22234 beforeDragOver : function(target, e, id){
22239 onDragOut : function(e, id){
22240 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
22241 if(this.beforeDragOut(target, e, id) !== false){
22242 if(target.isNotifyTarget){
22243 target.notifyOut(this, e, this.dragData);
22245 this.proxy.reset();
22246 if(this.afterDragOut){
22248 this.afterDragOut(target, e, id);
22251 this.cachedTarget = null;
22255 beforeDragOut : function(target, e, id){
22260 onDragDrop : function(e, id){
22261 var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
22262 if(this.beforeDragDrop(target, e, id) !== false){
22263 if(target.isNotifyTarget){
22264 if(target.notifyDrop(this, e, this.dragData)){
22265 this.onValidDrop(target, e, id);
22267 this.onInvalidDrop(target, e, id);
22270 this.onValidDrop(target, e, id);
22273 if(this.afterDragDrop){
22275 this.afterDragDrop(target, e, id);
22278 delete this.cachedTarget;
22282 beforeDragDrop : function(target, e, id){
22287 onValidDrop : function(target, e, id){
22289 if(this.afterValidDrop){
22291 this.afterValidDrop(target, e, id);
22296 getRepairXY : function(e, data){
22297 return this.el.getXY();
22301 onInvalidDrop : function(target, e, id){
22302 this.beforeInvalidDrop(target, e, id);
22303 if(this.cachedTarget){
22304 if(this.cachedTarget.isNotifyTarget){
22305 this.cachedTarget.notifyOut(this, e, this.dragData);
22307 this.cacheTarget = null;
22309 this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
22311 if(this.afterInvalidDrop){
22313 this.afterInvalidDrop(e, id);
22318 afterRepair : function(){
22320 this.el.highlight(this.hlColor || "c3daf9");
22322 this.dragging = false;
22326 beforeInvalidDrop : function(target, e, id){
22331 handleMouseDown : function(e){
22332 if(this.dragging) {
22335 var data = this.getDragData(e);
22336 if(data && this.onBeforeDrag(data, e) !== false){
22337 this.dragData = data;
22339 Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
22344 onBeforeDrag : function(data, e){
22349 onStartDrag : Ext.emptyFn,
22352 startDrag : function(x, y){
22353 this.proxy.reset();
22354 this.dragging = true;
22355 this.proxy.update("");
22356 this.onInitDrag(x, y);
22361 onInitDrag : function(x, y){
22362 var clone = this.el.dom.cloneNode(true);
22363 clone.id = Ext.id();
22364 this.proxy.update(clone);
22365 this.onStartDrag(x, y);
22370 getProxy : function(){
22375 hideProxy : function(){
22377 this.proxy.reset(true);
22378 this.dragging = false;
22382 triggerCacheRefresh : function(){
22383 Ext.dd.DDM.refreshCache(this.groups);
22387 b4EndDrag: function(e) {
22391 endDrag : function(e){
22392 this.onEndDrag(this.dragData, e);
22396 onEndDrag : function(data, e){
22400 autoOffset : function(x, y) {
22401 this.setDelta(-12, -20);
22404 destroy: function(){
22405 Ext.dd.DragSource.superclass.destroy.call(this);
22406 Ext.destroy(this.proxy);
22409 Ext.dd.DropTarget = Ext.extend(Ext.dd.DDTarget, {
22411 constructor : function(el, config){
22412 this.el = Ext.get(el);
22414 Ext.apply(this, config);
22416 if(this.containerScroll){
22417 Ext.dd.ScrollManager.register(this.el);
22420 Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
22427 dropAllowed : "x-dd-drop-ok",
22429 dropNotAllowed : "x-dd-drop-nodrop",
22435 isNotifyTarget : true,
22438 notifyEnter : function(dd, e, data){
22439 if(this.overClass){
22440 this.el.addClass(this.overClass);
22442 return this.dropAllowed;
22446 notifyOver : function(dd, e, data){
22447 return this.dropAllowed;
22451 notifyOut : function(dd, e, data){
22452 if(this.overClass){
22453 this.el.removeClass(this.overClass);
22458 notifyDrop : function(dd, e, data){
22462 destroy : function(){
22463 Ext.dd.DropTarget.superclass.destroy.call(this);
22464 if(this.containerScroll){
22465 Ext.dd.ScrollManager.unregister(this.el);
22469 Ext.dd.DragZone = Ext.extend(Ext.dd.DragSource, {
22471 constructor : function(el, config){
22472 Ext.dd.DragZone.superclass.constructor.call(this, el, config);
22473 if(this.containerScroll){
22474 Ext.dd.ScrollManager.register(this.el);
22483 getDragData : function(e){
22484 return Ext.dd.Registry.getHandleFromEvent(e);
22488 onInitDrag : function(x, y){
22489 this.proxy.update(this.dragData.ddel.cloneNode(true));
22490 this.onStartDrag(x, y);
22495 afterRepair : function(){
22497 Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
22499 this.dragging = false;
22503 getRepairXY : function(e){
22504 return Ext.Element.fly(this.dragData.ddel).getXY();
22507 destroy : function(){
22508 Ext.dd.DragZone.superclass.destroy.call(this);
22509 if(this.containerScroll){
22510 Ext.dd.ScrollManager.unregister(this.el);
22514 Ext.dd.DropZone = function(el, config){
22515 Ext.dd.DropZone.superclass.constructor.call(this, el, config);
22518 Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {
22520 getTargetFromEvent : function(e){
22521 return Ext.dd.Registry.getTargetFromEvent(e);
22525 onNodeEnter : function(n, dd, e, data){
22530 onNodeOver : function(n, dd, e, data){
22531 return this.dropAllowed;
22535 onNodeOut : function(n, dd, e, data){
22540 onNodeDrop : function(n, dd, e, data){
22545 onContainerOver : function(dd, e, data){
22546 return this.dropNotAllowed;
22550 onContainerDrop : function(dd, e, data){
22555 notifyEnter : function(dd, e, data){
22556 return this.dropNotAllowed;
22560 notifyOver : function(dd, e, data){
22561 var n = this.getTargetFromEvent(e);
22563 if(this.lastOverNode){
22564 this.onNodeOut(this.lastOverNode, dd, e, data);
22565 this.lastOverNode = null;
22567 return this.onContainerOver(dd, e, data);
22569 if(this.lastOverNode != n){
22570 if(this.lastOverNode){
22571 this.onNodeOut(this.lastOverNode, dd, e, data);
22573 this.onNodeEnter(n, dd, e, data);
22574 this.lastOverNode = n;
22576 return this.onNodeOver(n, dd, e, data);
22580 notifyOut : function(dd, e, data){
22581 if(this.lastOverNode){
22582 this.onNodeOut(this.lastOverNode, dd, e, data);
22583 this.lastOverNode = null;
22588 notifyDrop : function(dd, e, data){
22589 if(this.lastOverNode){
22590 this.onNodeOut(this.lastOverNode, dd, e, data);
22591 this.lastOverNode = null;
22593 var n = this.getTargetFromEvent(e);
22595 this.onNodeDrop(n, dd, e, data) :
22596 this.onContainerDrop(dd, e, data);
22600 triggerCacheRefresh : function(){
22601 Ext.dd.DDM.refreshCache(this.groups);
22604 Ext.Element.addMethods({
22606 initDD : function(group, config, overrides){
22607 var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
22608 return Ext.apply(dd, overrides);
22612 initDDProxy : function(group, config, overrides){
22613 var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
22614 return Ext.apply(dd, overrides);
22618 initDDTarget : function(group, config, overrides){
22619 var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
22620 return Ext.apply(dd, overrides);
22624 Ext.data.Api = (function() {
22630 var validActions = {};
22638 destroy : 'destroy'
22650 isAction : function(action) {
22651 return (Ext.data.Api.actions[action]) ? true : false;
22655 getVerb : function(name) {
22656 if (validActions[name]) {
22657 return validActions[name];
22659 for (var verb in this.actions) {
22660 if (this.actions[verb] === name) {
22661 validActions[name] = verb;
22665 return (validActions[name] !== undefined) ? validActions[name] : null;
22669 isValid : function(api){
22671 var crud = this.actions;
22672 for (var action in api) {
22673 if (!(action in crud)) {
22674 invalid.push(action);
22677 return (!invalid.length) ? true : invalid;
22681 hasUniqueUrl : function(proxy, verb) {
22682 var url = (proxy.api[verb]) ? proxy.api[verb].url : null;
22684 for (var action in proxy.api) {
22685 if ((unique = (action === verb) ? true : (proxy.api[action].url != url) ? true : false) === false) {
22693 prepare : function(proxy) {
22697 for (var verb in this.actions) {
22698 var action = this.actions[verb];
22699 proxy.api[action] = proxy.api[action] || proxy.url || proxy.directFn;
22700 if (typeof(proxy.api[action]) == 'string') {
22701 proxy.api[action] = {
22702 url: proxy.api[action],
22703 method: (proxy.restful === true) ? Ext.data.Api.restActions[action] : undefined
22710 restify : function(proxy) {
22711 proxy.restful = true;
22712 for (var verb in this.restActions) {
22713 proxy.api[this.actions[verb]].method ||
22714 (proxy.api[this.actions[verb]].method = this.restActions[verb]);
22718 proxy.onWrite = proxy.onWrite.createInterceptor(function(action, o, response, rs) {
22719 var reader = o.reader;
22720 var res = new Ext.data.Response({
22725 switch (response.status) {
22730 if (Ext.isEmpty(res.raw.responseText)) {
22731 res.success = true;
22738 res.success = true;
22745 if (res.success === true) {
22746 this.fireEvent("write", this, action, res.data, res, rs, o.request.arg);
22748 this.fireEvent('exception', this, 'remote', action, o, res, rs);
22750 o.request.callback.call(o.request.scope, res.data, res, res.success);
22759 Ext.data.Response = function(params, response) {
22760 Ext.apply(this, params, {
22764 Ext.data.Response.prototype = {
22771 getMessage : function() {
22772 return this.message;
22774 getSuccess : function() {
22775 return this.success;
22777 getStatus : function() {
22778 return this.status;
22780 getRoot : function() {
22783 getRawResponse : function() {
22789 Ext.data.Api.Error = Ext.extend(Ext.Error, {
22790 constructor : function(message, arg) {
22792 Ext.Error.call(this, message);
22794 name: 'Ext.data.Api'
22796 Ext.apply(Ext.data.Api.Error.prototype, {
22798 '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.',
22799 'invalid': 'received an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions defined in Ext.data.Api.actions',
22800 'invalid-url': 'Invalid url. Please review your proxy configuration.',
22801 'execute': 'Attempted to execute an unknown action. Valid API actions are defined in Ext.data.Api.actions"'
22808 Ext.data.SortTypes = {
22810 none : function(s){
22815 stripTagsRE : /<\/?[^>]+>/gi,
22818 asText : function(s){
22819 return String(s).replace(this.stripTagsRE, "");
22823 asUCText : function(s){
22824 return String(s).toUpperCase().replace(this.stripTagsRE, "");
22828 asUCString : function(s) {
22829 return String(s).toUpperCase();
22833 asDate : function(s) {
22838 return s.getTime();
22840 return Date.parse(String(s));
22844 asFloat : function(s) {
22845 var val = parseFloat(String(s).replace(/,/g, ""));
22846 return isNaN(val) ? 0 : val;
22850 asInt : function(s) {
22851 var val = parseInt(String(s).replace(/,/g, ""), 10);
22852 return isNaN(val) ? 0 : val;
22855 Ext.data.Record = function(data, id){
22857 this.id = (id || id === 0) ? id : Ext.data.Record.id(this);
22858 this.data = data || {};
22862 Ext.data.Record.create = function(o){
22863 var f = Ext.extend(Ext.data.Record, {});
22864 var p = f.prototype;
22865 p.fields = new Ext.util.MixedCollection(false, function(field){
22868 for(var i = 0, len = o.length; i < len; i++){
22869 p.fields.add(new Ext.data.Field(o[i]));
22871 f.getField = function(name){
22872 return p.fields.get(name);
22877 Ext.data.Record.PREFIX = 'ext-record';
22878 Ext.data.Record.AUTO_ID = 1;
22879 Ext.data.Record.EDIT = 'edit';
22880 Ext.data.Record.REJECT = 'reject';
22881 Ext.data.Record.COMMIT = 'commit';
22885 Ext.data.Record.id = function(rec) {
22886 rec.phantom = true;
22887 return [Ext.data.Record.PREFIX, '-', Ext.data.Record.AUTO_ID++].join('');
22890 Ext.data.Record.prototype = {
22906 join : function(store){
22908 this.store = store;
22912 set : function(name, value){
22913 var encode = Ext.isPrimitive(value) ? String : Ext.encode;
22914 if(encode(this.data[name]) == encode(value)) {
22918 if(!this.modified){
22919 this.modified = {};
22921 if(this.modified[name] === undefined){
22922 this.modified[name] = this.data[name];
22924 this.data[name] = value;
22931 afterEdit : function(){
22932 if (this.store != undefined && typeof this.store.afterEdit == "function") {
22933 this.store.afterEdit(this);
22938 afterReject : function(){
22940 this.store.afterReject(this);
22945 afterCommit : function(){
22947 this.store.afterCommit(this);
22952 get : function(name){
22953 return this.data[name];
22957 beginEdit : function(){
22958 this.editing = true;
22959 this.modified = this.modified || {};
22963 cancelEdit : function(){
22964 this.editing = false;
22965 delete this.modified;
22969 endEdit : function(){
22970 this.editing = false;
22977 reject : function(silent){
22978 var m = this.modified;
22980 if(typeof m[n] != "function"){
22981 this.data[n] = m[n];
22984 this.dirty = false;
22985 delete this.modified;
22986 this.editing = false;
22987 if(silent !== true){
22988 this.afterReject();
22993 commit : function(silent){
22994 this.dirty = false;
22995 delete this.modified;
22996 this.editing = false;
22997 if(silent !== true){
22998 this.afterCommit();
23003 getChanges : function(){
23004 var m = this.modified, cs = {};
23006 if(m.hasOwnProperty(n)){
23007 cs[n] = this.data[n];
23014 hasError : function(){
23015 return this.error !== null;
23019 clearError : function(){
23024 copy : function(newId) {
23025 return new this.constructor(Ext.apply({}, this.data), newId || this.id);
23029 isModified : function(fieldName){
23030 return !!(this.modified && this.modified.hasOwnProperty(fieldName));
23034 isValid : function() {
23035 return this.fields.find(function(f) {
23036 return (f.allowBlank === false && Ext.isEmpty(this.data[f.name])) ? true : false;
23037 },this) ? false : true;
23041 markDirty : function(){
23043 if(!this.modified){
23044 this.modified = {};
23046 this.fields.each(function(f) {
23047 this.modified[f.name] = this.data[f.name];
23052 Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {
23056 register : function(){
23057 for(var i = 0, s; (s = arguments[i]); i++){
23063 unregister : function(){
23064 for(var i = 0, s; (s = arguments[i]); i++){
23065 this.remove(this.lookup(s));
23070 lookup : function(id){
23071 if(Ext.isArray(id)){
23072 var fields = ['field1'], expand = !Ext.isArray(id[0]);
23074 for(var i = 2, len = id[0].length; i <= len; ++i){
23075 fields.push('field' + i);
23078 return new Ext.data.ArrayStore({
23081 expandData: expand,
23087 return Ext.isObject(id) ? (id.events ? id : Ext.create(id, 'store')) : this.get(id);
23091 getKey : function(o){
23095 Ext.data.Store = Ext.extend(Ext.util.Observable, {
23103 writer : undefined,
23107 remoteSort : false,
23110 autoDestroy : false,
23113 pruneModifiedRecords : false,
23116 lastOptions : null,
23128 paramNames : undefined,
23131 defaultParamNames : {
23138 isDestroyed: false,
23139 hasMultiSort: false,
23142 batchKey : '_ext_batch_',
23144 constructor : function(config){
23149 this.data = new Ext.util.MixedCollection(false);
23150 this.data.getKey = function(o){
23158 if(config && config.data){
23159 this.inlineData = config.data;
23160 delete config.data;
23163 Ext.apply(this, config);
23166 this.baseParams = Ext.isObject(this.baseParams) ? this.baseParams : {};
23168 this.paramNames = Ext.applyIf(this.paramNames || {}, this.defaultParamNames);
23170 if((this.url || this.api) && !this.proxy){
23171 this.proxy = new Ext.data.HttpProxy({url: this.url, api: this.api});
23174 if (this.restful === true && this.proxy) {
23177 this.batch = false;
23178 Ext.data.Api.restify(this.proxy);
23182 if(!this.recordType){
23183 this.recordType = this.reader.recordType;
23185 if(this.reader.onMetaChange){
23186 this.reader.onMetaChange = this.reader.onMetaChange.createSequence(this.onMetaChange, this);
23189 if (this.writer instanceof(Ext.data.DataWriter) === false) {
23190 this.writer = this.buildWriter(this.writer);
23192 this.writer.meta = this.reader.meta;
23193 this.pruneModifiedRecords = true;
23199 if(this.recordType){
23201 this.fields = this.recordType.prototype.fields;
23203 this.modified = [];
23239 this.relayEvents(this.proxy, ['loadexception', 'exception']);
23245 add: this.createRecords,
23246 remove: this.destroyRecord,
23247 update: this.updateRecord,
23248 clear: this.onClear
23252 this.sortToggle = {};
23253 if(this.sortField){
23254 this.setDefaultSort(this.sortField, this.sortDir);
23255 }else if(this.sortInfo){
23256 this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
23259 Ext.data.Store.superclass.constructor.call(this);
23262 this.storeId = this.id;
23266 Ext.StoreMgr.register(this);
23268 if(this.inlineData){
23269 this.loadData(this.inlineData);
23270 delete this.inlineData;
23271 }else if(this.autoLoad){
23272 this.load.defer(10, this, [
23273 typeof this.autoLoad == 'object' ?
23274 this.autoLoad : undefined]);
23277 this.batchCounter = 0;
23282 buildWriter : function(config) {
23283 var klass = undefined,
23284 type = (config.format || 'json').toLowerCase();
23287 klass = Ext.data.JsonWriter;
23290 klass = Ext.data.XmlWriter;
23293 klass = Ext.data.JsonWriter;
23295 return new klass(config);
23299 destroy : function(){
23300 if(!this.isDestroyed){
23302 Ext.StoreMgr.unregister(this);
23306 Ext.destroy(this.proxy);
23307 this.reader = this.writer = null;
23308 this.purgeListeners();
23309 this.isDestroyed = true;
23314 add : function(records) {
23315 var i, record, index;
23317 records = [].concat(records);
23318 if (records.length < 1) {
23322 for (i = 0, len = records.length; i < len; i++) {
23323 record = records[i];
23327 if (record.dirty || record.phantom) {
23328 this.modified.push(record);
23332 index = this.data.length;
23333 this.data.addAll(records);
23335 if (this.snapshot) {
23336 this.snapshot.addAll(records);
23339 this.fireEvent('add', this, records, index);
23343 addSorted : function(record){
23344 var index = this.findInsertIndex(record);
23345 this.insert(index, record);
23349 doUpdate : function(rec){
23350 this.data.replace(rec.id, rec);
23352 this.snapshot.replace(rec.id, rec);
23354 this.fireEvent('update', this, rec, Ext.data.Record.COMMIT);
23358 remove : function(record){
23359 if(Ext.isArray(record)){
23360 Ext.each(record, function(r){
23365 var index = this.data.indexOf(record);
23368 this.data.removeAt(index);
23370 if(this.pruneModifiedRecords){
23371 this.modified.remove(record);
23374 this.snapshot.remove(record);
23377 this.fireEvent('remove', this, record, index);
23382 removeAt : function(index){
23383 this.remove(this.getAt(index));
23387 removeAll : function(silent){
23389 this.each(function(rec){
23394 this.snapshot.clear();
23396 if(this.pruneModifiedRecords){
23397 this.modified = [];
23399 if (silent !== true) {
23400 this.fireEvent('clear', this, items);
23405 onClear: function(store, records){
23406 Ext.each(records, function(rec, index){
23407 this.destroyRecord(this, rec, index);
23412 insert : function(index, records) {
23415 records = [].concat(records);
23416 for (i = 0, len = records.length; i < len; i++) {
23417 record = records[i];
23419 this.data.insert(index + i, record);
23422 if (record.dirty || record.phantom) {
23423 this.modified.push(record);
23427 if (this.snapshot) {
23428 this.snapshot.addAll(records);
23431 this.fireEvent('add', this, records, index);
23435 indexOf : function(record){
23436 return this.data.indexOf(record);
23440 indexOfId : function(id){
23441 return this.data.indexOfKey(id);
23445 getById : function(id){
23446 return (this.snapshot || this.data).key(id);
23450 getAt : function(index){
23451 return this.data.itemAt(index);
23455 getRange : function(start, end){
23456 return this.data.getRange(start, end);
23460 storeOptions : function(o){
23461 o = Ext.apply({}, o);
23464 this.lastOptions = o;
23468 clearData: function(){
23469 this.data.each(function(rec) {
23476 load : function(options) {
23477 options = Ext.apply({}, options);
23478 this.storeOptions(options);
23479 if(this.sortInfo && this.remoteSort){
23480 var pn = this.paramNames;
23481 options.params = Ext.apply({}, options.params);
23482 options.params[pn.sort] = this.sortInfo.field;
23483 options.params[pn.dir] = this.sortInfo.direction;
23486 return this.execute('read', null, options);
23488 this.handleException(e);
23494 updateRecord : function(store, record, action) {
23495 if (action == Ext.data.Record.EDIT && this.autoSave === true && (!record.phantom || (record.phantom && record.isValid()))) {
23501 createRecords : function(store, records, index) {
23502 var modified = this.modified,
23503 length = records.length,
23506 for (i = 0; i < length; i++) {
23507 record = records[i];
23509 if (record.phantom && record.isValid()) {
23510 record.markDirty();
23512 if (modified.indexOf(record) == -1) {
23513 modified.push(record);
23517 if (this.autoSave === true) {
23523 destroyRecord : function(store, record, index) {
23524 if (this.modified.indexOf(record) != -1) {
23525 this.modified.remove(record);
23527 if (!record.phantom) {
23528 this.removed.push(record);
23533 record.lastIndex = index;
23535 if (this.autoSave === true) {
23542 execute : function(action, rs, options, batch) {
23544 if (!Ext.data.Api.isAction(action)) {
23545 throw new Ext.data.Api.Error('execute', action);
23548 options = Ext.applyIf(options||{}, {
23551 if(batch !== undefined){
23552 this.addToBatch(batch);
23556 var doRequest = true;
23558 if (action === 'read') {
23559 doRequest = this.fireEvent('beforeload', this, options);
23560 Ext.applyIf(options.params, this.baseParams);
23565 if (this.writer.listful === true && this.restful !== true) {
23566 rs = (Ext.isArray(rs)) ? rs : [rs];
23569 else if (Ext.isArray(rs) && rs.length == 1) {
23573 if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
23574 this.writer.apply(options.params, this.baseParams, action, rs);
23577 if (doRequest !== false) {
23579 if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
23580 options.params.xaction = action;
23587 this.proxy.request(Ext.data.Api.actions[action], rs, options.params, this.reader, this.createCallback(action, rs, batch), this, options);
23593 save : function() {
23594 if (!this.writer) {
23595 throw new Ext.data.Store.Error('writer-undefined');
23605 if(this.removed.length){
23606 queue.push(['destroy', this.removed]);
23610 var rs = [].concat(this.getModifiedRecords());
23614 for(i = rs.length-1; i >= 0; i--){
23615 if(rs[i].phantom === true){
23616 var rec = rs.splice(i, 1).shift();
23618 phantoms.push(rec);
23620 }else if(!rs[i].isValid()){
23625 if(phantoms.length){
23626 queue.push(['create', phantoms]);
23631 queue.push(['update', rs]);
23634 len = queue.length;
23636 batch = ++this.batchCounter;
23637 for(i = 0; i < len; ++i){
23639 data[trans[0]] = trans[1];
23641 if(this.fireEvent('beforesave', this, data) !== false){
23642 for(i = 0; i < len; ++i){
23644 this.doTransaction(trans[0], trans[1], batch);
23653 doTransaction : function(action, rs, batch) {
23654 function transaction(records) {
23656 this.execute(action, records, undefined, batch);
23658 this.handleException(e);
23661 if(this.batch === false){
23662 for(var i = 0, len = rs.length; i < len; i++){
23663 transaction.call(this, rs[i]);
23666 transaction.call(this, rs);
23671 addToBatch : function(batch){
23672 var b = this.batches,
23673 key = this.batchKey + batch,
23686 removeFromBatch : function(batch, action, data){
23687 var b = this.batches,
23688 key = this.batchKey + batch,
23694 arr = o.data[action] || [];
23695 o.data[action] = arr.concat(data);
23699 this.fireEvent('save', this, batch, data);
23708 createCallback : function(action, rs, batch) {
23709 var actions = Ext.data.Api.actions;
23710 return (action == 'read') ? this.loadRecords : function(data, response, success) {
23712 this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, [].concat(data));
23714 if (success === true) {
23715 this.fireEvent('write', this, action, data, response, rs);
23717 this.removeFromBatch(batch, action, data);
23724 clearModified : function(rs) {
23725 if (Ext.isArray(rs)) {
23726 for (var n=rs.length-1;n>=0;n--) {
23727 this.modified.splice(this.modified.indexOf(rs[n]), 1);
23730 this.modified.splice(this.modified.indexOf(rs), 1);
23735 reMap : function(record) {
23736 if (Ext.isArray(record)) {
23737 for (var i = 0, len = record.length; i < len; i++) {
23738 this.reMap(record[i]);
23741 delete this.data.map[record._phid];
23742 this.data.map[record.id] = record;
23743 var index = this.data.keys.indexOf(record._phid);
23744 this.data.keys.splice(index, 1, record.id);
23745 delete record._phid;
23750 onCreateRecords : function(success, rs, data) {
23751 if (success === true) {
23753 this.reader.realize(rs, data);
23757 this.handleException(e);
23758 if (Ext.isArray(rs)) {
23760 this.onCreateRecords(success, rs, data);
23767 onUpdateRecords : function(success, rs, data) {
23768 if (success === true) {
23770 this.reader.update(rs, data);
23772 this.handleException(e);
23773 if (Ext.isArray(rs)) {
23775 this.onUpdateRecords(success, rs, data);
23782 onDestroyRecords : function(success, rs, data) {
23784 rs = (rs instanceof Ext.data.Record) ? [rs] : [].concat(rs);
23785 for (var i=0,len=rs.length;i<len;i++) {
23786 this.removed.splice(this.removed.indexOf(rs[i]), 1);
23788 if (success === false) {
23791 for (i=rs.length-1;i>=0;i--) {
23792 this.insert(rs[i].lastIndex, rs[i]);
23798 handleException : function(e) {
23800 Ext.handleError(e);
23804 reload : function(options){
23805 this.load(Ext.applyIf(options||{}, this.lastOptions));
23810 loadRecords : function(o, options, success){
23813 if (this.isDestroyed === true) {
23816 if(!o || success === false){
23817 if(success !== false){
23818 this.fireEvent('load', this, [], options);
23820 if(options.callback){
23821 options.callback.call(options.scope || this, [], options, false, o);
23825 var r = o.records, t = o.totalRecords || r.length;
23826 if(!options || options.add !== true){
23827 if(this.pruneModifiedRecords){
23828 this.modified = [];
23830 for(i = 0, len = r.length; i < len; i++){
23834 this.data = this.snapshot;
23835 delete this.snapshot;
23838 this.data.addAll(r);
23839 this.totalLength = t;
23841 this.fireEvent('datachanged', this);
23846 for(i = 0, len = r.length; i < len; ++i){
23848 if(this.indexOfId(rec.id) > -1){
23849 this.doUpdate(rec);
23855 this.totalLength = Math.max(t, this.data.length + cnt);
23858 this.fireEvent('load', this, r, options);
23859 if(options.callback){
23860 options.callback.call(options.scope || this, r, options, true);
23865 loadData : function(o, append){
23866 var r = this.reader.readRecords(o);
23867 this.loadRecords(r, {add: append}, true);
23871 getCount : function(){
23872 return this.data.length || 0;
23876 getTotalCount : function(){
23877 return this.totalLength || 0;
23881 getSortState : function(){
23882 return this.sortInfo;
23886 applySort : function(){
23887 if ((this.sortInfo || this.multiSortInfo) && !this.remoteSort) {
23893 sortData : function() {
23894 var sortInfo = this.hasMultiSort ? this.multiSortInfo : this.sortInfo,
23895 direction = sortInfo.direction || "ASC",
23896 sorters = sortInfo.sorters,
23900 if (!this.hasMultiSort) {
23901 sorters = [{direction: direction, field: sortInfo.field}];
23905 for (var i=0, j = sorters.length; i < j; i++) {
23906 sortFns.push(this.createSortFunction(sorters[i].field, sorters[i].direction));
23909 if (sortFns.length == 0) {
23915 var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
23918 var fn = function(r1, r2) {
23919 var result = sortFns[0].call(this, r1, r2);
23922 if (sortFns.length > 1) {
23923 for (var i=1, j = sortFns.length; i < j; i++) {
23924 result = result || sortFns[i].call(this, r1, r2);
23928 return directionModifier * result;
23932 this.data.sort(direction, fn);
23933 if (this.snapshot && this.snapshot != this.data) {
23934 this.snapshot.sort(direction, fn);
23939 createSortFunction: function(field, direction) {
23940 direction = direction || "ASC";
23941 var directionModifier = direction.toUpperCase() == "DESC" ? -1 : 1;
23943 var sortType = this.fields.get(field).sortType;
23947 return function(r1, r2) {
23948 var v1 = sortType(r1.data[field]),
23949 v2 = sortType(r2.data[field]);
23951 return directionModifier * (v1 > v2 ? 1 : (v1 < v2 ? -1 : 0));
23956 setDefaultSort : function(field, dir) {
23957 dir = dir ? dir.toUpperCase() : 'ASC';
23958 this.sortInfo = {field: field, direction: dir};
23959 this.sortToggle[field] = dir;
23963 sort : function(fieldName, dir) {
23964 if (Ext.isArray(arguments[0])) {
23965 return this.multiSort.call(this, fieldName, dir);
23967 return this.singleSort(fieldName, dir);
23972 singleSort: function(fieldName, dir) {
23973 var field = this.fields.get(fieldName);
23978 var name = field.name,
23979 sortInfo = this.sortInfo || null,
23980 sortToggle = this.sortToggle ? this.sortToggle[name] : null;
23983 if (sortInfo && sortInfo.field == name) {
23984 dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
23986 dir = field.sortDir;
23990 this.sortToggle[name] = dir;
23991 this.sortInfo = {field: name, direction: dir};
23992 this.hasMultiSort = false;
23994 if (this.remoteSort) {
23995 if (!this.load(this.lastOptions)) {
23997 this.sortToggle[name] = sortToggle;
24000 this.sortInfo = sortInfo;
24005 this.fireEvent('datachanged', this);
24011 multiSort: function(sorters, direction) {
24012 this.hasMultiSort = true;
24013 direction = direction || "ASC";
24016 if (this.multiSortInfo && direction == this.multiSortInfo.direction) {
24017 direction = direction.toggle("ASC", "DESC");
24021 this.multiSortInfo = {
24023 direction: direction
24026 if (this.remoteSort) {
24027 this.singleSort(sorters[0].field, sorters[0].direction);
24031 this.fireEvent('datachanged', this);
24036 each : function(fn, scope){
24037 this.data.each(fn, scope);
24041 getModifiedRecords : function(){
24042 return this.modified;
24046 sum : function(property, start, end){
24047 var rs = this.data.items, v = 0;
24048 start = start || 0;
24049 end = (end || end === 0) ? end : rs.length-1;
24051 for(var i = start; i <= end; i++){
24052 v += (rs[i].data[property] || 0);
24058 createFilterFn : function(property, value, anyMatch, caseSensitive, exactMatch){
24059 if(Ext.isEmpty(value, false)){
24062 value = this.data.createValueMatcher(value, anyMatch, caseSensitive, exactMatch);
24063 return function(r) {
24064 return value.test(r.data[property]);
24069 createMultipleFilterFn: function(filters) {
24070 return function(record) {
24071 var isMatch = true;
24073 for (var i=0, j = filters.length; i < j; i++) {
24074 var filter = filters[i],
24076 scope = filter.scope;
24078 isMatch = isMatch && fn.call(scope, record);
24086 filter : function(property, value, anyMatch, caseSensitive, exactMatch){
24089 if (Ext.isObject(property)) {
24090 property = [property];
24093 if (Ext.isArray(property)) {
24097 for (var i=0, j = property.length; i < j; i++) {
24098 var filter = property[i],
24100 scope = filter.scope || this;
24103 if (!Ext.isFunction(func)) {
24104 func = this.createFilterFn(filter.property, filter.value, filter.anyMatch, filter.caseSensitive, filter.exactMatch);
24107 filters.push({fn: func, scope: scope});
24110 fn = this.createMultipleFilterFn(filters);
24113 fn = this.createFilterFn(property, value, anyMatch, caseSensitive, exactMatch);
24116 return fn ? this.filterBy(fn) : this.clearFilter();
24120 filterBy : function(fn, scope){
24121 this.snapshot = this.snapshot || this.data;
24122 this.data = this.queryBy(fn, scope || this);
24123 this.fireEvent('datachanged', this);
24127 clearFilter : function(suppressEvent){
24128 if(this.isFiltered()){
24129 this.data = this.snapshot;
24130 delete this.snapshot;
24131 if(suppressEvent !== true){
24132 this.fireEvent('datachanged', this);
24138 isFiltered : function(){
24139 return !!this.snapshot && this.snapshot != this.data;
24143 query : function(property, value, anyMatch, caseSensitive){
24144 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
24145 return fn ? this.queryBy(fn) : this.data.clone();
24149 queryBy : function(fn, scope){
24150 var data = this.snapshot || this.data;
24151 return data.filterBy(fn, scope||this);
24155 find : function(property, value, start, anyMatch, caseSensitive){
24156 var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
24157 return fn ? this.data.findIndexBy(fn, null, start) : -1;
24161 findExact: function(property, value, start){
24162 return this.data.findIndexBy(function(rec){
24163 return rec.get(property) === value;
24168 findBy : function(fn, scope, start){
24169 return this.data.findIndexBy(fn, scope, start);
24173 collect : function(dataIndex, allowNull, bypassFilter){
24174 var d = (bypassFilter === true && this.snapshot) ?
24175 this.snapshot.items : this.data.items;
24176 var v, sv, r = [], l = {};
24177 for(var i = 0, len = d.length; i < len; i++){
24178 v = d[i].data[dataIndex];
24180 if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
24189 afterEdit : function(record){
24190 if(this.modified.indexOf(record) == -1){
24191 this.modified.push(record);
24193 this.fireEvent('update', this, record, Ext.data.Record.EDIT);
24197 afterReject : function(record){
24198 this.modified.remove(record);
24199 this.fireEvent('update', this, record, Ext.data.Record.REJECT);
24203 afterCommit : function(record){
24204 this.modified.remove(record);
24205 this.fireEvent('update', this, record, Ext.data.Record.COMMIT);
24209 commitChanges : function(){
24210 var modified = this.modified.slice(0),
24211 length = modified.length,
24214 for (i = 0; i < length; i++){
24215 modified[i].commit();
24218 this.modified = [];
24223 rejectChanges : function() {
24224 var modified = this.modified.slice(0),
24225 removed = this.removed.slice(0).reverse(),
24226 mLength = modified.length,
24227 rLength = removed.length,
24230 for (i = 0; i < mLength; i++) {
24231 modified[i].reject();
24234 for (i = 0; i < rLength; i++) {
24235 this.insert(removed[i].lastIndex || 0, removed[i]);
24236 removed[i].reject();
24239 this.modified = [];
24244 onMetaChange : function(meta){
24245 this.recordType = this.reader.recordType;
24246 this.fields = this.recordType.prototype.fields;
24247 delete this.snapshot;
24248 if(this.reader.meta.sortInfo){
24249 this.sortInfo = this.reader.meta.sortInfo;
24250 }else if(this.sortInfo && !this.fields.get(this.sortInfo.field)){
24251 delete this.sortInfo;
24254 this.writer.meta = this.reader.meta;
24256 this.modified = [];
24257 this.fireEvent('metachange', this, this.reader.meta);
24261 findInsertIndex : function(record){
24262 this.suspendEvents();
24263 var data = this.data.clone();
24264 this.data.add(record);
24266 var index = this.data.indexOf(record);
24268 this.resumeEvents();
24273 setBaseParam : function (name, value){
24274 this.baseParams = this.baseParams || {};
24275 this.baseParams[name] = value;
24279 Ext.reg('store', Ext.data.Store);
24282 Ext.data.Store.Error = Ext.extend(Ext.Error, {
24283 name: 'Ext.data.Store'
24285 Ext.apply(Ext.data.Store.Error.prototype, {
24287 'writer-undefined' : 'Attempted to execute a write-action without a DataWriter installed.'
24291 Ext.data.Field = Ext.extend(Object, {
24293 constructor : function(config){
24294 if(Ext.isString(config)){
24295 config = {name: config};
24297 Ext.apply(this, config);
24299 var types = Ext.data.Types,
24300 st = this.sortType,
24304 if(Ext.isString(this.type)){
24305 this.type = Ext.data.Types[this.type.toUpperCase()] || types.AUTO;
24308 this.type = types.AUTO;
24312 if(Ext.isString(st)){
24313 this.sortType = Ext.data.SortTypes[st];
24314 }else if(Ext.isEmpty(st)){
24315 this.sortType = this.type.sortType;
24319 this.convert = this.type.convert;
24344 Ext.data.DataReader = function(meta, recordType){
24348 this.recordType = Ext.isArray(recordType) ?
24349 Ext.data.Record.create(recordType) : recordType;
24352 if (this.recordType){
24353 this.buildExtractors();
24357 Ext.data.DataReader.prototype = {
24360 getTotal: Ext.emptyFn,
24362 getRoot: Ext.emptyFn,
24364 getMessage: Ext.emptyFn,
24366 getSuccess: Ext.emptyFn,
24368 getId: Ext.emptyFn,
24370 buildExtractors : Ext.emptyFn,
24372 extractValues : Ext.emptyFn,
24375 realize: function(rs, data){
24376 if (Ext.isArray(rs)) {
24377 for (var i = rs.length - 1; i >= 0; i--) {
24379 if (Ext.isArray(data)) {
24380 this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift());
24385 this.realize(rs.splice(i,1).shift(), data);
24391 if (Ext.isArray(data) && data.length == 1) {
24392 data = data.shift();
24394 if (!this.isData(data)) {
24397 throw new Ext.data.DataReader.Error('realize', rs);
24399 rs.phantom = false;
24401 rs.id = this.getId(data);
24409 update : function(rs, data) {
24410 if (Ext.isArray(rs)) {
24411 for (var i=rs.length-1; i >= 0; i--) {
24412 if (Ext.isArray(data)) {
24413 this.update(rs.splice(i,1).shift(), data.splice(i,1).shift());
24418 this.update(rs.splice(i,1).shift(), data);
24424 if (Ext.isArray(data) && data.length == 1) {
24425 data = data.shift();
24427 if (this.isData(data)) {
24428 rs.data = Ext.apply(rs.data, data);
24435 extractData : function(root, returnRecords) {
24437 var rawName = (this instanceof Ext.data.JsonReader) ? 'json' : 'node';
24443 if (this.isData(root) && !(this instanceof Ext.data.XmlReader)) {
24446 var f = this.recordType.prototype.fields,
24450 if (returnRecords === true) {
24451 var Record = this.recordType;
24452 for (var i = 0; i < root.length; i++) {
24454 var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
24455 record[rawName] = n;
24460 for (var i = 0; i < root.length; i++) {
24461 var data = this.extractValues(root[i], fi, fl);
24462 data[this.meta.idProperty] = this.getId(root[i]);
24470 isData : function(data) {
24471 return (data && Ext.isObject(data) && !Ext.isEmpty(this.getId(data))) ? true : false;
24475 onMetaChange : function(meta){
24478 this.recordType = Ext.data.Record.create(meta.fields);
24479 this.buildExtractors();
24484 Ext.data.DataReader.Error = Ext.extend(Ext.Error, {
24485 constructor : function(message, arg) {
24487 Ext.Error.call(this, message);
24489 name: 'Ext.data.DataReader'
24491 Ext.apply(Ext.data.DataReader.Error.prototype, {
24493 'update': "#update received invalid data from server. Please see docs for DataReader#update and review your DataReader configuration.",
24494 'realize': "#realize was called with invalid remote-data. Please see the docs for DataReader#realize and review your DataReader configuration.",
24495 'invalid-response': "#readResponse received an invalid response from the server."
24499 Ext.data.DataWriter = function(config){
24500 Ext.apply(this, config);
24502 Ext.data.DataWriter.prototype = {
24505 writeAllFields : false,
24510 apply : function(params, baseParams, action, rs) {
24512 renderer = action + 'Record';
24514 if (Ext.isArray(rs)) {
24515 Ext.each(rs, function(rec){
24516 data.push(this[renderer](rec));
24519 else if (rs instanceof Ext.data.Record) {
24520 data = this[renderer](rs);
24522 this.render(params, baseParams, data);
24526 render : Ext.emptyFn,
24529 updateRecord : Ext.emptyFn,
24532 createRecord : Ext.emptyFn,
24535 destroyRecord : Ext.emptyFn,
24538 toHash : function(rec, config) {
24539 var map = rec.fields.map,
24541 raw = (this.writeAllFields === false && rec.phantom === false) ? rec.getChanges() : rec.data,
24543 Ext.iterate(raw, function(prop, value){
24544 if((m = map[prop])){
24545 data[m.mapping ? m.mapping : m.name] = value;
24552 if (rec.fields.containsKey(this.meta.idProperty) && Ext.isEmpty(rec.data[this.meta.idProperty])) {
24553 delete data[this.meta.idProperty];
24556 data[this.meta.idProperty] = rec.id;
24562 toArray : function(data) {
24564 Ext.iterate(data, function(k, v) {fields.push({name: k, value: v});},this);
24568 Ext.data.DataProxy = function(conn){
24577 this.api = conn.api;
24578 this.url = conn.url;
24579 this.restful = conn.restful;
24580 this.listeners = conn.listeners;
24583 this.prettyUrls = conn.prettyUrls;
24601 Ext.data.DataProxy.superclass.constructor.call(this);
24605 Ext.data.Api.prepare(this);
24607 if (e instanceof Ext.data.Api.Error) {
24612 Ext.data.DataProxy.relayEvents(this, ['beforewrite', 'write', 'exception']);
24615 Ext.extend(Ext.data.DataProxy, Ext.util.Observable, {
24620 setApi : function() {
24621 if (arguments.length == 1) {
24622 var valid = Ext.data.Api.isValid(arguments[0]);
24623 if (valid === true) {
24624 this.api = arguments[0];
24627 throw new Ext.data.Api.Error('invalid', valid);
24630 else if (arguments.length == 2) {
24631 if (!Ext.data.Api.isAction(arguments[0])) {
24632 throw new Ext.data.Api.Error('invalid', arguments[0]);
24634 this.api[arguments[0]] = arguments[1];
24636 Ext.data.Api.prepare(this);
24640 isApiAction : function(action) {
24641 return (this.api[action]) ? true : false;
24645 request : function(action, rs, params, reader, callback, scope, options) {
24646 if (!this.api[action] && !this.load) {
24647 throw new Ext.data.DataProxy.Error('action-undefined', action);
24649 params = params || {};
24650 if ((action === Ext.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) {
24651 this.doRequest.apply(this, arguments);
24654 callback.call(scope || this, null, options, false);
24663 doRequest : function(action, rs, params, reader, callback, scope, options) {
24667 this.load(params, reader, callback, scope, options);
24671 onRead : Ext.emptyFn,
24673 onWrite : Ext.emptyFn,
24675 buildUrl : function(action, record) {
24676 record = record || null;
24681 var url = (this.conn && this.conn.url) ? this.conn.url : (this.api[action]) ? this.api[action].url : this.url;
24683 throw new Ext.data.Api.Error('invalid-url', action);
24692 var provides = null;
24693 var m = url.match(/(.*)(\.json|\.xml|\.html)$/);
24699 if ((this.restful === true || this.prettyUrls === true) && record instanceof Ext.data.Record && !record.phantom) {
24700 url += '/' + record.id;
24702 return (provides === null) ? url : url + provides;
24706 destroy: function(){
24707 this.purgeListeners();
24713 Ext.apply(Ext.data.DataProxy, Ext.util.Observable.prototype);
24714 Ext.util.Observable.call(Ext.data.DataProxy);
24717 Ext.data.DataProxy.Error = Ext.extend(Ext.Error, {
24718 constructor : function(message, arg) {
24720 Ext.Error.call(this, message);
24722 name: 'Ext.data.DataProxy'
24724 Ext.apply(Ext.data.DataProxy.Error.prototype, {
24726 'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function. Please review your Proxy url/api-configuration.",
24727 'api-invalid': 'Recieved an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.'
24733 Ext.data.Request = function(params) {
24734 Ext.apply(this, params);
24736 Ext.data.Request.prototype = {
24738 action : undefined,
24744 callback : Ext.emptyFn,
24751 Ext.data.Response = function(params) {
24752 Ext.apply(this, params);
24754 Ext.data.Response.prototype = {
24758 success : undefined,
24760 message : undefined,
24769 Ext.data.ScriptTagProxy = function(config){
24770 Ext.apply(this, config);
24772 Ext.data.ScriptTagProxy.superclass.constructor.call(this, config);
24774 this.head = document.getElementsByTagName("head")[0];
24779 Ext.data.ScriptTagProxy.TRANS_ID = 1000;
24781 Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {
24786 callbackParam : "callback",
24791 doRequest : function(action, rs, params, reader, callback, scope, arg) {
24792 var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
24794 var url = this.buildUrl(action, rs);
24796 throw new Ext.data.Api.Error('invalid-url', url);
24798 url = Ext.urlAppend(url, p);
24801 url = Ext.urlAppend(url, '_dc=' + (new Date().getTime()));
24803 var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
24807 cb : "stcCallback"+transId,
24808 scriptId : "stcScript"+transId,
24812 callback : callback,
24816 window[trans.cb] = this.createCallback(action, rs, trans);
24817 url += String.format("&{0}={1}", this.callbackParam, trans.cb);
24818 if(this.autoAbort !== false){
24822 trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
24824 var script = document.createElement("script");
24825 script.setAttribute("src", url);
24826 script.setAttribute("type", "text/javascript");
24827 script.setAttribute("id", trans.scriptId);
24828 this.head.appendChild(script);
24830 this.trans = trans;
24834 createCallback : function(action, rs, trans) {
24836 return function(res) {
24837 self.trans = false;
24838 self.destroyTrans(trans, true);
24839 if (action === Ext.data.Api.actions.read) {
24840 self.onRead.call(self, action, trans, res);
24842 self.onWrite.call(self, action, trans, res, rs);
24847 onRead : function(action, trans, res) {
24850 result = trans.reader.readRecords(res);
24853 this.fireEvent("loadexception", this, trans, res, e);
24855 this.fireEvent('exception', this, 'response', action, trans, res, e);
24856 trans.callback.call(trans.scope||window, null, trans.arg, false);
24859 if (result.success === false) {
24861 this.fireEvent('loadexception', this, trans, res);
24863 this.fireEvent('exception', this, 'remote', action, trans, res, null);
24865 this.fireEvent("load", this, res, trans.arg);
24867 trans.callback.call(trans.scope||window, result, trans.arg, result.success);
24870 onWrite : function(action, trans, response, rs) {
24871 var reader = trans.reader;
24874 var res = reader.readResponse(action, response);
24876 this.fireEvent('exception', this, 'response', action, trans, res, e);
24877 trans.callback.call(trans.scope||window, null, res, false);
24880 if(!res.success === true){
24881 this.fireEvent('exception', this, 'remote', action, trans, res, rs);
24882 trans.callback.call(trans.scope||window, null, res, false);
24885 this.fireEvent("write", this, action, res.data, res, rs, trans.arg );
24886 trans.callback.call(trans.scope||window, res.data, res, true);
24890 isLoading : function(){
24891 return this.trans ? true : false;
24895 abort : function(){
24896 if(this.isLoading()){
24897 this.destroyTrans(this.trans);
24902 destroyTrans : function(trans, isLoaded){
24903 this.head.removeChild(document.getElementById(trans.scriptId));
24904 clearTimeout(trans.timeoutId);
24906 window[trans.cb] = undefined;
24908 delete window[trans.cb];
24912 window[trans.cb] = function(){
24913 window[trans.cb] = undefined;
24915 delete window[trans.cb];
24922 handleFailure : function(trans){
24923 this.trans = false;
24924 this.destroyTrans(trans, false);
24925 if (trans.action === Ext.data.Api.actions.read) {
24927 this.fireEvent("loadexception", this, null, trans.arg);
24930 this.fireEvent('exception', this, 'response', trans.action, {
24934 trans.callback.call(trans.scope||window, null, trans.arg, false);
24938 destroy: function(){
24940 Ext.data.ScriptTagProxy.superclass.destroy.call(this);
24943 Ext.data.HttpProxy = function(conn){
24944 Ext.data.HttpProxy.superclass.constructor.call(this, conn);
24953 this.conn.url = null;
24955 this.useAjax = !conn || !conn.events;
24958 var actions = Ext.data.Api.actions;
24959 this.activeRequest = {};
24960 for (var verb in actions) {
24961 this.activeRequest[actions[verb]] = undefined;
24965 Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
24967 getConnection : function() {
24968 return this.useAjax ? Ext.Ajax : this.conn;
24972 setUrl : function(url, makePermanent) {
24973 this.conn.url = url;
24974 if (makePermanent === true) {
24977 Ext.data.Api.prepare(this);
24982 doRequest : function(action, rs, params, reader, cb, scope, arg) {
24984 method: (this.api[action]) ? this.api[action]['method'] : undefined,
24991 callback : this.createCallback(action, rs),
24997 if (params.jsonData) {
24998 o.jsonData = params.jsonData;
24999 } else if (params.xmlData) {
25000 o.xmlData = params.xmlData;
25002 o.params = params || {};
25007 this.conn.url = this.buildUrl(action, rs);
25011 Ext.applyIf(o, this.conn);
25014 if (this.activeRequest[action]) {
25021 this.activeRequest[action] = Ext.Ajax.request(o);
25023 this.conn.request(o);
25026 this.conn.url = null;
25030 createCallback : function(action, rs) {
25031 return function(o, success, response) {
25032 this.activeRequest[action] = undefined;
25034 if (action === Ext.data.Api.actions.read) {
25037 this.fireEvent('loadexception', this, o, response);
25039 this.fireEvent('exception', this, 'response', action, o, response);
25040 o.request.callback.call(o.request.scope, null, o.request.arg, false);
25043 if (action === Ext.data.Api.actions.read) {
25044 this.onRead(action, o, response);
25046 this.onWrite(action, o, response, rs);
25052 onRead : function(action, o, response) {
25055 result = o.reader.read(response);
25059 this.fireEvent('loadexception', this, o, response, e);
25061 this.fireEvent('exception', this, 'response', action, o, response, e);
25062 o.request.callback.call(o.request.scope, null, o.request.arg, false);
25065 if (result.success === false) {
25068 this.fireEvent('loadexception', this, o, response);
25071 var res = o.reader.readResponse(action, response);
25072 this.fireEvent('exception', this, 'remote', action, o, res, null);
25075 this.fireEvent('load', this, o, o.request.arg);
25080 o.request.callback.call(o.request.scope, result, o.request.arg, result.success);
25083 onWrite : function(action, o, response, rs) {
25084 var reader = o.reader;
25087 res = reader.readResponse(action, response);
25089 this.fireEvent('exception', this, 'response', action, o, response, e);
25090 o.request.callback.call(o.request.scope, null, o.request.arg, false);
25093 if (res.success === true) {
25094 this.fireEvent('write', this, action, res.data, res, rs, o.request.arg);
25096 this.fireEvent('exception', this, 'remote', action, o, res, rs);
25101 o.request.callback.call(o.request.scope, res.data, res, res.success);
25105 destroy: function(){
25108 }else if(this.activeRequest){
25109 var actions = Ext.data.Api.actions;
25110 for (var verb in actions) {
25111 if(this.activeRequest[actions[verb]]){
25112 Ext.Ajax.abort(this.activeRequest[actions[verb]]);
25116 Ext.data.HttpProxy.superclass.destroy.call(this);
25119 Ext.data.MemoryProxy = function(data){
25122 api[Ext.data.Api.actions.read] = true;
25123 Ext.data.MemoryProxy.superclass.constructor.call(this, {
25129 Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
25133 doRequest : function(action, rs, params, reader, callback, scope, arg) {
25135 params = params || {};
25138 result = reader.readRecords(this.data);
25141 this.fireEvent("loadexception", this, null, arg, e);
25143 this.fireEvent('exception', this, 'response', action, arg, null, e);
25144 callback.call(scope, null, arg, false);
25147 callback.call(scope, result, arg, true);
25150 Ext.data.Types = new function(){
25151 var st = Ext.data.SortTypes;
25154 stripRe: /[\$,%]/g,
25158 convert: function(v){ return v; },
25165 convert: function(v){ return (v === undefined || v === null) ? '' : String(v); },
25166 sortType: st.asUCString,
25172 convert: function(v){
25173 return v !== undefined && v !== null && v !== '' ?
25174 parseInt(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
25182 convert: function(v){
25183 return v !== undefined && v !== null && v !== '' ?
25184 parseFloat(String(v).replace(Ext.data.Types.stripRe, ''), 10) : (this.useNull ? null : 0);
25192 convert: function(v){ return v === true || v === 'true' || v == 1; },
25199 convert: function(v){
25200 var df = this.dateFormat;
25208 if(df == 'timestamp'){
25209 return new Date(v*1000);
25212 return new Date(parseInt(v, 10));
25214 return Date.parseDate(v, df);
25216 var parsed = Date.parse(v);
25217 return parsed ? new Date(parsed) : null;
25219 sortType: st.asDate,
25226 BOOLEAN: this.BOOL,
25233 Ext.data.JsonWriter = Ext.extend(Ext.data.DataWriter, {
25237 encodeDelete: false,
25239 constructor : function(config){
25240 Ext.data.JsonWriter.superclass.constructor.call(this, config);
25244 render : function(params, baseParams, data) {
25245 if (this.encode === true) {
25247 Ext.apply(params, baseParams);
25248 params[this.meta.root] = Ext.encode(data);
25251 var jdata = Ext.apply({}, baseParams);
25252 jdata[this.meta.root] = data;
25253 params.jsonData = jdata;
25257 createRecord : function(rec) {
25258 return this.toHash(rec);
25261 updateRecord : function(rec) {
25262 return this.toHash(rec);
25266 destroyRecord : function(rec){
25267 if(this.encodeDelete){
25269 data[this.meta.idProperty] = rec.id;
25276 Ext.data.JsonReader = function(meta, recordType){
25282 Ext.applyIf(meta, {
25284 successProperty: 'success',
25285 totalProperty: 'total'
25288 Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
25290 Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
25293 read : function(response){
25294 var json = response.responseText;
25295 var o = Ext.decode(json);
25297 throw {message: 'JsonReader.read: Json object not found'};
25299 return this.readRecords(o);
25304 readResponse : function(action, response) {
25305 var o = (response.responseText !== undefined) ? Ext.decode(response.responseText) : response;
25307 throw new Ext.data.JsonReader.Error('response');
25310 var root = this.getRoot(o);
25311 if (action === Ext.data.Api.actions.create) {
25312 var def = Ext.isDefined(root);
25313 if (def && Ext.isEmpty(root)) {
25314 throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
25317 throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
25322 var res = new Ext.data.Response({
25324 success: this.getSuccess(o),
25325 data: (root) ? this.extractData(root, false) : [],
25326 message: this.getMessage(o),
25331 if (Ext.isEmpty(res.success)) {
25332 throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
25338 readRecords : function(o){
25342 this.onMetaChange(o.metaData);
25344 var s = this.meta, Record = this.recordType,
25345 f = Record.prototype.fields, fi = f.items, fl = f.length, v;
25347 var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
25348 if(s.totalProperty){
25349 v = parseInt(this.getTotal(o), 10);
25354 if(s.successProperty){
25355 v = this.getSuccess(o);
25356 if(v === false || v === 'false'){
25364 records : this.extractData(root, true),
25365 totalRecords : totalRecords
25370 buildExtractors : function() {
25374 var s = this.meta, Record = this.recordType,
25375 f = Record.prototype.fields, fi = f.items, fl = f.length;
25377 if(s.totalProperty) {
25378 this.getTotal = this.createAccessor(s.totalProperty);
25380 if(s.successProperty) {
25381 this.getSuccess = this.createAccessor(s.successProperty);
25383 if (s.messageProperty) {
25384 this.getMessage = this.createAccessor(s.messageProperty);
25386 this.getRoot = s.root ? this.createAccessor(s.root) : function(p){return p;};
25387 if (s.id || s.idProperty) {
25388 var g = this.createAccessor(s.id || s.idProperty);
25389 this.getId = function(rec) {
25391 return (r === undefined || r === '') ? null : r;
25394 this.getId = function(){return null;};
25397 for(var i = 0; i < fl; i++){
25399 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
25400 ef.push(this.createAccessor(map));
25406 simpleAccess : function(obj, subsc) {
25411 createAccessor : function(){
25413 return function(expr) {
25414 if(Ext.isEmpty(expr)){
25415 return Ext.emptyFn;
25417 if(Ext.isFunction(expr)){
25420 var i = String(expr).search(re);
25422 return new Function('obj', 'return obj' + (i > 0 ? '.' : '') + expr);
25424 return function(obj){
25432 extractValues : function(data, items, len) {
25433 var f, values = {};
25434 for(var j = 0; j < len; j++){
25436 var v = this.ef[j](data);
25437 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
25444 Ext.data.JsonReader.Error = Ext.extend(Ext.Error, {
25445 constructor : function(message, arg) {
25447 Ext.Error.call(this, message);
25449 name : 'Ext.data.JsonReader'
25451 Ext.apply(Ext.data.JsonReader.Error.prototype, {
25453 'response': 'An error occurred while json-decoding your server response',
25454 '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.',
25455 '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.',
25456 '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.',
25457 '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.'
25461 Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
25466 readRecords : function(o){
25467 this.arrayData = o;
25469 sid = s ? Ext.num(s.idIndex, s.id) : null,
25470 recordType = this.recordType,
25471 fields = recordType.prototype.fields,
25476 var root = this.getRoot(o);
25478 for(var i = 0, len = root.length; i < len; i++) {
25481 id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
25482 for(var j = 0, jlen = fields.length; j < jlen; j++) {
25483 var f = fields.items[j],
25484 k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
25485 v = n[k] !== undefined ? n[k] : f.defaultValue;
25486 v = f.convert(v, n);
25487 values[f.name] = v;
25489 var record = new recordType(values, id);
25491 records[records.length] = record;
25494 var totalRecords = records.length;
25496 if(s.totalProperty) {
25497 v = parseInt(this.getTotal(o), 10);
25502 if(s.successProperty){
25503 v = this.getSuccess(o);
25504 if(v === false || v === 'false'){
25512 totalRecords : totalRecords
25516 Ext.data.ArrayStore = Ext.extend(Ext.data.Store, {
25518 constructor: function(config){
25519 Ext.data.ArrayStore.superclass.constructor.call(this, Ext.apply(config, {
25520 reader: new Ext.data.ArrayReader(config)
25524 loadData : function(data, append){
25525 if(this.expandData === true){
25527 for(var i = 0, len = data.length; i < len; i++){
25528 r[r.length] = [data[i]];
25532 Ext.data.ArrayStore.superclass.loadData.call(this, data, append);
25535 Ext.reg('arraystore', Ext.data.ArrayStore);
25538 Ext.data.SimpleStore = Ext.data.ArrayStore;
25539 Ext.reg('simplestore', Ext.data.SimpleStore);
25540 Ext.data.JsonStore = Ext.extend(Ext.data.Store, {
25542 constructor: function(config){
25543 Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
25544 reader: new Ext.data.JsonReader(config)
25548 Ext.reg('jsonstore', Ext.data.JsonStore);
25549 Ext.data.XmlWriter = function(params) {
25550 Ext.data.XmlWriter.superclass.constructor.apply(this, arguments);
25552 this.tpl = (typeof(this.tpl) === 'string') ? new Ext.XTemplate(this.tpl).compile() : this.tpl.compile();
25554 Ext.extend(Ext.data.XmlWriter, Ext.data.DataWriter, {
25556 documentRoot: 'xrequest',
25558 forceDocumentRoot: false,
25562 xmlVersion : '1.0',
25564 xmlEncoding: 'ISO-8859-15',
25567 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>',
25571 render : function(params, baseParams, data) {
25572 baseParams = this.toArray(baseParams);
25573 params.xmlData = this.tpl.applyTemplate({
25574 version: this.xmlVersion,
25575 encoding: this.xmlEncoding,
25576 documentRoot: (baseParams.length > 0 || this.forceDocumentRoot === true) ? this.documentRoot : false,
25577 record: this.meta.record,
25579 baseParams: baseParams,
25580 records: (Ext.isArray(data[0])) ? data : [data]
25585 createRecord : function(rec) {
25586 return this.toArray(this.toHash(rec));
25590 updateRecord : function(rec) {
25591 return this.toArray(this.toHash(rec));
25595 destroyRecord : function(rec) {
25597 data[this.meta.idProperty] = rec.id;
25598 return this.toArray(data);
25602 Ext.data.XmlReader = function(meta, recordType){
25606 Ext.applyIf(meta, {
25607 idProperty: meta.idProperty || meta.idPath || meta.id,
25608 successProperty: meta.successProperty || meta.success
25611 Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
25613 Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
25615 read : function(response){
25616 var doc = response.responseXML;
25618 throw {message: "XmlReader.read: XML Document not available"};
25620 return this.readRecords(doc);
25624 readRecords : function(doc){
25626 this.xmlData = doc;
25628 var root = doc.documentElement || doc,
25633 if(this.meta.totalProperty){
25634 totalRecords = this.getTotal(root, 0);
25636 if(this.meta.successProperty){
25637 success = this.getSuccess(root);
25640 var records = this.extractData(q.select(this.meta.record, root), true);
25646 totalRecords : totalRecords || records.length
25651 readResponse : function(action, response) {
25652 var q = Ext.DomQuery,
25653 doc = response.responseXML,
25654 root = doc.documentElement || doc;
25657 var res = new Ext.data.Response({
25659 success : this.getSuccess(root),
25660 message: this.getMessage(root),
25661 data: this.extractData(q.select(this.meta.record, root) || q.select(this.meta.root, root), false),
25665 if (Ext.isEmpty(res.success)) {
25666 throw new Ext.data.DataReader.Error('successProperty-response', this.meta.successProperty);
25670 if (action === Ext.data.Api.actions.create) {
25671 var def = Ext.isDefined(res.data);
25672 if (def && Ext.isEmpty(res.data)) {
25673 throw new Ext.data.JsonReader.Error('root-empty', this.meta.root);
25676 throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
25682 getSuccess : function() {
25687 buildExtractors : function() {
25692 Record = this.recordType,
25693 f = Record.prototype.fields,
25697 if(s.totalProperty) {
25698 this.getTotal = this.createAccessor(s.totalProperty);
25700 if(s.successProperty) {
25701 this.getSuccess = this.createAccessor(s.successProperty);
25703 if (s.messageProperty) {
25704 this.getMessage = this.createAccessor(s.messageProperty);
25706 this.getRoot = function(res) {
25707 return (!Ext.isEmpty(res[this.meta.record])) ? res[this.meta.record] : res[this.meta.root];
25709 if (s.idPath || s.idProperty) {
25710 var g = this.createAccessor(s.idPath || s.idProperty);
25711 this.getId = function(rec) {
25712 var id = g(rec) || rec.id;
25713 return (id === undefined || id === '') ? null : id;
25716 this.getId = function(){return null;};
25719 for(var i = 0; i < fl; i++){
25721 var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
25722 ef.push(this.createAccessor(map));
25728 createAccessor : function(){
25729 var q = Ext.DomQuery;
25730 return function(key) {
25732 case this.meta.totalProperty:
25733 return function(root, def){
25734 return q.selectNumber(key, root, def);
25737 case this.meta.successProperty:
25738 return function(root, def) {
25739 var sv = q.selectValue(key, root, true);
25740 var success = sv !== false && sv !== 'false';
25745 return function(root, def) {
25746 return q.selectValue(key, root, def);
25754 extractValues : function(data, items, len) {
25755 var f, values = {};
25756 for(var j = 0; j < len; j++){
25758 var v = this.ef[j](data);
25759 values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
25764 Ext.data.XmlStore = Ext.extend(Ext.data.Store, {
25766 constructor: function(config){
25767 Ext.data.XmlStore.superclass.constructor.call(this, Ext.apply(config, {
25768 reader: new Ext.data.XmlReader(config)
25772 Ext.reg('xmlstore', Ext.data.XmlStore);
25773 Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
25776 constructor: function(config) {
25777 config = config || {};
25783 this.hasMultiSort = true;
25784 this.multiSortInfo = this.multiSortInfo || {sorters: []};
25786 var sorters = this.multiSortInfo.sorters,
25787 groupField = config.groupField || this.groupField,
25788 sortInfo = config.sortInfo || this.sortInfo,
25789 groupDir = config.groupDir || this.groupDir;
25794 field : groupField,
25795 direction: groupDir
25801 sorters.push(sortInfo);
25804 Ext.data.GroupingStore.superclass.constructor.call(this, config);
25811 this.applyGroupField();
25816 remoteGroup : false,
25823 clearGrouping : function(){
25824 this.groupField = false;
25826 if(this.remoteGroup){
25827 if(this.baseParams){
25828 delete this.baseParams.groupBy;
25829 delete this.baseParams.groupDir;
25831 var lo = this.lastOptions;
25832 if(lo && lo.params){
25833 delete lo.params.groupBy;
25834 delete lo.params.groupDir;
25840 this.fireEvent('datachanged', this);
25845 groupBy : function(field, forceRegroup, direction) {
25846 direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir;
25848 if (this.groupField == field && this.groupDir == direction && !forceRegroup) {
25854 var sorters = this.multiSortInfo.sorters;
25855 if (sorters.length > 0 && sorters[0].field == this.groupField) {
25859 this.groupField = field;
25860 this.groupDir = direction;
25861 this.applyGroupField();
25863 var fireGroupEvent = function() {
25864 this.fireEvent('groupchange', this, this.getGroupState());
25867 if (this.groupOnSort) {
25868 this.sort(field, direction);
25869 fireGroupEvent.call(this);
25873 if (this.remoteGroup) {
25874 this.on('load', fireGroupEvent, this, {single: true});
25877 this.sort(sorters);
25878 fireGroupEvent.call(this);
25884 sort : function(fieldName, dir) {
25885 if (this.remoteSort) {
25886 return Ext.data.GroupingStore.superclass.sort.call(this, fieldName, dir);
25892 if (Ext.isArray(arguments[0])) {
25893 sorters = arguments[0];
25894 } else if (fieldName == undefined) {
25897 sorters = this.sortInfo ? [this.sortInfo] : [];
25901 var field = this.fields.get(fieldName);
25902 if (!field) return false;
25904 var name = field.name,
25905 sortInfo = this.sortInfo || null,
25906 sortToggle = this.sortToggle ? this.sortToggle[name] : null;
25909 if (sortInfo && sortInfo.field == name) {
25910 dir = (this.sortToggle[name] || 'ASC').toggle('ASC', 'DESC');
25912 dir = field.sortDir;
25916 this.sortToggle[name] = dir;
25917 this.sortInfo = {field: name, direction: dir};
25919 sorters = [this.sortInfo];
25923 if (this.groupField) {
25924 sorters.unshift({direction: this.groupDir, field: this.groupField});
25927 return this.multiSort.call(this, sorters, dir);
25931 applyGroupField: function(){
25932 if (this.remoteGroup) {
25933 if(!this.baseParams){
25934 this.baseParams = {};
25937 Ext.apply(this.baseParams, {
25938 groupBy : this.groupField,
25939 groupDir: this.groupDir
25942 var lo = this.lastOptions;
25943 if (lo && lo.params) {
25944 lo.params.groupDir = this.groupDir;
25947 delete lo.params.groupBy;
25953 applyGrouping : function(alwaysFireChange){
25954 if(this.groupField !== false){
25955 this.groupBy(this.groupField, true, this.groupDir);
25958 if(alwaysFireChange === true){
25959 this.fireEvent('datachanged', this);
25966 getGroupState : function(){
25967 return this.groupOnSort && this.groupField !== false ?
25968 (this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
25971 Ext.reg('groupingstore', Ext.data.GroupingStore);
25973 Ext.data.DirectProxy = function(config){
25974 Ext.apply(this, config);
25975 if(typeof this.paramOrder == 'string'){
25976 this.paramOrder = this.paramOrder.split(/[\s,|]/);
25978 Ext.data.DirectProxy.superclass.constructor.call(this, config);
25981 Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, {
25983 paramOrder: undefined,
25986 paramsAsHash: true,
25989 directFn : undefined,
25992 doRequest : function(action, rs, params, reader, callback, scope, options) {
25994 directFn = this.api[action] || this.directFn;
25997 case Ext.data.Api.actions.create:
25998 args.push(params.jsonData);
26000 case Ext.data.Api.actions.read:
26002 if(directFn.directCfg.method.len > 0){
26003 if(this.paramOrder){
26004 for(var i = 0, len = this.paramOrder.length; i < len; i++){
26005 args.push(params[this.paramOrder[i]]);
26007 }else if(this.paramsAsHash){
26012 case Ext.data.Api.actions.update:
26013 args.push(params.jsonData);
26015 case Ext.data.Api.actions.destroy:
26016 args.push(params.jsonData);
26021 params : params || {},
26023 callback : callback,
26030 args.push(this.createCallback(action, rs, trans), this);
26031 directFn.apply(window, args);
26035 createCallback : function(action, rs, trans) {
26037 return function(result, res) {
26040 if (action === Ext.data.Api.actions.read) {
26041 me.fireEvent("loadexception", me, trans, res, null);
26043 me.fireEvent('exception', me, 'remote', action, trans, res, null);
26044 trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
26047 if (action === Ext.data.Api.actions.read) {
26048 me.onRead(action, trans, result, res);
26050 me.onWrite(action, trans, result, res, rs);
26056 onRead : function(action, trans, result, res) {
26059 records = trans.reader.readRecords(result);
26063 this.fireEvent("loadexception", this, trans, res, ex);
26065 this.fireEvent('exception', this, 'response', action, trans, res, ex);
26066 trans.request.callback.call(trans.request.scope, null, trans.request.arg, false);
26069 this.fireEvent("load", this, res, trans.request.arg);
26070 trans.request.callback.call(trans.request.scope, records, trans.request.arg, true);
26073 onWrite : function(action, trans, result, res, rs) {
26074 var data = trans.reader.extractData(trans.reader.getRoot(result), false);
26075 var success = trans.reader.getSuccess(result);
26076 success = (success !== false);
26078 this.fireEvent("write", this, action, data, res, rs, trans.request.arg);
26080 this.fireEvent('exception', this, 'remote', action, trans, result, rs);
26082 trans.request.callback.call(trans.request.scope, data, res, success);
26086 Ext.data.DirectStore = Ext.extend(Ext.data.Store, {
26087 constructor : function(config){
26089 var c = Ext.apply({}, {
26090 batchTransactions: false
26092 Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, {
26093 proxy: Ext.isDefined(c.proxy) ? c.proxy : new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')),
26094 reader: (!Ext.isDefined(c.reader) && c.fields) ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader
26098 Ext.reg('directstore', Ext.data.DirectStore);
26100 Ext.Direct = Ext.extend(Ext.util.Observable, {
26108 SERVER: 'exception'
26112 constructor: function(){
26119 this.transactions = {};
26120 this.providers = {};
26124 addProvider : function(provider){
26127 for(var i = 0, len = a.length; i < len; i++){
26128 this.addProvider(a[i]);
26134 if(!provider.events){
26135 provider = new Ext.Direct.PROVIDERS[provider.type](provider);
26137 provider.id = provider.id || Ext.id();
26138 this.providers[provider.id] = provider;
26140 provider.on('data', this.onProviderData, this);
26141 provider.on('exception', this.onProviderException, this);
26144 if(!provider.isConnected()){
26145 provider.connect();
26152 getProvider : function(id){
26153 return this.providers[id];
26156 removeProvider : function(id){
26157 var provider = id.id ? id : this.providers[id];
26158 provider.un('data', this.onProviderData, this);
26159 provider.un('exception', this.onProviderException, this);
26160 delete this.providers[provider.id];
26164 addTransaction: function(t){
26165 this.transactions[t.tid] = t;
26169 removeTransaction: function(t){
26170 delete this.transactions[t.tid || t];
26174 getTransaction: function(tid){
26175 return this.transactions[tid.tid || tid];
26178 onProviderData : function(provider, e){
26179 if(Ext.isArray(e)){
26180 for(var i = 0, len = e.length; i < len; i++){
26181 this.onProviderData(provider, e[i]);
26185 if(e.name && e.name != 'event' && e.name != 'exception'){
26186 this.fireEvent(e.name, e);
26187 }else if(e.type == 'exception'){
26188 this.fireEvent('exception', e);
26190 this.fireEvent('event', e, provider);
26193 createEvent : function(response, extraProps){
26194 return new Ext.Direct.eventTypes[response.type](Ext.apply(response, extraProps));
26198 Ext.Direct = new Ext.Direct();
26200 Ext.Direct.TID = 1;
26201 Ext.Direct.PROVIDERS = {};
26202 Ext.Direct.Transaction = function(config){
26203 Ext.apply(this, config);
26204 this.tid = ++Ext.Direct.TID;
26205 this.retryCount = 0;
26207 Ext.Direct.Transaction.prototype = {
26209 this.provider.queueTransaction(this);
26217 getProvider: function(){
26218 return this.provider;
26220 };Ext.Direct.Event = function(config){
26221 Ext.apply(this, config);
26224 Ext.Direct.Event.prototype = {
26226 getData: function(){
26231 Ext.Direct.RemotingEvent = Ext.extend(Ext.Direct.Event, {
26233 getTransaction: function(){
26234 return this.transaction || Ext.Direct.getTransaction(this.tid);
26238 Ext.Direct.ExceptionEvent = Ext.extend(Ext.Direct.RemotingEvent, {
26243 Ext.Direct.eventTypes = {
26244 'rpc': Ext.Direct.RemotingEvent,
26245 'event': Ext.Direct.Event,
26246 'exception': Ext.Direct.ExceptionEvent
26249 Ext.direct.Provider = Ext.extend(Ext.util.Observable, {
26258 constructor : function(config){
26259 Ext.apply(this, config);
26270 Ext.direct.Provider.superclass.constructor.call(this, config);
26274 isConnected: function(){
26279 connect: Ext.emptyFn,
26282 disconnect: Ext.emptyFn
26285 Ext.direct.JsonProvider = Ext.extend(Ext.direct.Provider, {
26286 parseResponse: function(xhr){
26287 if(!Ext.isEmpty(xhr.responseText)){
26288 if(typeof xhr.responseText == 'object'){
26289 return xhr.responseText;
26291 return Ext.decode(xhr.responseText);
26296 getEvents: function(xhr){
26299 data = this.parseResponse(xhr);
26301 var event = new Ext.Direct.ExceptionEvent({
26304 code: Ext.Direct.exceptions.PARSE,
26305 message: 'Error parsing json response: \n\n ' + data
26310 if(Ext.isArray(data)){
26311 for(var i = 0, len = data.length; i < len; i++){
26312 events.push(Ext.Direct.createEvent(data[i]));
26315 events.push(Ext.Direct.createEvent(data));
26320 Ext.direct.PollingProvider = Ext.extend(Ext.direct.JsonProvider, {
26333 constructor : function(config){
26334 Ext.direct.PollingProvider.superclass.constructor.call(this, config);
26344 isConnected: function(){
26345 return !!this.pollTask;
26349 connect: function(){
26350 if(this.url && !this.pollTask){
26351 this.pollTask = Ext.TaskMgr.start({
26353 if(this.fireEvent('beforepoll', this) !== false){
26354 if(typeof this.url == 'function'){
26355 this.url(this.baseParams);
26359 callback: this.onData,
26361 params: this.baseParams
26366 interval: this.interval,
26369 this.fireEvent('connect', this);
26370 }else if(!this.url){
26371 throw 'Error initializing PollingProvider, no url configured.';
26376 disconnect: function(){
26378 Ext.TaskMgr.stop(this.pollTask);
26379 delete this.pollTask;
26380 this.fireEvent('disconnect', this);
26385 onData: function(opt, success, xhr){
26387 var events = this.getEvents(xhr);
26388 for(var i = 0, len = events.length; i < len; i++){
26390 this.fireEvent('data', this, e);
26393 var e = new Ext.Direct.ExceptionEvent({
26395 code: Ext.Direct.exceptions.TRANSPORT,
26396 message: 'Unable to connect to the server.',
26399 this.fireEvent('data', this, e);
26404 Ext.Direct.PROVIDERS['polling'] = Ext.direct.PollingProvider;
26405 Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {
26421 timeout: undefined,
26423 constructor : function(config){
26424 Ext.direct.RemotingProvider.superclass.constructor.call(this, config);
26431 this.namespace = (Ext.isString(this.namespace)) ? Ext.ns(this.namespace) : this.namespace || window;
26432 this.transactions = {};
26433 this.callBuffer = [];
26437 initAPI : function(){
26438 var o = this.actions;
26440 var cls = this.namespace[c] || (this.namespace[c] = {}),
26442 for(var i = 0, len = ms.length; i < len; i++){
26444 cls[m.name] = this.createMethod(c, m);
26450 isConnected: function(){
26451 return !!this.connected;
26454 connect: function(){
26457 this.connected = true;
26458 this.fireEvent('connect', this);
26459 }else if(!this.url){
26460 throw 'Error initializing RemotingProvider, no url configured.';
26464 disconnect: function(){
26465 if(this.connected){
26466 this.connected = false;
26467 this.fireEvent('disconnect', this);
26471 onData: function(opt, success, xhr){
26473 var events = this.getEvents(xhr);
26474 for(var i = 0, len = events.length; i < len; i++){
26476 t = this.getTransaction(e);
26477 this.fireEvent('data', this, e);
26479 this.doCallback(t, e, true);
26480 Ext.Direct.removeTransaction(t);
26484 var ts = [].concat(opt.ts);
26485 for(var i = 0, len = ts.length; i < len; i++){
26486 var t = this.getTransaction(ts[i]);
26487 if(t && t.retryCount < this.maxRetries){
26490 var e = new Ext.Direct.ExceptionEvent({
26493 code: Ext.Direct.exceptions.TRANSPORT,
26494 message: 'Unable to connect to the server.',
26497 this.fireEvent('data', this, e);
26499 this.doCallback(t, e, false);
26500 Ext.Direct.removeTransaction(t);
26507 getCallData: function(t){
26517 doSend : function(data){
26520 callback: this.onData,
26523 timeout: this.timeout
26526 if(Ext.isArray(data)){
26528 for(var i = 0, len = data.length; i < len; i++){
26529 callData.push(this.getCallData(data[i]));
26532 callData = this.getCallData(data);
26535 if(this.enableUrlEncode){
26537 params[Ext.isString(this.enableUrlEncode) ? this.enableUrlEncode : 'data'] = Ext.encode(callData);
26540 o.jsonData = callData;
26542 Ext.Ajax.request(o);
26545 combineAndSend : function(){
26546 var len = this.callBuffer.length;
26548 this.doSend(len == 1 ? this.callBuffer[0] : this.callBuffer);
26549 this.callBuffer = [];
26553 queueTransaction: function(t){
26555 this.processForm(t);
26558 this.callBuffer.push(t);
26559 if(this.enableBuffer){
26560 if(!this.callTask){
26561 this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this);
26563 this.callTask.delay(Ext.isNumber(this.enableBuffer) ? this.enableBuffer : 10);
26565 this.combineAndSend();
26569 doCall : function(c, m, args){
26570 var data = null, hs = args[m.len], scope = args[m.len+1];
26573 data = args.slice(0, m.len);
26576 var t = new Ext.Direct.Transaction({
26582 cb: scope && Ext.isFunction(hs) ? hs.createDelegate(scope) : hs
26585 if(this.fireEvent('beforecall', this, t, m) !== false){
26586 Ext.Direct.addTransaction(t);
26587 this.queueTransaction(t);
26588 this.fireEvent('call', this, t, m);
26592 doForm : function(c, m, form, callback, scope){
26593 var t = new Ext.Direct.Transaction({
26597 args:[form, callback, scope],
26598 cb: scope && Ext.isFunction(callback) ? callback.createDelegate(scope) : callback,
26602 if(this.fireEvent('beforecall', this, t, m) !== false){
26603 Ext.Direct.addTransaction(t);
26604 var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data',
26610 extUpload: String(isUpload)
26616 form: Ext.getDom(form),
26617 isUpload: isUpload,
26618 params: callback && Ext.isObject(callback.params) ? Ext.apply(params, callback.params) : params
26620 this.fireEvent('call', this, t, m);
26621 this.processForm(t);
26625 processForm: function(t){
26629 callback: this.onData,
26632 isUpload: t.isUpload,
26637 createMethod : function(c, m){
26639 if(!m.formHandler){
26641 this.doCall(c, m, Array.prototype.slice.call(arguments, 0));
26642 }.createDelegate(this);
26644 f = function(form, callback, scope){
26645 this.doForm(c, m, form, callback, scope);
26646 }.createDelegate(this);
26655 getTransaction: function(opt){
26656 return opt && opt.tid ? Ext.Direct.getTransaction(opt.tid) : null;
26659 doCallback: function(t, e){
26660 var fn = e.status ? 'success' : 'failure';
26663 result = Ext.isDefined(e.result) ? e.result : e.data;
26664 if(Ext.isFunction(hs)){
26667 Ext.callback(hs[fn], hs.scope, [result, e]);
26668 Ext.callback(hs.callback, hs.scope, [result, e]);
26673 Ext.Direct.PROVIDERS['remoting'] = Ext.direct.RemotingProvider;
26674 Ext.Resizable = Ext.extend(Ext.util.Observable, {
26676 constructor: function(el, config){
26677 this.el = Ext.get(el);
26678 if(config && config.wrap){
26679 config.resizeChild = this.el;
26680 this.el = this.el.wrap(typeof config.wrap == 'object' ? config.wrap : {cls:'xresizable-wrap'});
26681 this.el.id = this.el.dom.id = config.resizeChild.id + '-rzwrap';
26682 this.el.setStyle('overflow', 'hidden');
26683 this.el.setPositioning(config.resizeChild.getPositioning());
26684 config.resizeChild.clearPositioning();
26685 if(!config.width || !config.height){
26686 var csize = config.resizeChild.getSize();
26687 this.el.setSize(csize.width, csize.height);
26689 if(config.pinned && !config.adjustments){
26690 config.adjustments = 'auto';
26695 this.proxy = this.el.createProxy({tag: 'div', cls: 'x-resizable-proxy', id: this.el.id + '-rzproxy'}, Ext.getBody());
26696 this.proxy.unselectable();
26697 this.proxy.enableDisplayMode('block');
26699 Ext.apply(this, config);
26702 this.disableTrackOver = true;
26703 this.el.addClass('x-resizable-pinned');
26706 var position = this.el.getStyle('position');
26707 if(position != 'absolute' && position != 'fixed'){
26708 this.el.setStyle('position', 'relative');
26711 this.handles = 's,e,se';
26712 if(this.multiDirectional){
26713 this.handles += ',n,w';
26716 if(this.handles == 'all'){
26717 this.handles = 'n s e w ne nw se sw';
26719 var hs = this.handles.split(/\s*?[,;]\s*?| /);
26720 var ps = Ext.Resizable.positions;
26721 for(var i = 0, len = hs.length; i < len; i++){
26722 if(hs[i] && ps[hs[i]]){
26723 var pos = ps[hs[i]];
26724 this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent, this.handleCls);
26728 this.corner = this.southeast;
26730 if(this.handles.indexOf('n') != -1 || this.handles.indexOf('w') != -1){
26731 this.updateBox = true;
26734 this.activeHandle = null;
26736 if(this.resizeChild){
26737 if(typeof this.resizeChild == 'boolean'){
26738 this.resizeChild = Ext.get(this.el.dom.firstChild, true);
26740 this.resizeChild = Ext.get(this.resizeChild, true);
26744 if(this.adjustments == 'auto'){
26745 var rc = this.resizeChild;
26746 var hw = this.west, he = this.east, hn = this.north, hs = this.south;
26747 if(rc && (hw || hn)){
26748 rc.position('relative');
26749 rc.setLeft(hw ? hw.el.getWidth() : 0);
26750 rc.setTop(hn ? hn.el.getHeight() : 0);
26752 this.adjustments = [
26753 (he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
26754 (hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1
26758 if(this.draggable){
26759 this.dd = this.dynamic ?
26760 this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
26761 this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
26762 if(this.constrainTo){
26763 this.dd.constrainTo(this.constrainTo);
26774 if(this.width !== null && this.height !== null){
26775 this.resizeTo(this.width, this.height);
26777 this.updateChildSize();
26780 this.el.dom.style.zoom = 1;
26782 Ext.Resizable.superclass.constructor.call(this);
26786 adjustments : [0, 0],
26791 disableTrackOver : false,
26799 easing : 'easeOutStrong',
26806 multiDirectional : false,
26812 heightIncrement : 0,
26814 widthIncrement : 0,
26830 preserveRatio : false,
26832 resizeChild : false,
26834 transparent: false,
26841 resizeTo : function(width, height){
26842 this.el.setSize(width, height);
26843 this.updateChildSize();
26844 this.fireEvent('resize', this, width, height, null);
26848 startSizing : function(e, handle){
26849 this.fireEvent('beforeresize', this, e);
26853 this.overlay = this.el.createProxy({tag: 'div', cls: 'x-resizable-overlay', html: ' '}, Ext.getBody());
26854 this.overlay.unselectable();
26855 this.overlay.enableDisplayMode('block');
26858 mousemove: this.onMouseMove,
26859 mouseup: this.onMouseUp
26862 this.overlay.setStyle('cursor', handle.el.getStyle('cursor'));
26864 this.resizing = true;
26865 this.startBox = this.el.getBox();
26866 this.startPoint = e.getXY();
26867 this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
26868 (this.startBox.y + this.startBox.height) - this.startPoint[1]];
26870 this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
26871 this.overlay.show();
26873 if(this.constrainTo) {
26874 var ct = Ext.get(this.constrainTo);
26875 this.resizeRegion = ct.getRegion().adjust(
26876 ct.getFrameWidth('t'),
26877 ct.getFrameWidth('l'),
26878 -ct.getFrameWidth('b'),
26879 -ct.getFrameWidth('r')
26883 this.proxy.setStyle('visibility', 'hidden');
26885 this.proxy.setBox(this.startBox);
26887 this.proxy.setStyle('visibility', 'visible');
26893 onMouseDown : function(handle, e){
26896 this.activeHandle = handle;
26897 this.startSizing(e, handle);
26902 onMouseUp : function(e){
26903 this.activeHandle = null;
26904 var size = this.resizeElement();
26905 this.resizing = false;
26907 this.overlay.hide();
26909 this.fireEvent('resize', this, size.width, size.height, e);
26913 updateChildSize : function(){
26914 if(this.resizeChild){
26916 var child = this.resizeChild;
26917 var adj = this.adjustments;
26918 if(el.dom.offsetWidth){
26919 var b = el.getSize(true);
26920 child.setSize(b.width+adj[0], b.height+adj[1]);
26927 setTimeout(function(){
26928 if(el.dom.offsetWidth){
26929 var b = el.getSize(true);
26930 child.setSize(b.width+adj[0], b.height+adj[1]);
26938 snap : function(value, inc, min){
26939 if(!inc || !value){
26942 var newValue = value;
26943 var m = value % inc;
26946 newValue = value + (inc-m);
26948 newValue = value - m;
26951 return Math.max(min, newValue);
26955 resizeElement : function(){
26956 var box = this.proxy.getBox();
26957 if(this.updateBox){
26958 this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
26960 this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing);
26962 this.updateChildSize();
26966 if(this.draggable && this.constrainTo){
26967 this.dd.resetConstraints();
26968 this.dd.constrainTo(this.constrainTo);
26974 constrain : function(v, diff, m, mx){
26977 }else if(v - diff > mx){
26984 onMouseMove : function(e){
26985 if(this.enabled && this.activeHandle){
26988 if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {
26993 var curSize = this.curSize || this.startBox,
26994 x = this.startBox.x, y = this.startBox.y,
26998 h = curSize.height,
27001 mw = this.minWidth,
27002 mh = this.minHeight,
27003 mxw = this.maxWidth,
27004 mxh = this.maxHeight,
27005 wi = this.widthIncrement,
27006 hi = this.heightIncrement,
27007 eventXY = e.getXY(),
27008 diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0])),
27009 diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1])),
27010 pos = this.activeHandle.position,
27017 w = Math.min(Math.max(mw, w), mxw);
27021 h = Math.min(Math.max(mh, h), mxh);
27026 w = Math.min(Math.max(mw, w), mxw);
27027 h = Math.min(Math.max(mh, h), mxh);
27030 diffY = this.constrain(h, diffY, mh, mxh);
27035 diffX = this.constrain(w, diffX, mw, mxw);
27041 w = Math.min(Math.max(mw, w), mxw);
27042 diffY = this.constrain(h, diffY, mh, mxh);
27047 diffX = this.constrain(w, diffX, mw, mxw);
27048 diffY = this.constrain(h, diffY, mh, mxh);
27055 diffX = this.constrain(w, diffX, mw, mxw);
27057 h = Math.min(Math.max(mh, h), mxh);
27063 var sw = this.snap(w, wi, mw);
27064 var sh = this.snap(h, hi, mh);
27065 if(sw != w || sh != h){
27088 if(this.preserveRatio){
27093 h = Math.min(Math.max(mh, h), mxh);
27098 w = Math.min(Math.max(mw, w), mxw);
27103 w = Math.min(Math.max(mw, w), mxw);
27109 w = Math.min(Math.max(mw, w), mxw);
27115 h = Math.min(Math.max(mh, h), mxh);
27123 h = Math.min(Math.max(mh, h), mxh);
27133 h = Math.min(Math.max(mh, h), mxh);
27141 this.proxy.setBounds(x, y, w, h);
27143 this.resizeElement();
27150 handleOver : function(){
27152 this.el.addClass('x-resizable-over');
27157 handleOut : function(){
27158 if(!this.resizing){
27159 this.el.removeClass('x-resizable-over');
27164 getEl : function(){
27169 getResizeChild : function(){
27170 return this.resizeChild;
27174 destroy : function(removeEl){
27175 Ext.destroy(this.dd, this.overlay, this.proxy);
27176 this.overlay = null;
27179 var ps = Ext.Resizable.positions;
27181 if(typeof ps[k] != 'function' && this[ps[k]]){
27182 this[ps[k]].destroy();
27186 this.el.update('');
27187 Ext.destroy(this.el);
27190 this.purgeListeners();
27193 syncHandleHeight : function(){
27194 var h = this.el.getHeight(true);
27196 this.west.el.setHeight(h);
27199 this.east.el.setHeight(h);
27206 Ext.Resizable.positions = {
27207 n: 'north', s: 'south', e: 'east', w: 'west', se: 'southeast', sw: 'southwest', nw: 'northwest', ne: 'northeast'
27210 Ext.Resizable.Handle = Ext.extend(Object, {
27211 constructor : function(rz, pos, disableTrackOver, transparent, cls){
27214 var tpl = Ext.DomHelper.createTemplate(
27215 {tag: 'div', cls: 'x-resizable-handle x-resizable-handle-{0}'}
27218 Ext.Resizable.Handle.prototype.tpl = tpl;
27220 this.position = pos;
27222 this.el = this.tpl.append(rz.el.dom, [this.position], true);
27223 this.el.unselectable();
27225 this.el.setOpacity(0);
27227 if(!Ext.isEmpty(cls)){
27228 this.el.addClass(cls);
27230 this.el.on('mousedown', this.onMouseDown, this);
27231 if(!disableTrackOver){
27234 mouseover: this.onMouseOver,
27235 mouseout: this.onMouseOut
27241 afterResize : function(rz){
27245 onMouseDown : function(e){
27246 this.rz.onMouseDown(this, e);
27249 onMouseOver : function(e){
27250 this.rz.handleOver(this, e);
27253 onMouseOut : function(e){
27254 this.rz.handleOut(this, e);
27257 destroy : function(){
27258 Ext.destroy(this.el);
27263 Ext.Window = Ext.extend(Ext.Panel, {
27276 baseCls : 'x-window',
27284 closeAction : 'close',
27288 constrainHeader : false,
27292 minimizable : false,
27294 maximizable : false,
27300 expandOnShow : true,
27303 showAnimDuration: 0.25,
27306 hideAnimDuration: 0.25,
27309 collapsible : false,
27312 initHidden : undefined,
27322 elements : 'header,body',
27329 initComponent : function(){
27331 Ext.Window.superclass.initComponent.call(this);
27345 if(Ext.isDefined(this.initHidden)){
27346 this.hidden = this.initHidden;
27348 if(this.hidden === false){
27349 this.hidden = true;
27355 getState : function(){
27356 return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox(true));
27360 onRender : function(ct, position){
27361 Ext.Window.superclass.onRender.call(this, ct, position);
27364 this.el.addClass('x-window-plain');
27368 this.focusEl = this.el.createChild({
27369 tag: 'a', href:'#', cls:'x-dlg-focus',
27370 tabIndex:'-1', html: ' '});
27371 this.focusEl.swallowEvent('click', true);
27373 this.proxy = this.el.createProxy('x-window-proxy');
27374 this.proxy.enableDisplayMode('block');
27377 this.mask = this.container.createChild({cls:'ext-el-mask'}, this.el.dom);
27378 this.mask.enableDisplayMode('block');
27380 this.mon(this.mask, 'click', this.focus, this);
27382 if(this.maximizable){
27383 this.mon(this.header, 'dblclick', this.toggleMaximize, this);
27388 initEvents : function(){
27389 Ext.Window.superclass.initEvents.call(this);
27390 if(this.animateTarget){
27391 this.setAnimateTarget(this.animateTarget);
27394 if(this.resizable){
27395 this.resizer = new Ext.Resizable(this.el, {
27396 minWidth: this.minWidth,
27397 minHeight:this.minHeight,
27398 handles: this.resizeHandles || 'all',
27400 resizeElement : this.resizerAction,
27401 handleCls: 'x-window-handle'
27403 this.resizer.window = this;
27404 this.mon(this.resizer, 'beforeresize', this.beforeResize, this);
27407 if(this.draggable){
27408 this.header.addClass('x-window-draggable');
27410 this.mon(this.el, 'mousedown', this.toFront, this);
27411 this.manager = this.manager || Ext.WindowMgr;
27412 this.manager.register(this);
27413 if(this.maximized){
27414 this.maximized = false;
27418 var km = this.getKeyMap();
27419 km.on(27, this.onEsc, this);
27424 initDraggable : function(){
27426 this.dd = new Ext.Window.DD(this);
27430 onEsc : function(k, e){
27432 this[this.closeAction]();
27436 beforeDestroy : function(){
27439 this.clearAnchor();
27448 Ext.Window.superclass.beforeDestroy.call(this);
27452 onDestroy : function(){
27454 this.manager.unregister(this);
27456 Ext.Window.superclass.onDestroy.call(this);
27460 initTools : function(){
27461 if(this.minimizable){
27464 handler: this.minimize.createDelegate(this, [])
27467 if(this.maximizable){
27470 handler: this.maximize.createDelegate(this, [])
27474 handler: this.restore.createDelegate(this, []),
27481 handler: this[this.closeAction].createDelegate(this, [])
27487 resizerAction : function(){
27488 var box = this.proxy.getBox();
27490 this.window.handleResize(box);
27495 beforeResize : function(){
27496 this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40);
27497 this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
27498 this.resizeBox = this.el.getBox();
27502 updateHandles : function(){
27503 if(Ext.isIE && this.resizer){
27504 this.resizer.syncHandleHeight();
27510 handleResize : function(box){
27511 var rz = this.resizeBox;
27512 if(rz.x != box.x || rz.y != box.y){
27513 this.updateBox(box);
27516 if (Ext.isIE6 && Ext.isStrict) {
27521 this.updateHandles();
27526 focus : function(){
27527 var f = this.focusEl,
27528 db = this.defaultButton,
27532 if(Ext.isDefined(db)){
27533 if(Ext.isNumber(db) && this.fbar){
27534 f = this.fbar.items.get(db);
27535 }else if(Ext.isString(db)){
27536 f = Ext.getCmp(db);
27541 ct = Ext.getDom(this.container);
27543 if (ct != document.body && !Ext.lib.Region.getRegion(ct).contains(Ext.lib.Region.getRegion(el.dom))){
27548 f = f || this.focusEl;
27549 f.focus.defer(10, f);
27553 setAnimateTarget : function(el){
27555 this.animateTarget = el;
27559 beforeShow : function(){
27560 delete this.el.lastXY;
27561 delete this.el.lastLT;
27562 if(this.x === undefined || this.y === undefined){
27563 var xy = this.el.getAlignToXY(this.container, 'c-c');
27564 var pos = this.el.translatePoints(xy[0], xy[1]);
27565 this.x = this.x === undefined? pos.left : this.x;
27566 this.y = this.y === undefined? pos.top : this.y;
27568 this.el.setLeftTop(this.x, this.y);
27570 if(this.expandOnShow){
27571 this.expand(false);
27575 Ext.getBody().addClass('x-body-masked');
27576 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
27582 show : function(animateTarget, cb, scope){
27583 if(!this.rendered){
27584 this.render(Ext.getBody());
27586 if(this.hidden === false){
27590 if(this.fireEvent('beforeshow', this) === false){
27594 this.on('show', cb, scope, {single:true});
27596 this.hidden = false;
27597 if(Ext.isDefined(animateTarget)){
27598 this.setAnimateTarget(animateTarget);
27601 if(this.animateTarget){
27610 afterShow : function(isAnim){
27611 if (this.isDestroyed){
27615 this.el.setStyle('display', 'block');
27617 if(this.maximized){
27618 this.fitContainer();
27620 if(Ext.isMac && Ext.isGecko2){
27621 this.cascade(this.setAutoScroll);
27624 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
27625 Ext.EventManager.onWindowResize(this.onWindowResize, this);
27627 this.doConstrain();
27630 this.keyMap.enable();
27633 this.updateHandles();
27634 if(isAnim && (Ext.isIE || Ext.isWebKit)){
27635 var sz = this.getSize();
27636 this.onResize(sz.width, sz.height);
27639 this.fireEvent('show', this);
27643 animShow : function(){
27645 this.proxy.setBox(this.animateTarget.getBox());
27646 this.proxy.setOpacity(0);
27647 var b = this.getBox();
27648 this.el.setStyle('display', 'none');
27649 this.proxy.shift(Ext.apply(b, {
27650 callback: this.afterShow.createDelegate(this, [true], false),
27652 easing: 'easeNone',
27653 duration: this.showAnimDuration,
27659 hide : function(animateTarget, cb, scope){
27660 if(this.hidden || this.fireEvent('beforehide', this) === false){
27664 this.on('hide', cb, scope, {single:true});
27666 this.hidden = true;
27667 if(animateTarget !== undefined){
27668 this.setAnimateTarget(animateTarget);
27672 Ext.getBody().removeClass('x-body-masked');
27674 if(this.animateTarget){
27684 afterHide : function(){
27686 if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
27687 Ext.EventManager.removeResizeListener(this.onWindowResize, this);
27690 this.keyMap.disable();
27693 this.fireEvent('hide', this);
27697 animHide : function(){
27698 this.proxy.setOpacity(0.5);
27700 var tb = this.getBox(false);
27701 this.proxy.setBox(tb);
27703 this.proxy.shift(Ext.apply(this.animateTarget.getBox(), {
27704 callback: this.afterHide,
27706 duration: this.hideAnimDuration,
27707 easing: 'easeNone',
27713 onShow : Ext.emptyFn,
27716 onHide : Ext.emptyFn,
27719 onWindowResize : function(){
27720 if(this.maximized){
27721 this.fitContainer();
27724 this.mask.setSize('100%', '100%');
27725 var force = this.mask.dom.offsetHeight;
27726 this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
27728 this.doConstrain();
27732 doConstrain : function(){
27733 if(this.constrain || this.constrainHeader){
27735 if(this.constrain){
27737 right:this.el.shadowOffset,
27738 left:this.el.shadowOffset,
27739 bottom:this.el.shadowOffset
27742 var s = this.getSize();
27744 right:-(s.width - 100),
27745 bottom:-(s.height - 25)
27749 var xy = this.el.getConstrainToXY(this.container, true, offsets);
27751 this.setPosition(xy[0], xy[1]);
27757 ghost : function(cls){
27758 var ghost = this.createGhost(cls);
27759 var box = this.getBox(true);
27760 ghost.setLeftTop(box.x, box.y);
27761 ghost.setWidth(box.width);
27763 this.activeGhost = ghost;
27768 unghost : function(show, matchPosition){
27769 if(!this.activeGhost) {
27772 if(show !== false){
27774 this.focus.defer(10, this);
27775 if(Ext.isMac && Ext.isGecko2){
27776 this.cascade(this.setAutoScroll);
27779 if(matchPosition !== false){
27780 this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
27782 this.activeGhost.hide();
27783 this.activeGhost.remove();
27784 delete this.activeGhost;
27788 minimize : function(){
27789 this.fireEvent('minimize', this);
27794 close : function(){
27795 if(this.fireEvent('beforeclose', this) !== false){
27799 this.hide(null, this.doClose, this);
27805 doClose : function(){
27806 this.fireEvent('close', this);
27811 maximize : function(){
27812 if(!this.maximized){
27813 this.expand(false);
27814 this.restoreSize = this.getSize();
27815 this.restorePos = this.getPosition(true);
27816 if (this.maximizable){
27817 this.tools.maximize.hide();
27818 this.tools.restore.show();
27820 this.maximized = true;
27821 this.el.disableShadow();
27826 if(this.collapsible){
27827 this.tools.toggle.hide();
27829 this.el.addClass('x-window-maximized');
27830 this.container.addClass('x-window-maximized-ct');
27832 this.setPosition(0, 0);
27833 this.fitContainer();
27834 this.fireEvent('maximize', this);
27840 restore : function(){
27841 if(this.maximized){
27842 var t = this.tools;
27843 this.el.removeClass('x-window-maximized');
27850 this.setPosition(this.restorePos[0], this.restorePos[1]);
27851 this.setSize(this.restoreSize.width, this.restoreSize.height);
27852 delete this.restorePos;
27853 delete this.restoreSize;
27854 this.maximized = false;
27855 this.el.enableShadow(true);
27860 if(this.collapsible && t.toggle){
27863 this.container.removeClass('x-window-maximized-ct');
27865 this.doConstrain();
27866 this.fireEvent('restore', this);
27872 toggleMaximize : function(){
27873 return this[this.maximized ? 'restore' : 'maximize']();
27877 fitContainer : function(){
27878 var vs = this.container.getViewSize(false);
27879 this.setSize(vs.width, vs.height);
27884 setZIndex : function(index){
27886 this.mask.setStyle('z-index', index);
27888 this.el.setZIndex(++index);
27892 this.resizer.proxy.setStyle('z-index', ++index);
27895 this.lastZIndex = index;
27899 alignTo : function(element, position, offsets){
27900 var xy = this.el.getAlignToXY(element, position, offsets);
27901 this.setPagePosition(xy[0], xy[1]);
27906 anchorTo : function(el, alignment, offsets, monitorScroll){
27907 this.clearAnchor();
27908 this.anchorTarget = {
27910 alignment: alignment,
27914 Ext.EventManager.onWindowResize(this.doAnchor, this);
27915 var tm = typeof monitorScroll;
27916 if(tm != 'undefined'){
27917 Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
27918 {buffer: tm == 'number' ? monitorScroll : 50});
27920 return this.doAnchor();
27924 doAnchor : function(){
27925 var o = this.anchorTarget;
27926 this.alignTo(o.el, o.alignment, o.offsets);
27931 clearAnchor : function(){
27932 if(this.anchorTarget){
27933 Ext.EventManager.removeResizeListener(this.doAnchor, this);
27934 Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
27935 delete this.anchorTarget;
27941 toFront : function(e){
27942 if(this.manager.bringToFront(this)){
27943 if(!e || !e.getTarget().focus){
27951 setActive : function(active){
27953 if(!this.maximized){
27954 this.el.enableShadow(true);
27956 this.fireEvent('activate', this);
27958 this.el.disableShadow();
27959 this.fireEvent('deactivate', this);
27964 toBack : function(){
27965 this.manager.sendToBack(this);
27970 center : function(){
27971 var xy = this.el.getAlignToXY(this.container, 'c-c');
27972 this.setPagePosition(xy[0], xy[1]);
27978 Ext.reg('window', Ext.Window);
27981 Ext.Window.DD = Ext.extend(Ext.dd.DD, {
27983 constructor : function(win){
27985 Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
27986 this.setHandleElId(win.header.id);
27987 this.scroll = false;
27991 headerOffsets:[100, 25],
27992 startDrag : function(){
27994 this.proxy = w.ghost(w.initialConfig.cls);
27995 if(w.constrain !== false){
27996 var so = w.el.shadowOffset;
27997 this.constrainTo(w.container, {right: so, left: so, bottom: so});
27998 }else if(w.constrainHeader !== false){
27999 var s = this.proxy.getSize();
28000 this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
28003 b4Drag : Ext.emptyFn,
28005 onDrag : function(e){
28006 this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
28009 endDrag : function(e){
28010 this.win.unghost();
28011 this.win.saveState();
28015 Ext.WindowGroup = function(){
28017 var accessList = [];
28021 var sortWindows = function(d1, d2){
28022 return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
28026 var orderWindows = function(){
28027 var a = accessList, len = a.length;
28029 a.sort(sortWindows);
28030 var seed = a[0].manager.zseed;
28031 for(var i = 0; i < len; i++){
28033 if(win && !win.hidden){
28034 win.setZIndex(seed + (i*10));
28042 var setActiveWin = function(win){
28045 front.setActive(false);
28049 win.setActive(true);
28055 var activateLast = function(){
28056 for(var i = accessList.length-1; i >=0; --i) {
28057 if(!accessList[i].hidden){
28058 setActiveWin(accessList[i]);
28063 setActiveWin(null);
28071 register : function(win){
28073 win.manager.unregister(win);
28075 win.manager = this;
28077 list[win.id] = win;
28078 accessList.push(win);
28079 win.on('hide', activateLast);
28083 unregister : function(win){
28084 delete win.manager;
28085 delete list[win.id];
28086 win.un('hide', activateLast);
28087 accessList.remove(win);
28091 get : function(id){
28092 return typeof id == "object" ? id : list[id];
28096 bringToFront : function(win){
28097 win = this.get(win);
28099 win._lastAccess = new Date().getTime();
28107 sendToBack : function(win){
28108 win = this.get(win);
28109 win._lastAccess = -(new Date().getTime());
28115 hideAll : function(){
28116 for(var id in list){
28117 if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
28124 getActive : function(){
28129 getBy : function(fn, scope){
28131 for(var i = accessList.length-1; i >=0; --i) {
28132 var win = accessList[i];
28133 if(fn.call(scope||win, win) !== false){
28141 each : function(fn, scope){
28142 for(var id in list){
28143 if(list[id] && typeof list[id] != "function"){
28144 if(fn.call(scope || list[id], list[id]) === false){
28155 Ext.WindowMgr = new Ext.WindowGroup();
28156 Ext.MessageBox = function(){
28157 var dlg, opt, mask, waitTimer,
28158 bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl,
28159 buttons, activeTextEl, bwidth, bufferIcon = '', iconCls = '',
28160 buttonNames = ['ok', 'yes', 'no', 'cancel'];
28163 var handleButton = function(button){
28164 buttons[button].blur();
28165 if(dlg.isVisible()){
28168 Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1);
28173 var handleHide = function(){
28174 if(opt && opt.cls){
28175 dlg.el.removeClass(opt.cls);
28177 progressBar.reset();
28181 var handleEsc = function(d, k, e){
28182 if(opt && opt.closable !== false){
28192 var updateButtons = function(b){
28196 Ext.each(buttonNames, function(name){
28197 buttons[name].hide();
28201 dlg.footer.dom.style.display = '';
28202 Ext.iterate(buttons, function(name, btn){
28206 btn.setText(Ext.isString(cfg) ? cfg : Ext.MessageBox.buttonText[name]);
28207 width += btn.getEl().getWidth() + 15;
28217 getDialog : function(titleText){
28222 Ext.each(buttonNames, function(name){
28223 btns.push(buttons[name] = new Ext.Button({
28224 text: this.buttonText[name],
28225 handler: handleButton.createCallback(name),
28226 hideMode: 'offsets'
28229 dlg = new Ext.Window({
28234 constrainHeader:true,
28235 minimizable : false,
28236 maximizable : false,
28240 buttonAlign:"center",
28247 close : function(){
28248 if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
28249 handleButton("no");
28251 handleButton("cancel");
28254 fbar: new Ext.Toolbar({
28256 enableOverflow: false
28259 dlg.render(document.body);
28260 dlg.getEl().addClass('x-window-dlg');
28262 bodyEl = dlg.body.createChild({
28263 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>'
28265 iconEl = Ext.get(bodyEl.dom.firstChild);
28266 var contentEl = bodyEl.dom.childNodes[1];
28267 msgEl = Ext.get(contentEl.firstChild);
28268 textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
28269 textboxEl.enableDisplayMode();
28270 textboxEl.addKeyListener([10,13], function(){
28271 if(dlg.isVisible() && opt && opt.buttons){
28272 if(opt.buttons.ok){
28273 handleButton("ok");
28274 }else if(opt.buttons.yes){
28275 handleButton("yes");
28279 textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
28280 textareaEl.enableDisplayMode();
28281 progressBar = new Ext.ProgressBar({
28284 bodyEl.createChild({cls:'x-clear'});
28290 updateText : function(text){
28291 if(!dlg.isVisible() && !opt.width){
28292 dlg.setSize(this.maxWidth, 100);
28295 msgEl.update(text ? text + ' ' : ' ');
28297 var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0,
28298 mw = msgEl.getWidth() + msgEl.getMargins('lr'),
28299 fw = dlg.getFrameWidth('lr'),
28300 bw = dlg.body.getFrameWidth('lr'),
28303 w = Math.max(Math.min(opt.width || iw+mw+fw+bw, opt.maxWidth || this.maxWidth),
28304 Math.max(opt.minWidth || this.minWidth, bwidth || 0));
28306 if(opt.prompt === true){
28307 activeTextEl.setWidth(w-iw-fw-bw);
28309 if(opt.progress === true || opt.wait === true){
28310 progressBar.setSize(w-iw-fw-bw);
28312 if(Ext.isIE && w == bwidth){
28315 msgEl.update(text || ' ');
28316 dlg.setSize(w, 'auto').center();
28321 updateProgress : function(value, progressText, msg){
28322 progressBar.updateProgress(value, progressText);
28324 this.updateText(msg);
28330 isVisible : function(){
28331 return dlg && dlg.isVisible();
28336 var proxy = dlg ? dlg.activeGhost : null;
28337 if(this.isVisible() || proxy){
28343 dlg.unghost(false, false);
28350 show : function(options){
28351 if(this.isVisible()){
28355 var d = this.getDialog(opt.title || " ");
28357 d.setTitle(opt.title || " ");
28358 var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
28359 d.tools.close.setDisplayed(allowClose);
28360 activeTextEl = textboxEl;
28361 opt.prompt = opt.prompt || (opt.multiline ? true : false);
28366 textareaEl.setHeight(Ext.isNumber(opt.multiline) ? opt.multiline : this.defaultTextHeight);
28367 activeTextEl = textareaEl;
28376 activeTextEl.dom.value = opt.value || "";
28378 d.focusEl = activeTextEl;
28380 var bs = opt.buttons;
28383 db = buttons["ok"];
28384 }else if(bs && bs.yes){
28385 db = buttons["yes"];
28391 if(Ext.isDefined(opt.iconCls)){
28392 d.setIconClass(opt.iconCls);
28394 this.setIcon(Ext.isDefined(opt.icon) ? opt.icon : bufferIcon);
28395 bwidth = updateButtons(opt.buttons);
28396 progressBar.setVisible(opt.progress === true || opt.wait === true);
28397 this.updateProgress(0, opt.progressText);
28398 this.updateText(opt.msg);
28400 d.el.addClass(opt.cls);
28402 d.proxyDrag = opt.proxyDrag === true;
28403 d.modal = opt.modal !== false;
28404 d.mask = opt.modal !== false ? mask : false;
28405 if(!d.isVisible()){
28407 document.body.appendChild(dlg.el.dom);
28408 d.setAnimateTarget(opt.animEl);
28410 d.on('show', function(){
28411 if(allowClose === true){
28414 d.keyMap.disable();
28416 }, this, {single:true});
28417 d.show(opt.animEl);
28419 if(opt.wait === true){
28420 progressBar.wait(opt.waitConfig);
28426 setIcon : function(icon){
28431 bufferIcon = undefined;
28432 if(icon && icon != ''){
28433 iconEl.removeClass('x-hidden');
28434 iconEl.replaceClass(iconCls, icon);
28435 bodyEl.addClass('x-dlg-icon');
28438 iconEl.replaceClass(iconCls, 'x-hidden');
28439 bodyEl.removeClass('x-dlg-icon');
28446 progress : function(title, msg, progressText){
28453 minWidth: this.minProgressWidth,
28454 progressText: progressText
28460 wait : function(msg, title, config){
28468 minWidth: this.minProgressWidth,
28475 alert : function(title, msg, fn, scope){
28482 minWidth: this.minWidth
28488 confirm : function(title, msg, fn, scope){
28492 buttons: this.YESNO,
28495 icon: this.QUESTION,
28496 minWidth: this.minWidth
28502 prompt : function(title, msg, fn, scope, multiline, value){
28506 buttons: this.OKCANCEL,
28508 minWidth: this.minPromptWidth,
28511 multiline: multiline,
28520 CANCEL : {cancel:true},
28522 OKCANCEL : {ok:true, cancel:true},
28524 YESNO : {yes:true, no:true},
28526 YESNOCANCEL : {yes:true, no:true, cancel:true},
28528 INFO : 'ext-mb-info',
28530 WARNING : 'ext-mb-warning',
28532 QUESTION : 'ext-mb-question',
28534 ERROR : 'ext-mb-error',
28537 defaultTextHeight : 75,
28543 minProgressWidth : 250,
28545 minPromptWidth: 250,
28557 Ext.Msg = Ext.MessageBox;
28558 Ext.dd.PanelProxy = Ext.extend(Object, {
28560 constructor : function(panel, config){
28561 this.panel = panel;
28562 this.id = this.panel.id +'-ddproxy';
28563 Ext.apply(this, config);
28567 insertProxy : true,
28570 setStatus : Ext.emptyFn,
28571 reset : Ext.emptyFn,
28572 update : Ext.emptyFn,
28573 stop : Ext.emptyFn,
28577 getEl : function(){
28582 getGhost : function(){
28587 getProxy : function(){
28595 this.proxy.remove();
28598 this.panel.el.dom.style.display = '';
28599 this.ghost.remove();
28607 this.ghost = this.panel.createGhost(this.panel.initialConfig.cls, undefined, Ext.getBody());
28608 this.ghost.setXY(this.panel.el.getXY());
28609 if(this.insertProxy){
28610 this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
28611 this.proxy.setSize(this.panel.getSize());
28613 this.panel.el.dom.style.display = 'none';
28618 repair : function(xy, callback, scope){
28620 if(typeof callback == "function"){
28621 callback.call(scope || this);
28626 moveProxy : function(parentNode, before){
28628 parentNode.insertBefore(this.proxy.dom, before);
28634 Ext.Panel.DD = Ext.extend(Ext.dd.DragSource, {
28636 constructor : function(panel, cfg){
28637 this.panel = panel;
28638 this.dragData = {panel: panel};
28639 this.proxy = new Ext.dd.PanelProxy(panel, cfg);
28640 Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
28641 var h = panel.header,
28644 this.setHandleElId(h.id);
28647 el.setStyle('cursor', 'move');
28648 this.scroll = false;
28651 showFrame: Ext.emptyFn,
28652 startDrag: Ext.emptyFn,
28653 b4StartDrag: function(x, y) {
28656 b4MouseDown: function(e) {
28657 var x = e.getPageX(),
28659 this.autoOffset(x, y);
28661 onInitDrag : function(x, y){
28662 this.onStartDrag(x, y);
28665 createFrame : Ext.emptyFn,
28666 getDragEl : function(e){
28667 return this.proxy.ghost.dom;
28669 endDrag : function(e){
28671 this.panel.saveState();
28674 autoOffset : function(x, y) {
28675 x -= this.startPageX;
28676 y -= this.startPageY;
28677 this.setDelta(x, y);
28680 Ext.state.Provider = Ext.extend(Ext.util.Observable, {
28682 constructor : function(){
28684 this.addEvents("statechange");
28686 Ext.state.Provider.superclass.constructor.call(this);
28690 get : function(name, defaultValue){
28691 return typeof this.state[name] == "undefined" ?
28692 defaultValue : this.state[name];
28696 clear : function(name){
28697 delete this.state[name];
28698 this.fireEvent("statechange", this, name, null);
28702 set : function(name, value){
28703 this.state[name] = value;
28704 this.fireEvent("statechange", this, name, value);
28708 decodeValue : function(cookie){
28710 var re = /^(a|n|d|b|s|o|e)\:(.*)$/,
28711 matches = re.exec(unescape(cookie)),
28716 if(!matches || !matches[1]){
28725 return parseFloat(v);
28727 return new Date(Date.parse(v));
28733 Ext.each(v.split('^'), function(val){
28734 all.push(this.decodeValue(val));
28741 Ext.each(v.split('^'), function(val){
28742 kv = val.split('=');
28743 all[kv[0]] = this.decodeValue(kv[1]);
28753 encodeValue : function(v){
28761 }else if(typeof v == 'number'){
28763 }else if(typeof v == 'boolean'){
28764 enc = 'b:' + (v ? '1' : '0');
28765 }else if(Ext.isDate(v)){
28766 enc = 'd:' + v.toGMTString();
28767 }else if(Ext.isArray(v)){
28768 for(len = v.length; i < len; i++){
28769 flat += this.encodeValue(v[i]);
28775 }else if(typeof v == 'object'){
28777 if(typeof v[key] != 'function' && v[key] !== undefined){
28778 flat += key + '=' + this.encodeValue(v[key]) + '^';
28781 enc = 'o:' + flat.substring(0, flat.length-1);
28785 return escape(enc);
28789 Ext.state.Manager = function(){
28790 var provider = new Ext.state.Provider();
28794 setProvider : function(stateProvider){
28795 provider = stateProvider;
28799 get : function(key, defaultValue){
28800 return provider.get(key, defaultValue);
28804 set : function(key, value){
28805 provider.set(key, value);
28809 clear : function(key){
28810 provider.clear(key);
28814 getProvider : function(){
28820 Ext.state.CookieProvider = Ext.extend(Ext.state.Provider, {
28822 constructor : function(config){
28823 Ext.state.CookieProvider.superclass.constructor.call(this);
28825 this.expires = new Date(new Date().getTime()+(1000*60*60*24*7));
28826 this.domain = null;
28827 this.secure = false;
28828 Ext.apply(this, config);
28829 this.state = this.readCookies();
28833 set : function(name, value){
28834 if(typeof value == "undefined" || value === null){
28838 this.setCookie(name, value);
28839 Ext.state.CookieProvider.superclass.set.call(this, name, value);
28843 clear : function(name){
28844 this.clearCookie(name);
28845 Ext.state.CookieProvider.superclass.clear.call(this, name);
28849 readCookies : function(){
28851 c = document.cookie + ";",
28852 re = /\s?(.*?)=(.*?);/g,
28856 while((matches = re.exec(c)) != null){
28858 value = matches[2];
28859 if(name && name.substring(0,3) == "ys-"){
28860 cookies[name.substr(3)] = this.decodeValue(value);
28867 setCookie : function(name, value){
28868 document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
28869 ((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +
28870 ((this.path == null) ? "" : ("; path=" + this.path)) +
28871 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
28872 ((this.secure == true) ? "; secure" : "");
28876 clearCookie : function(name){
28877 document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
28878 ((this.path == null) ? "" : ("; path=" + this.path)) +
28879 ((this.domain == null) ? "" : ("; domain=" + this.domain)) +
28880 ((this.secure == true) ? "; secure" : "");
28883 Ext.DataView = Ext.extend(Ext.BoxComponent, {
28893 selectedClass : "x-view-selected",
28898 deferEmptyText: true,
28903 blockRefresh: false,
28909 initComponent : function(){
28910 Ext.DataView.superclass.initComponent.call(this);
28911 if(Ext.isString(this.tpl) || Ext.isArray(this.tpl)){
28912 this.tpl = new Ext.XTemplate(this.tpl);
28931 "containercontextmenu",
28939 this.store = Ext.StoreMgr.lookup(this.store);
28940 this.all = new Ext.CompositeElementLite();
28941 this.selected = new Ext.CompositeElementLite();
28945 afterRender : function(){
28946 Ext.DataView.superclass.afterRender.call(this);
28948 this.mon(this.getTemplateTarget(), {
28949 "click": this.onClick,
28950 "dblclick": this.onDblClick,
28951 "contextmenu": this.onContextMenu,
28955 if(this.overClass || this.trackOver){
28956 this.mon(this.getTemplateTarget(), {
28957 "mouseover": this.onMouseOver,
28958 "mouseout": this.onMouseOut,
28964 this.bindStore(this.store, true);
28969 refresh : function() {
28970 this.clearSelections(false, true);
28971 var el = this.getTemplateTarget(),
28972 records = this.store.getRange();
28975 if(records.length < 1){
28976 if(!this.deferEmptyText || this.hasSkippedEmptyText){
28977 el.update(this.emptyText);
28981 this.tpl.overwrite(el, this.collectData(records, 0));
28982 this.all.fill(Ext.query(this.itemSelector, el.dom));
28983 this.updateIndexes(0);
28985 this.hasSkippedEmptyText = true;
28988 getTemplateTarget: function(){
28993 prepareData : function(data){
28998 collectData : function(records, startIndex){
29001 len = records.length;
29002 for(; i < len; i++){
29003 r[r.length] = this.prepareData(records[i].data, startIndex + i, records[i]);
29009 bufferRender : function(records, index){
29010 var div = document.createElement('div');
29011 this.tpl.overwrite(div, this.collectData(records, index));
29012 return Ext.query(this.itemSelector, div);
29016 onUpdate : function(ds, record){
29017 var index = this.store.indexOf(record);
29019 var sel = this.isSelected(index),
29020 original = this.all.elements[index],
29021 node = this.bufferRender([record], index)[0];
29023 this.all.replaceElement(index, node, true);
29025 this.selected.replaceElement(original, node);
29026 this.all.item(index).addClass(this.selectedClass);
29028 this.updateIndexes(index, index);
29033 onAdd : function(ds, records, index){
29034 if(this.all.getCount() === 0){
29038 var nodes = this.bufferRender(records, index), n, a = this.all.elements;
29039 if(index < this.all.getCount()){
29040 n = this.all.item(index).insertSibling(nodes, 'before', true);
29041 a.splice.apply(a, [index, 0].concat(nodes));
29043 n = this.all.last().insertSibling(nodes, 'after', true);
29044 a.push.apply(a, nodes);
29046 this.updateIndexes(index);
29050 onRemove : function(ds, record, index){
29051 this.deselect(index);
29052 this.all.removeElement(index, true);
29053 this.updateIndexes(index);
29054 if (this.store.getCount() === 0){
29060 refreshNode : function(index){
29061 this.onUpdate(this.store, this.store.getAt(index));
29065 updateIndexes : function(startIndex, endIndex){
29066 var ns = this.all.elements;
29067 startIndex = startIndex || 0;
29068 endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
29069 for(var i = startIndex; i <= endIndex; i++){
29070 ns[i].viewIndex = i;
29075 getStore : function(){
29080 bindStore : function(store, initial){
29081 if(!initial && this.store){
29082 if(store !== this.store && this.store.autoDestroy){
29083 this.store.destroy();
29085 this.store.un("beforeload", this.onBeforeLoad, this);
29086 this.store.un("datachanged", this.onDataChanged, this);
29087 this.store.un("add", this.onAdd, this);
29088 this.store.un("remove", this.onRemove, this);
29089 this.store.un("update", this.onUpdate, this);
29090 this.store.un("clear", this.refresh, this);
29097 store = Ext.StoreMgr.lookup(store);
29100 beforeload: this.onBeforeLoad,
29101 datachanged: this.onDataChanged,
29103 remove: this.onRemove,
29104 update: this.onUpdate,
29105 clear: this.refresh
29108 this.store = store;
29115 onDataChanged: function() {
29116 if (this.blockRefresh !== true) {
29117 this.refresh.apply(this, arguments);
29122 findItemFromChild : function(node){
29123 return Ext.fly(node).findParent(this.itemSelector, this.getTemplateTarget());
29127 onClick : function(e){
29128 var item = e.getTarget(this.itemSelector, this.getTemplateTarget()),
29131 index = this.indexOf(item);
29132 if(this.onItemClick(item, index, e) !== false){
29133 this.fireEvent("click", this, index, item, e);
29136 if(this.fireEvent("containerclick", this, e) !== false){
29137 this.onContainerClick(e);
29142 onContainerClick : function(e){
29143 this.clearSelections();
29147 onContextMenu : function(e){
29148 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
29150 this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
29152 this.fireEvent("containercontextmenu", this, e);
29157 onDblClick : function(e){
29158 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
29160 this.fireEvent("dblclick", this, this.indexOf(item), item, e);
29165 onMouseOver : function(e){
29166 var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
29167 if(item && item !== this.lastItem){
29168 this.lastItem = item;
29169 Ext.fly(item).addClass(this.overClass);
29170 this.fireEvent("mouseenter", this, this.indexOf(item), item, e);
29175 onMouseOut : function(e){
29177 if(!e.within(this.lastItem, true, true)){
29178 Ext.fly(this.lastItem).removeClass(this.overClass);
29179 this.fireEvent("mouseleave", this, this.indexOf(this.lastItem), this.lastItem, e);
29180 delete this.lastItem;
29186 onItemClick : function(item, index, e){
29187 if(this.fireEvent("beforeclick", this, index, item, e) === false){
29190 if(this.multiSelect){
29191 this.doMultiSelection(item, index, e);
29192 e.preventDefault();
29193 }else if(this.singleSelect){
29194 this.doSingleSelection(item, index, e);
29195 e.preventDefault();
29201 doSingleSelection : function(item, index, e){
29202 if(e.ctrlKey && this.isSelected(index)){
29203 this.deselect(index);
29205 this.select(index, false);
29210 doMultiSelection : function(item, index, e){
29211 if(e.shiftKey && this.last !== false){
29212 var last = this.last;
29213 this.selectRange(last, index, e.ctrlKey);
29216 if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){
29217 this.deselect(index);
29219 this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);
29225 getSelectionCount : function(){
29226 return this.selected.getCount();
29230 getSelectedNodes : function(){
29231 return this.selected.elements;
29235 getSelectedIndexes : function(){
29237 selected = this.selected.elements,
29239 len = selected.length;
29241 for(; i < len; i++){
29242 indexes.push(selected[i].viewIndex);
29248 getSelectedRecords : function(){
29249 return this.getRecords(this.selected.elements);
29253 getRecords : function(nodes){
29256 len = nodes.length;
29258 for(; i < len; i++){
29259 records[records.length] = this.store.getAt(nodes[i].viewIndex);
29265 getRecord : function(node){
29266 return this.store.getAt(node.viewIndex);
29270 clearSelections : function(suppressEvent, skipUpdate){
29271 if((this.multiSelect || this.singleSelect) && this.selected.getCount() > 0){
29273 this.selected.removeClass(this.selectedClass);
29275 this.selected.clear();
29277 if(!suppressEvent){
29278 this.fireEvent("selectionchange", this, this.selected.elements);
29284 isSelected : function(node){
29285 return this.selected.contains(this.getNode(node));
29289 deselect : function(node){
29290 if(this.isSelected(node)){
29291 node = this.getNode(node);
29292 this.selected.removeElement(node);
29293 if(this.last == node.viewIndex){
29296 Ext.fly(node).removeClass(this.selectedClass);
29297 this.fireEvent("selectionchange", this, this.selected.elements);
29302 select : function(nodeInfo, keepExisting, suppressEvent){
29303 if(Ext.isArray(nodeInfo)){
29305 this.clearSelections(true);
29307 for(var i = 0, len = nodeInfo.length; i < len; i++){
29308 this.select(nodeInfo[i], true, true);
29310 if(!suppressEvent){
29311 this.fireEvent("selectionchange", this, this.selected.elements);
29314 var node = this.getNode(nodeInfo);
29316 this.clearSelections(true);
29318 if(node && !this.isSelected(node)){
29319 if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){
29320 Ext.fly(node).addClass(this.selectedClass);
29321 this.selected.add(node);
29322 this.last = node.viewIndex;
29323 if(!suppressEvent){
29324 this.fireEvent("selectionchange", this, this.selected.elements);
29332 selectRange : function(start, end, keepExisting){
29334 this.clearSelections(true);
29336 this.select(this.getNodes(start, end), true);
29340 getNode : function(nodeInfo){
29341 if(Ext.isString(nodeInfo)){
29342 return document.getElementById(nodeInfo);
29343 }else if(Ext.isNumber(nodeInfo)){
29344 return this.all.elements[nodeInfo];
29345 }else if(nodeInfo instanceof Ext.data.Record){
29346 var idx = this.store.indexOf(nodeInfo);
29347 return this.all.elements[idx];
29353 getNodes : function(start, end){
29354 var ns = this.all.elements,
29358 start = start || 0;
29359 end = !Ext.isDefined(end) ? Math.max(ns.length - 1, 0) : end;
29361 for(i = start; i <= end && ns[i]; i++){
29365 for(i = start; i >= end && ns[i]; i--){
29373 indexOf : function(node){
29374 node = this.getNode(node);
29375 if(Ext.isNumber(node.viewIndex)){
29376 return node.viewIndex;
29378 return this.all.indexOf(node);
29382 onBeforeLoad : function(){
29383 if(this.loadingText){
29384 this.clearSelections(false, true);
29385 this.getTemplateTarget().update('<div class="loading-indicator">'+this.loadingText+'</div>');
29390 onDestroy : function(){
29392 this.selected.clear();
29393 Ext.DataView.superclass.onDestroy.call(this);
29394 this.bindStore(null);
29399 Ext.DataView.prototype.setStore = Ext.DataView.prototype.bindStore;
29401 Ext.reg('dataview', Ext.DataView);
29403 Ext.list.ListView = Ext.extend(Ext.DataView, {
29407 itemSelector: 'dl',
29409 selectedClass:'x-list-selected',
29411 overClass:'x-list-over',
29414 scrollOffset : undefined,
29416 columnResize: true,
29423 maxColumnWidth: Ext.isIE ? 99 : 100,
29425 initComponent : function(){
29426 if(this.columnResize){
29427 this.colResizer = new Ext.list.ColumnResizer(this.colResizer);
29428 this.colResizer.init(this);
29430 if(this.columnSort){
29431 this.colSorter = new Ext.list.Sorter(this.columnSort);
29432 this.colSorter.init(this);
29434 if(!this.internalTpl){
29435 this.internalTpl = new Ext.XTemplate(
29436 '<div class="x-list-header"><div class="x-list-header-inner">',
29437 '<tpl for="columns">',
29438 '<div style="width:{[values.width*100]}%;text-align:{align};"><em unselectable="on" id="',this.id, '-xlhd-{#}">',
29442 '<div class="x-clear"></div>',
29444 '<div class="x-list-body"><div class="x-list-body-inner">',
29449 this.tpl = new Ext.XTemplate(
29450 '<tpl for="rows">',
29452 '<tpl for="parent.columns">',
29453 '<dt style="width:{[values.width*100]}%;text-align:{align};">',
29454 '<em unselectable="on"<tpl if="cls"> class="{cls}</tpl>">',
29455 '{[values.tpl.apply(parent)]}',
29458 '<div class="x-clear"></div>',
29464 var cs = this.columns,
29465 allocatedWidth = 0,
29470 for(var i = 0; i < len; i++){
29473 c.xtype = c.xtype ? (/^lv/.test(c.xtype) ? c.xtype : 'lv' + c.xtype) : 'lvcolumn';
29477 allocatedWidth += c.width*100;
29478 if(allocatedWidth > this.maxColumnWidth){
29479 c.width -= (allocatedWidth - this.maxColumnWidth) / 100;
29486 cs = this.columns = columns;
29489 if(colsWithWidth < len){
29490 var remaining = len - colsWithWidth;
29491 if(allocatedWidth < this.maxColumnWidth){
29492 var perCol = ((this.maxColumnWidth-allocatedWidth) / remaining)/100;
29493 for(var j = 0; j < len; j++){
29501 Ext.list.ListView.superclass.initComponent.call(this);
29504 onRender : function(){
29508 Ext.list.ListView.superclass.onRender.apply(this, arguments);
29510 this.internalTpl.overwrite(this.el, {columns: this.columns});
29512 this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild);
29513 this.innerHd = Ext.get(this.el.dom.firstChild.firstChild);
29515 if(this.hideHeaders){
29516 this.el.dom.firstChild.style.display = 'none';
29520 getTemplateTarget : function(){
29521 return this.innerBody;
29525 collectData : function(){
29526 var rs = Ext.list.ListView.superclass.collectData.apply(this, arguments);
29528 columns: this.columns,
29533 verifyInternalSize : function(){
29535 this.onResize(this.lastSize.width, this.lastSize.height);
29540 onResize : function(w, h){
29541 var body = this.innerBody.dom,
29542 header = this.innerHd.dom,
29543 scrollWidth = w - Ext.num(this.scrollOffset, Ext.getScrollBarWidth()) + 'px',
29549 parentNode = body.parentNode;
29550 if(Ext.isNumber(w)){
29551 if(this.reserveScrollOffset || ((parentNode.offsetWidth - parentNode.clientWidth) > 10)){
29552 body.style.width = scrollWidth;
29553 header.style.width = scrollWidth;
29555 body.style.width = w + 'px';
29556 header.style.width = w + 'px';
29557 setTimeout(function(){
29558 if((parentNode.offsetWidth - parentNode.clientWidth) > 10){
29559 body.style.width = scrollWidth;
29560 header.style.width = scrollWidth;
29565 if(Ext.isNumber(h)){
29566 parentNode.style.height = Math.max(0, h - header.parentNode.offsetHeight) + 'px';
29570 updateIndexes : function(){
29571 Ext.list.ListView.superclass.updateIndexes.apply(this, arguments);
29572 this.verifyInternalSize();
29575 findHeaderIndex : function(header){
29576 header = header.dom || header;
29577 var parentNode = header.parentNode,
29578 children = parentNode.parentNode.childNodes,
29581 for(; c = children[i]; i++){
29582 if(c == parentNode){
29589 setHdWidths : function(){
29590 var els = this.innerHd.dom.getElementsByTagName('div'),
29592 columns = this.columns,
29593 len = columns.length;
29595 for(; i < len; i++){
29596 els[i].style.width = (columns[i].width*100) + '%';
29601 Ext.reg('listview', Ext.list.ListView);
29604 Ext.ListView = Ext.list.ListView;
29605 Ext.list.Column = Ext.extend(Object, {
29624 constructor : function(c){
29626 c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}');
29628 else if(Ext.isString(c.tpl)){
29629 c.tpl = new Ext.XTemplate(c.tpl);
29632 Ext.apply(this, c);
29636 Ext.reg('lvcolumn', Ext.list.Column);
29639 Ext.list.NumberColumn = Ext.extend(Ext.list.Column, {
29641 format: '0,000.00',
29643 constructor : function(c) {
29644 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':number("' + (c.format || this.format) + '")}');
29645 Ext.list.NumberColumn.superclass.constructor.call(this, c);
29649 Ext.reg('lvnumbercolumn', Ext.list.NumberColumn);
29652 Ext.list.DateColumn = Ext.extend(Ext.list.Column, {
29654 constructor : function(c) {
29655 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':date("' + (c.format || this.format) + '")}');
29656 Ext.list.DateColumn.superclass.constructor.call(this, c);
29659 Ext.reg('lvdatecolumn', Ext.list.DateColumn);
29662 Ext.list.BooleanColumn = Ext.extend(Ext.list.Column, {
29666 falseText: 'false',
29668 undefinedText: ' ',
29670 constructor : function(c) {
29671 c.tpl = c.tpl || new Ext.XTemplate('{' + c.dataIndex + ':this.format}');
29673 var t = this.trueText, f = this.falseText, u = this.undefinedText;
29674 c.tpl.format = function(v){
29675 if(v === undefined){
29678 if(!v || v === 'false'){
29684 Ext.list.DateColumn.superclass.constructor.call(this, c);
29688 Ext.reg('lvbooleancolumn', Ext.list.BooleanColumn);
29689 Ext.list.ColumnResizer = Ext.extend(Ext.util.Observable, {
29693 constructor: function(config){
29694 Ext.apply(this, config);
29695 Ext.list.ColumnResizer.superclass.constructor.call(this);
29697 init : function(listView){
29698 this.view = listView;
29699 listView.on('render', this.initEvents, this);
29702 initEvents : function(view){
29703 view.mon(view.innerHd, 'mousemove', this.handleHdMove, this);
29704 this.tracker = new Ext.dd.DragTracker({
29705 onBeforeStart: this.onBeforeStart.createDelegate(this),
29706 onStart: this.onStart.createDelegate(this),
29707 onDrag: this.onDrag.createDelegate(this),
29708 onEnd: this.onEnd.createDelegate(this),
29712 this.tracker.initEl(view.innerHd);
29713 view.on('beforedestroy', this.tracker.destroy, this.tracker);
29716 handleHdMove : function(e, t){
29717 var handleWidth = 5,
29719 header = e.getTarget('em', 3, true);
29721 var region = header.getRegion(),
29722 style = header.dom.style,
29723 parentNode = header.dom.parentNode;
29725 if(x - region.left <= handleWidth && parentNode != parentNode.parentNode.firstChild){
29726 this.activeHd = Ext.get(parentNode.previousSibling.firstChild);
29727 style.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
29728 } else if(region.right - x <= handleWidth && parentNode != parentNode.parentNode.lastChild.previousSibling){
29729 this.activeHd = header;
29730 style.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
29732 delete this.activeHd;
29738 onBeforeStart : function(e){
29739 this.dragHd = this.activeHd;
29740 return !!this.dragHd;
29743 onStart: function(e){
29747 dragHeader = me.dragHd,
29748 x = me.tracker.getXY()[0];
29750 me.proxy = view.el.createChild({cls:'x-list-resizer'});
29751 me.dragX = dragHeader.getX();
29752 me.headerIndex = view.findHeaderIndex(dragHeader);
29754 me.headersDisabled = view.disableHeaders;
29755 view.disableHeaders = true;
29757 me.proxy.setHeight(view.el.getHeight());
29758 me.proxy.setX(me.dragX);
29759 me.proxy.setWidth(x - me.dragX);
29761 this.setBoundaries();
29766 setBoundaries: function(relativeX){
29767 var view = this.view,
29768 headerIndex = this.headerIndex,
29769 width = view.innerHd.getWidth(),
29770 relativeX = view.innerHd.getX(),
29771 minWidth = Math.ceil(width * this.minPct),
29772 maxWidth = width - minWidth,
29773 numColumns = view.columns.length,
29774 headers = view.innerHd.select('em', true),
29775 minX = minWidth + relativeX,
29776 maxX = maxWidth + relativeX,
29779 if (numColumns == 2) {
29783 header = headers.item(headerIndex + 2);
29784 this.minX = headers.item(headerIndex).getX() + minWidth;
29785 this.maxX = header ? header.getX() - minWidth : maxX;
29786 if (headerIndex == 0) {
29789 } else if (headerIndex == numColumns - 2) {
29796 onDrag: function(e){
29798 cursorX = me.tracker.getXY()[0].constrain(me.minX, me.maxX);
29800 me.proxy.setWidth(cursorX - this.dragX);
29803 onEnd: function(e){
29805 var newWidth = this.proxy.getWidth(),
29806 index = this.headerIndex,
29808 columns = view.columns,
29809 width = view.innerHd.getWidth(),
29810 newPercent = Math.ceil(newWidth * view.maxColumnWidth / width) / 100,
29811 disabled = this.headersDisabled,
29812 headerCol = columns[index],
29813 otherCol = columns[index + 1],
29814 totalPercent = headerCol.width + otherCol.width;
29816 this.proxy.remove();
29818 headerCol.width = newPercent;
29819 otherCol.width = totalPercent - newPercent;
29821 delete this.dragHd;
29822 view.setHdWidths();
29825 setTimeout(function(){
29826 view.disableHeaders = disabled;
29832 Ext.ListView.ColumnResizer = Ext.list.ColumnResizer;
29833 Ext.list.Sorter = Ext.extend(Ext.util.Observable, {
29835 sortClasses : ["sort-asc", "sort-desc"],
29837 constructor: function(config){
29838 Ext.apply(this, config);
29839 Ext.list.Sorter.superclass.constructor.call(this);
29842 init : function(listView){
29843 this.view = listView;
29844 listView.on('render', this.initEvents, this);
29847 initEvents : function(view){
29848 view.mon(view.innerHd, 'click', this.onHdClick, this);
29849 view.innerHd.setStyle('cursor', 'pointer');
29850 view.mon(view.store, 'datachanged', this.updateSortState, this);
29851 this.updateSortState.defer(10, this, [view.store]);
29854 updateSortState : function(store){
29855 var state = store.getSortState();
29859 this.sortState = state;
29860 var cs = this.view.columns, sortColumn = -1;
29861 for(var i = 0, len = cs.length; i < len; i++){
29862 if(cs[i].dataIndex == state.field){
29867 if(sortColumn != -1){
29868 var sortDir = state.direction;
29869 this.updateSortIcon(sortColumn, sortDir);
29873 updateSortIcon : function(col, dir){
29874 var sc = this.sortClasses;
29875 var hds = this.view.innerHd.select('em').removeClass(sc);
29876 hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
29879 onHdClick : function(e){
29880 var hd = e.getTarget('em', 3);
29881 if(hd && !this.view.disableHeaders){
29882 var index = this.view.findHeaderIndex(hd);
29883 this.view.store.sort(this.view.columns[index].dataIndex);
29889 Ext.ListView.Sorter = Ext.list.Sorter;
29890 Ext.TabPanel = Ext.extend(Ext.Panel, {
29894 deferredRender : true,
29900 resizeTabs : false,
29902 enableTabScroll : false,
29904 scrollIncrement : 0,
29906 scrollRepeatInterval : 400,
29908 scrollDuration : 0.35,
29912 tabPosition : 'top',
29914 baseCls : 'x-tab-panel',
29918 autoTabSelector : 'div.x-tab',
29920 activeTab : undefined,
29926 wheelIncrement : 20,
29929 idDelimiter : '__',
29932 itemCls : 'x-tab-item',
29936 headerAsText : false,
29941 initComponent : function(){
29942 this.frame = false;
29943 Ext.TabPanel.superclass.initComponent.call(this);
29953 this.setLayout(new Ext.layout.CardLayout(Ext.apply({
29954 layoutOnCardChange: this.layoutOnTabChange,
29955 deferredRender: this.deferredRender
29956 }, this.layoutConfig)));
29958 if(this.tabPosition == 'top'){
29959 this.elements += ',header';
29960 this.stripTarget = 'header';
29962 this.elements += ',footer';
29963 this.stripTarget = 'footer';
29966 this.stack = Ext.TabPanel.AccessStack();
29972 onRender : function(ct, position){
29973 Ext.TabPanel.superclass.onRender.call(this, ct, position);
29976 var pos = this.tabPosition == 'top' ? 'header' : 'footer';
29977 this[pos].addClass('x-tab-panel-'+pos+'-plain');
29980 var st = this[this.stripTarget];
29982 this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{
29983 tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}});
29985 var beforeEl = (this.tabPosition=='bottom' ? this.stripWrap : null);
29986 st.createChild({cls:'x-tab-strip-spacer'}, beforeEl);
29987 this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
29990 this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge', cn: [{tag: 'span', cls: 'x-tab-strip-text', cn: ' '}]});
29991 this.strip.createChild({cls:'x-clear'});
29993 this.body.addClass('x-tab-panel-body-'+this.tabPosition);
29997 var tt = new Ext.Template(
29998 '<li class="{cls}" id="{id}"><a class="x-tab-strip-close"></a>',
29999 '<a class="x-tab-right" href="#"><em class="x-tab-left">',
30000 '<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
30003 tt.disableFormats = true;
30005 Ext.TabPanel.prototype.itemTpl = tt;
30008 this.items.each(this.initTab, this);
30012 afterRender : function(){
30013 Ext.TabPanel.superclass.afterRender.call(this);
30015 this.readTabs(false);
30017 if(this.activeTab !== undefined){
30018 var item = Ext.isObject(this.activeTab) ? this.activeTab : this.items.get(this.activeTab);
30019 delete this.activeTab;
30020 this.setActiveTab(item);
30025 initEvents : function(){
30026 Ext.TabPanel.superclass.initEvents.call(this);
30027 this.mon(this.strip, {
30029 mousedown: this.onStripMouseDown,
30030 contextmenu: this.onStripContextMenu
30032 if(this.enableTabScroll){
30033 this.mon(this.strip, 'mousewheel', this.onWheel, this);
30038 findTargets : function(e){
30040 itemEl = e.getTarget('li:not(.x-tab-edge)', this.strip);
30043 item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
30053 close : e.getTarget('.x-tab-strip-close', this.strip),
30060 onStripMouseDown : function(e){
30061 if(e.button !== 0){
30064 e.preventDefault();
30065 var t = this.findTargets(e);
30067 if (t.item.fireEvent('beforeclose', t.item) !== false) {
30068 t.item.fireEvent('close', t.item);
30069 this.remove(t.item);
30073 if(t.item && t.item != this.activeTab){
30074 this.setActiveTab(t.item);
30079 onStripContextMenu : function(e){
30080 e.preventDefault();
30081 var t = this.findTargets(e);
30083 this.fireEvent('contextmenu', this, t.item, e);
30088 readTabs : function(removeExisting){
30089 if(removeExisting === true){
30090 this.items.each(function(item){
30094 var tabs = this.el.query(this.autoTabSelector);
30095 for(var i = 0, len = tabs.length; i < len; i++){
30097 title = tab.getAttribute('title');
30098 tab.removeAttribute('title');
30107 initTab : function(item, index){
30108 var before = this.strip.dom.childNodes[index],
30109 p = this.getTemplateArgs(item),
30111 this.itemTpl.insertBefore(before, p) :
30112 this.itemTpl.append(this.strip, p),
30113 cls = 'x-tab-strip-over',
30114 tabEl = Ext.get(el);
30116 tabEl.hover(function(){
30117 if(!item.disabled){
30118 tabEl.addClass(cls);
30121 tabEl.removeClass(cls);
30125 tabEl.child('span.x-tab-strip-text', true).qtip = item.tabTip;
30130 tabEl.select('a').on('click', function(e){
30132 this.onStripMouseDown(e);
30134 }, this, {preventDefault: true});
30138 disable: this.onItemDisabled,
30139 enable: this.onItemEnabled,
30140 titlechange: this.onItemTitleChanged,
30141 iconchange: this.onItemIconChanged,
30142 beforeshow: this.onBeforeShowItem
30149 getTemplateArgs : function(item) {
30150 var cls = item.closable ? 'x-tab-strip-closable' : '';
30152 cls += ' x-item-disabled';
30155 cls += ' x-tab-with-icon';
30158 cls += ' ' + item.tabCls;
30162 id: this.id + this.idDelimiter + item.getItemId(),
30165 iconCls: item.iconCls || ''
30170 onAdd : function(c){
30171 Ext.TabPanel.superclass.onAdd.call(this, c);
30173 var items = this.items;
30174 this.initTab(c, items.indexOf(c));
30175 this.delegateUpdates();
30180 onBeforeAdd : function(item){
30181 var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
30183 this.setActiveTab(item);
30186 Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
30187 var es = item.elements;
30188 item.elements = es ? es.replace(',header', '') : es;
30189 item.border = (item.border === true);
30193 onRemove : function(c){
30194 var te = Ext.get(c.tabEl);
30197 te.select('a').removeAllListeners();
30200 Ext.TabPanel.superclass.onRemove.call(this, c);
30201 this.stack.remove(c);
30203 c.un('disable', this.onItemDisabled, this);
30204 c.un('enable', this.onItemEnabled, this);
30205 c.un('titlechange', this.onItemTitleChanged, this);
30206 c.un('iconchange', this.onItemIconChanged, this);
30207 c.un('beforeshow', this.onBeforeShowItem, this);
30208 if(c == this.activeTab){
30209 var next = this.stack.next();
30211 this.setActiveTab(next);
30212 }else if(this.items.getCount() > 0){
30213 this.setActiveTab(0);
30215 this.setActiveTab(null);
30218 if(!this.destroying){
30219 this.delegateUpdates();
30224 onBeforeShowItem : function(item){
30225 if(item != this.activeTab){
30226 this.setActiveTab(item);
30232 onItemDisabled : function(item){
30233 var el = this.getTabEl(item);
30235 Ext.fly(el).addClass('x-item-disabled');
30237 this.stack.remove(item);
30241 onItemEnabled : function(item){
30242 var el = this.getTabEl(item);
30244 Ext.fly(el).removeClass('x-item-disabled');
30249 onItemTitleChanged : function(item){
30250 var el = this.getTabEl(item);
30252 Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
30257 onItemIconChanged : function(item, iconCls, oldCls){
30258 var el = this.getTabEl(item);
30261 el.child('span.x-tab-strip-text').replaceClass(oldCls, iconCls);
30262 el[Ext.isEmpty(iconCls) ? 'removeClass' : 'addClass']('x-tab-with-icon');
30267 getTabEl : function(item){
30268 var c = this.getComponent(item);
30269 return c ? c.tabEl : null;
30273 onResize : function(){
30274 Ext.TabPanel.superclass.onResize.apply(this, arguments);
30275 this.delegateUpdates();
30279 beginUpdate : function(){
30280 this.suspendUpdates = true;
30284 endUpdate : function(){
30285 this.suspendUpdates = false;
30286 this.delegateUpdates();
30290 hideTabStripItem : function(item){
30291 item = this.getComponent(item);
30292 var el = this.getTabEl(item);
30294 el.style.display = 'none';
30295 this.delegateUpdates();
30297 this.stack.remove(item);
30301 unhideTabStripItem : function(item){
30302 item = this.getComponent(item);
30303 var el = this.getTabEl(item);
30305 el.style.display = '';
30306 this.delegateUpdates();
30311 delegateUpdates : function(){
30312 var rendered = this.rendered;
30313 if(this.suspendUpdates){
30316 if(this.resizeTabs && rendered){
30317 this.autoSizeTabs();
30319 if(this.enableTabScroll && rendered){
30320 this.autoScrollTabs();
30325 autoSizeTabs : function(){
30326 var count = this.items.length,
30327 ce = this.tabPosition != 'bottom' ? 'header' : 'footer',
30328 ow = this[ce].dom.offsetWidth,
30329 aw = this[ce].dom.clientWidth;
30331 if(!this.resizeTabs || count < 1 || !aw){
30335 var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth);
30336 this.lastTabWidth = each;
30337 var lis = this.strip.query('li:not(.x-tab-edge)');
30338 for(var i = 0, len = lis.length; i < len; i++) {
30340 inner = Ext.fly(li).child('.x-tab-strip-inner', true),
30341 tw = li.offsetWidth,
30342 iw = inner.offsetWidth;
30343 inner.style.width = (each - (tw-iw)) + 'px';
30348 adjustBodyWidth : function(w){
30350 this.header.setWidth(w);
30353 this.footer.setWidth(w);
30359 setActiveTab : function(item){
30360 item = this.getComponent(item);
30361 if(this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
30364 if(!this.rendered){
30365 this.activeTab = item;
30368 if(this.activeTab != item){
30369 if(this.activeTab){
30370 var oldEl = this.getTabEl(this.activeTab);
30372 Ext.fly(oldEl).removeClass('x-tab-strip-active');
30375 this.activeTab = item;
30377 var el = this.getTabEl(item);
30378 Ext.fly(el).addClass('x-tab-strip-active');
30379 this.stack.add(item);
30381 this.layout.setActiveItem(item);
30383 this.delegateUpdates();
30384 if(this.scrolling){
30385 this.scrollToTab(item, this.animScroll);
30388 this.fireEvent('tabchange', this, item);
30393 getActiveTab : function(){
30394 return this.activeTab || null;
30398 getItem : function(item){
30399 return this.getComponent(item);
30403 autoScrollTabs : function(){
30404 this.pos = this.tabPosition=='bottom' ? this.footer : this.header;
30405 var count = this.items.length,
30406 ow = this.pos.dom.offsetWidth,
30407 tw = this.pos.dom.clientWidth,
30408 wrap = this.stripWrap,
30410 cw = wd.offsetWidth,
30411 pos = this.getScrollPos(),
30412 l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
30414 if(!this.enableTabScroll || cw < 20){
30417 if(count == 0 || l <= tw){
30421 if(this.scrolling){
30422 this.scrolling = false;
30423 this.pos.removeClass('x-tab-scrolling');
30424 this.scrollLeft.hide();
30425 this.scrollRight.hide();
30427 if(Ext.isAir || Ext.isWebKit){
30428 wd.style.marginLeft = '';
30429 wd.style.marginRight = '';
30433 if(!this.scrolling){
30434 this.pos.addClass('x-tab-scrolling');
30436 if(Ext.isAir || Ext.isWebKit){
30437 wd.style.marginLeft = '18px';
30438 wd.style.marginRight = '18px';
30441 tw -= wrap.getMargins('lr');
30442 wrap.setWidth(tw > 20 ? tw : 20);
30443 if(!this.scrolling){
30444 if(!this.scrollLeft){
30445 this.createScrollers();
30447 this.scrollLeft.show();
30448 this.scrollRight.show();
30451 this.scrolling = true;
30453 wd.scrollLeft = l-tw;
30455 this.scrollToTab(this.activeTab, false);
30457 this.updateScrollButtons();
30462 createScrollers : function(){
30463 this.pos.addClass('x-tab-scrolling-' + this.tabPosition);
30464 var h = this.stripWrap.dom.offsetHeight;
30467 var sl = this.pos.insertFirst({
30468 cls:'x-tab-scroller-left'
30471 sl.addClassOnOver('x-tab-scroller-left-over');
30472 this.leftRepeater = new Ext.util.ClickRepeater(sl, {
30473 interval : this.scrollRepeatInterval,
30474 handler: this.onScrollLeft,
30477 this.scrollLeft = sl;
30480 var sr = this.pos.insertFirst({
30481 cls:'x-tab-scroller-right'
30484 sr.addClassOnOver('x-tab-scroller-right-over');
30485 this.rightRepeater = new Ext.util.ClickRepeater(sr, {
30486 interval : this.scrollRepeatInterval,
30487 handler: this.onScrollRight,
30490 this.scrollRight = sr;
30494 getScrollWidth : function(){
30495 return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
30499 getScrollPos : function(){
30500 return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
30504 getScrollArea : function(){
30505 return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
30509 getScrollAnim : function(){
30510 return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this};
30514 getScrollIncrement : function(){
30515 return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
30520 scrollToTab : function(item, animate){
30524 var el = this.getTabEl(item),
30525 pos = this.getScrollPos(),
30526 area = this.getScrollArea(),
30527 left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos,
30528 right = left + el.offsetWidth;
30530 this.scrollTo(left, animate);
30531 }else if(right > (pos + area)){
30532 this.scrollTo(right - area, animate);
30537 scrollTo : function(pos, animate){
30538 this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
30540 this.updateScrollButtons();
30544 onWheel : function(e){
30545 var d = e.getWheelDelta()*this.wheelIncrement*-1;
30548 var pos = this.getScrollPos(),
30550 sw = this.getScrollWidth()-this.getScrollArea();
30552 var s = Math.max(0, Math.min(sw, newpos));
30554 this.scrollTo(s, false);
30559 onScrollRight : function(){
30560 var sw = this.getScrollWidth()-this.getScrollArea(),
30561 pos = this.getScrollPos(),
30562 s = Math.min(sw, pos + this.getScrollIncrement());
30564 this.scrollTo(s, this.animScroll);
30569 onScrollLeft : function(){
30570 var pos = this.getScrollPos(),
30571 s = Math.max(0, pos - this.getScrollIncrement());
30573 this.scrollTo(s, this.animScroll);
30578 updateScrollButtons : function(){
30579 var pos = this.getScrollPos();
30580 this.scrollLeft[pos === 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
30581 this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
30585 beforeDestroy : function() {
30586 Ext.destroy(this.leftRepeater, this.rightRepeater);
30587 this.deleteMembers('strip', 'edge', 'scrollLeft', 'scrollRight', 'stripWrap');
30588 this.activeTab = null;
30589 Ext.TabPanel.superclass.beforeDestroy.apply(this);
30605 Ext.reg('tabpanel', Ext.TabPanel);
30608 Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;
30611 Ext.TabPanel.AccessStack = function(){
30614 add : function(item){
30616 if(items.length > 10){
30621 remove : function(item){
30623 for(var i = 0, len = items.length; i < len; i++) {
30624 if(items[i] != item){
30632 return items.pop();
30637 Ext.Button = Ext.extend(Ext.BoxComponent, {
30650 enableToggle : false,
30654 menuAlign : 'tl-bl?',
30662 menuClassTarget : 'tr:nth(2)',
30665 clickEvent : 'click',
30668 handleMouseEvents : true,
30671 tooltipType : 'qtip',
30674 buttonSelector : 'button:first-child',
30682 iconAlign : 'left',
30685 arrowAlign : 'right',
30692 initComponent : function(){
30693 Ext.Button.superclass.initComponent.call(this);
30714 this.menu = Ext.menu.MenuMgr.get(this.menu);
30716 if(Ext.isString(this.toggleGroup)){
30717 this.enableToggle = true;
30722 getTemplateArgs : function(){
30723 return [this.type, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass(), this.cls, this.id];
30727 setButtonClass : function(){
30728 if(this.useSetClass){
30729 if(!Ext.isEmpty(this.oldCls)){
30730 this.el.removeClass([this.oldCls, 'x-btn-pressed']);
30732 this.oldCls = (this.iconCls || this.icon) ? (this.text ? 'x-btn-text-icon' : 'x-btn-icon') : 'x-btn-noicon';
30733 this.el.addClass([this.oldCls, this.pressed ? 'x-btn-pressed' : null]);
30738 getMenuClass : function(){
30739 return this.menu ? (this.arrowAlign != 'bottom' ? 'x-btn-arrow' : 'x-btn-arrow-bottom') : '';
30743 onRender : function(ct, position){
30744 if(!this.template){
30745 if(!Ext.Button.buttonTemplate){
30747 Ext.Button.buttonTemplate = new Ext.Template(
30748 '<table id="{4}" cellspacing="0" class="x-btn {3}"><tbody class="{1}">',
30749 '<tr><td class="x-btn-tl"><i> </i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i> </i></td></tr>',
30750 '<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>',
30751 '<tr><td class="x-btn-bl"><i> </i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i> </i></td></tr>',
30752 '</tbody></table>');
30753 Ext.Button.buttonTemplate.compile();
30755 this.template = Ext.Button.buttonTemplate;
30758 var btn, targs = this.getTemplateArgs();
30761 btn = this.template.insertBefore(position, targs, true);
30763 btn = this.template.append(ct, targs, true);
30766 this.btnEl = btn.child(this.buttonSelector);
30767 this.mon(this.btnEl, {
30769 focus: this.onFocus,
30773 this.initButtonEl(btn, this.btnEl);
30775 Ext.ButtonToggleMgr.register(this);
30779 initButtonEl : function(btn, btnEl){
30781 this.setIcon(this.icon);
30782 this.setText(this.text);
30783 this.setIconClass(this.iconCls);
30784 if(Ext.isDefined(this.tabIndex)){
30785 btnEl.dom.tabIndex = this.tabIndex;
30788 this.setTooltip(this.tooltip, true);
30791 if(this.handleMouseEvents){
30794 mouseover: this.onMouseOver,
30795 mousedown: this.onMouseDown
30803 this.mon(this.menu, {
30805 show: this.onMenuShow,
30806 hide: this.onMenuHide
30811 var repeater = new Ext.util.ClickRepeater(btn, Ext.isObject(this.repeat) ? this.repeat : {});
30812 this.mon(repeater, 'click', this.onRepeatClick, this);
30814 this.mon(btn, this.clickEvent, this.onClick, this);
30819 afterRender : function(){
30820 Ext.Button.superclass.afterRender.call(this);
30821 this.useSetClass = true;
30822 this.setButtonClass();
30823 this.doc = Ext.getDoc();
30824 this.doAutoWidth();
30828 setIconClass : function(cls){
30829 this.iconCls = cls;
30831 this.btnEl.dom.className = '';
30832 this.btnEl.addClass(['x-btn-text', cls || '']);
30833 this.setButtonClass();
30839 setTooltip : function(tooltip, initial){
30844 if(Ext.isObject(tooltip)){
30845 Ext.QuickTips.register(Ext.apply({
30846 target: this.btnEl.id
30848 this.tooltip = tooltip;
30850 this.btnEl.dom[this.tooltipType] = tooltip;
30853 this.tooltip = tooltip;
30859 clearTip : function(){
30860 if(Ext.isObject(this.tooltip)){
30861 Ext.QuickTips.unregister(this.btnEl);
30866 beforeDestroy : function(){
30870 if(this.menu && this.destroyMenu !== false) {
30871 Ext.destroy(this.btnEl, this.menu);
30873 Ext.destroy(this.repeater);
30877 onDestroy : function(){
30879 this.doc.un('mouseover', this.monitorMouseOver, this);
30880 this.doc.un('mouseup', this.onMouseUp, this);
30883 Ext.ButtonToggleMgr.unregister(this);
30885 Ext.Button.superclass.onDestroy.call(this);
30889 doAutoWidth : function(){
30890 if(this.autoWidth !== false && this.el && this.text && this.width === undefined){
30891 this.el.setWidth('auto');
30892 if(Ext.isIE7 && Ext.isStrict){
30893 var ib = this.btnEl;
30894 if(ib && ib.getWidth() > 20){
30896 ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
30900 if(this.el.getWidth() < this.minWidth){
30901 this.el.setWidth(this.minWidth);
30908 setHandler : function(handler, scope){
30909 this.handler = handler;
30910 this.scope = scope;
30915 setText : function(text){
30918 this.btnEl.update(text || ' ');
30919 this.setButtonClass();
30921 this.doAutoWidth();
30926 setIcon : function(icon){
30929 this.btnEl.setStyle('background-image', icon ? 'url(' + icon + ')' : '');
30930 this.setButtonClass();
30936 getText : function(){
30941 toggle : function(state, suppressEvent){
30942 state = state === undefined ? !this.pressed : !!state;
30943 if(state != this.pressed){
30945 this.el[state ? 'addClass' : 'removeClass']('x-btn-pressed');
30947 this.pressed = state;
30948 if(!suppressEvent){
30949 this.fireEvent('toggle', this, state);
30950 if(this.toggleHandler){
30951 this.toggleHandler.call(this.scope || this, this, state);
30959 onDisable : function(){
30960 this.onDisableChange(true);
30964 onEnable : function(){
30965 this.onDisableChange(false);
30968 onDisableChange : function(disabled){
30970 if(!Ext.isIE6 || !this.text){
30971 this.el[disabled ? 'addClass' : 'removeClass'](this.disabledClass);
30973 this.el.dom.disabled = disabled;
30975 this.disabled = disabled;
30979 showMenu : function(){
30980 if(this.rendered && this.menu){
30982 Ext.QuickTips.getQuickTip().cancelShow(this.btnEl);
30984 if(this.menu.isVisible()){
30987 this.menu.ownerCt = this;
30988 this.menu.show(this.el, this.menuAlign);
30994 hideMenu : function(){
30995 if(this.hasVisibleMenu()){
31002 hasVisibleMenu : function(){
31003 return this.menu && this.menu.ownerCt == this && this.menu.isVisible();
31007 onRepeatClick : function(repeat, e){
31012 onClick : function(e){
31014 e.preventDefault();
31016 if(e.button !== 0){
31019 if(!this.disabled){
31021 if(this.menu && !this.hasVisibleMenu() && !this.ignoreNextClick){
31024 this.fireEvent('click', this, e);
31027 this.handler.call(this.scope || this, this, e);
31033 doToggle: function(){
31034 if (this.enableToggle && (this.allowDepress !== false || !this.pressed)) {
31040 isMenuTriggerOver : function(e, internal){
31041 return this.menu && !internal;
31045 isMenuTriggerOut : function(e, internal){
31046 return this.menu && !internal;
31050 onMouseOver : function(e){
31051 if(!this.disabled){
31052 var internal = e.within(this.el, true);
31054 this.el.addClass('x-btn-over');
31055 if(!this.monitoringMouseOver){
31056 this.doc.on('mouseover', this.monitorMouseOver, this);
31057 this.monitoringMouseOver = true;
31059 this.fireEvent('mouseover', this, e);
31061 if(this.isMenuTriggerOver(e, internal)){
31062 this.fireEvent('menutriggerover', this, this.menu, e);
31068 monitorMouseOver : function(e){
31069 if(e.target != this.el.dom && !e.within(this.el)){
31070 if(this.monitoringMouseOver){
31071 this.doc.un('mouseover', this.monitorMouseOver, this);
31072 this.monitoringMouseOver = false;
31074 this.onMouseOut(e);
31079 onMouseOut : function(e){
31080 var internal = e.within(this.el) && e.target != this.el.dom;
31081 this.el.removeClass('x-btn-over');
31082 this.fireEvent('mouseout', this, e);
31083 if(this.isMenuTriggerOut(e, internal)){
31084 this.fireEvent('menutriggerout', this, this.menu, e);
31088 focus : function() {
31089 this.btnEl.focus();
31092 blur : function() {
31097 onFocus : function(e){
31098 if(!this.disabled){
31099 this.el.addClass('x-btn-focus');
31103 onBlur : function(e){
31104 this.el.removeClass('x-btn-focus');
31108 getClickEl : function(e, isUp){
31113 onMouseDown : function(e){
31114 if(!this.disabled && e.button === 0){
31115 this.getClickEl(e).addClass('x-btn-click');
31116 this.doc.on('mouseup', this.onMouseUp, this);
31120 onMouseUp : function(e){
31121 if(e.button === 0){
31122 this.getClickEl(e, true).removeClass('x-btn-click');
31123 this.doc.un('mouseup', this.onMouseUp, this);
31127 onMenuShow : function(e){
31128 if(this.menu.ownerCt == this){
31129 this.menu.ownerCt = this;
31130 this.ignoreNextClick = 0;
31131 this.el.addClass('x-btn-menu-active');
31132 this.fireEvent('menushow', this, this.menu);
31136 onMenuHide : function(e){
31137 if(this.menu.ownerCt == this){
31138 this.el.removeClass('x-btn-menu-active');
31139 this.ignoreNextClick = this.restoreClick.defer(250, this);
31140 this.fireEvent('menuhide', this, this.menu);
31141 delete this.menu.ownerCt;
31146 restoreClick : function(){
31147 this.ignoreNextClick = 0;
31157 Ext.reg('button', Ext.Button);
31160 Ext.ButtonToggleMgr = function(){
31163 function toggleGroup(btn, state){
31165 var g = groups[btn.toggleGroup];
31166 for(var i = 0, l = g.length; i < l; i++){
31168 g[i].toggle(false);
31175 register : function(btn){
31176 if(!btn.toggleGroup){
31179 var g = groups[btn.toggleGroup];
31181 g = groups[btn.toggleGroup] = [];
31184 btn.on('toggle', toggleGroup);
31187 unregister : function(btn){
31188 if(!btn.toggleGroup){
31191 var g = groups[btn.toggleGroup];
31194 btn.un('toggle', toggleGroup);
31199 getPressed : function(group){
31200 var g = groups[group];
31202 for(var i = 0, len = g.length; i < len; i++){
31203 if(g[i].pressed === true){
31213 Ext.SplitButton = Ext.extend(Ext.Button, {
31215 arrowSelector : 'em',
31219 initComponent : function(){
31220 Ext.SplitButton.superclass.initComponent.call(this);
31222 this.addEvents("arrowclick");
31226 onRender : function(){
31227 Ext.SplitButton.superclass.onRender.apply(this, arguments);
31228 if(this.arrowTooltip){
31229 this.el.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
31234 setArrowHandler : function(handler, scope){
31235 this.arrowHandler = handler;
31236 this.scope = scope;
31239 getMenuClass : function(){
31240 return 'x-btn-split' + (this.arrowAlign == 'bottom' ? '-bottom' : '');
31243 isClickOnArrow : function(e){
31244 if (this.arrowAlign != 'bottom') {
31245 var visBtn = this.el.child('em.x-btn-split');
31246 var right = visBtn.getRegion().right - visBtn.getPadding('r');
31247 return e.getPageX() > right;
31249 return e.getPageY() > this.btnEl.getRegion().bottom;
31254 onClick : function(e, t){
31255 e.preventDefault();
31256 if(!this.disabled){
31257 if(this.isClickOnArrow(e)){
31258 if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
31261 this.fireEvent("arrowclick", this, e);
31262 if(this.arrowHandler){
31263 this.arrowHandler.call(this.scope || this, this, e);
31267 this.fireEvent("click", this, e);
31269 this.handler.call(this.scope || this, this, e);
31276 isMenuTriggerOver : function(e){
31277 return this.menu && e.target.tagName == this.arrowSelector;
31281 isMenuTriggerOut : function(e, internal){
31282 return this.menu && e.target.tagName != this.arrowSelector;
31286 Ext.reg('splitbutton', Ext.SplitButton);
31287 Ext.CycleButton = Ext.extend(Ext.SplitButton, {
31296 getItemText : function(item){
31297 if(item && this.showText === true){
31299 if(this.prependText){
31300 text += this.prependText;
31309 setActiveItem : function(item, suppressEvent){
31310 if(!Ext.isObject(item)){
31311 item = this.menu.getComponent(item);
31314 if(!this.rendered){
31315 this.text = this.getItemText(item);
31316 this.iconCls = item.iconCls;
31318 var t = this.getItemText(item);
31322 this.setIconClass(item.iconCls);
31324 this.activeItem = item;
31326 item.setChecked(true, false);
31328 if(this.forceIcon){
31329 this.setIconClass(this.forceIcon);
31331 if(!suppressEvent){
31332 this.fireEvent('change', this, item);
31338 getActiveItem : function(){
31339 return this.activeItem;
31343 initComponent : function(){
31349 if(this.changeHandler){
31350 this.on('change', this.changeHandler, this.scope||this);
31351 delete this.changeHandler;
31354 this.itemCount = this.items.length;
31356 this.menu = {cls:'x-cycle-menu', items:[]};
31358 Ext.each(this.items, function(item, i){
31360 group: item.group || this.id,
31362 checkHandler: this.checkHandler,
31364 checked: item.checked || false
31366 this.menu.items.push(item);
31371 Ext.CycleButton.superclass.initComponent.call(this);
31372 this.on('click', this.toggleSelected, this);
31373 this.setActiveItem(checked, true);
31377 checkHandler : function(item, pressed){
31379 this.setActiveItem(item);
31384 toggleSelected : function(){
31392 var nextIdx, checkItem;
31393 for (var i = 1; i < this.itemCount; i++) {
31394 nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
31396 checkItem = m.items.itemAt(nextIdx);
31398 if (!checkItem.disabled) {
31399 checkItem.setChecked(true);
31405 Ext.reg('cycle', Ext.CycleButton);
31406 Ext.Toolbar = function(config){
31407 if(Ext.isArray(config)){
31408 config = {items: config, layout: 'toolbar'};
31410 config = Ext.apply({
31413 if(config.buttons) {
31414 config.items = config.buttons;
31417 Ext.Toolbar.superclass.constructor.call(this, config);
31422 var T = Ext.Toolbar;
31424 Ext.extend(T, Ext.Container, {
31426 defaultType: 'button',
31430 enableOverflow : false,
31436 internalDefaults: {removeMode: 'container', hideParent: true},
31437 toolbarCls: 'x-toolbar',
31439 initComponent : function(){
31440 T.superclass.initComponent.call(this);
31443 this.addEvents('overflowchange');
31447 onRender : function(ct, position){
31449 if(!this.autoCreate){
31450 this.autoCreate = {
31451 cls: this.toolbarCls + ' x-small-editor'
31454 this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
31455 Ext.Toolbar.superclass.onRender.apply(this, arguments);
31462 lookupComponent : function(c){
31463 if(Ext.isString(c)){
31465 c = new T.Separator();
31466 }else if(c == ' '){
31467 c = new T.Spacer();
31468 }else if(c == '->'){
31471 c = new T.TextItem(c);
31473 this.applyDefaults(c);
31475 if(c.isFormField || c.render){
31476 c = this.createComponent(c);
31478 c = new T.Item({autoEl: c});
31479 }else if(c.tagName){
31480 c = new T.Item({el:c});
31481 }else if(Ext.isObject(c)){
31482 c = c.xtype ? this.createComponent(c) : this.constructButton(c);
31489 applyDefaults : function(c){
31490 if(!Ext.isString(c)){
31491 c = Ext.Toolbar.superclass.applyDefaults.call(this, c);
31492 var d = this.internalDefaults;
31494 Ext.applyIf(c.initialConfig, d);
31504 addSeparator : function(){
31505 return this.add(new T.Separator());
31509 addSpacer : function(){
31510 return this.add(new T.Spacer());
31514 addFill : function(){
31515 this.add(new T.Fill());
31519 addElement : function(el){
31520 return this.addItem(new T.Item({el:el}));
31524 addItem : function(item){
31525 return this.add.apply(this, arguments);
31529 addButton : function(config){
31530 if(Ext.isArray(config)){
31532 for(var i = 0, len = config.length; i < len; i++) {
31533 buttons.push(this.addButton(config[i]));
31537 return this.add(this.constructButton(config));
31541 addText : function(text){
31542 return this.addItem(new T.TextItem(text));
31546 addDom : function(config){
31547 return this.add(new T.Item({autoEl: config}));
31551 addField : function(field){
31552 return this.add(field);
31556 insertButton : function(index, item){
31557 if(Ext.isArray(item)){
31559 for(var i = 0, len = item.length; i < len; i++) {
31560 buttons.push(this.insertButton(index + i, item[i]));
31564 return Ext.Toolbar.superclass.insert.call(this, index, item);
31568 trackMenu : function(item, remove){
31569 if(this.trackMenus && item.menu){
31570 var method = remove ? 'mun' : 'mon';
31571 this[method](item, 'menutriggerover', this.onButtonTriggerOver, this);
31572 this[method](item, 'menushow', this.onButtonMenuShow, this);
31573 this[method](item, 'menuhide', this.onButtonMenuHide, this);
31578 constructButton : function(item){
31579 var b = item.events ? item : this.createComponent(item, item.split ? 'splitbutton' : this.defaultType);
31584 onAdd : function(c){
31585 Ext.Toolbar.superclass.onAdd.call(this);
31593 onRemove : function(c){
31594 Ext.Toolbar.superclass.onRemove.call(this);
31595 if (c == this.activeMenuBtn) {
31596 delete this.activeMenuBtn;
31598 this.trackMenu(c, true);
31602 onDisable : function(){
31603 this.items.each(function(item){
31611 onEnable : function(){
31612 this.items.each(function(item){
31620 onButtonTriggerOver : function(btn){
31621 if(this.activeMenuBtn && this.activeMenuBtn != btn){
31622 this.activeMenuBtn.hideMenu();
31624 this.activeMenuBtn = btn;
31629 onButtonMenuShow : function(btn){
31630 this.activeMenuBtn = btn;
31634 onButtonMenuHide : function(btn){
31635 delete this.activeMenuBtn;
31638 Ext.reg('toolbar', Ext.Toolbar);
31641 T.Item = Ext.extend(Ext.BoxComponent, {
31643 enable:Ext.emptyFn,
31644 disable:Ext.emptyFn,
31648 Ext.reg('tbitem', T.Item);
31651 T.Separator = Ext.extend(T.Item, {
31652 onRender : function(ct, position){
31653 this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position);
31656 Ext.reg('tbseparator', T.Separator);
31659 T.Spacer = Ext.extend(T.Item, {
31662 onRender : function(ct, position){
31663 this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position);
31666 Ext.reg('tbspacer', T.Spacer);
31669 T.Fill = Ext.extend(T.Item, {
31671 render : Ext.emptyFn,
31674 Ext.reg('tbfill', T.Fill);
31677 T.TextItem = Ext.extend(T.Item, {
31680 constructor: function(config){
31681 T.TextItem.superclass.constructor.call(this, Ext.isString(config) ? {text: config} : config);
31685 onRender : function(ct, position) {
31686 this.autoEl = {cls: 'xtb-text', html: this.text || ''};
31687 T.TextItem.superclass.onRender.call(this, ct, position);
31691 setText : function(t) {
31699 Ext.reg('tbtext', T.TextItem);
31702 T.Button = Ext.extend(Ext.Button, {});
31703 T.SplitButton = Ext.extend(Ext.SplitButton, {});
31704 Ext.reg('tbbutton', T.Button);
31705 Ext.reg('tbsplit', T.SplitButton);
31709 Ext.ButtonGroup = Ext.extend(Ext.Panel, {
31712 baseCls: 'x-btn-group',
31715 defaultType: 'button',
31718 internalDefaults: {removeMode: 'container', hideParent: true},
31720 initComponent : function(){
31721 this.layoutConfig = this.layoutConfig || {};
31722 Ext.applyIf(this.layoutConfig, {
31723 columns : this.columns
31726 this.addClass('x-btn-group-notitle');
31728 this.on('afterlayout', this.onAfterLayout, this);
31729 Ext.ButtonGroup.superclass.initComponent.call(this);
31732 applyDefaults : function(c){
31733 c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c);
31734 var d = this.internalDefaults;
31736 Ext.applyIf(c.initialConfig, d);
31744 onAfterLayout : function(){
31745 var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth;
31746 this.body.setWidth(bodyWidth);
31747 this.el.setWidth(bodyWidth + this.getFrameWidth());
31752 Ext.reg('buttongroup', Ext.ButtonGroup);
31756 var T = Ext.Toolbar;
31758 Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
31765 displayMsg : 'Displaying {0} - {1} of {2}',
31767 emptyMsg : 'No data to display',
31769 beforePageText : 'Page',
31771 afterPageText : 'of {0}',
31773 firstText : 'First Page',
31775 prevText : 'Previous Page',
31777 nextText : 'Next Page',
31779 lastText : 'Last Page',
31781 refreshText : 'Refresh',
31789 initComponent : function(){
31790 var pagingItems = [this.first = new T.Button({
31791 tooltip: this.firstText,
31792 overflowText: this.firstText,
31793 iconCls: 'x-tbar-page-first',
31795 handler: this.moveFirst,
31797 }), this.prev = new T.Button({
31798 tooltip: this.prevText,
31799 overflowText: this.prevText,
31800 iconCls: 'x-tbar-page-prev',
31802 handler: this.movePrevious,
31804 }), '-', this.beforePageText,
31805 this.inputItem = new Ext.form.NumberField({
31806 cls: 'x-tbar-page-number',
31807 allowDecimals: false,
31808 allowNegative: false,
31809 enableKeyEvents: true,
31810 selectOnFocus: true,
31811 submitValue: false,
31814 keydown: this.onPagingKeyDown,
31815 blur: this.onPagingBlur
31817 }), this.afterTextItem = new T.TextItem({
31818 text: String.format(this.afterPageText, 1)
31819 }), '-', this.next = new T.Button({
31820 tooltip: this.nextText,
31821 overflowText: this.nextText,
31822 iconCls: 'x-tbar-page-next',
31824 handler: this.moveNext,
31826 }), this.last = new T.Button({
31827 tooltip: this.lastText,
31828 overflowText: this.lastText,
31829 iconCls: 'x-tbar-page-last',
31831 handler: this.moveLast,
31833 }), '-', this.refresh = new T.Button({
31834 tooltip: this.refreshText,
31835 overflowText: this.refreshText,
31836 iconCls: 'x-tbar-loading',
31837 handler: this.doRefresh,
31842 var userItems = this.items || this.buttons || [];
31843 if (this.prependButtons) {
31844 this.items = userItems.concat(pagingItems);
31846 this.items = pagingItems.concat(userItems);
31848 delete this.buttons;
31849 if(this.displayInfo){
31850 this.items.push('->');
31851 this.items.push(this.displayItem = new T.TextItem({}));
31853 Ext.PagingToolbar.superclass.initComponent.call(this);
31860 this.on('afterlayout', this.onFirstLayout, this, {single: true});
31862 this.bindStore(this.store, true);
31866 onFirstLayout : function(){
31868 this.onLoad.apply(this, this.dsLoaded);
31873 updateInfo : function(){
31874 if(this.displayItem){
31875 var count = this.store.getCount();
31876 var msg = count == 0 ?
31880 this.cursor+1, this.cursor+count, this.store.getTotalCount()
31882 this.displayItem.setText(msg);
31887 onLoad : function(store, r, o){
31888 if(!this.rendered){
31889 this.dsLoaded = [store, r, o];
31892 var p = this.getParams();
31893 this.cursor = (o.params && o.params[p.start]) ? o.params[p.start] : 0;
31894 var d = this.getPageData(), ap = d.activePage, ps = d.pages;
31896 this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
31897 this.inputItem.setValue(ap);
31898 this.first.setDisabled(ap == 1);
31899 this.prev.setDisabled(ap == 1);
31900 this.next.setDisabled(ap == ps);
31901 this.last.setDisabled(ap == ps);
31902 this.refresh.enable();
31904 this.fireEvent('change', this, d);
31908 getPageData : function(){
31909 var total = this.store.getTotalCount();
31912 activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
31913 pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
31918 changePage : function(page){
31919 this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount()));
31923 onLoadError : function(){
31924 if(!this.rendered){
31927 this.refresh.enable();
31931 readPage : function(d){
31932 var v = this.inputItem.getValue(), pageNum;
31933 if (!v || isNaN(pageNum = parseInt(v, 10))) {
31934 this.inputItem.setValue(d.activePage);
31940 onPagingFocus : function(){
31941 this.inputItem.select();
31945 onPagingBlur : function(e){
31946 this.inputItem.setValue(this.getPageData().activePage);
31950 onPagingKeyDown : function(field, e){
31951 var k = e.getKey(), d = this.getPageData(), pageNum;
31952 if (k == e.RETURN) {
31954 pageNum = this.readPage(d);
31955 if(pageNum !== false){
31956 pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
31957 this.doLoad(pageNum * this.pageSize);
31959 }else if (k == e.HOME || k == e.END){
31961 pageNum = k == e.HOME ? 1 : d.pages;
31962 field.setValue(pageNum);
31963 }else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
31965 if((pageNum = this.readPage(d))){
31966 var increment = e.shiftKey ? 10 : 1;
31967 if(k == e.DOWN || k == e.PAGEDOWN){
31970 pageNum += increment;
31971 if(pageNum >= 1 & pageNum <= d.pages){
31972 field.setValue(pageNum);
31979 getParams : function(){
31981 return this.paramNames || this.store.paramNames;
31985 beforeLoad : function(){
31986 if(this.rendered && this.refresh){
31987 this.refresh.disable();
31992 doLoad : function(start){
31993 var o = {}, pn = this.getParams();
31994 o[pn.start] = start;
31995 o[pn.limit] = this.pageSize;
31996 if(this.fireEvent('beforechange', this, o) !== false){
31997 this.store.load({params:o});
32002 moveFirst : function(){
32007 movePrevious : function(){
32008 this.doLoad(Math.max(0, this.cursor-this.pageSize));
32012 moveNext : function(){
32013 this.doLoad(this.cursor+this.pageSize);
32017 moveLast : function(){
32018 var total = this.store.getTotalCount(),
32019 extra = total % this.pageSize;
32021 this.doLoad(extra ? (total - extra) : total - this.pageSize);
32025 doRefresh : function(){
32026 this.doLoad(this.cursor);
32030 bindStore : function(store, initial){
32032 if(!initial && this.store){
32033 if(store !== this.store && this.store.autoDestroy){
32034 this.store.destroy();
32036 this.store.un('beforeload', this.beforeLoad, this);
32037 this.store.un('load', this.onLoad, this);
32038 this.store.un('exception', this.onLoadError, this);
32045 store = Ext.StoreMgr.lookup(store);
32048 beforeload: this.beforeLoad,
32050 exception: this.onLoadError
32054 this.store = store;
32056 this.onLoad(store, null, {});
32061 unbind : function(store){
32062 this.bindStore(null);
32066 bind : function(store){
32067 this.bindStore(store);
32071 onDestroy : function(){
32072 this.bindStore(null);
32073 Ext.PagingToolbar.superclass.onDestroy.call(this);
32078 Ext.reg('paging', Ext.PagingToolbar);
32079 Ext.History = (function () {
32080 var iframe, hiddenField;
32084 function getHash() {
32085 var href = location.href, i = href.indexOf("#");
32086 return i >= 0 ? href.substr(i + 1) : null;
32089 function doSave() {
32090 hiddenField.value = currentToken;
32093 function handleStateChange(token) {
32094 currentToken = token;
32095 Ext.History.fireEvent('change', token);
32098 function updateIFrame (token) {
32099 var html = ['<html><body><div id="state">',Ext.util.Format.htmlEncode(token),'</div></body></html>'].join('');
32101 var doc = iframe.contentWindow.document;
32111 function checkIFrame() {
32112 if (!iframe.contentWindow || !iframe.contentWindow.document) {
32113 setTimeout(checkIFrame, 10);
32117 var doc = iframe.contentWindow.document;
32118 var elem = doc.getElementById("state");
32119 var token = elem ? elem.innerText : null;
32121 var hash = getHash();
32123 setInterval(function () {
32125 doc = iframe.contentWindow.document;
32126 elem = doc.getElementById("state");
32128 var newtoken = elem ? elem.innerText : null;
32130 var newHash = getHash();
32132 if (newtoken !== token) {
32134 handleStateChange(token);
32135 top.location.hash = token;
32138 } else if (newHash !== hash) {
32140 updateIFrame(newHash);
32147 Ext.History.fireEvent('ready', Ext.History);
32150 function startUp() {
32151 currentToken = hiddenField.value ? hiddenField.value : getHash();
32156 var hash = getHash();
32157 setInterval(function () {
32158 var newHash = getHash();
32159 if (newHash !== hash) {
32161 handleStateChange(hash);
32166 Ext.History.fireEvent('ready', Ext.History);
32172 fieldId: 'x-history-field',
32174 iframeId: 'x-history-frame',
32179 init: function (onReady, scope) {
32181 Ext.callback(onReady, scope, [this]);
32185 Ext.onReady(function(){
32186 Ext.History.init(onReady, scope);
32190 hiddenField = Ext.getDom(Ext.History.fieldId);
32192 iframe = Ext.getDom(Ext.History.iframeId);
32201 this.on('ready', onReady, scope, {single:true});
32207 add: function (token, preventDup) {
32208 if(preventDup !== false){
32209 if(this.getToken() == token){
32214 return updateIFrame(token);
32216 top.location.hash = token;
32227 forward: function(){
32232 getToken: function() {
32233 return ready ? currentToken : getHash();
32237 Ext.apply(Ext.History, new Ext.util.Observable());
32238 Ext.Tip = Ext.extend(Ext.Panel, {
32248 defaultAlign : "tl-bl?",
32250 quickShowInterval : 250,
32256 floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
32259 closeAction: 'hide',
32262 initComponent : function(){
32263 Ext.Tip.superclass.initComponent.call(this);
32264 if(this.closable && !this.title){
32265 this.elements += ',header';
32270 afterRender : function(){
32271 Ext.Tip.superclass.afterRender.call(this);
32275 handler: this[this.closeAction],
32282 showAt : function(xy){
32283 Ext.Tip.superclass.show.call(this);
32284 if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
32285 this.doAutoWidth();
32287 if(this.constrainPosition){
32288 xy = this.el.adjustForConstraints(xy);
32290 this.setPagePosition(xy[0], xy[1]);
32294 doAutoWidth : function(adjust){
32295 adjust = adjust || 0;
32296 var bw = this.body.getTextWidth();
32298 bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
32300 bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr") + adjust;
32301 this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
32304 if(Ext.isIE7 && !this.repainted){
32306 this.repainted = true;
32311 showBy : function(el, pos){
32312 if(!this.rendered){
32313 this.render(Ext.getBody());
32315 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
32318 initDraggable : function(){
32319 this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
32320 this.header.addClass('x-tip-draggable');
32324 Ext.reg('tip', Ext.Tip);
32327 Ext.Tip.DD = function(tip, config){
32328 Ext.apply(this, config);
32330 Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
32331 this.setHandleElId(tip.header.id);
32332 this.scroll = false;
32335 Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
32338 headerOffsets:[100, 25],
32339 startDrag : function(){
32340 this.tip.el.disableShadow();
32342 endDrag : function(e){
32343 this.tip.el.enableShadow(true);
32346 Ext.ToolTip = Ext.extend(Ext.Tip, {
32355 dismissDelay : 5000,
32358 trackMouse : false,
32360 anchorToTarget : true,
32368 constrainPosition : false,
32371 initComponent : function(){
32372 Ext.ToolTip.superclass.initComponent.call(this);
32373 this.lastActive = new Date();
32374 this.initTarget(this.target);
32375 this.origAnchor = this.anchor;
32379 onRender : function(ct, position){
32380 Ext.ToolTip.superclass.onRender.call(this, ct, position);
32381 this.anchorCls = 'x-tip-anchor-' + this.getAnchorPosition();
32382 this.anchorEl = this.el.createChild({
32383 cls: 'x-tip-anchor ' + this.anchorCls
32388 afterRender : function(){
32389 Ext.ToolTip.superclass.afterRender.call(this);
32390 this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1).setVisibilityMode(Ext.Element.DISPLAY);
32394 initTarget : function(target){
32396 if((t = Ext.get(target))){
32398 var tg = Ext.get(this.target);
32399 this.mun(tg, 'mouseover', this.onTargetOver, this);
32400 this.mun(tg, 'mouseout', this.onTargetOut, this);
32401 this.mun(tg, 'mousemove', this.onMouseMove, this);
32404 mouseover: this.onTargetOver,
32405 mouseout: this.onTargetOut,
32406 mousemove: this.onMouseMove,
32412 this.anchorTarget = this.target;
32417 onMouseMove : function(e){
32418 var t = this.delegate ? e.getTarget(this.delegate) : this.triggerElement = true;
32420 this.targetXY = e.getXY();
32421 if (t === this.triggerElement) {
32422 if(!this.hidden && this.trackMouse){
32423 this.setPagePosition(this.getTargetXY());
32427 this.lastActive = new Date(0);
32428 this.onTargetOver(e);
32430 } else if (!this.closable && this.isVisible()) {
32436 getTargetXY : function(){
32438 this.anchorTarget = this.triggerElement;
32441 this.targetCounter++;
32442 var offsets = this.getOffsets(),
32443 xy = (this.anchorToTarget && !this.trackMouse) ? this.el.getAlignToXY(this.anchorTarget, this.getAnchorAlign()) : this.targetXY,
32444 dw = Ext.lib.Dom.getViewWidth() - 5,
32445 dh = Ext.lib.Dom.getViewHeight() - 5,
32446 de = document.documentElement,
32447 bd = document.body,
32448 scrollX = (de.scrollLeft || bd.scrollLeft || 0) + 5,
32449 scrollY = (de.scrollTop || bd.scrollTop || 0) + 5,
32450 axy = [xy[0] + offsets[0], xy[1] + offsets[1]],
32451 sz = this.getSize();
32453 this.anchorEl.removeClass(this.anchorCls);
32455 if(this.targetCounter < 2){
32456 if(axy[0] < scrollX){
32457 if(this.anchorToTarget){
32458 this.defaultAlign = 'l-r';
32459 if(this.mouseOffset){this.mouseOffset[0] *= -1;}
32461 this.anchor = 'left';
32462 return this.getTargetXY();
32464 if(axy[0]+sz.width > dw){
32465 if(this.anchorToTarget){
32466 this.defaultAlign = 'r-l';
32467 if(this.mouseOffset){this.mouseOffset[0] *= -1;}
32469 this.anchor = 'right';
32470 return this.getTargetXY();
32472 if(axy[1] < scrollY){
32473 if(this.anchorToTarget){
32474 this.defaultAlign = 't-b';
32475 if(this.mouseOffset){this.mouseOffset[1] *= -1;}
32477 this.anchor = 'top';
32478 return this.getTargetXY();
32480 if(axy[1]+sz.height > dh){
32481 if(this.anchorToTarget){
32482 this.defaultAlign = 'b-t';
32483 if(this.mouseOffset){this.mouseOffset[1] *= -1;}
32485 this.anchor = 'bottom';
32486 return this.getTargetXY();
32490 this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition();
32491 this.anchorEl.addClass(this.anchorCls);
32492 this.targetCounter = 0;
32495 var mouseOffset = this.getMouseOffset();
32496 return [this.targetXY[0]+mouseOffset[0], this.targetXY[1]+mouseOffset[1]];
32500 getMouseOffset : function(){
32501 var offset = this.anchor ? [0,0] : [15,18];
32502 if(this.mouseOffset){
32503 offset[0] += this.mouseOffset[0];
32504 offset[1] += this.mouseOffset[1];
32510 getAnchorPosition : function(){
32512 this.tipAnchor = this.anchor.charAt(0);
32514 var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);
32516 throw 'AnchorTip.defaultAlign is invalid';
32518 this.tipAnchor = m[1].charAt(0);
32521 switch(this.tipAnchor){
32522 case 't': return 'top';
32523 case 'b': return 'bottom';
32524 case 'r': return 'right';
32530 getAnchorAlign : function(){
32531 switch(this.anchor){
32532 case 'top' : return 'tl-bl';
32533 case 'left' : return 'tl-tr';
32534 case 'right': return 'tr-tl';
32535 default : return 'bl-tl';
32540 getOffsets : function(){
32542 ap = this.getAnchorPosition().charAt(0);
32543 if(this.anchorToTarget && !this.trackMouse){
32549 offsets = [0, -13];
32552 offsets = [-13, 0];
32561 offsets = [-15-this.anchorOffset, 30];
32564 offsets = [-19-this.anchorOffset, -13-this.el.dom.offsetHeight];
32567 offsets = [-15-this.el.dom.offsetWidth, -13-this.anchorOffset];
32570 offsets = [25, -13-this.anchorOffset];
32574 var mouseOffset = this.getMouseOffset();
32575 offsets[0] += mouseOffset[0];
32576 offsets[1] += mouseOffset[1];
32582 onTargetOver : function(e){
32583 if(this.disabled || e.within(this.target.dom, true)){
32586 var t = e.getTarget(this.delegate);
32588 this.triggerElement = t;
32589 this.clearTimer('hide');
32590 this.targetXY = e.getXY();
32596 delayShow : function(){
32597 if(this.hidden && !this.showTimer){
32598 if(this.lastActive.getElapsed() < this.quickShowInterval){
32601 this.showTimer = this.show.defer(this.showDelay, this);
32603 }else if(!this.hidden && this.autoHide !== false){
32609 onTargetOut : function(e){
32610 if(this.disabled || e.within(this.target.dom, true)){
32613 this.clearTimer('show');
32614 if(this.autoHide !== false){
32620 delayHide : function(){
32621 if(!this.hidden && !this.hideTimer){
32622 this.hideTimer = this.hide.defer(this.hideDelay, this);
32628 this.clearTimer('dismiss');
32629 this.lastActive = new Date();
32631 this.anchorEl.hide();
32633 Ext.ToolTip.superclass.hide.call(this);
32634 delete this.triggerElement;
32642 this.showAt([-1000,-1000]);
32643 this.origConstrainPosition = this.constrainPosition;
32644 this.constrainPosition = false;
32645 this.anchor = this.origAnchor;
32647 this.showAt(this.getTargetXY());
32650 this.anchorEl.show();
32652 this.constrainPosition = this.origConstrainPosition;
32654 this.anchorEl.hide();
32659 showAt : function(xy){
32660 this.lastActive = new Date();
32661 this.clearTimers();
32662 Ext.ToolTip.superclass.showAt.call(this, xy);
32663 if(this.dismissDelay && this.autoHide !== false){
32664 this.dismissTimer = this.hide.defer(this.dismissDelay, this);
32666 if(this.anchor && !this.anchorEl.isVisible()){
32668 this.anchorEl.show();
32670 this.anchorEl.hide();
32675 syncAnchor : function(){
32676 var anchorPos, targetPos, offset;
32677 switch(this.tipAnchor.charAt(0)){
32681 offset = [20+this.anchorOffset, 2];
32686 offset = [-2, 11+this.anchorOffset];
32691 offset = [20+this.anchorOffset, -2];
32696 offset = [2, 11+this.anchorOffset];
32699 this.anchorEl.alignTo(this.el, anchorPos+'-'+targetPos, offset);
32703 setPagePosition : function(x, y){
32704 Ext.ToolTip.superclass.setPagePosition.call(this, x, y);
32711 clearTimer : function(name){
32712 name = name + 'Timer';
32713 clearTimeout(this[name]);
32718 clearTimers : function(){
32719 this.clearTimer('show');
32720 this.clearTimer('dismiss');
32721 this.clearTimer('hide');
32725 onShow : function(){
32726 Ext.ToolTip.superclass.onShow.call(this);
32727 Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
32731 onHide : function(){
32732 Ext.ToolTip.superclass.onHide.call(this);
32733 Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
32737 onDocMouseDown : function(e){
32738 if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){
32740 this.doEnable.defer(100, this);
32745 doEnable : function(){
32746 if(!this.isDestroyed){
32752 onDisable : function(){
32753 this.clearTimers();
32758 adjustPosition : function(x, y){
32759 if(this.contstrainPosition){
32760 var ay = this.targetXY[1], h = this.getSize().height;
32761 if(y <= ay && (y+h) >= ay){
32765 return {x : x, y: y};
32768 beforeDestroy : function(){
32769 this.clearTimers();
32770 Ext.destroy(this.anchorEl);
32771 delete this.anchorEl;
32772 delete this.target;
32773 delete this.anchorTarget;
32774 delete this.triggerElement;
32775 Ext.ToolTip.superclass.beforeDestroy.call(this);
32779 onDestroy : function(){
32780 Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
32781 Ext.ToolTip.superclass.onDestroy.call(this);
32785 Ext.reg('tooltip', Ext.ToolTip);
32786 Ext.QuickTip = Ext.extend(Ext.ToolTip, {
32789 interceptTitles : false,
32794 attribute : "qtip",
32805 initComponent : function(){
32806 this.target = this.target || Ext.getDoc();
32807 this.targets = this.targets || {};
32808 Ext.QuickTip.superclass.initComponent.call(this);
32812 register : function(config){
32813 var cs = Ext.isArray(config) ? config : arguments;
32814 for(var i = 0, len = cs.length; i < len; i++){
32816 var target = c.target;
32818 if(Ext.isArray(target)){
32819 for(var j = 0, jlen = target.length; j < jlen; j++){
32820 this.targets[Ext.id(target[j])] = c;
32823 this.targets[Ext.id(target)] = c;
32830 unregister : function(el){
32831 delete this.targets[Ext.id(el)];
32835 cancelShow: function(el){
32836 var at = this.activeTarget;
32837 el = Ext.get(el).dom;
32838 if(this.isVisible()){
32839 if(at && at.el == el){
32842 }else if(at && at.el == el){
32843 this.clearTimer('show');
32847 getTipCfg: function(e) {
32848 var t = e.getTarget(),
32851 if(this.interceptTitles && t.title && Ext.isString(t.title)){
32854 t.removeAttribute("title");
32855 e.preventDefault();
32857 cfg = this.tagConfig;
32858 ttp = t.qtip || Ext.fly(t).getAttribute(cfg.attribute, cfg.namespace);
32864 onTargetOver : function(e){
32868 this.targetXY = e.getXY();
32869 var t = e.getTarget();
32870 if(!t || t.nodeType !== 1 || t == document || t == document.body){
32873 if(this.activeTarget && ((t == this.activeTarget.el) || Ext.fly(this.activeTarget.el).contains(t))){
32874 this.clearTimer('hide');
32878 if(t && this.targets[t.id]){
32879 this.activeTarget = this.targets[t.id];
32880 this.activeTarget.el = t;
32881 this.anchor = this.activeTarget.anchor;
32883 this.anchorTarget = t;
32888 var ttp, et = Ext.fly(t), cfg = this.tagConfig, ns = cfg.namespace;
32889 if(ttp = this.getTipCfg(e)){
32890 var autoHide = et.getAttribute(cfg.hide, ns);
32891 this.activeTarget = {
32894 width: et.getAttribute(cfg.width, ns),
32895 autoHide: autoHide != "user" && autoHide !== 'false',
32896 title: et.getAttribute(cfg.title, ns),
32897 cls: et.getAttribute(cfg.cls, ns),
32898 align: et.getAttribute(cfg.align, ns)
32901 this.anchor = et.getAttribute(cfg.anchor, ns);
32903 this.anchorTarget = t;
32910 onTargetOut : function(e){
32913 if (this.activeTarget && e.within(this.activeTarget.el) && !this.getTipCfg(e)) {
32917 this.clearTimer('show');
32918 if(this.autoHide !== false){
32924 showAt : function(xy){
32925 var t = this.activeTarget;
32927 if(!this.rendered){
32928 this.render(Ext.getBody());
32929 this.activeTarget = t;
32932 this.setWidth(t.width);
32933 this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
32934 this.measureWidth = false;
32936 this.measureWidth = true;
32938 this.setTitle(t.title || '');
32939 this.body.update(t.text);
32940 this.autoHide = t.autoHide;
32941 this.dismissDelay = t.dismissDelay || this.dismissDelay;
32943 this.el.removeClass(this.lastCls);
32944 delete this.lastCls;
32947 this.el.addClass(t.cls);
32948 this.lastCls = t.cls;
32951 this.constrainPosition = false;
32953 xy = this.el.getAlignToXY(t.el, t.align);
32954 this.constrainPosition = false;
32956 this.constrainPosition = true;
32959 Ext.QuickTip.superclass.showAt.call(this, xy);
32964 delete this.activeTarget;
32965 Ext.QuickTip.superclass.hide.call(this);
32968 Ext.reg('quicktip', Ext.QuickTip);
32969 Ext.QuickTips = function(){
32975 init : function(autoRender){
32978 Ext.onReady(function(){
32979 Ext.QuickTips.init(autoRender);
32983 tip = new Ext.QuickTip({
32984 elements:'header,body',
32987 if(autoRender !== false){
32988 tip.render(Ext.getBody());
32994 ddDisable : function(){
32996 if(tip && !disabled){
33002 ddEnable : function(){
33004 if(tip && !disabled){
33010 enable : function(){
33018 disable : function(){
33026 isEnabled : function(){
33027 return tip !== undefined && !tip.disabled;
33031 getQuickTip : function(){
33036 register : function(){
33037 tip.register.apply(tip, arguments);
33041 unregister : function(){
33042 tip.unregister.apply(tip, arguments);
33047 tip.register.apply(tip, arguments);
33051 Ext.slider.Tip = Ext.extend(Ext.Tip, {
33053 offsets : [0, -10],
33055 init: function(slider) {
33058 dragstart: this.onSlide,
33059 drag : this.onSlide,
33060 dragend : this.hide,
33061 destroy : this.destroy
33066 onSlide : function(slider, e, thumb) {
33068 this.body.update(this.getText(thumb));
33069 this.doAutoWidth();
33070 this.el.alignTo(thumb.el, 'b-t?', this.offsets);
33074 getText : function(thumb) {
33075 return String(thumb.value);
33080 Ext.ux.SliderTip = Ext.slider.Tip;
33081 Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
33082 rootVisible : true,
33083 animate : Ext.enableFx,
33086 hlDrop : Ext.enableFx,
33087 pathSeparator : '/',
33092 initComponent : function(){
33093 Ext.tree.TreePanel.superclass.initComponent.call(this);
33095 if(!this.eventModel){
33096 this.eventModel = new Ext.tree.TreeEventModel(this);
33100 var l = this.loader;
33102 l = new Ext.tree.TreeLoader({
33103 dataUrl: this.dataUrl,
33104 requestMethod: this.requestMethod
33106 }else if(Ext.isObject(l) && !l.load){
33107 l = new Ext.tree.TreeLoader(l);
33111 this.nodeHash = {};
33117 this.setRootNode(r);
33147 'beforeexpandnode',
33149 'beforecollapsenode',
33169 'containerdblclick',
33173 'containercontextmenu',
33175 'beforechildrenrendered',
33189 if(this.singleExpand){
33190 this.on('beforeexpandnode', this.restrictExpand, this);
33195 proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
33196 if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
33197 ename = ename+'node';
33200 return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
33205 getRootNode : function(){
33210 setRootNode : function(node){
33211 this.destroyRoot();
33213 node = this.loader.createNode(node);
33216 node.ownerTree = this;
33217 node.isRoot = true;
33218 this.registerNode(node);
33219 if(!this.rootVisible){
33220 var uiP = node.attributes.uiProvider;
33221 node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
33224 this.clearInnerCt();
33230 clearInnerCt : function(){
33231 this.innerCt.update('');
33235 renderRoot : function(){
33236 this.root.render();
33237 if(!this.rootVisible){
33238 this.root.renderChildren();
33243 getNodeById : function(id){
33244 return this.nodeHash[id];
33248 registerNode : function(node){
33249 this.nodeHash[node.id] = node;
33253 unregisterNode : function(node){
33254 delete this.nodeHash[node.id];
33258 toString : function(){
33259 return '[Tree'+(this.id?' '+this.id:'')+']';
33263 restrictExpand : function(node){
33264 var p = node.parentNode;
33266 if(p.expandedChild && p.expandedChild.parentNode == p){
33267 p.expandedChild.collapse();
33269 p.expandedChild = node;
33274 getChecked : function(a, startNode){
33275 startNode = startNode || this.root;
33277 var f = function(){
33278 if(this.attributes.checked){
33279 r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
33282 startNode.cascade(f);
33287 getLoader : function(){
33288 return this.loader;
33292 expandAll : function(){
33293 this.root.expand(true);
33297 collapseAll : function(){
33298 this.root.collapse(true);
33302 getSelectionModel : function(){
33303 if(!this.selModel){
33304 this.selModel = new Ext.tree.DefaultSelectionModel();
33306 return this.selModel;
33310 expandPath : function(path, attr, callback){
33311 if(Ext.isEmpty(path)){
33313 callback(false, undefined);
33317 attr = attr || 'id';
33318 var keys = path.split(this.pathSeparator);
33319 var curNode = this.root;
33320 if(curNode.attributes[attr] != keys[1]){
33322 callback(false, null);
33327 var f = function(){
33328 if(++index == keys.length){
33330 callback(true, curNode);
33334 var c = curNode.findChild(attr, keys[index]);
33337 callback(false, curNode);
33342 c.expand(false, false, f);
33344 curNode.expand(false, false, f);
33348 selectPath : function(path, attr, callback){
33349 if(Ext.isEmpty(path)){
33351 callback(false, undefined);
33355 attr = attr || 'id';
33356 var keys = path.split(this.pathSeparator),
33358 if(keys.length > 1){
33359 var f = function(success, node){
33360 if(success && node){
33361 var n = node.findChild(attr, v);
33367 }else if(callback){
33368 callback(false, n);
33372 callback(false, n);
33376 this.expandPath(keys.join(this.pathSeparator), attr, f);
33378 this.root.select();
33380 callback(true, this.root);
33386 getTreeEl : function(){
33391 onRender : function(ct, position){
33392 Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
33393 this.el.addClass('x-tree');
33394 this.innerCt = this.body.createChild({tag:'ul',
33395 cls:'x-tree-root-ct ' +
33396 (this.useArrows ? 'x-tree-arrows' : this.lines ? 'x-tree-lines' : 'x-tree-no-lines')});
33400 initEvents : function(){
33401 Ext.tree.TreePanel.superclass.initEvents.call(this);
33403 if(this.containerScroll){
33404 Ext.dd.ScrollManager.register(this.body);
33406 if((this.enableDD || this.enableDrop) && !this.dropZone){
33408 this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
33409 ddGroup: this.ddGroup || 'TreeDD', appendOnly: this.ddAppendOnly === true
33412 if((this.enableDD || this.enableDrag) && !this.dragZone){
33414 this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
33415 ddGroup: this.ddGroup || 'TreeDD',
33416 scroll: this.ddScroll
33419 this.getSelectionModel().init(this);
33423 afterRender : function(){
33424 Ext.tree.TreePanel.superclass.afterRender.call(this);
33428 beforeDestroy : function(){
33430 Ext.dd.ScrollManager.unregister(this.body);
33431 Ext.destroy(this.dropZone, this.dragZone);
33433 this.destroyRoot();
33434 Ext.destroy(this.loader);
33435 this.nodeHash = this.root = this.loader = null;
33436 Ext.tree.TreePanel.superclass.beforeDestroy.call(this);
33440 destroyRoot : function(){
33441 if(this.root && this.root.destroy){
33442 this.root.destroy(true);
33498 Ext.tree.TreePanel.nodeTypes = {};
33500 Ext.reg('treepanel', Ext.tree.TreePanel);Ext.tree.TreeEventModel = function(tree){
33502 this.tree.on('render', this.initEvents, this);
33505 Ext.tree.TreeEventModel.prototype = {
33506 initEvents : function(){
33509 if(t.trackMouseOver !== false){
33512 mouseover: this.delegateOver,
33513 mouseout: this.delegateOut
33516 t.mon(t.getTreeEl(), {
33518 click: this.delegateClick,
33519 dblclick: this.delegateDblClick,
33520 contextmenu: this.delegateContextMenu
33524 getNode : function(e){
33526 if(t = e.getTarget('.x-tree-node-el', 10)){
33527 var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext');
33529 return this.tree.getNodeById(id);
33535 getNodeTarget : function(e){
33536 var t = e.getTarget('.x-tree-node-icon', 1);
33538 t = e.getTarget('.x-tree-node-el', 6);
33543 delegateOut : function(e, t){
33544 if(!this.beforeEvent(e)){
33547 if(e.getTarget('.x-tree-ec-icon', 1)){
33548 var n = this.getNode(e);
33549 this.onIconOut(e, n);
33550 if(n == this.lastEcOver){
33551 delete this.lastEcOver;
33554 if((t = this.getNodeTarget(e)) && !e.within(t, true)){
33555 this.onNodeOut(e, this.getNode(e));
33559 delegateOver : function(e, t){
33560 if(!this.beforeEvent(e)){
33563 if(Ext.isGecko && !this.trackingDoc){
33564 Ext.getBody().on('mouseover', this.trackExit, this);
33565 this.trackingDoc = true;
33567 if(this.lastEcOver){
33568 this.onIconOut(e, this.lastEcOver);
33569 delete this.lastEcOver;
33571 if(e.getTarget('.x-tree-ec-icon', 1)){
33572 this.lastEcOver = this.getNode(e);
33573 this.onIconOver(e, this.lastEcOver);
33575 if(t = this.getNodeTarget(e)){
33576 this.onNodeOver(e, this.getNode(e));
33580 trackExit : function(e){
33581 if(this.lastOverNode){
33582 if(this.lastOverNode.ui && !e.within(this.lastOverNode.ui.getEl())){
33583 this.onNodeOut(e, this.lastOverNode);
33585 delete this.lastOverNode;
33586 Ext.getBody().un('mouseover', this.trackExit, this);
33587 this.trackingDoc = false;
33592 delegateClick : function(e, t){
33593 if(this.beforeEvent(e)){
33594 if(e.getTarget('input[type=checkbox]', 1)){
33595 this.onCheckboxClick(e, this.getNode(e));
33596 }else if(e.getTarget('.x-tree-ec-icon', 1)){
33597 this.onIconClick(e, this.getNode(e));
33598 }else if(this.getNodeTarget(e)){
33599 this.onNodeClick(e, this.getNode(e));
33602 this.checkContainerEvent(e, 'click');
33606 delegateDblClick : function(e, t){
33607 if(this.beforeEvent(e)){
33608 if(this.getNodeTarget(e)){
33609 this.onNodeDblClick(e, this.getNode(e));
33612 this.checkContainerEvent(e, 'dblclick');
33616 delegateContextMenu : function(e, t){
33617 if(this.beforeEvent(e)){
33618 if(this.getNodeTarget(e)){
33619 this.onNodeContextMenu(e, this.getNode(e));
33622 this.checkContainerEvent(e, 'contextmenu');
33626 checkContainerEvent: function(e, type){
33631 this.onContainerEvent(e, type);
33634 onContainerEvent: function(e, type){
33635 this.tree.fireEvent('container' + type, this.tree, e);
33638 onNodeClick : function(e, node){
33639 node.ui.onClick(e);
33642 onNodeOver : function(e, node){
33643 this.lastOverNode = node;
33647 onNodeOut : function(e, node){
33651 onIconOver : function(e, node){
33652 node.ui.addClass('x-tree-ec-over');
33655 onIconOut : function(e, node){
33656 node.ui.removeClass('x-tree-ec-over');
33659 onIconClick : function(e, node){
33660 node.ui.ecClick(e);
33663 onCheckboxClick : function(e, node){
33664 node.ui.onCheckChange(e);
33667 onNodeDblClick : function(e, node){
33668 node.ui.onDblClick(e);
33671 onNodeContextMenu : function(e, node){
33672 node.ui.onContextMenu(e);
33675 beforeEvent : function(e){
33676 var node = this.getNode(e);
33677 if(this.disabled || !node || !node.ui){
33684 disable: function(){
33685 this.disabled = true;
33688 enable: function(){
33689 this.disabled = false;
33692 Ext.tree.DefaultSelectionModel = Ext.extend(Ext.util.Observable, {
33694 constructor : function(config){
33695 this.selNode = null;
33705 Ext.apply(this, config);
33706 Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
33709 init : function(tree){
33711 tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
33712 tree.on('click', this.onNodeClick, this);
33715 onNodeClick : function(node, e){
33720 select : function(node, selectNextNode){
33722 if (!Ext.fly(node.ui.wrap).isVisible() && selectNextNode) {
33723 return selectNextNode.call(this, node);
33725 var last = this.selNode;
33727 node.ui.onSelectedChange(true);
33728 }else if(this.fireEvent('beforeselect', this, node, last) !== false){
33729 if(last && last.ui){
33730 last.ui.onSelectedChange(false);
33732 this.selNode = node;
33733 node.ui.onSelectedChange(true);
33734 this.fireEvent('selectionchange', this, node, last);
33740 unselect : function(node, silent){
33741 if(this.selNode == node){
33742 this.clearSelections(silent);
33747 clearSelections : function(silent){
33748 var n = this.selNode;
33750 n.ui.onSelectedChange(false);
33751 this.selNode = null;
33752 if(silent !== true){
33753 this.fireEvent('selectionchange', this, null);
33760 getSelectedNode : function(){
33761 return this.selNode;
33765 isSelected : function(node){
33766 return this.selNode == node;
33770 selectPrevious : function( s){
33771 if(!(s = s || this.selNode || this.lastSelNode)){
33775 var ps = s.previousSibling;
33777 if(!ps.isExpanded() || ps.childNodes.length < 1){
33778 return this.select(ps, this.selectPrevious);
33780 var lc = ps.lastChild;
33781 while(lc && lc.isExpanded() && Ext.fly(lc.ui.wrap).isVisible() && lc.childNodes.length > 0){
33784 return this.select(lc, this.selectPrevious);
33786 } else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
33787 return this.select(s.parentNode, this.selectPrevious);
33793 selectNext : function( s){
33794 if(!(s = s || this.selNode || this.lastSelNode)){
33798 if(s.firstChild && s.isExpanded() && Ext.fly(s.ui.wrap).isVisible()){
33799 return this.select(s.firstChild, this.selectNext);
33800 }else if(s.nextSibling){
33801 return this.select(s.nextSibling, this.selectNext);
33802 }else if(s.parentNode){
33804 s.parentNode.bubble(function(){
33805 if(this.nextSibling){
33806 newS = this.getOwnerTree().selModel.select(this.nextSibling, this.selectNext);
33815 onKeyDown : function(e){
33816 var s = this.selNode || this.lastSelNode;
33822 var k = e.getKey();
33830 this.selectPrevious();
33833 e.preventDefault();
33834 if(s.hasChildNodes()){
33835 if(!s.isExpanded()){
33837 }else if(s.firstChild){
33838 this.select(s.firstChild, e);
33843 e.preventDefault();
33844 if(s.hasChildNodes() && s.isExpanded()){
33846 }else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
33847 this.select(s.parentNode, e);
33855 Ext.tree.MultiSelectionModel = Ext.extend(Ext.util.Observable, {
33857 constructor : function(config){
33858 this.selNodes = [];
33864 Ext.apply(this, config);
33865 Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
33868 init : function(tree){
33870 tree.mon(tree.getTreeEl(), 'keydown', this.onKeyDown, this);
33871 tree.on('click', this.onNodeClick, this);
33874 onNodeClick : function(node, e){
33875 if(e.ctrlKey && this.isSelected(node)){
33876 this.unselect(node);
33878 this.select(node, e, e.ctrlKey);
33883 select : function(node, e, keepExisting){
33884 if(keepExisting !== true){
33885 this.clearSelections(true);
33887 if(this.isSelected(node)){
33888 this.lastSelNode = node;
33891 this.selNodes.push(node);
33892 this.selMap[node.id] = node;
33893 this.lastSelNode = node;
33894 node.ui.onSelectedChange(true);
33895 this.fireEvent('selectionchange', this, this.selNodes);
33900 unselect : function(node){
33901 if(this.selMap[node.id]){
33902 node.ui.onSelectedChange(false);
33903 var sn = this.selNodes;
33904 var index = sn.indexOf(node);
33906 this.selNodes.splice(index, 1);
33908 delete this.selMap[node.id];
33909 this.fireEvent('selectionchange', this, this.selNodes);
33914 clearSelections : function(suppressEvent){
33915 var sn = this.selNodes;
33917 for(var i = 0, len = sn.length; i < len; i++){
33918 sn[i].ui.onSelectedChange(false);
33920 this.selNodes = [];
33922 if(suppressEvent !== true){
33923 this.fireEvent('selectionchange', this, this.selNodes);
33929 isSelected : function(node){
33930 return this.selMap[node.id] ? true : false;
33934 getSelectedNodes : function(){
33935 return this.selNodes.concat([]);
33938 onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
33940 selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
33942 selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
33944 Ext.data.Tree = Ext.extend(Ext.util.Observable, {
33946 constructor: function(root){
33947 this.nodeHash = {};
33951 this.setRootNode(root);
33971 Ext.data.Tree.superclass.constructor.call(this);
33975 pathSeparator: "/",
33978 proxyNodeEvent : function(){
33979 return this.fireEvent.apply(this, arguments);
33983 getRootNode : function(){
33988 setRootNode : function(node){
33990 node.ownerTree = this;
33991 node.isRoot = true;
33992 this.registerNode(node);
33997 getNodeById : function(id){
33998 return this.nodeHash[id];
34002 registerNode : function(node){
34003 this.nodeHash[node.id] = node;
34007 unregisterNode : function(node){
34008 delete this.nodeHash[node.id];
34011 toString : function(){
34012 return "[Tree"+(this.id?" "+this.id:"")+"]";
34017 Ext.data.Node = Ext.extend(Ext.util.Observable, {
34019 constructor: function(attributes){
34021 this.attributes = attributes || {};
34022 this.leaf = this.attributes.leaf;
34024 this.id = this.attributes.id;
34026 this.id = Ext.id(null, "xnode-");
34027 this.attributes.id = this.id;
34030 this.childNodes = [];
34032 this.parentNode = null;
34034 this.firstChild = null;
34036 this.lastChild = null;
34038 this.previousSibling = null;
34040 this.nextSibling = null;
34052 "beforeappend" : true,
34054 "beforeremove" : true,
34056 "beforemove" : true,
34058 "beforeinsert" : true
34060 this.listeners = this.attributes.listeners;
34061 Ext.data.Node.superclass.constructor.call(this);
34065 fireEvent : function(evtName){
34067 if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
34071 var ot = this.getOwnerTree();
34073 if(ot.proxyNodeEvent.apply(ot, arguments) === false){
34081 isLeaf : function(){
34082 return this.leaf === true;
34086 setFirstChild : function(node){
34087 this.firstChild = node;
34091 setLastChild : function(node){
34092 this.lastChild = node;
34097 isLast : function(){
34098 return (!this.parentNode ? true : this.parentNode.lastChild == this);
34102 isFirst : function(){
34103 return (!this.parentNode ? true : this.parentNode.firstChild == this);
34107 hasChildNodes : function(){
34108 return !this.isLeaf() && this.childNodes.length > 0;
34112 isExpandable : function(){
34113 return this.attributes.expandable || this.hasChildNodes();
34117 appendChild : function(node){
34119 if(Ext.isArray(node)){
34121 }else if(arguments.length > 1){
34126 for(var i = 0, len = multi.length; i < len; i++) {
34127 this.appendChild(multi[i]);
34130 if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
34133 var index = this.childNodes.length;
34134 var oldParent = node.parentNode;
34137 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
34140 oldParent.removeChild(node);
34142 index = this.childNodes.length;
34144 this.setFirstChild(node);
34146 this.childNodes.push(node);
34147 node.parentNode = this;
34148 var ps = this.childNodes[index-1];
34150 node.previousSibling = ps;
34151 ps.nextSibling = node;
34153 node.previousSibling = null;
34155 node.nextSibling = null;
34156 this.setLastChild(node);
34157 node.setOwnerTree(this.getOwnerTree());
34158 this.fireEvent("append", this.ownerTree, this, node, index);
34160 node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
34167 removeChild : function(node, destroy){
34168 var index = this.childNodes.indexOf(node);
34172 if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
34177 this.childNodes.splice(index, 1);
34180 if(node.previousSibling){
34181 node.previousSibling.nextSibling = node.nextSibling;
34183 if(node.nextSibling){
34184 node.nextSibling.previousSibling = node.previousSibling;
34188 if(this.firstChild == node){
34189 this.setFirstChild(node.nextSibling);
34191 if(this.lastChild == node){
34192 this.setLastChild(node.previousSibling);
34195 this.fireEvent("remove", this.ownerTree, this, node);
34197 node.destroy(true);
34205 clear : function(destroy){
34207 this.setOwnerTree(null, destroy);
34208 this.parentNode = this.previousSibling = this.nextSibling = null;
34210 this.firstChild = this.lastChild = null;
34215 destroy : function( silent){
34217 if(silent === true){
34218 this.purgeListeners();
34220 Ext.each(this.childNodes, function(n){
34223 this.childNodes = null;
34230 insertBefore : function(node, refNode){
34232 return this.appendChild(node);
34235 if(node == refNode){
34239 if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
34242 var index = this.childNodes.indexOf(refNode);
34243 var oldParent = node.parentNode;
34244 var refIndex = index;
34247 if(oldParent == this && this.childNodes.indexOf(node) < index){
34253 if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
34256 oldParent.removeChild(node);
34258 if(refIndex === 0){
34259 this.setFirstChild(node);
34261 this.childNodes.splice(refIndex, 0, node);
34262 node.parentNode = this;
34263 var ps = this.childNodes[refIndex-1];
34265 node.previousSibling = ps;
34266 ps.nextSibling = node;
34268 node.previousSibling = null;
34270 node.nextSibling = refNode;
34271 refNode.previousSibling = node;
34272 node.setOwnerTree(this.getOwnerTree());
34273 this.fireEvent("insert", this.ownerTree, this, node, refNode);
34275 node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
34281 remove : function(destroy){
34282 if (this.parentNode) {
34283 this.parentNode.removeChild(this, destroy);
34289 removeAll : function(destroy){
34290 var cn = this.childNodes,
34292 while((n = cn[0])){
34293 this.removeChild(n, destroy);
34299 item : function(index){
34300 return this.childNodes[index];
34304 replaceChild : function(newChild, oldChild){
34305 var s = oldChild ? oldChild.nextSibling : null;
34306 this.removeChild(oldChild);
34307 this.insertBefore(newChild, s);
34312 indexOf : function(child){
34313 return this.childNodes.indexOf(child);
34317 getOwnerTree : function(){
34319 if(!this.ownerTree){
34323 this.ownerTree = p.ownerTree;
34329 return this.ownerTree;
34333 getDepth : function(){
34336 while(p.parentNode){
34344 setOwnerTree : function(tree, destroy){
34346 if(tree != this.ownerTree){
34347 if(this.ownerTree){
34348 this.ownerTree.unregisterNode(this);
34350 this.ownerTree = tree;
34352 if(destroy !== true){
34353 Ext.each(this.childNodes, function(n){
34354 n.setOwnerTree(tree);
34358 tree.registerNode(this);
34364 setId: function(id){
34365 if(id !== this.id){
34366 var t = this.ownerTree;
34368 t.unregisterNode(this);
34370 this.id = this.attributes.id = id;
34372 t.registerNode(this);
34374 this.onIdChange(id);
34379 onIdChange: Ext.emptyFn,
34382 getPath : function(attr){
34383 attr = attr || "id";
34384 var p = this.parentNode;
34385 var b = [this.attributes[attr]];
34387 b.unshift(p.attributes[attr]);
34390 var sep = this.getOwnerTree().pathSeparator;
34391 return sep + b.join(sep);
34395 bubble : function(fn, scope, args){
34398 if(fn.apply(scope || p, args || [p]) === false){
34406 cascade : function(fn, scope, args){
34407 if(fn.apply(scope || this, args || [this]) !== false){
34408 var cs = this.childNodes;
34409 for(var i = 0, len = cs.length; i < len; i++) {
34410 cs[i].cascade(fn, scope, args);
34416 eachChild : function(fn, scope, args){
34417 var cs = this.childNodes;
34418 for(var i = 0, len = cs.length; i < len; i++) {
34419 if(fn.apply(scope || cs[i], args || [cs[i]]) === false){
34426 findChild : function(attribute, value, deep){
34427 return this.findChildBy(function(){
34428 return this.attributes[attribute] == value;
34433 findChildBy : function(fn, scope, deep){
34434 var cs = this.childNodes,
34439 for(; i < len; i++){
34441 if(fn.call(scope || n, n) === true){
34444 res = n.findChildBy(fn, scope, deep);
34455 sort : function(fn, scope){
34456 var cs = this.childNodes;
34457 var len = cs.length;
34459 var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
34461 for(var i = 0; i < len; i++){
34463 n.previousSibling = cs[i-1];
34464 n.nextSibling = cs[i+1];
34466 this.setFirstChild(n);
34469 this.setLastChild(n);
34476 contains : function(node){
34477 return node.isAncestor(this);
34481 isAncestor : function(node){
34482 var p = this.parentNode;
34492 toString : function(){
34493 return "[Node"+(this.id?" "+this.id:"")+"]";
34496 Ext.tree.TreeNode = Ext.extend(Ext.data.Node, {
34498 constructor : function(attributes){
34499 attributes = attributes || {};
34500 if(Ext.isString(attributes)){
34501 attributes = {text: attributes};
34503 this.childrenRendered = false;
34504 this.rendered = false;
34505 Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
34506 this.expanded = attributes.expanded === true;
34507 this.isTarget = attributes.isTarget !== false;
34508 this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
34509 this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
34512 this.text = attributes.text;
34514 this.disabled = attributes.disabled === true;
34516 this.hidden = attributes.hidden === true;
34544 'beforechildrenrendered'
34547 var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
34550 this.ui = new uiClass(this);
34553 preventHScroll : true,
34555 isExpanded : function(){
34556 return this.expanded;
34560 getUI : function(){
34564 getLoader : function(){
34566 return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : (this.loader = new Ext.tree.TreeLoader()));
34570 setFirstChild : function(node){
34571 var of = this.firstChild;
34572 Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
34573 if(this.childrenRendered && of && node != of){
34574 of.renderIndent(true, true);
34577 this.renderIndent(true, true);
34582 setLastChild : function(node){
34583 var ol = this.lastChild;
34584 Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
34585 if(this.childrenRendered && ol && node != ol){
34586 ol.renderIndent(true, true);
34589 this.renderIndent(true, true);
34595 appendChild : function(n){
34596 if(!n.render && !Ext.isArray(n)){
34597 n = this.getLoader().createNode(n);
34599 var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
34600 if(node && this.childrenRendered){
34603 this.ui.updateExpandIcon();
34608 removeChild : function(node, destroy){
34609 this.ownerTree.getSelectionModel().unselect(node);
34610 Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
34613 var rendered = node.ui.rendered;
34618 if(rendered && this.childNodes.length < 1){
34619 this.collapse(false, false);
34621 this.ui.updateExpandIcon();
34623 if(!this.firstChild && !this.isHiddenRoot()){
34624 this.childrenRendered = false;
34631 insertBefore : function(node, refNode){
34633 node = this.getLoader().createNode(node);
34635 var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);
34636 if(newNode && refNode && this.childrenRendered){
34639 this.ui.updateExpandIcon();
34644 setText : function(text){
34645 var oldText = this.text;
34646 this.text = this.attributes.text = text;
34648 this.ui.onTextChange(this, text, oldText);
34650 this.fireEvent('textchange', this, text, oldText);
34654 setIconCls : function(cls){
34655 var old = this.attributes.iconCls;
34656 this.attributes.iconCls = cls;
34658 this.ui.onIconClsChange(this, cls, old);
34663 setTooltip : function(tip, title){
34664 this.attributes.qtip = tip;
34665 this.attributes.qtipTitle = title;
34667 this.ui.onTipChange(this, tip, title);
34672 setIcon : function(icon){
34673 this.attributes.icon = icon;
34675 this.ui.onIconChange(this, icon);
34680 setHref : function(href, target){
34681 this.attributes.href = href;
34682 this.attributes.hrefTarget = target;
34684 this.ui.onHrefChange(this, href, target);
34689 setCls : function(cls){
34690 var old = this.attributes.cls;
34691 this.attributes.cls = cls;
34693 this.ui.onClsChange(this, cls, old);
34698 select : function(){
34699 var t = this.getOwnerTree();
34701 t.getSelectionModel().select(this);
34706 unselect : function(silent){
34707 var t = this.getOwnerTree();
34709 t.getSelectionModel().unselect(this, silent);
34714 isSelected : function(){
34715 var t = this.getOwnerTree();
34716 return t ? t.getSelectionModel().isSelected(this) : false;
34720 expand : function(deep, anim, callback, scope){
34721 if(!this.expanded){
34722 if(this.fireEvent('beforeexpand', this, deep, anim) === false){
34725 if(!this.childrenRendered){
34726 this.renderChildren();
34728 this.expanded = true;
34729 if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
34730 this.ui.animExpand(function(){
34731 this.fireEvent('expand', this);
34732 this.runCallback(callback, scope || this, [this]);
34734 this.expandChildNodes(true, true);
34736 }.createDelegate(this));
34740 this.fireEvent('expand', this);
34741 this.runCallback(callback, scope || this, [this]);
34744 this.runCallback(callback, scope || this, [this]);
34747 this.expandChildNodes(true);
34751 runCallback : function(cb, scope, args){
34752 if(Ext.isFunction(cb)){
34753 cb.apply(scope, args);
34757 isHiddenRoot : function(){
34758 return this.isRoot && !this.getOwnerTree().rootVisible;
34762 collapse : function(deep, anim, callback, scope){
34763 if(this.expanded && !this.isHiddenRoot()){
34764 if(this.fireEvent('beforecollapse', this, deep, anim) === false){
34767 this.expanded = false;
34768 if((this.getOwnerTree().animate && anim !== false) || anim){
34769 this.ui.animCollapse(function(){
34770 this.fireEvent('collapse', this);
34771 this.runCallback(callback, scope || this, [this]);
34773 this.collapseChildNodes(true);
34775 }.createDelegate(this));
34778 this.ui.collapse();
34779 this.fireEvent('collapse', this);
34780 this.runCallback(callback, scope || this, [this]);
34782 }else if(!this.expanded){
34783 this.runCallback(callback, scope || this, [this]);
34786 var cs = this.childNodes;
34787 for(var i = 0, len = cs.length; i < len; i++) {
34788 cs[i].collapse(true, false);
34794 delayedExpand : function(delay){
34795 if(!this.expandProcId){
34796 this.expandProcId = this.expand.defer(delay, this);
34801 cancelExpand : function(){
34802 if(this.expandProcId){
34803 clearTimeout(this.expandProcId);
34805 this.expandProcId = false;
34809 toggle : function(){
34818 ensureVisible : function(callback, scope){
34819 var tree = this.getOwnerTree();
34820 tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){
34821 var node = tree.getNodeById(this.id);
34822 tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
34823 this.runCallback(callback, scope || this, [this]);
34824 }.createDelegate(this));
34828 expandChildNodes : function(deep, anim) {
34829 var cs = this.childNodes,
34832 for (i = 0; i < len; i++) {
34833 cs[i].expand(deep, anim);
34838 collapseChildNodes : function(deep){
34839 var cs = this.childNodes;
34840 for(var i = 0, len = cs.length; i < len; i++) {
34841 cs[i].collapse(deep);
34846 disable : function(){
34847 this.disabled = true;
34849 if(this.rendered && this.ui.onDisableChange){
34850 this.ui.onDisableChange(this, true);
34852 this.fireEvent('disabledchange', this, true);
34856 enable : function(){
34857 this.disabled = false;
34858 if(this.rendered && this.ui.onDisableChange){
34859 this.ui.onDisableChange(this, false);
34861 this.fireEvent('disabledchange', this, false);
34865 renderChildren : function(suppressEvent){
34866 if(suppressEvent !== false){
34867 this.fireEvent('beforechildrenrendered', this);
34869 var cs = this.childNodes;
34870 for(var i = 0, len = cs.length; i < len; i++){
34871 cs[i].render(true);
34873 this.childrenRendered = true;
34877 sort : function(fn, scope){
34878 Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
34879 if(this.childrenRendered){
34880 var cs = this.childNodes;
34881 for(var i = 0, len = cs.length; i < len; i++){
34882 cs[i].render(true);
34888 render : function(bulkRender){
34889 this.ui.render(bulkRender);
34890 if(!this.rendered){
34892 this.getOwnerTree().registerNode(this);
34893 this.rendered = true;
34895 this.expanded = false;
34896 this.expand(false, false);
34902 renderIndent : function(deep, refresh){
34904 this.ui.childIndent = null;
34906 this.ui.renderIndent();
34907 if(deep === true && this.childrenRendered){
34908 var cs = this.childNodes;
34909 for(var i = 0, len = cs.length; i < len; i++){
34910 cs[i].renderIndent(true, refresh);
34915 beginUpdate : function(){
34916 this.childrenRendered = false;
34919 endUpdate : function(){
34920 if(this.expanded && this.rendered){
34921 this.renderChildren();
34926 destroy : function(silent){
34927 if(silent === true){
34928 this.unselect(true);
34930 Ext.tree.TreeNode.superclass.destroy.call(this, silent);
34931 Ext.destroy(this.ui, this.loader);
34932 this.ui = this.loader = null;
34936 onIdChange : function(id){
34937 this.ui.onIdChange(id);
34941 Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode;
34942 Ext.tree.AsyncTreeNode = function(config){
34943 this.loaded = config && config.loaded === true;
34944 this.loading = false;
34945 Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
34947 this.addEvents('beforeload', 'load');
34951 Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
34952 expand : function(deep, anim, callback, scope){
34955 var f = function(){
34957 clearInterval(timer);
34958 this.expand(deep, anim, callback, scope);
34960 }.createDelegate(this);
34961 timer = setInterval(f, 200);
34965 if(this.fireEvent("beforeload", this) === false){
34968 this.loading = true;
34969 this.ui.beforeLoad(this);
34970 var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
34972 loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback, scope]), this);
34976 Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback, scope);
34980 isLoading : function(){
34981 return this.loading;
34984 loadComplete : function(deep, anim, callback, scope){
34985 this.loading = false;
34986 this.loaded = true;
34987 this.ui.afterLoad(this);
34988 this.fireEvent("load", this);
34989 this.expand(deep, anim, callback, scope);
34993 isLoaded : function(){
34994 return this.loaded;
34997 hasChildNodes : function(){
34998 if(!this.isLeaf() && !this.loaded){
35001 return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
35006 reload : function(callback, scope){
35007 this.collapse(false, false);
35008 while(this.firstChild){
35009 this.removeChild(this.firstChild).destroy();
35011 this.childrenRendered = false;
35012 this.loaded = false;
35013 if(this.isHiddenRoot()){
35014 this.expanded = false;
35016 this.expand(false, false, callback, scope);
35020 Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode;
35021 Ext.tree.TreeNodeUI = Ext.extend(Object, {
35023 constructor : function(node){
35029 ecc: 'x-tree-ec-icon x-tree-elbow',
35030 emptyIcon: Ext.BLANK_IMAGE_URL
35035 removeChild : function(node){
35037 this.ctNode.removeChild(node.ui.getEl());
35042 beforeLoad : function(){
35043 this.addClass("x-tree-node-loading");
35047 afterLoad : function(){
35048 this.removeClass("x-tree-node-loading");
35052 onTextChange : function(node, text, oldText){
35054 this.textNode.innerHTML = text;
35059 onIconClsChange : function(node, cls, oldCls){
35061 Ext.fly(this.iconNode).replaceClass(oldCls, cls);
35066 onIconChange : function(node, icon){
35069 var empty = Ext.isEmpty(icon);
35070 this.iconNode.src = empty ? this.emptyIcon : icon;
35071 Ext.fly(this.iconNode)[empty ? 'removeClass' : 'addClass']('x-tree-node-inline-icon');
35076 onTipChange : function(node, tip, title){
35078 var hasTitle = Ext.isDefined(title);
35079 if(this.textNode.setAttributeNS){
35080 this.textNode.setAttributeNS("ext", "qtip", tip);
35082 this.textNode.setAttributeNS("ext", "qtitle", title);
35085 this.textNode.setAttribute("ext:qtip", tip);
35087 this.textNode.setAttribute("ext:qtitle", title);
35094 onHrefChange : function(node, href, target){
35096 this.anchor.href = this.getHref(href);
35097 if(Ext.isDefined(target)){
35098 this.anchor.target = target;
35104 onClsChange : function(node, cls, oldCls){
35106 Ext.fly(this.elNode).replaceClass(oldCls, cls);
35111 onDisableChange : function(node, state){
35112 this.disabled = state;
35113 if (this.checkbox) {
35114 this.checkbox.disabled = state;
35116 this[state ? 'addClass' : 'removeClass']('x-tree-node-disabled');
35120 onSelectedChange : function(state){
35123 this.addClass("x-tree-selected");
35126 this.removeClass("x-tree-selected");
35131 onMove : function(tree, node, oldParent, newParent, index, refNode){
35132 this.childIndent = null;
35134 var targetNode = newParent.ui.getContainer();
35136 this.holder = document.createElement("div");
35137 this.holder.appendChild(this.wrap);
35140 var insertBefore = refNode ? refNode.ui.getEl() : null;
35142 targetNode.insertBefore(this.wrap, insertBefore);
35144 targetNode.appendChild(this.wrap);
35146 this.node.renderIndent(true, oldParent != newParent);
35151 addClass : function(cls){
35153 Ext.fly(this.elNode).addClass(cls);
35158 removeClass : function(cls){
35160 Ext.fly(this.elNode).removeClass(cls);
35165 remove : function(){
35167 this.holder = document.createElement("div");
35168 this.holder.appendChild(this.wrap);
35173 fireEvent : function(){
35174 return this.node.fireEvent.apply(this.node, arguments);
35178 initEvents : function(){
35179 this.node.on("move", this.onMove, this);
35181 if(this.node.disabled){
35182 this.onDisableChange(this.node, true);
35184 if(this.node.hidden){
35187 var ot = this.node.getOwnerTree();
35188 var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
35189 if(dd && (!this.node.isRoot || ot.rootVisible)){
35190 Ext.dd.Registry.register(this.elNode, {
35192 handles: this.getDDHandles(),
35199 getDDHandles : function(){
35200 return [this.iconNode, this.textNode, this.elNode];
35205 this.node.hidden = true;
35207 this.wrap.style.display = "none";
35213 this.node.hidden = false;
35215 this.wrap.style.display = "";
35220 onContextMenu : function(e){
35221 if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
35222 e.preventDefault();
35224 this.fireEvent("contextmenu", this.node, e);
35229 onClick : function(e){
35234 if(this.fireEvent("beforeclick", this.node, e) !== false){
35235 var a = e.getTarget('a');
35236 if(!this.disabled && this.node.attributes.href && a){
35237 this.fireEvent("click", this.node, e);
35239 }else if(a && e.ctrlKey){
35242 e.preventDefault();
35247 if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){
35248 this.node.toggle();
35251 this.fireEvent("click", this.node, e);
35258 onDblClick : function(e){
35259 e.preventDefault();
35263 if(this.fireEvent("beforedblclick", this.node, e) !== false){
35265 this.toggleCheck();
35267 if(!this.animating && this.node.isExpandable()){
35268 this.node.toggle();
35270 this.fireEvent("dblclick", this.node, e);
35274 onOver : function(e){
35275 this.addClass('x-tree-node-over');
35278 onOut : function(e){
35279 this.removeClass('x-tree-node-over');
35283 onCheckChange : function(){
35284 var checked = this.checkbox.checked;
35286 this.checkbox.defaultChecked = checked;
35287 this.node.attributes.checked = checked;
35288 this.fireEvent('checkchange', this.node, checked);
35292 ecClick : function(e){
35293 if(!this.animating && this.node.isExpandable()){
35294 this.node.toggle();
35299 startDrop : function(){
35300 this.dropping = true;
35304 endDrop : function(){
35305 setTimeout(function(){
35306 this.dropping = false;
35307 }.createDelegate(this), 50);
35311 expand : function(){
35312 this.updateExpandIcon();
35313 this.ctNode.style.display = "";
35317 focus : function(){
35318 if(!this.node.preventHScroll){
35319 try{this.anchor.focus();
35323 var noscroll = this.node.getOwnerTree().getTreeEl().dom;
35324 var l = noscroll.scrollLeft;
35325 this.anchor.focus();
35326 noscroll.scrollLeft = l;
35332 toggleCheck : function(value){
35333 var cb = this.checkbox;
35335 cb.checked = (value === undefined ? !cb.checked : value);
35336 this.onCheckChange();
35343 this.anchor.blur();
35348 animExpand : function(callback){
35349 var ct = Ext.get(this.ctNode);
35351 if(!this.node.isExpandable()){
35352 this.updateExpandIcon();
35353 this.ctNode.style.display = "";
35354 Ext.callback(callback);
35357 this.animating = true;
35358 this.updateExpandIcon();
35361 callback : function(){
35362 this.animating = false;
35363 Ext.callback(callback);
35366 duration: this.node.ownerTree.duration || .25
35371 highlight : function(){
35372 var tree = this.node.getOwnerTree();
35373 Ext.fly(this.wrap).highlight(
35374 tree.hlColor || "C3DAF9",
35375 {endColor: tree.hlBaseColor}
35380 collapse : function(){
35381 this.updateExpandIcon();
35382 this.ctNode.style.display = "none";
35386 animCollapse : function(callback){
35387 var ct = Ext.get(this.ctNode);
35388 ct.enableDisplayMode('block');
35391 this.animating = true;
35392 this.updateExpandIcon();
35395 callback : function(){
35396 this.animating = false;
35397 Ext.callback(callback);
35400 duration: this.node.ownerTree.duration || .25
35405 getContainer : function(){
35406 return this.ctNode;
35410 getEl : function(){
35415 appendDDGhost : function(ghostNode){
35416 ghostNode.appendChild(this.elNode.cloneNode(true));
35420 getDDRepairXY : function(){
35421 return Ext.lib.Dom.getXY(this.iconNode);
35425 onRender : function(){
35430 render : function(bulkRender){
35431 var n = this.node, a = n.attributes;
35432 var targetNode = n.parentNode ?
35433 n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
35435 if(!this.rendered){
35436 this.rendered = true;
35438 this.renderElements(n, a, targetNode, bulkRender);
35441 this.onTipChange(n, a.qtip, a.qtipTitle);
35442 }else if(a.qtipCfg){
35443 a.qtipCfg.target = Ext.id(this.textNode);
35444 Ext.QuickTips.register(a.qtipCfg);
35447 if(!this.node.expanded){
35448 this.updateExpandIcon(true);
35451 if(bulkRender === true) {
35452 targetNode.appendChild(this.wrap);
35458 renderElements : function(n, a, targetNode, bulkRender){
35460 this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
35462 var cb = Ext.isBoolean(a.checked),
35464 href = this.getHref(a.href),
35465 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">',
35466 '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
35467 '<img alt="" src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
35468 '<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" />',
35469 cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
35470 '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
35471 a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
35472 '<ul class="x-tree-node-ct" style="display:none;"></ul>',
35475 if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
35476 this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
35478 this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
35481 this.elNode = this.wrap.childNodes[0];
35482 this.ctNode = this.wrap.childNodes[1];
35483 var cs = this.elNode.childNodes;
35484 this.indentNode = cs[0];
35485 this.ecNode = cs[1];
35486 this.iconNode = cs[2];
35489 this.checkbox = cs[3];
35491 this.checkbox.defaultChecked = this.checkbox.checked;
35494 this.anchor = cs[index];
35495 this.textNode = cs[index].firstChild;
35499 getHref : function(href){
35500 return Ext.isEmpty(href) ? (Ext.isGecko ? '' : '#') : href;
35504 getAnchor : function(){
35505 return this.anchor;
35509 getTextEl : function(){
35510 return this.textNode;
35514 getIconEl : function(){
35515 return this.iconNode;
35519 isChecked : function(){
35520 return this.checkbox ? this.checkbox.checked : false;
35524 updateExpandIcon : function(){
35529 cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow",
35530 hasChild = n.hasChildNodes();
35531 if(hasChild || n.attributes.expandable){
35534 c1 = "x-tree-node-collapsed";
35535 c2 = "x-tree-node-expanded";
35538 c1 = "x-tree-node-expanded";
35539 c2 = "x-tree-node-collapsed";
35542 this.removeClass("x-tree-node-leaf");
35543 this.wasLeaf = false;
35545 if(this.c1 != c1 || this.c2 != c2){
35546 Ext.fly(this.elNode).replaceClass(c1, c2);
35547 this.c1 = c1; this.c2 = c2;
35551 Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-collapsed");
35554 this.wasLeaf = true;
35557 var ecc = "x-tree-ec-icon "+cls;
35558 if(this.ecc != ecc){
35559 this.ecNode.className = ecc;
35566 onIdChange: function(id){
35568 this.elNode.setAttribute('ext:tree-node-id', id);
35573 getChildIndent : function(){
35574 if(!this.childIndent){
35578 if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
35580 buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
35582 buf.unshift('<img alt="" src="'+this.emptyIcon+'" class="x-tree-icon" />');
35587 this.childIndent = buf.join("");
35589 return this.childIndent;
35593 renderIndent : function(){
35596 p = this.node.parentNode;
35598 indent = p.ui.getChildIndent();
35600 if(this.indentMarkup != indent){
35601 this.indentNode.innerHTML = indent;
35602 this.indentMarkup = indent;
35604 this.updateExpandIcon();
35608 destroy : function(){
35610 Ext.dd.Registry.unregister(this.elNode.id);
35613 Ext.each(['textnode', 'anchor', 'checkbox', 'indentNode', 'ecNode', 'iconNode', 'elNode', 'ctNode', 'wrap', 'holder'], function(el){
35615 Ext.fly(this[el]).remove();
35624 Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
35626 render : function(){
35627 if(!this.rendered){
35628 var targetNode = this.node.ownerTree.innerCt.dom;
35629 this.node.expanded = true;
35630 targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
35631 this.wrap = this.ctNode = targetNode.firstChild;
35634 collapse : Ext.emptyFn,
35635 expand : Ext.emptyFn
35637 Ext.tree.TreeLoader = function(config){
35638 this.baseParams = {};
35639 Ext.apply(this, config);
35649 Ext.tree.TreeLoader.superclass.constructor.call(this);
35650 if(Ext.isString(this.paramOrder)){
35651 this.paramOrder = this.paramOrder.split(/[\s,|]/);
35655 Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
35666 clearOnLoad : true,
35669 paramOrder: undefined,
35672 paramsAsHash: false,
35675 nodeParameter: 'node',
35678 directFn : undefined,
35681 load : function(node, callback, scope){
35682 if(this.clearOnLoad){
35683 while(node.firstChild){
35684 node.removeChild(node.firstChild);
35687 if(this.doPreload(node)){
35688 this.runCallback(callback, scope || node, [node]);
35689 }else if(this.directFn || this.dataUrl || this.url){
35690 this.requestData(node, callback, scope || node);
35694 doPreload : function(node){
35695 if(node.attributes.children){
35696 if(node.childNodes.length < 1){
35697 var cs = node.attributes.children;
35698 node.beginUpdate();
35699 for(var i = 0, len = cs.length; i < len; i++){
35700 var cn = node.appendChild(this.createNode(cs[i]));
35701 if(this.preloadChildren){
35702 this.doPreload(cn);
35712 getParams: function(node){
35713 var bp = Ext.apply({}, this.baseParams),
35714 np = this.nodeParameter,
35715 po = this.paramOrder;
35717 np && (bp[ np ] = node.id);
35720 var buf = [node.id];
35723 if(np && po.indexOf(np) > -1){
35727 for(var i = 0, len = po.length; i < len; i++){
35728 buf.push(bp[ po[i] ]);
35730 }else if(this.paramsAsHash){
35739 requestData : function(node, callback, scope){
35740 if(this.fireEvent("beforeload", this, node, callback) !== false){
35742 var args = this.getParams(node);
35743 args.push(this.processDirectResponse.createDelegate(this, [{callback: callback, node: node, scope: scope}], true));
35744 this.directFn.apply(window, args);
35746 this.transId = Ext.Ajax.request({
35747 method:this.requestMethod,
35748 url: this.dataUrl||this.url,
35749 success: this.handleResponse,
35750 failure: this.handleFailure,
35752 argument: {callback: callback, node: node, scope: scope},
35753 params: this.getParams(node)
35759 this.runCallback(callback, scope || node, []);
35763 processDirectResponse: function(result, response, args){
35764 if(response.status){
35765 this.handleResponse({
35766 responseData: Ext.isArray(result) ? result : null,
35767 responseText: result,
35771 this.handleFailure({
35778 runCallback: function(cb, scope, args){
35779 if(Ext.isFunction(cb)){
35780 cb.apply(scope, args);
35784 isLoading : function(){
35785 return !!this.transId;
35788 abort : function(){
35789 if(this.isLoading()){
35790 Ext.Ajax.abort(this.transId);
35795 createNode : function(attr){
35797 if(this.baseAttrs){
35798 Ext.applyIf(attr, this.baseAttrs);
35800 if(this.applyLoader !== false && !attr.loader){
35801 attr.loader = this;
35803 if(Ext.isString(attr.uiProvider)){
35804 attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
35807 return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr);
35810 new Ext.tree.TreeNode(attr) :
35811 new Ext.tree.AsyncTreeNode(attr);
35815 processResponse : function(response, node, callback, scope){
35816 var json = response.responseText;
35818 var o = response.responseData || Ext.decode(json);
35819 node.beginUpdate();
35820 for(var i = 0, len = o.length; i < len; i++){
35821 var n = this.createNode(o[i]);
35823 node.appendChild(n);
35827 this.runCallback(callback, scope || node, [node]);
35829 this.handleFailure(response);
35833 handleResponse : function(response){
35834 this.transId = false;
35835 var a = response.argument;
35836 this.processResponse(response, a.node, a.callback, a.scope);
35837 this.fireEvent("load", this, a.node, response);
35840 handleFailure : function(response){
35841 this.transId = false;
35842 var a = response.argument;
35843 this.fireEvent("loadexception", this, a.node, response);
35844 this.runCallback(a.callback, a.scope || a.node, [a.node]);
35847 destroy : function(){
35849 this.purgeListeners();
35852 Ext.tree.TreeFilter = function(tree, config){
35854 this.filtered = {};
35855 Ext.apply(this, config);
35858 Ext.tree.TreeFilter.prototype = {
35865 filter : function(value, attr, startNode){
35866 attr = attr || "text";
35868 if(typeof value == "string"){
35869 var vlen = value.length;
35871 if(vlen == 0 && this.clearBlank){
35875 value = value.toLowerCase();
35877 return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
35879 }else if(value.exec){
35881 return value.test(n.attributes[attr]);
35884 throw 'Illegal filter type, must be string or regex';
35886 this.filterBy(f, null, startNode);
35890 filterBy : function(fn, scope, startNode){
35891 startNode = startNode || this.tree.root;
35892 if(this.autoClear){
35895 var af = this.filtered, rv = this.reverse;
35896 var f = function(n){
35897 if(n == startNode){
35903 var m = fn.call(scope || n, n);
35911 startNode.cascade(f);
35914 if(typeof id != "function"){
35916 if(n && n.parentNode){
35917 n.parentNode.removeChild(n);
35925 clear : function(){
35927 var af = this.filtered;
35929 if(typeof id != "function"){
35936 this.filtered = {};
35940 Ext.tree.TreeSorter = Ext.extend(Object, {
35942 constructor: function(tree, config){
35950 Ext.apply(this, config);
35953 beforechildrenrendered: this.doSort,
35954 append: this.updateSort,
35955 insert: this.updateSort,
35956 textchange: this.updateSortParent
35959 var desc = this.dir && this.dir.toLowerCase() == 'desc',
35960 prop = this.property || 'text';
35961 sortType = this.sortType;
35962 folderSort = this.folderSort;
35963 caseSensitive = this.caseSensitive === true;
35964 leafAttr = this.leafAttr || 'leaf';
35966 if(Ext.isString(sortType)){
35967 sortType = Ext.data.SortTypes[sortType];
35969 this.sortFn = function(n1, n2){
35970 var attr1 = n1.attributes,
35971 attr2 = n2.attributes;
35974 if(attr1[leafAttr] && !attr2[leafAttr]){
35977 if(!attr1[leafAttr] && attr2[leafAttr]){
35981 var prop1 = attr1[prop],
35982 prop2 = attr2[prop],
35983 v1 = sortType ? sortType(prop1) : (caseSensitive ? prop1 : prop1.toUpperCase());
35984 v2 = sortType ? sortType(prop2) : (caseSensitive ? prop2 : prop2.toUpperCase());
35987 return desc ? 1 : -1;
35989 return desc ? -1 : 1;
35995 doSort : function(node){
35996 node.sort(this.sortFn);
35999 updateSort : function(tree, node){
36000 if(node.childrenRendered){
36001 this.doSort.defer(1, this, [node]);
36005 updateSortParent : function(node){
36006 var p = node.parentNode;
36007 if(p && p.childrenRendered){
36008 this.doSort.defer(1, this, [p]);
36012 if(Ext.dd.DropZone){
36014 Ext.tree.TreeDropZone = function(tree, config){
36016 this.allowParentInsert = config.allowParentInsert || false;
36018 this.allowContainerDrop = config.allowContainerDrop || false;
36020 this.appendOnly = config.appendOnly || false;
36022 Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.getTreeEl(), config);
36026 this.dragOverData = {};
36028 this.lastInsertClass = "x-tree-no-status";
36031 Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
36033 ddGroup : "TreeDD",
36036 expandDelay : 1000,
36039 expandNode : function(node){
36040 if(node.hasChildNodes() && !node.isExpanded()){
36041 node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
36046 queueExpand : function(node){
36047 this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
36051 cancelExpand : function(){
36052 if(this.expandProcId){
36053 clearTimeout(this.expandProcId);
36054 this.expandProcId = false;
36059 isValidDropPoint : function(n, pt, dd, e, data){
36060 if(!n || !data){ return false; }
36061 var targetNode = n.node;
36062 var dropNode = data.node;
36064 if(!(targetNode && targetNode.isTarget && pt)){
36067 if(pt == "append" && targetNode.allowChildren === false){
36070 if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
36073 if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
36077 var overEvent = this.dragOverData;
36078 overEvent.tree = this.tree;
36079 overEvent.target = targetNode;
36080 overEvent.data = data;
36081 overEvent.point = pt;
36082 overEvent.source = dd;
36083 overEvent.rawEvent = e;
36084 overEvent.dropNode = dropNode;
36085 overEvent.cancel = false;
36086 var result = this.tree.fireEvent("nodedragover", overEvent);
36087 return overEvent.cancel === false && result !== false;
36091 getDropPoint : function(e, n, dd){
36094 return tn.allowChildren !== false ? "append" : false;
36096 var dragEl = n.ddel;
36097 var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
36098 var y = Ext.lib.Event.getPageY(e);
36099 var noAppend = tn.allowChildren === false || tn.isLeaf();
36100 if(this.appendOnly || tn.parentNode.allowChildren === false){
36101 return noAppend ? false : "append";
36103 var noBelow = false;
36104 if(!this.allowParentInsert){
36105 noBelow = tn.hasChildNodes() && tn.isExpanded();
36107 var q = (b - t) / (noAppend ? 2 : 3);
36108 if(y >= t && y < (t + q)){
36110 }else if(!noBelow && (noAppend || y >= b-q && y <= b)){
36118 onNodeEnter : function(n, dd, e, data){
36119 this.cancelExpand();
36122 onContainerOver : function(dd, e, data) {
36123 if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
36124 return this.dropAllowed;
36126 return this.dropNotAllowed;
36130 onNodeOver : function(n, dd, e, data){
36131 var pt = this.getDropPoint(e, n, dd);
36135 if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
36136 this.queueExpand(node);
36137 }else if(pt != "append"){
36138 this.cancelExpand();
36142 var returnCls = this.dropNotAllowed;
36143 if(this.isValidDropPoint(n, pt, dd, e, data)){
36148 returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
36149 cls = "x-tree-drag-insert-above";
36150 }else if(pt == "below"){
36151 returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
36152 cls = "x-tree-drag-insert-below";
36154 returnCls = "x-tree-drop-ok-append";
36155 cls = "x-tree-drag-append";
36157 if(this.lastInsertClass != cls){
36158 Ext.fly(el).replaceClass(this.lastInsertClass, cls);
36159 this.lastInsertClass = cls;
36167 onNodeOut : function(n, dd, e, data){
36168 this.cancelExpand();
36169 this.removeDropIndicators(n);
36173 onNodeDrop : function(n, dd, e, data){
36174 var point = this.getDropPoint(e, n, dd);
36175 var targetNode = n.node;
36176 targetNode.ui.startDrop();
36177 if(!this.isValidDropPoint(n, point, dd, e, data)){
36178 targetNode.ui.endDrop();
36182 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
36183 return this.processDrop(targetNode, data, point, dd, e, dropNode);
36186 onContainerDrop : function(dd, e, data){
36187 if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
36188 var targetNode = this.tree.getRootNode();
36189 targetNode.ui.startDrop();
36190 var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, 'append', e) : null);
36191 return this.processDrop(targetNode, data, 'append', dd, e, dropNode);
36197 processDrop: function(target, data, point, dd, e, dropNode){
36205 dropNode: dropNode,
36209 var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
36210 if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
36211 target.ui.endDrop();
36212 return dropEvent.dropStatus;
36215 target = dropEvent.target;
36216 if(point == 'append' && !target.isExpanded()){
36217 target.expand(false, null, function(){
36218 this.completeDrop(dropEvent);
36219 }.createDelegate(this));
36221 this.completeDrop(dropEvent);
36227 completeDrop : function(de){
36228 var ns = de.dropNode, p = de.point, t = de.target;
36229 if(!Ext.isArray(ns)){
36233 for(var i = 0, len = ns.length; i < len; i++){
36236 t.parentNode.insertBefore(n, t);
36237 }else if(p == "below"){
36238 t.parentNode.insertBefore(n, t.nextSibling);
36244 if(Ext.enableFx && this.tree.hlDrop){
36248 this.tree.fireEvent("nodedrop", de);
36252 afterNodeMoved : function(dd, data, e, targetNode, dropNode){
36253 if(Ext.enableFx && this.tree.hlDrop){
36254 dropNode.ui.focus();
36255 dropNode.ui.highlight();
36257 this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
36261 getTree : function(){
36266 removeDropIndicators : function(n){
36269 Ext.fly(el).removeClass([
36270 "x-tree-drag-insert-above",
36271 "x-tree-drag-insert-below",
36272 "x-tree-drag-append"]);
36273 this.lastInsertClass = "_noclass";
36278 beforeDragDrop : function(target, e, id){
36279 this.cancelExpand();
36284 afterRepair : function(data){
36285 if(data && Ext.enableFx){
36286 data.node.ui.highlight();
36293 if(Ext.dd.DragZone){
36294 Ext.tree.TreeDragZone = function(tree, config){
36295 Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.innerCt, config);
36300 Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
36302 ddGroup : "TreeDD",
36305 onBeforeDrag : function(data, e){
36307 return n && n.draggable && !n.disabled;
36311 onInitDrag : function(e){
36312 var data = this.dragData;
36313 this.tree.getSelectionModel().select(data.node);
36314 this.tree.eventModel.disable();
36315 this.proxy.update("");
36316 data.node.ui.appendDDGhost(this.proxy.ghost.dom);
36317 this.tree.fireEvent("startdrag", this.tree, data.node, e);
36321 getRepairXY : function(e, data){
36322 return data.node.ui.getDDRepairXY();
36326 onEndDrag : function(data, e){
36327 this.tree.eventModel.enable.defer(100, this.tree.eventModel);
36328 this.tree.fireEvent("enddrag", this.tree, data.node, e);
36332 onValidDrop : function(dd, e, id){
36333 this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);
36338 beforeInvalidDrop : function(e, id){
36340 var sm = this.tree.getSelectionModel();
36341 sm.clearSelections();
36342 sm.select(this.dragData.node);
36346 afterRepair : function(){
36347 if (Ext.enableFx && this.tree.hlDrop) {
36348 Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
36350 this.dragging = false;
36354 Ext.tree.TreeEditor = function(tree, fc, config){
36356 var field = fc.events ? fc : new Ext.form.TextField(fc);
36358 Ext.tree.TreeEditor.superclass.constructor.call(this, field, config);
36362 if(!tree.rendered){
36363 tree.on('render', this.initEditor, this);
36365 this.initEditor(tree);
36369 Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
36377 cls: "x-small-editor x-tree-editor",
36387 initEditor : function(tree){
36390 beforeclick: this.beforeNodeClick,
36391 dblclick : this.onNodeDblClick
36396 complete : this.updateNode,
36397 beforestartedit: this.fitToTree,
36398 specialkey : this.onSpecialKey
36401 this.on('startedit', this.bindScroll, this, {delay:10});
36405 fitToTree : function(ed, el){
36406 var td = this.tree.getTreeEl().dom, nd = el.dom;
36407 if(td.scrollLeft > nd.offsetLeft){
36408 td.scrollLeft = nd.offsetLeft;
36412 (td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
36413 this.setSize(w, '');
36417 triggerEdit : function(node, defer){
36418 this.completeEdit();
36419 if(node.attributes.editable !== false){
36421 this.editNode = node;
36422 if(this.tree.autoScroll){
36423 Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body);
36425 var value = node.text || '';
36426 if (!Ext.isGecko && Ext.isEmpty(node.text)){
36427 node.setText(' ');
36429 this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]);
36435 bindScroll : function(){
36436 this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
36440 beforeNodeClick : function(node, e){
36441 clearTimeout(this.autoEditTimer);
36442 if(this.tree.getSelectionModel().isSelected(node)){
36444 return this.triggerEdit(node);
36448 onNodeDblClick : function(node, e){
36449 clearTimeout(this.autoEditTimer);
36453 updateNode : function(ed, value){
36454 this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
36455 this.editNode.setText(value);
36459 onHide : function(){
36460 Ext.tree.TreeEditor.superclass.onHide.call(this);
36462 this.editNode.ui.focus.defer(50, this.editNode.ui);
36467 onSpecialKey : function(field, e){
36468 var k = e.getKey();
36472 }else if(k == e.ENTER && !e.hasModifier()){
36474 this.completeEdit();
36478 onDestroy : function(){
36479 clearTimeout(this.autoEditTimer);
36480 Ext.tree.TreeEditor.superclass.onDestroy.call(this);
36481 var tree = this.tree;
36482 tree.un('beforeclick', this.beforeNodeClick, this);
36483 tree.un('dblclick', this.onNodeDblClick, this);
36487 var swfobject = function() {
36489 var UNDEF = "undefined",
36491 SHOCKWAVE_FLASH = "Shockwave Flash",
36492 SHOCKWAVE_FLASH_AX = "ShockwaveFlash.ShockwaveFlash",
36493 FLASH_MIME_TYPE = "application/x-shockwave-flash",
36494 EXPRESS_INSTALL_ID = "SWFObjectExprInst",
36495 ON_READY_STATE_CHANGE = "onreadystatechange",
36502 domLoadFnArr = [main],
36507 storedAltContentId,
36510 isDomLoaded = false,
36511 isExpressInstallActive = false,
36513 dynamicStylesheetMedia,
36514 autoHideShow = true,
36518 var w3cdom = typeof doc.getElementById != UNDEF && typeof doc.getElementsByTagName != UNDEF && typeof doc.createElement != UNDEF,
36519 u = nav.userAgent.toLowerCase(),
36520 p = nav.platform.toLowerCase(),
36521 windows = p ? (/win/).test(p) : /win/.test(u),
36522 mac = p ? (/mac/).test(p) : /mac/.test(u),
36523 webkit = /webkit/.test(u) ? parseFloat(u.replace(/^.*webkit\/(\d+(\.\d+)?).*$/, "$1")) : false,
36525 playerVersion = [0,0,0],
36527 if (typeof nav.plugins != UNDEF && typeof nav.plugins[SHOCKWAVE_FLASH] == OBJECT) {
36528 d = nav.plugins[SHOCKWAVE_FLASH].description;
36529 if (d && !(typeof nav.mimeTypes != UNDEF && nav.mimeTypes[FLASH_MIME_TYPE] && !nav.mimeTypes[FLASH_MIME_TYPE].enabledPlugin)) {
36532 d = d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
36533 playerVersion[0] = parseInt(d.replace(/^(.*)\..*$/, "$1"), 10);
36534 playerVersion[1] = parseInt(d.replace(/^.*\.(.*)\s.*$/, "$1"), 10);
36535 playerVersion[2] = /[a-zA-Z]/.test(d) ? parseInt(d.replace(/^.*[a-zA-Z]+(.*)$/, "$1"), 10) : 0;
36538 else if (typeof win.ActiveXObject != UNDEF) {
36540 var a = new ActiveXObject(SHOCKWAVE_FLASH_AX);
36542 d = a.GetVariable("$version");
36545 d = d.split(" ")[1].split(",");
36546 playerVersion = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
36552 return { w3:w3cdom, pv:playerVersion, wk:webkit, ie:ie, win:windows, mac:mac };
36556 onDomLoad = function() {
36557 if (!ua.w3) { return; }
36558 if ((typeof doc.readyState != UNDEF && doc.readyState == "complete") || (typeof doc.readyState == UNDEF && (doc.getElementsByTagName("body")[0] || doc.body))) {
36559 callDomLoadFunctions();
36561 if (!isDomLoaded) {
36562 if (typeof doc.addEventListener != UNDEF) {
36563 doc.addEventListener("DOMContentLoaded", callDomLoadFunctions, false);
36565 if (ua.ie && ua.win) {
36566 doc.attachEvent(ON_READY_STATE_CHANGE, function() {
36567 if (doc.readyState == "complete") {
36568 doc.detachEvent(ON_READY_STATE_CHANGE, arguments.callee);
36569 callDomLoadFunctions();
36574 if (isDomLoaded) { return; }
36576 doc.documentElement.doScroll("left");
36579 setTimeout(arguments.callee, 0);
36582 callDomLoadFunctions();
36588 if (isDomLoaded) { return; }
36589 if (!(/loaded|complete/).test(doc.readyState)) {
36590 setTimeout(arguments.callee, 0);
36593 callDomLoadFunctions();
36596 addLoadEvent(callDomLoadFunctions);
36600 function callDomLoadFunctions() {
36601 if (isDomLoaded) { return; }
36603 var t = doc.getElementsByTagName("body")[0].appendChild(createElement("span"));
36604 t.parentNode.removeChild(t);
36606 catch (e) { return; }
36607 isDomLoaded = true;
36608 var dl = domLoadFnArr.length;
36609 for (var i = 0; i < dl; i++) {
36614 function addDomLoadEvent(fn) {
36619 domLoadFnArr[domLoadFnArr.length] = fn;
36624 function addLoadEvent(fn) {
36625 if (typeof win.addEventListener != UNDEF) {
36626 win.addEventListener("load", fn, false);
36628 else if (typeof doc.addEventListener != UNDEF) {
36629 doc.addEventListener("load", fn, false);
36631 else if (typeof win.attachEvent != UNDEF) {
36632 addListener(win, "onload", fn);
36634 else if (typeof win.onload == "function") {
36635 var fnOld = win.onload;
36636 win.onload = function() {
36649 testPlayerVersion();
36657 function testPlayerVersion() {
36658 var b = doc.getElementsByTagName("body")[0];
36659 var o = createElement(OBJECT);
36660 o.setAttribute("type", FLASH_MIME_TYPE);
36661 var t = b.appendChild(o);
36665 if (typeof t.GetVariable != UNDEF) {
36666 var d = t.GetVariable("$version");
36668 d = d.split(" ")[1].split(",");
36669 ua.pv = [parseInt(d[0], 10), parseInt(d[1], 10), parseInt(d[2], 10)];
36672 else if (counter < 10) {
36674 setTimeout(arguments.callee, 10);
36688 function matchVersions() {
36689 var rl = regObjArr.length;
36691 for (var i = 0; i < rl; i++) {
36692 var id = regObjArr[i].id;
36693 var cb = regObjArr[i].callbackFn;
36694 var cbObj = {success:false, id:id};
36695 if (ua.pv[0] > 0) {
36696 var obj = getElementById(id);
36698 if (hasPlayerVersion(regObjArr[i].swfVersion) && !(ua.wk && ua.wk < 312)) {
36699 setVisibility(id, true);
36701 cbObj.success = true;
36702 cbObj.ref = getObjectById(id);
36706 else if (regObjArr[i].expressInstall && canExpressInstall()) {
36708 att.data = regObjArr[i].expressInstall;
36709 att.width = obj.getAttribute("width") || "0";
36710 att.height = obj.getAttribute("height") || "0";
36711 if (obj.getAttribute("class")) { att.styleclass = obj.getAttribute("class"); }
36712 if (obj.getAttribute("align")) { att.align = obj.getAttribute("align"); }
36715 var p = obj.getElementsByTagName("param");
36717 for (var j = 0; j < pl; j++) {
36718 if (p[j].getAttribute("name").toLowerCase() != "movie") {
36719 par[p[j].getAttribute("name")] = p[j].getAttribute("value");
36722 showExpressInstall(att, par, id, cb);
36725 displayAltContent(obj);
36726 if (cb) { cb(cbObj); }
36731 setVisibility(id, true);
36733 var o = getObjectById(id);
36734 if (o && typeof o.SetVariable != UNDEF) {
36735 cbObj.success = true;
36745 function getObjectById(objectIdStr) {
36747 var o = getElementById(objectIdStr);
36748 if (o && o.nodeName == "OBJECT") {
36749 if (typeof o.SetVariable != UNDEF) {
36753 var n = o.getElementsByTagName(OBJECT)[0];
36763 function canExpressInstall() {
36764 return !isExpressInstallActive && hasPlayerVersion("6.0.65") && (ua.win || ua.mac) && !(ua.wk && ua.wk < 312);
36768 function showExpressInstall(att, par, replaceElemIdStr, callbackFn) {
36769 isExpressInstallActive = true;
36770 storedCallbackFn = callbackFn || null;
36771 storedCallbackObj = {success:false, id:replaceElemIdStr};
36772 var obj = getElementById(replaceElemIdStr);
36774 if (obj.nodeName == "OBJECT") {
36775 storedAltContent = abstractAltContent(obj);
36776 storedAltContentId = null;
36779 storedAltContent = obj;
36780 storedAltContentId = replaceElemIdStr;
36782 att.id = EXPRESS_INSTALL_ID;
36783 if (typeof att.width == UNDEF || (!(/%$/).test(att.width) && parseInt(att.width, 10) < 310)) {
36787 if (typeof att.height == UNDEF || (!(/%$/).test(att.height) && parseInt(att.height, 10) < 137)) {
36788 att.height = "137";
36790 doc.title = doc.title.slice(0, 47) + " - Flash Player Installation";
36791 var pt = ua.ie && ua.win ? "ActiveX" : "PlugIn",
36792 fv = "MMredirectURL=" + win.location.toString().replace(/&/g,"%26") + "&MMplayerType=" + pt + "&MMdoctitle=" + doc.title;
36793 if (typeof par.flashvars != UNDEF) {
36794 par.flashvars += "&" + fv;
36797 par.flashvars = fv;
36801 if (ua.ie && ua.win && obj.readyState != 4) {
36802 var newObj = createElement("div");
36803 replaceElemIdStr += "SWFObjectNew";
36804 newObj.setAttribute("id", replaceElemIdStr);
36805 obj.parentNode.insertBefore(newObj, obj);
36806 obj.style.display = "none";
36808 if (obj.readyState == 4) {
36809 obj.parentNode.removeChild(obj);
36812 setTimeout(arguments.callee, 10);
36816 createSWF(att, par, replaceElemIdStr);
36821 function displayAltContent(obj) {
36822 if (ua.ie && ua.win && obj.readyState != 4) {
36825 var el = createElement("div");
36826 obj.parentNode.insertBefore(el, obj);
36827 el.parentNode.replaceChild(abstractAltContent(obj), el);
36828 obj.style.display = "none";
36830 if (obj.readyState == 4) {
36831 obj.parentNode.removeChild(obj);
36834 setTimeout(arguments.callee, 10);
36839 obj.parentNode.replaceChild(abstractAltContent(obj), obj);
36843 function abstractAltContent(obj) {
36844 var ac = createElement("div");
36845 if (ua.win && ua.ie) {
36846 ac.innerHTML = obj.innerHTML;
36849 var nestedObj = obj.getElementsByTagName(OBJECT)[0];
36851 var c = nestedObj.childNodes;
36854 for (var i = 0; i < cl; i++) {
36855 if (!(c[i].nodeType == 1 && c[i].nodeName == "PARAM") && !(c[i].nodeType == 8)) {
36856 ac.appendChild(c[i].cloneNode(true));
36866 function createSWF(attObj, parObj, id) {
36867 var r, el = getElementById(id);
36868 if (ua.wk && ua.wk < 312) { return r; }
36870 if (typeof attObj.id == UNDEF) {
36873 if (ua.ie && ua.win) {
36875 for (var i in attObj) {
36876 if (attObj[i] != Object.prototype[i]) {
36877 if (i.toLowerCase() == "data") {
36878 parObj.movie = attObj[i];
36880 else if (i.toLowerCase() == "styleclass") {
36881 att += ' class="' + attObj[i] + '"';
36883 else if (i.toLowerCase() != "classid") {
36884 att += ' ' + i + '="' + attObj[i] + '"';
36889 for (var j in parObj) {
36890 if (parObj[j] != Object.prototype[j]) {
36891 par += '<param name="' + j + '" value="' + parObj[j] + '" />';
36894 el.outerHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"' + att + '>' + par + '</object>';
36895 objIdArr[objIdArr.length] = attObj.id;
36896 r = getElementById(attObj.id);
36899 var o = createElement(OBJECT);
36900 o.setAttribute("type", FLASH_MIME_TYPE);
36901 for (var m in attObj) {
36902 if (attObj[m] != Object.prototype[m]) {
36903 if (m.toLowerCase() == "styleclass") {
36904 o.setAttribute("class", attObj[m]);
36906 else if (m.toLowerCase() != "classid") {
36907 o.setAttribute(m, attObj[m]);
36911 for (var n in parObj) {
36912 if (parObj[n] != Object.prototype[n] && n.toLowerCase() != "movie") {
36913 createObjParam(o, n, parObj[n]);
36916 el.parentNode.replaceChild(o, el);
36923 function createObjParam(el, pName, pValue) {
36924 var p = createElement("param");
36925 p.setAttribute("name", pName);
36926 p.setAttribute("value", pValue);
36931 function removeSWF(id) {
36932 var obj = getElementById(id);
36933 if (obj && obj.nodeName == "OBJECT") {
36934 if (ua.ie && ua.win) {
36935 obj.style.display = "none";
36937 if (obj.readyState == 4) {
36938 removeObjectInIE(id);
36941 setTimeout(arguments.callee, 10);
36946 obj.parentNode.removeChild(obj);
36951 function removeObjectInIE(id) {
36952 var obj = getElementById(id);
36954 for (var i in obj) {
36955 if (typeof obj[i] == "function") {
36959 obj.parentNode.removeChild(obj);
36964 function getElementById(id) {
36967 el = doc.getElementById(id);
36973 function createElement(el) {
36974 return doc.createElement(el);
36978 function addListener(target, eventType, fn) {
36979 target.attachEvent(eventType, fn);
36980 listenersArr[listenersArr.length] = [target, eventType, fn];
36984 function hasPlayerVersion(rv) {
36985 var pv = ua.pv, v = rv.split(".");
36986 v[0] = parseInt(v[0], 10);
36987 v[1] = parseInt(v[1], 10) || 0;
36988 v[2] = parseInt(v[2], 10) || 0;
36989 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;
36993 function createCSS(sel, decl, media, newStyle) {
36994 if (ua.ie && ua.mac) { return; }
36995 var h = doc.getElementsByTagName("head")[0];
36996 if (!h) { return; }
36997 var m = (media && typeof media == "string") ? media : "screen";
36999 dynamicStylesheet = null;
37000 dynamicStylesheetMedia = null;
37002 if (!dynamicStylesheet || dynamicStylesheetMedia != m) {
37004 var s = createElement("style");
37005 s.setAttribute("type", "text/css");
37006 s.setAttribute("media", m);
37007 dynamicStylesheet = h.appendChild(s);
37008 if (ua.ie && ua.win && typeof doc.styleSheets != UNDEF && doc.styleSheets.length > 0) {
37009 dynamicStylesheet = doc.styleSheets[doc.styleSheets.length - 1];
37011 dynamicStylesheetMedia = m;
37014 if (ua.ie && ua.win) {
37015 if (dynamicStylesheet && typeof dynamicStylesheet.addRule == OBJECT) {
37016 dynamicStylesheet.addRule(sel, decl);
37020 if (dynamicStylesheet && typeof doc.createTextNode != UNDEF) {
37021 dynamicStylesheet.appendChild(doc.createTextNode(sel + " {" + decl + "}"));
37026 function setVisibility(id, isVisible) {
37027 if (!autoHideShow) { return; }
37028 var v = isVisible ? "visible" : "hidden";
37029 if (isDomLoaded && getElementById(id)) {
37030 getElementById(id).style.visibility = v;
37033 createCSS("#" + id, "visibility:" + v);
37038 function urlEncodeIfNecessary(s) {
37039 var regex = /[\\\"<>\.;]/;
37040 var hasBadChars = regex.exec(s) != null;
37041 return hasBadChars && typeof encodeURIComponent != UNDEF ? encodeURIComponent(s) : s;
37045 var cleanup = function() {
37046 if (ua.ie && ua.win) {
37047 window.attachEvent("onunload", function() {
37049 var ll = listenersArr.length;
37050 for (var i = 0; i < ll; i++) {
37051 listenersArr[i][0].detachEvent(listenersArr[i][1], listenersArr[i][2]);
37054 var il = objIdArr.length;
37055 for (var j = 0; j < il; j++) {
37056 removeSWF(objIdArr[j]);
37059 for (var k in ua) {
37063 for (var l in swfobject) {
37064 swfobject[l] = null;
37073 registerObject: function(objectIdStr, swfVersionStr, xiSwfUrlStr, callbackFn) {
37074 if (ua.w3 && objectIdStr && swfVersionStr) {
37076 regObj.id = objectIdStr;
37077 regObj.swfVersion = swfVersionStr;
37078 regObj.expressInstall = xiSwfUrlStr;
37079 regObj.callbackFn = callbackFn;
37080 regObjArr[regObjArr.length] = regObj;
37081 setVisibility(objectIdStr, false);
37083 else if (callbackFn) {
37084 callbackFn({success:false, id:objectIdStr});
37088 getObjectById: function(objectIdStr) {
37090 return getObjectById(objectIdStr);
37094 embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) {
37095 var callbackObj = {success:false, id:replaceElemIdStr};
37096 if (ua.w3 && !(ua.wk && ua.wk < 312) && swfUrlStr && replaceElemIdStr && widthStr && heightStr && swfVersionStr) {
37097 setVisibility(replaceElemIdStr, false);
37098 addDomLoadEvent(function() {
37102 if (attObj && typeof attObj === OBJECT) {
37103 for (var i in attObj) {
37104 att[i] = attObj[i];
37107 att.data = swfUrlStr;
37108 att.width = widthStr;
37109 att.height = heightStr;
37111 if (parObj && typeof parObj === OBJECT) {
37112 for (var j in parObj) {
37113 par[j] = parObj[j];
37116 if (flashvarsObj && typeof flashvarsObj === OBJECT) {
37117 for (var k in flashvarsObj) {
37118 if (typeof par.flashvars != UNDEF) {
37119 par.flashvars += "&" + k + "=" + flashvarsObj[k];
37122 par.flashvars = k + "=" + flashvarsObj[k];
37126 if (hasPlayerVersion(swfVersionStr)) {
37127 var obj = createSWF(att, par, replaceElemIdStr);
37128 if (att.id == replaceElemIdStr) {
37129 setVisibility(replaceElemIdStr, true);
37131 callbackObj.success = true;
37132 callbackObj.ref = obj;
37134 else if (xiSwfUrlStr && canExpressInstall()) {
37135 att.data = xiSwfUrlStr;
37136 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
37140 setVisibility(replaceElemIdStr, true);
37142 if (callbackFn) { callbackFn(callbackObj); }
37145 else if (callbackFn) { callbackFn(callbackObj); }
37148 switchOffAutoHideShow: function() {
37149 autoHideShow = false;
37154 getFlashPlayerVersion: function() {
37155 return { major:ua.pv[0], minor:ua.pv[1], release:ua.pv[2] };
37158 hasFlashPlayerVersion: hasPlayerVersion,
37160 createSWF: function(attObj, parObj, replaceElemIdStr) {
37162 return createSWF(attObj, parObj, replaceElemIdStr);
37169 showExpressInstall: function(att, par, replaceElemIdStr, callbackFn) {
37170 if (ua.w3 && canExpressInstall()) {
37171 showExpressInstall(att, par, replaceElemIdStr, callbackFn);
37175 removeSWF: function(objElemIdStr) {
37177 removeSWF(objElemIdStr);
37181 createCSS: function(selStr, declStr, mediaStr, newStyleBoolean) {
37183 createCSS(selStr, declStr, mediaStr, newStyleBoolean);
37187 addDomLoadEvent: addDomLoadEvent,
37189 addLoadEvent: addLoadEvent,
37191 getQueryParamValue: function(param) {
37192 var q = doc.location.search || doc.location.hash;
37194 if (/\?/.test(q)) { q = q.split("?")[1]; }
37195 if (param == null) {
37196 return urlEncodeIfNecessary(q);
37198 var pairs = q.split("&");
37199 for (var i = 0; i < pairs.length; i++) {
37200 if (pairs[i].substring(0, pairs[i].indexOf("=")) == param) {
37201 return urlEncodeIfNecessary(pairs[i].substring((pairs[i].indexOf("=") + 1)));
37209 expressInstallCallback: function() {
37210 if (isExpressInstallActive) {
37211 var obj = getElementById(EXPRESS_INSTALL_ID);
37212 if (obj && storedAltContent) {
37213 obj.parentNode.replaceChild(storedAltContent, obj);
37214 if (storedAltContentId) {
37215 setVisibility(storedAltContentId, true);
37216 if (ua.ie && ua.win) { storedAltContent.style.display = "block"; }
37218 if (storedCallbackFn) { storedCallbackFn(storedCallbackObj); }
37220 isExpressInstallActive = false;
37226 Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
37228 flashVersion : '9.0.115',
37231 backgroundColor: '#ffffff',
37237 flashVars: undefined,
37240 flashParams: undefined,
37249 expressInstall: false,
37251 initComponent : function(){
37252 Ext.FlashComponent.superclass.initComponent.call(this);
37260 onRender : function(){
37261 Ext.FlashComponent.superclass.onRender.apply(this, arguments);
37263 var params = Ext.apply({
37264 allowScriptAccess: 'always',
37265 bgcolor: this.backgroundColor,
37267 }, this.flashParams), vars = Ext.apply({
37268 allowedDomain: document.location.hostname,
37269 YUISwfId: this.getId(),
37270 YUIBridgeCallback: 'Ext.FlashEventProxy.onEvent'
37271 }, this.flashVars);
37273 new swfobject.embedSWF(this.url, this.id, this.swfWidth, this.swfHeight, this.flashVersion,
37274 this.expressInstall ? Ext.FlashComponent.EXPRESS_INSTALL_URL : undefined, vars, params);
37276 this.swf = Ext.getDom(this.id);
37277 this.el = Ext.get(this.swf);
37280 getSwfId : function(){
37281 return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID));
37284 getId : function(){
37285 return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID));
37288 onFlashEvent : function(e){
37296 e.component = this;
37297 this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e);
37300 initSwf : function(){
37301 this.onSwfReady(!!this.isInitialized);
37302 this.isInitialized = true;
37303 this.fireEvent('initialize', this);
37306 beforeDestroy: function(){
37308 swfobject.removeSWF(this.swf.id);
37310 Ext.FlashComponent.superclass.beforeDestroy.call(this);
37313 onSwfReady : Ext.emptyFn
37317 Ext.FlashComponent.EXPRESS_INSTALL_URL = 'http:/' + '/swfobject.googlecode.com/svn/trunk/swfobject/expressInstall.swf';
37319 Ext.reg('flash', Ext.FlashComponent);
37320 Ext.FlashEventProxy = {
37321 onEvent : function(id, e){
37322 var fp = Ext.getCmp(id);
37324 fp.onFlashEvent(e);
37326 arguments.callee.defer(10, this, [id, e]);
37331 Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
37332 refreshBuffer: 100,
37339 animationEnabled: true,
37370 seriesStyles: null,
37373 disableCaching: Ext.isIE || Ext.isOpera,
37374 disableCacheParam: '_dc',
37376 initComponent : function(){
37377 Ext.chart.Chart.superclass.initComponent.call(this);
37379 this.url = Ext.chart.Chart.CHART_URL;
37381 if(this.disableCaching){
37382 this.url = Ext.urlAppend(this.url, String.format('{0}={1}', this.disableCacheParam, new Date().getTime()));
37397 this.store = Ext.StoreMgr.lookup(this.store);
37401 setStyle: function(name, value){
37402 this.swf.setStyle(name, Ext.encode(value));
37406 setStyles: function(styles){
37407 this.swf.setStyles(Ext.encode(styles));
37411 setSeriesStyles: function(styles){
37412 this.seriesStyles = styles;
37414 Ext.each(styles, function(style){
37415 s.push(Ext.encode(style));
37417 this.swf.setSeriesStyles(s);
37420 setCategoryNames : function(names){
37421 this.swf.setCategoryNames(names);
37424 setLegendRenderer : function(fn, scope){
37426 scope = scope || chart;
37427 chart.removeFnProxy(chart.legendFnName);
37428 chart.legendFnName = chart.createFnProxy(function(name){
37429 return fn.call(scope, name);
37431 chart.swf.setLegendLabelFunction(chart.legendFnName);
37434 setTipRenderer : function(fn, scope){
37436 scope = scope || chart;
37437 chart.removeFnProxy(chart.tipFnName);
37438 chart.tipFnName = chart.createFnProxy(function(item, index, series){
37439 var record = chart.store.getAt(index);
37440 return fn.call(scope, chart, record, index, series);
37442 chart.swf.setDataTipFunction(chart.tipFnName);
37445 setSeries : function(series){
37446 this.series = series;
37451 bindStore : function(store, initial){
37452 if(!initial && this.store){
37453 if(store !== this.store && this.store.autoDestroy){
37454 this.store.destroy();
37456 this.store.un("datachanged", this.refresh, this);
37457 this.store.un("add", this.delayRefresh, this);
37458 this.store.un("remove", this.delayRefresh, this);
37459 this.store.un("update", this.delayRefresh, this);
37460 this.store.un("clear", this.refresh, this);
37464 store = Ext.StoreMgr.lookup(store);
37467 datachanged: this.refresh,
37468 add: this.delayRefresh,
37469 remove: this.delayRefresh,
37470 update: this.delayRefresh,
37471 clear: this.refresh
37474 this.store = store;
37475 if(store && !initial){
37480 onSwfReady : function(isReset){
37481 Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
37483 this.swf.setType(this.type);
37485 if(this.chartStyle){
37486 this.setStyles(Ext.apply({}, this.extraStyle, this.chartStyle));
37489 if(this.categoryNames){
37490 this.setCategoryNames(this.categoryNames);
37493 if(this.tipRenderer){
37494 ref = this.getFunctionRef(this.tipRenderer);
37495 this.setTipRenderer(ref.fn, ref.scope);
37497 if(this.legendRenderer){
37498 ref = this.getFunctionRef(this.legendRenderer);
37499 this.setLegendRenderer(ref.fn, ref.scope);
37502 this.bindStore(this.store, true);
37504 this.refresh.defer(10, this);
37507 delayRefresh : function(){
37508 if(!this.refreshTask){
37509 this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
37511 this.refreshTask.delay(this.refreshBuffer);
37514 refresh : function(){
37515 if(this.fireEvent('beforerefresh', this) !== false){
37516 var styleChanged = false;
37518 var data = [], rs = this.store.data.items;
37519 for(var j = 0, len = rs.length; j < len; j++){
37520 data[j] = rs[j].data;
37524 var dataProvider = [];
37525 var seriesCount = 0;
37526 var currentSeries = null;
37529 seriesCount = this.series.length;
37530 for(i = 0; i < seriesCount; i++){
37531 currentSeries = this.series[i];
37532 var clonedSeries = {};
37533 for(var prop in currentSeries){
37534 if(prop == "style" && currentSeries.style !== null){
37535 clonedSeries.style = Ext.encode(currentSeries.style);
37536 styleChanged = true;
37542 clonedSeries[prop] = currentSeries[prop];
37545 dataProvider.push(clonedSeries);
37549 if(seriesCount > 0){
37550 for(i = 0; i < seriesCount; i++){
37551 currentSeries = dataProvider[i];
37552 if(!currentSeries.type){
37553 currentSeries.type = this.type;
37555 currentSeries.dataProvider = data;
37558 dataProvider.push({type: this.type, dataProvider: data});
37560 this.swf.setDataProvider(dataProvider);
37561 if(this.seriesStyles){
37562 this.setSeriesStyles(this.seriesStyles);
37564 this.fireEvent('refresh', this);
37569 createFnProxy : function(fn){
37570 var fnName = 'extFnProxy' + (++Ext.chart.Chart.PROXY_FN_ID);
37571 Ext.chart.Chart.proxyFunction[fnName] = fn;
37572 return 'Ext.chart.Chart.proxyFunction.' + fnName;
37576 removeFnProxy : function(fn){
37577 if(!Ext.isEmpty(fn)){
37578 fn = fn.replace('Ext.chart.Chart.proxyFunction.', '');
37579 delete Ext.chart.Chart.proxyFunction[fn];
37584 getFunctionRef : function(val){
37585 if(Ext.isFunction(val)){
37593 scope: val.scope || this
37599 onDestroy: function(){
37600 if (this.refreshTask && this.refreshTask.cancel){
37601 this.refreshTask.cancel();
37603 Ext.chart.Chart.superclass.onDestroy.call(this);
37604 this.bindStore(null);
37605 this.removeFnProxy(this.tipFnName);
37606 this.removeFnProxy(this.legendFnName);
37609 Ext.reg('chart', Ext.chart.Chart);
37610 Ext.chart.Chart.PROXY_FN_ID = 0;
37611 Ext.chart.Chart.proxyFunction = {};
37614 Ext.chart.Chart.CHART_URL = 'http:/' + '/yui.yahooapis.com/2.8.0/build/charts/assets/charts.swf';
37617 Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
37620 onSwfReady : function(isReset){
37621 Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
37623 this.setDataField(this.dataField);
37624 this.setCategoryField(this.categoryField);
37627 setDataField : function(field){
37628 this.dataField = field;
37629 this.swf.setDataField(field);
37632 setCategoryField : function(field){
37633 this.categoryField = field;
37634 this.swf.setCategoryField(field);
37637 Ext.reg('piechart', Ext.chart.PieChart);
37640 Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
37641 onSwfReady : function(isReset){
37642 Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
37645 this.setXField(this.xField);
37648 this.setYField(this.yField);
37651 this.setXAxis(this.xAxis);
37654 this.setXAxes(this.xAxes);
37657 this.setYAxis(this.yAxis);
37660 this.setYAxes(this.yAxes);
37662 if(Ext.isDefined(this.constrainViewport)){
37663 this.swf.setConstrainViewport(this.constrainViewport);
37667 setXField : function(value){
37668 this.xField = value;
37669 this.swf.setHorizontalField(value);
37672 setYField : function(value){
37673 this.yField = value;
37674 this.swf.setVerticalField(value);
37677 setXAxis : function(value){
37678 this.xAxis = this.createAxis('xAxis', value);
37679 this.swf.setHorizontalAxis(this.xAxis);
37682 setXAxes : function(value){
37684 for(var i = 0; i < value.length; i++) {
37685 axis = this.createAxis('xAxis' + i, value[i]);
37686 this.swf.setHorizontalAxis(axis);
37690 setYAxis : function(value){
37691 this.yAxis = this.createAxis('yAxis', value);
37692 this.swf.setVerticalAxis(this.yAxis);
37695 setYAxes : function(value){
37697 for(var i = 0; i < value.length; i++) {
37698 axis = this.createAxis('yAxis' + i, value[i]);
37699 this.swf.setVerticalAxis(axis);
37703 createAxis : function(axis, value){
37704 var o = Ext.apply({}, value),
37709 old = this[axis].labelFunction;
37710 this.removeFnProxy(old);
37711 this.labelFn.remove(old);
37713 if(o.labelRenderer){
37714 ref = this.getFunctionRef(o.labelRenderer);
37715 o.labelFunction = this.createFnProxy(function(v){
37716 return ref.fn.call(ref.scope, v);
37718 delete o.labelRenderer;
37719 this.labelFn.push(o.labelFunction);
37721 if(axis.indexOf('xAxis') > -1 && o.position == 'left'){
37722 o.position = 'bottom';
37727 onDestroy : function(){
37728 Ext.chart.CartesianChart.superclass.onDestroy.call(this);
37729 Ext.each(this.labelFn, function(fn){
37730 this.removeFnProxy(fn);
37734 Ext.reg('cartesianchart', Ext.chart.CartesianChart);
37737 Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
37740 Ext.reg('linechart', Ext.chart.LineChart);
37743 Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
37746 Ext.reg('columnchart', Ext.chart.ColumnChart);
37749 Ext.chart.StackedColumnChart = Ext.extend(Ext.chart.CartesianChart, {
37750 type: 'stackcolumn'
37752 Ext.reg('stackedcolumnchart', Ext.chart.StackedColumnChart);
37755 Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
37758 Ext.reg('barchart', Ext.chart.BarChart);
37761 Ext.chart.StackedBarChart = Ext.extend(Ext.chart.CartesianChart, {
37764 Ext.reg('stackedbarchart', Ext.chart.StackedBarChart);
37769 Ext.chart.Axis = function(config){
37770 Ext.apply(this, config);
37773 Ext.chart.Axis.prototype =
37779 orientation: "horizontal",
37785 labelFunction: null,
37788 hideOverlappingLabels: true,
37795 Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
37814 alwaysShowZero: true,
37820 roundMajorUnit: true,
37823 calculateByLabelSize: true,
37829 adjustMaximumByMajorUnit: true,
37832 adjustMinimumByMajorUnit: true
37837 Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
37850 majorTimeUnit: null,
37856 minorTimeUnit: null,
37862 stackingEnabled: false,
37865 calculateByLabelSize: true
37870 Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
37874 categoryNames: null,
37877 calculateCategoryCount: false
37882 Ext.chart.Series = function(config) { Ext.apply(this, config); };
37884 Ext.chart.Series.prototype =
37894 Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
37902 showInLegend: true,
37909 Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
37914 Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
37919 Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
37925 Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
37928 categoryField: null
37930 Ext.menu.Menu = Ext.extend(Ext.Container, {
37938 subMenuAlign : 'tl-tr?',
37940 defaultAlign : 'tl-bl?',
37942 allowOtherMenus : false,
37944 ignoreParentClicks : false,
37946 enableScrolling : true,
37950 scrollIncrement : 24,
37952 showSeparator : true,
37954 defaultOffsets : [0, 0],
37971 hideMode : 'offsets',
37972 scrollerHeight : 8,
37974 defaultType : 'menuitem',
37975 bufferResize : false,
37977 initComponent : function(){
37978 if(Ext.isArray(this.initialConfig)){
37979 Ext.apply(this, {items:this.initialConfig});
37991 Ext.menu.MenuMgr.register(this);
37993 Ext.EventManager.onWindowResize(this.hide, this);
37995 if(this.initialConfig.hidden !== false){
37996 this.hidden = false;
37998 this.internalDefaults = {hideOnClick: false};
38000 Ext.menu.Menu.superclass.initComponent.call(this);
38001 if(this.autoLayout){
38002 var fn = this.doLayout.createDelegate(this, []);
38011 getLayoutTarget : function() {
38016 onRender : function(ct, position){
38018 ct = Ext.getBody();
38023 cls: 'x-menu ' + ((this.floating) ? 'x-menu-floating x-layer ' : '') + (this.cls || '') + (this.plain ? ' x-menu-plain' : '') + (this.showSeparator ? '' : ' x-menu-nosep'),
38026 {tag: 'a', cls: 'x-menu-focus', href: '#', onclick: 'return false;', tabIndex: '-1'},
38027 {tag: 'ul', cls: 'x-menu-list'}
38031 this.el = new Ext.Layer({
38032 shadow: this.shadow,
38036 zindex: this.zIndex
38039 this.el = ct.createChild(dh);
38041 Ext.menu.Menu.superclass.onRender.call(this, ct, position);
38044 this.keyNav = new Ext.menu.MenuNav(this);
38047 this.focusEl = this.el.child('a.x-menu-focus');
38048 this.ul = this.el.child('ul.x-menu-list');
38049 this.mon(this.ul, {
38051 click: this.onClick,
38052 mouseover: this.onMouseOver,
38053 mouseout: this.onMouseOut
38055 if(this.enableScrolling){
38056 this.mon(this.el, {
38058 delegate: '.x-menu-scroller',
38059 click: this.onScroll,
38060 mouseover: this.deactivateActive
38066 findTargetItem : function(e){
38067 var t = e.getTarget('.x-menu-list-item', this.ul, true);
38068 if(t && t.menuItemId){
38069 return this.items.get(t.menuItemId);
38074 onClick : function(e){
38075 var t = this.findTargetItem(e);
38078 this.setActiveItem(t);
38079 }else if(t instanceof Ext.menu.BaseItem){
38080 if(t.menu && this.ignoreParentClicks){
38082 e.preventDefault();
38083 }else if(t.onClick){
38085 this.fireEvent('click', this, t, e);
38092 setActiveItem : function(item, autoExpand){
38093 if(item != this.activeItem){
38094 this.deactivateActive();
38095 if((this.activeItem = item).isFormField){
38098 item.activate(autoExpand);
38100 }else if(autoExpand){
38105 deactivateActive : function(){
38106 var a = this.activeItem;
38116 delete this.activeItem;
38121 tryActivate : function(start, step){
38122 var items = this.items;
38123 for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
38124 var item = items.get(i);
38125 if(item.isVisible() && !item.disabled && (item.canActivate || item.isFormField)){
38126 this.setActiveItem(item, false);
38134 onMouseOver : function(e){
38135 var t = this.findTargetItem(e);
38137 if(t.canActivate && !t.disabled){
38138 this.setActiveItem(t, true);
38142 this.fireEvent('mouseover', this, e, t);
38146 onMouseOut : function(e){
38147 var t = this.findTargetItem(e);
38149 if(t == this.activeItem && t.shouldDeactivate && t.shouldDeactivate(e)){
38150 this.activeItem.deactivate();
38151 delete this.activeItem;
38155 this.fireEvent('mouseout', this, e, t);
38159 onScroll : function(e, t){
38163 var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
38164 ul.scrollTop += this.scrollIncrement * (top ? -1 : 1);
38165 if(top ? ul.scrollTop <= 0 : ul.scrollTop + this.activeMax >= ul.scrollHeight){
38166 this.onScrollerOut(null, t);
38171 onScrollerIn : function(e, t){
38172 var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
38173 if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){
38174 Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']);
38179 onScrollerOut : function(e, t){
38180 Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']);
38184 show : function(el, pos, parentMenu){
38186 this.parentMenu = parentMenu;
38189 this.doLayout(false, true);
38191 this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign, this.defaultOffsets), parentMenu);
38193 Ext.menu.Menu.superclass.show.call(this);
38198 showAt : function(xy, parentMenu){
38199 if(this.fireEvent('beforeshow', this) !== false){
38200 this.parentMenu = parentMenu;
38204 if(this.enableScrolling){
38208 xy[1] = this.constrainScroll(xy[1]);
38209 xy = [this.el.adjustForConstraints(xy)[0], xy[1]];
38212 xy = this.el.adjustForConstraints(xy);
38216 Ext.menu.Menu.superclass.onShow.call(this);
38219 this.fireEvent('autosize', this);
38224 this.hidden = false;
38226 this.fireEvent('show', this);
38230 constrainScroll : function(y){
38231 var max, full = this.ul.setHeight('auto').getHeight(),
38232 returnY = y, normalY, parentEl, scrollTop, viewHeight;
38234 parentEl = Ext.fly(this.el.dom.parentNode);
38235 scrollTop = parentEl.getScroll().top;
38236 viewHeight = parentEl.getViewSize().height;
38239 normalY = y - scrollTop;
38240 max = this.maxHeight ? this.maxHeight : viewHeight - normalY;
38241 if(full > viewHeight) {
38244 returnY = y - normalY;
38245 } else if(max < full) {
38246 returnY = y - (full - max);
38250 max = this.getHeight();
38253 if (this.maxHeight){
38254 max = Math.min(this.maxHeight, max);
38256 if(full > max && max > 0){
38257 this.activeMax = max - this.scrollerHeight * 2 - this.el.getFrameWidth('tb') - Ext.num(this.el.shadowOffset, 0);
38258 this.ul.setHeight(this.activeMax);
38259 this.createScrollers();
38260 this.el.select('.x-menu-scroller').setDisplayed('');
38262 this.ul.setHeight(full);
38263 this.el.select('.x-menu-scroller').setDisplayed('none');
38265 this.ul.dom.scrollTop = 0;
38269 createScrollers : function(){
38270 if(!this.scroller){
38273 top: this.el.insertFirst({
38275 cls: 'x-menu-scroller x-menu-scroller-top',
38278 bottom: this.el.createChild({
38280 cls: 'x-menu-scroller x-menu-scroller-bottom',
38284 this.scroller.top.hover(this.onScrollerIn, this.onScrollerOut, this);
38285 this.scroller.topRepeater = new Ext.util.ClickRepeater(this.scroller.top, {
38287 click: this.onScroll.createDelegate(this, [null, this.scroller.top], false)
38290 this.scroller.bottom.hover(this.onScrollerIn, this.onScrollerOut, this);
38291 this.scroller.bottomRepeater = new Ext.util.ClickRepeater(this.scroller.bottom, {
38293 click: this.onScroll.createDelegate(this, [null, this.scroller.bottom], false)
38299 onLayout : function(){
38300 if(this.isVisible()){
38301 if(this.enableScrolling){
38302 this.constrainScroll(this.el.getTop());
38310 focus : function(){
38312 this.doFocus.defer(50, this);
38316 doFocus : function(){
38318 this.focusEl.focus();
38323 hide : function(deep){
38324 if (!this.isDestroyed) {
38325 this.deepHide = deep;
38326 Ext.menu.Menu.superclass.hide.call(this);
38327 delete this.deepHide;
38332 onHide : function(){
38333 Ext.menu.Menu.superclass.onHide.call(this);
38334 this.deactivateActive();
38335 if(this.el && this.floating){
38338 var pm = this.parentMenu;
38339 if(this.deepHide === true && pm){
38343 pm.deactivateActive();
38349 lookupComponent : function(c){
38350 if(Ext.isString(c)){
38351 c = (c == 'separator' || c == '-') ? new Ext.menu.Separator() : new Ext.menu.TextItem(c);
38352 this.applyDefaults(c);
38354 if(Ext.isObject(c)){
38355 c = this.getMenuItem(c);
38356 }else if(c.tagName || c.el){
38357 c = new Ext.BoxComponent({
38365 applyDefaults : function(c) {
38366 if (!Ext.isString(c)) {
38367 c = Ext.menu.Menu.superclass.applyDefaults.call(this, c);
38368 var d = this.internalDefaults;
38371 Ext.applyIf(c.initialConfig, d);
38382 getMenuItem : function(config) {
38383 if (!config.isXType) {
38384 if (!config.xtype && Ext.isBoolean(config.checked)) {
38385 return new Ext.menu.CheckItem(config);
38387 return Ext.create(config, this.defaultType);
38393 addSeparator : function() {
38394 return this.add(new Ext.menu.Separator());
38398 addElement : function(el) {
38399 return this.add(new Ext.menu.BaseItem({
38405 addItem : function(item) {
38406 return this.add(item);
38410 addMenuItem : function(config) {
38411 return this.add(this.getMenuItem(config));
38415 addText : function(text){
38416 return this.add(new Ext.menu.TextItem(text));
38420 onDestroy : function(){
38421 Ext.EventManager.removeResizeListener(this.hide, this);
38422 var pm = this.parentMenu;
38423 if(pm && pm.activeChild == this){
38424 delete pm.activeChild;
38426 delete this.parentMenu;
38427 Ext.menu.Menu.superclass.onDestroy.call(this);
38428 Ext.menu.MenuMgr.unregister(this);
38430 this.keyNav.disable();
38432 var s = this.scroller;
38434 Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom);
38444 Ext.reg('menu', Ext.menu.Menu);
38447 Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
38449 if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
38450 m.tryActivate(m.items.length-1, -1);
38453 function down(e, m){
38454 if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
38455 m.tryActivate(0, 1);
38459 constructor : function(menu){
38460 Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
38461 this.scope = this.menu = menu;
38464 doRelay : function(e, h){
38465 var k = e.getKey();
38467 if (this.menu.activeItem && this.menu.activeItem.isFormField && k != e.TAB) {
38470 if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
38471 this.menu.tryActivate(0, 1);
38474 return h.call(this.scope || this, e, this.menu);
38477 tab: function(e, m) {
38490 right : function(e, m){
38492 m.activeItem.expandMenu(true);
38496 left : function(e, m){
38498 if(m.parentMenu && m.parentMenu.activeItem){
38499 m.parentMenu.activeItem.activate();
38503 enter : function(e, m){
38505 e.stopPropagation();
38506 m.activeItem.onClick(e);
38507 m.fireEvent('click', this, m.activeItem);
38514 Ext.menu.MenuMgr = function(){
38515 var menus, active, groups = {}, attached = false, lastShow = new Date();
38520 active = new Ext.util.MixedCollection();
38521 Ext.getDoc().addKeyListener(27, function(){
38522 if(active.length > 0){
38529 function hideAll(){
38530 if(active && active.length > 0){
38531 var c = active.clone();
38532 c.each(function(m){
38541 function onHide(m){
38543 if(active.length < 1){
38544 Ext.getDoc().un("mousedown", onMouseDown);
38550 function onShow(m){
38551 var last = active.last();
38552 lastShow = new Date();
38555 Ext.getDoc().on("mousedown", onMouseDown);
38559 m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
38560 m.parentMenu.activeChild = m;
38561 }else if(last && !last.isDestroyed && last.isVisible()){
38562 m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
38567 function onBeforeHide(m){
38569 m.activeChild.hide();
38571 if(m.autoHideTimer){
38572 clearTimeout(m.autoHideTimer);
38573 delete m.autoHideTimer;
38578 function onBeforeShow(m){
38579 var pm = m.parentMenu;
38580 if(!pm && !m.allowOtherMenus){
38582 }else if(pm && pm.activeChild){
38583 pm.activeChild.hide();
38588 function onMouseDown(e){
38589 if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
38597 hideAll : function(){
38602 register : function(menu){
38606 menus[menu.id] = menu;
38608 beforehide: onBeforeHide,
38610 beforeshow: onBeforeShow,
38616 get : function(menu){
38617 if(typeof menu == "string"){
38621 return menus[menu];
38622 }else if(menu.events){
38624 }else if(typeof menu.length == 'number'){
38625 return new Ext.menu.Menu({items:menu});
38627 return Ext.create(menu, 'menu');
38632 unregister : function(menu){
38633 delete menus[menu.id];
38634 menu.un("beforehide", onBeforeHide);
38635 menu.un("hide", onHide);
38636 menu.un("beforeshow", onBeforeShow);
38637 menu.un("show", onShow);
38641 registerCheckable : function(menuItem){
38642 var g = menuItem.group;
38647 groups[g].push(menuItem);
38652 unregisterCheckable : function(menuItem){
38653 var g = menuItem.group;
38655 groups[g].remove(menuItem);
38660 onCheckChange: function(item, state){
38661 if(item.group && state){
38662 var group = groups[item.group],
38664 len = group.length,
38667 for(; i < len; i++){
38668 current = group[i];
38669 if(current != item){
38670 current.setChecked(false);
38676 getCheckedItem : function(groupId){
38677 var g = groups[groupId];
38679 for(var i = 0, l = g.length; i < l; i++){
38688 setCheckedItem : function(groupId, itemId){
38689 var g = groups[groupId];
38691 for(var i = 0, l = g.length; i < l; i++){
38692 if(g[i].id == itemId){
38693 g[i].setChecked(true);
38702 Ext.menu.BaseItem = Ext.extend(Ext.Component, {
38707 canActivate : false,
38709 activeClass : "x-menu-item-active",
38711 hideOnClick : true,
38713 clickHideDelay : 1,
38716 ctype : "Ext.menu.BaseItem",
38719 actionMode : "container",
38721 initComponent : function(){
38722 Ext.menu.BaseItem.superclass.initComponent.call(this);
38732 this.on("click", this.handler, this.scope);
38737 onRender : function(container, position){
38738 Ext.menu.BaseItem.superclass.onRender.apply(this, arguments);
38739 if(this.ownerCt && this.ownerCt instanceof Ext.menu.Menu){
38740 this.parentMenu = this.ownerCt;
38742 this.container.addClass('x-menu-list-item');
38743 this.mon(this.el, {
38745 click: this.onClick,
38746 mouseenter: this.activate,
38747 mouseleave: this.deactivate
38753 setHandler : function(handler, scope){
38755 this.un("click", this.handler, this.scope);
38757 this.on("click", this.handler = handler, this.scope = scope);
38761 onClick : function(e){
38762 if(!this.disabled && this.fireEvent("click", this, e) !== false
38763 && (this.parentMenu && this.parentMenu.fireEvent("itemclick", this, e) !== false)){
38764 this.handleClick(e);
38771 activate : function(){
38775 var li = this.container;
38776 li.addClass(this.activeClass);
38777 this.region = li.getRegion().adjust(2, 2, -2, -2);
38778 this.fireEvent("activate", this);
38783 deactivate : function(){
38784 this.container.removeClass(this.activeClass);
38785 this.fireEvent("deactivate", this);
38789 shouldDeactivate : function(e){
38790 return !this.region || !this.region.contains(e.getPoint());
38794 handleClick : function(e){
38795 var pm = this.parentMenu;
38796 if(this.hideOnClick){
38798 pm.hide.defer(this.clickHideDelay, pm, [true]);
38800 pm.deactivateActive();
38806 expandMenu : Ext.emptyFn,
38809 hideMenu : Ext.emptyFn
38811 Ext.reg('menubaseitem', Ext.menu.BaseItem);
38812 Ext.menu.TextItem = Ext.extend(Ext.menu.BaseItem, {
38815 hideOnClick : false,
38817 itemCls : "x-menu-text",
38819 constructor : function(config) {
38820 if (typeof config == 'string') {
38825 Ext.menu.TextItem.superclass.constructor.call(this, config);
38829 onRender : function() {
38830 var s = document.createElement("span");
38831 s.className = this.itemCls;
38832 s.innerHTML = this.text;
38834 Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
38837 Ext.reg('menutextitem', Ext.menu.TextItem);
38838 Ext.menu.Separator = Ext.extend(Ext.menu.BaseItem, {
38840 itemCls : "x-menu-sep",
38842 hideOnClick : false,
38848 onRender : function(li){
38849 var s = document.createElement("span");
38850 s.className = this.itemCls;
38851 s.innerHTML = " ";
38853 li.addClass("x-menu-sep-li");
38854 Ext.menu.Separator.superclass.onRender.apply(this, arguments);
38857 Ext.reg('menuseparator', Ext.menu.Separator);
38858 Ext.menu.Item = Ext.extend(Ext.menu.BaseItem, {
38867 itemCls : 'x-menu-item',
38869 canActivate : true,
38880 ctype: 'Ext.menu.Item',
38882 initComponent : function(){
38883 Ext.menu.Item.superclass.initComponent.call(this);
38885 this.menu = Ext.menu.MenuMgr.get(this.menu);
38886 this.menu.ownerCt = this;
38891 onRender : function(container, position){
38892 if (!this.itemTpl) {
38893 this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
38894 '<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}"',
38895 '<tpl if="hrefTarget">',
38896 ' target="{hrefTarget}"',
38899 '<img alt="{altText}" src="{icon}" class="x-menu-item-icon {iconCls}"/>',
38900 '<span class="x-menu-item-text">{text}</span>',
38904 var a = this.getTemplateArgs();
38905 this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
38906 this.iconEl = this.el.child('img.x-menu-item-icon');
38907 this.textEl = this.el.child('.x-menu-item-text');
38909 this.mon(this.el, 'click', Ext.emptyFn, null, { preventDefault: true });
38911 Ext.menu.Item.superclass.onRender.call(this, container, position);
38914 getTemplateArgs: function() {
38917 cls: this.itemCls + (this.menu ? ' x-menu-item-arrow' : '') + (this.cls ? ' ' + this.cls : ''),
38918 href: this.href || '#',
38919 hrefTarget: this.hrefTarget,
38920 icon: this.icon || Ext.BLANK_IMAGE_URL,
38921 iconCls: this.iconCls || '',
38922 text: this.itemText||this.text||' ',
38923 altText: this.altText || ''
38928 setText : function(text){
38929 this.text = text||' ';
38931 this.textEl.update(this.text);
38932 this.parentMenu.layout.doAutoSize();
38937 setIconClass : function(cls){
38938 var oldCls = this.iconCls;
38939 this.iconCls = cls;
38941 this.iconEl.replaceClass(oldCls, this.iconCls);
38946 beforeDestroy: function(){
38948 delete this.menu.ownerCt;
38949 this.menu.destroy();
38951 Ext.menu.Item.superclass.beforeDestroy.call(this);
38955 handleClick : function(e){
38959 Ext.menu.Item.superclass.handleClick.apply(this, arguments);
38963 activate : function(autoExpand){
38964 if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
38974 shouldDeactivate : function(e){
38975 if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
38976 if(this.menu && this.menu.isVisible()){
38977 return !this.menu.getEl().getRegion().contains(e.getPoint());
38985 deactivate : function(){
38986 Ext.menu.Item.superclass.deactivate.apply(this, arguments);
38991 expandMenu : function(autoActivate){
38992 if(!this.disabled && this.menu){
38993 clearTimeout(this.hideTimer);
38994 delete this.hideTimer;
38995 if(!this.menu.isVisible() && !this.showTimer){
38996 this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
38997 }else if (this.menu.isVisible() && autoActivate){
38998 this.menu.tryActivate(0, 1);
39004 deferExpand : function(autoActivate){
39005 delete this.showTimer;
39006 this.menu.show(this.container, this.parentMenu.subMenuAlign || 'tl-tr?', this.parentMenu);
39008 this.menu.tryActivate(0, 1);
39013 hideMenu : function(){
39014 clearTimeout(this.showTimer);
39015 delete this.showTimer;
39016 if(!this.hideTimer && this.menu && this.menu.isVisible()){
39017 this.hideTimer = this.deferHide.defer(this.hideDelay, this);
39022 deferHide : function(){
39023 delete this.hideTimer;
39024 if(this.menu.over){
39025 this.parentMenu.setActiveItem(this, false);
39031 Ext.reg('menuitem', Ext.menu.Item);
39032 Ext.menu.CheckItem = Ext.extend(Ext.menu.Item, {
39035 itemCls : "x-menu-item x-menu-check-item",
39037 groupClass : "x-menu-group-item",
39043 ctype: "Ext.menu.CheckItem",
39045 initComponent : function(){
39046 Ext.menu.CheckItem.superclass.initComponent.call(this);
39049 "beforecheckchange" ,
39054 if(this.checkHandler){
39055 this.on('checkchange', this.checkHandler, this.scope);
39057 Ext.menu.MenuMgr.registerCheckable(this);
39061 onRender : function(c){
39062 Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
39064 this.el.addClass(this.groupClass);
39067 this.checked = false;
39068 this.setChecked(true, true);
39073 destroy : function(){
39074 Ext.menu.MenuMgr.unregisterCheckable(this);
39075 Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
39079 setChecked : function(state, suppressEvent){
39080 var suppress = suppressEvent === true;
39081 if(this.checked != state && (suppress || this.fireEvent("beforecheckchange", this, state) !== false)){
39082 Ext.menu.MenuMgr.onCheckChange(this, state);
39083 if(this.container){
39084 this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
39086 this.checked = state;
39088 this.fireEvent("checkchange", this, state);
39094 handleClick : function(e){
39095 if(!this.disabled && !(this.checked && this.group)){
39096 this.setChecked(!this.checked);
39098 Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
39101 Ext.reg('menucheckitem', Ext.menu.CheckItem);
39102 Ext.menu.DateMenu = Ext.extend(Ext.menu.Menu, {
39104 enableScrolling : false,
39108 hideOnClick : true,
39116 cls : 'x-date-menu',
39122 initComponent : function(){
39123 this.on('beforeshow', this.onBeforeShow, this);
39124 if(this.strict = (Ext.isIE7 && Ext.isStrict)){
39125 this.on('show', this.onShow, this, {single: true, delay: 20});
39129 showSeparator: false,
39130 items: this.picker = new Ext.DatePicker(Ext.applyIf({
39131 internalRender: this.strict || !Ext.isIE,
39132 ctCls: 'x-menu-date-item',
39134 }, this.initialConfig))
39136 this.picker.purgeListeners();
39137 Ext.menu.DateMenu.superclass.initComponent.call(this);
39139 this.relayEvents(this.picker, ['select']);
39140 this.on('show', this.picker.focus, this.picker);
39141 this.on('select', this.menuHide, this);
39143 this.on('select', this.handler, this.scope || this);
39147 menuHide : function() {
39148 if(this.hideOnClick){
39153 onBeforeShow : function(){
39155 this.picker.hideMonthPicker(true);
39159 onShow : function(){
39160 var el = this.picker.getEl();
39161 el.setWidth(el.getWidth());
39164 Ext.reg('datemenu', Ext.menu.DateMenu);
39166 Ext.menu.ColorMenu = Ext.extend(Ext.menu.Menu, {
39168 enableScrolling : false,
39173 hideOnClick : true,
39175 cls : 'x-color-menu',
39189 initComponent : function(){
39192 showSeparator: false,
39193 items: this.palette = new Ext.ColorPalette(Ext.applyIf({
39195 }, this.initialConfig))
39197 this.palette.purgeListeners();
39198 Ext.menu.ColorMenu.superclass.initComponent.call(this);
39200 this.relayEvents(this.palette, ['select']);
39201 this.on('select', this.menuHide, this);
39203 this.on('select', this.handler, this.scope || this);
39207 menuHide : function(){
39208 if(this.hideOnClick){
39213 Ext.reg('colormenu', Ext.menu.ColorMenu);
39215 Ext.form.Field = Ext.extend(Ext.BoxComponent, {
39224 invalidClass : 'x-form-invalid',
39226 invalidText : 'The value in this field is invalid',
39228 focusClass : 'x-form-focus',
39231 validationEvent : 'keyup',
39233 validateOnBlur : true,
39235 validationDelay : 250,
39237 defaultAutoCreate : {tag: 'input', type: 'text', size: '20', autocomplete: 'off'},
39239 fieldClass : 'x-form-field',
39241 msgTarget : 'qtip',
39252 isFormField : true,
39261 initComponent : function(){
39262 Ext.form.Field.superclass.initComponent.call(this);
39280 getName : function(){
39281 return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || '';
39285 onRender : function(ct, position){
39287 var cfg = this.getAutoCreate();
39290 cfg.name = this.name || this.id;
39292 if(this.inputType){
39293 cfg.type = this.inputType;
39297 Ext.form.Field.superclass.onRender.call(this, ct, position);
39298 if(this.submitValue === false){
39299 this.el.dom.removeAttribute('name');
39301 var type = this.el.dom.type;
39303 if(type == 'password'){
39306 this.el.addClass('x-form-'+type);
39309 this.setReadOnly(true);
39311 if(this.tabIndex !== undefined){
39312 this.el.dom.setAttribute('tabIndex', this.tabIndex);
39315 this.el.addClass([this.fieldClass, this.cls]);
39319 getItemCt : function(){
39320 return this.itemCt;
39324 initValue : function(){
39325 if(this.value !== undefined){
39326 this.setValue(this.value);
39327 }else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){
39328 this.setValue(this.el.dom.value);
39331 this.originalValue = this.getValue();
39335 isDirty : function() {
39336 if(this.disabled || !this.rendered) {
39339 return String(this.getValue()) !== String(this.originalValue);
39343 setReadOnly : function(readOnly){
39345 this.el.dom.readOnly = readOnly;
39347 this.readOnly = readOnly;
39351 afterRender : function(){
39352 Ext.form.Field.superclass.afterRender.call(this);
39358 fireKey : function(e){
39359 if(e.isSpecialKey()){
39360 this.fireEvent('specialkey', this, e);
39365 reset : function(){
39366 this.setValue(this.originalValue);
39367 this.clearInvalid();
39371 initEvents : function(){
39372 this.mon(this.el, Ext.EventManager.getKeyEvent(), this.fireKey, this);
39373 this.mon(this.el, 'focus', this.onFocus, this);
39377 this.mon(this.el, 'blur', this.onBlur, this, this.inEditor ? {buffer:10} : null);
39381 preFocus: Ext.emptyFn,
39384 onFocus : function(){
39386 if(this.focusClass){
39387 this.el.addClass(this.focusClass);
39389 if(!this.hasFocus){
39390 this.hasFocus = true;
39392 this.startValue = this.getValue();
39393 this.fireEvent('focus', this);
39398 beforeBlur : Ext.emptyFn,
39401 onBlur : function(){
39403 if(this.focusClass){
39404 this.el.removeClass(this.focusClass);
39406 this.hasFocus = false;
39407 if(this.validationEvent !== false && (this.validateOnBlur || this.validationEvent == 'blur')){
39410 var v = this.getValue();
39411 if(String(v) !== String(this.startValue)){
39412 this.fireEvent('change', this, v, this.startValue);
39414 this.fireEvent('blur', this);
39419 postBlur : Ext.emptyFn,
39422 isValid : function(preventMark){
39426 var restore = this.preventMark;
39427 this.preventMark = preventMark === true;
39428 var v = this.validateValue(this.processValue(this.getRawValue()));
39429 this.preventMark = restore;
39434 validate : function(){
39435 if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
39436 this.clearInvalid();
39443 processValue : function(value){
39448 validateValue : function(value) {
39450 var error = this.getErrors(value)[0];
39452 if (error == undefined) {
39455 this.markInvalid(error);
39461 getErrors: function() {
39466 getActiveError : function(){
39467 return this.activeError || '';
39471 markInvalid : function(msg){
39473 if (this.rendered && !this.preventMark) {
39474 msg = msg || this.invalidText;
39476 var mt = this.getMessageHandler();
39478 mt.mark(this, msg);
39479 }else if(this.msgTarget){
39480 this.el.addClass(this.invalidClass);
39481 var t = Ext.getDom(this.msgTarget);
39484 t.style.display = this.msgDisplay;
39489 this.setActiveError(msg);
39493 clearInvalid : function(){
39495 if (this.rendered && !this.preventMark) {
39496 this.el.removeClass(this.invalidClass);
39497 var mt = this.getMessageHandler();
39500 }else if(this.msgTarget){
39501 this.el.removeClass(this.invalidClass);
39502 var t = Ext.getDom(this.msgTarget);
39505 t.style.display = 'none';
39510 this.unsetActiveError();
39514 setActiveError: function(msg, suppressEvent) {
39515 this.activeError = msg;
39516 if (suppressEvent !== true) this.fireEvent('invalid', this, msg);
39520 unsetActiveError: function(suppressEvent) {
39521 delete this.activeError;
39522 if (suppressEvent !== true) this.fireEvent('valid', this);
39526 getMessageHandler : function(){
39527 return Ext.form.MessageTargets[this.msgTarget];
39531 getErrorCt : function(){
39532 return this.el.findParent('.x-form-element', 5, true) ||
39533 this.el.findParent('.x-form-field-wrap', 5, true);
39537 alignErrorEl : function(){
39538 this.errorEl.setWidth(this.getErrorCt().getWidth(true) - 20);
39542 alignErrorIcon : function(){
39543 this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
39547 getRawValue : function(){
39548 var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
39549 if(v === this.emptyText){
39556 getValue : function(){
39557 if(!this.rendered) {
39560 var v = this.el.getValue();
39561 if(v === this.emptyText || v === undefined){
39568 setRawValue : function(v){
39569 return this.rendered ? (this.el.dom.value = (Ext.isEmpty(v) ? '' : v)) : '';
39573 setValue : function(v){
39576 this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
39583 append : function(v){
39584 this.setValue([this.getValue(), v].join(''));
39594 Ext.form.MessageTargets = {
39596 mark: function(field, msg){
39597 field.el.addClass(field.invalidClass);
39598 field.el.dom.qtip = msg;
39599 field.el.dom.qclass = 'x-form-invalid-tip';
39601 Ext.QuickTips.enable();
39604 clear: function(field){
39605 field.el.removeClass(field.invalidClass);
39606 field.el.dom.qtip = '';
39610 mark: function(field, msg){
39611 field.el.addClass(field.invalidClass);
39612 field.el.dom.title = msg;
39614 clear: function(field){
39615 field.el.dom.title = '';
39619 mark: function(field, msg){
39620 field.el.addClass(field.invalidClass);
39621 if(!field.errorEl){
39622 var elp = field.getErrorCt();
39624 field.el.dom.title = msg;
39627 field.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
39628 field.on('resize', field.alignErrorEl, field);
39629 field.on('destroy', function(){
39630 Ext.destroy(this.errorEl);
39633 field.alignErrorEl();
39634 field.errorEl.update(msg);
39635 Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field);
39637 clear: function(field){
39638 field.el.removeClass(field.invalidClass);
39640 Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl, field);
39642 field.el.dom.title = '';
39647 mark: function(field, msg){
39648 field.el.addClass(field.invalidClass);
39649 if(!field.errorIcon){
39650 var elp = field.getErrorCt();
39653 field.el.dom.title = msg;
39656 field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
39657 if (field.ownerCt) {
39658 field.ownerCt.on('afterlayout', field.alignErrorIcon, field);
39659 field.ownerCt.on('expand', field.alignErrorIcon, field);
39661 field.on('resize', field.alignErrorIcon, field);
39662 field.on('destroy', function(){
39663 Ext.destroy(this.errorIcon);
39666 field.alignErrorIcon();
39667 field.errorIcon.dom.qtip = msg;
39668 field.errorIcon.dom.qclass = 'x-form-invalid-tip';
39669 field.errorIcon.show();
39671 clear: function(field){
39672 field.el.removeClass(field.invalidClass);
39673 if(field.errorIcon){
39674 field.errorIcon.dom.qtip = '';
39675 field.errorIcon.hide();
39677 field.el.dom.title = '';
39684 Ext.form.Field.msgFx = {
39686 show: function(msgEl, f){
39687 msgEl.setDisplayed('block');
39690 hide : function(msgEl, f){
39691 msgEl.setDisplayed(false).update('');
39696 show: function(msgEl, f){
39697 msgEl.slideIn('t', {stopFx:true});
39700 hide : function(msgEl, f){
39701 msgEl.slideOut('t', {stopFx:true,useDisplay:true});
39706 show: function(msgEl, f){
39707 msgEl.fixDisplay();
39708 msgEl.alignTo(f.el, 'tl-tr');
39709 msgEl.slideIn('l', {stopFx:true});
39712 hide : function(msgEl, f){
39713 msgEl.slideOut('l', {stopFx:true,useDisplay:true});
39717 Ext.reg('field', Ext.form.Field);
39719 Ext.form.TextField = Ext.extend(Ext.form.Field, {
39733 disableKeyFilter : false,
39739 maxLength : Number.MAX_VALUE,
39741 minLengthText : 'The minimum length for this field is {0}',
39743 maxLengthText : 'The maximum length for this field is {0}',
39745 selectOnFocus : false,
39747 blankText : 'This field is required',
39757 emptyClass : 'x-form-empty-field',
39761 initComponent : function(){
39762 Ext.form.TextField.superclass.initComponent.call(this);
39777 initEvents : function(){
39778 Ext.form.TextField.superclass.initEvents.call(this);
39779 if(this.validationEvent == 'keyup'){
39780 this.validationTask = new Ext.util.DelayedTask(this.validate, this);
39781 this.mon(this.el, 'keyup', this.filterValidation, this);
39783 else if(this.validationEvent !== false && this.validationEvent != 'blur'){
39784 this.mon(this.el, this.validationEvent, this.validate, this, {buffer: this.validationDelay});
39786 if(this.selectOnFocus || this.emptyText){
39787 this.mon(this.el, 'mousedown', this.onMouseDown, this);
39789 if(this.emptyText){
39790 this.applyEmptyText();
39793 if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
39794 this.mon(this.el, 'keypress', this.filterKeys, this);
39797 this.mon(this.el, 'keyup', this.onKeyUpBuffered, this, {buffer: 50});
39798 this.mon(this.el, 'click', this.autoSize, this);
39800 if(this.enableKeyEvents){
39801 this.mon(this.el, {
39803 keyup: this.onKeyUp,
39804 keydown: this.onKeyDown,
39805 keypress: this.onKeyPress
39810 onMouseDown: function(e){
39811 if(!this.hasFocus){
39812 this.mon(this.el, 'mouseup', Ext.emptyFn, this, { single: true, preventDefault: true });
39816 processValue : function(value){
39817 if(this.stripCharsRe){
39818 var newValue = value.replace(this.stripCharsRe, '');
39819 if(newValue !== value){
39820 this.setRawValue(newValue);
39827 filterValidation : function(e){
39828 if(!e.isNavKeyPress()){
39829 this.validationTask.delay(this.validationDelay);
39834 onDisable: function(){
39835 Ext.form.TextField.superclass.onDisable.call(this);
39837 this.el.dom.unselectable = 'on';
39842 onEnable: function(){
39843 Ext.form.TextField.superclass.onEnable.call(this);
39845 this.el.dom.unselectable = '';
39850 onKeyUpBuffered : function(e){
39851 if(this.doAutoSize(e)){
39857 doAutoSize : function(e){
39858 return !e.isNavKeyPress();
39862 onKeyUp : function(e){
39863 this.fireEvent('keyup', this, e);
39867 onKeyDown : function(e){
39868 this.fireEvent('keydown', this, e);
39872 onKeyPress : function(e){
39873 this.fireEvent('keypress', this, e);
39877 reset : function(){
39878 Ext.form.TextField.superclass.reset.call(this);
39879 this.applyEmptyText();
39882 applyEmptyText : function(){
39883 if(this.rendered && this.emptyText && this.getRawValue().length < 1 && !this.hasFocus){
39884 this.setRawValue(this.emptyText);
39885 this.el.addClass(this.emptyClass);
39890 preFocus : function(){
39893 if(this.emptyText){
39894 if(el.dom.value == this.emptyText){
39895 this.setRawValue('');
39898 el.removeClass(this.emptyClass);
39900 if(this.selectOnFocus || isEmpty){
39906 postBlur : function(){
39907 this.applyEmptyText();
39911 filterKeys : function(e){
39915 var k = e.getKey();
39916 if(Ext.isGecko && (e.isNavKeyPress() || k == e.BACKSPACE || (k == e.DELETE && e.button == -1))){
39919 var cc = String.fromCharCode(e.getCharCode());
39920 if(!Ext.isGecko && e.isSpecialKey() && !cc){
39923 if(!this.maskRe.test(cc)){
39928 setValue : function(v){
39929 if(this.emptyText && this.el && !Ext.isEmpty(v)){
39930 this.el.removeClass(this.emptyClass);
39932 Ext.form.TextField.superclass.setValue.apply(this, arguments);
39933 this.applyEmptyText();
39939 getErrors: function(value) {
39940 var errors = Ext.form.TextField.superclass.getErrors.apply(this, arguments);
39942 value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());
39944 if (Ext.isFunction(this.validator)) {
39945 var msg = this.validator(value);
39946 if (msg !== true) {
39951 if (value.length < 1 || value === this.emptyText) {
39952 if (this.allowBlank) {
39956 errors.push(this.blankText);
39960 if (!this.allowBlank && (value.length < 1 || value === this.emptyText)) {
39961 errors.push(this.blankText);
39964 if (value.length < this.minLength) {
39965 errors.push(String.format(this.minLengthText, this.minLength));
39968 if (value.length > this.maxLength) {
39969 errors.push(String.format(this.maxLengthText, this.maxLength));
39973 var vt = Ext.form.VTypes;
39974 if(!vt[this.vtype](value, this)){
39975 errors.push(this.vtypeText || vt[this.vtype +'Text']);
39979 if (this.regex && !this.regex.test(value)) {
39980 errors.push(this.regexText);
39987 selectText : function(start, end){
39988 var v = this.getRawValue();
39989 var doFocus = false;
39991 start = start === undefined ? 0 : start;
39992 end = end === undefined ? v.length : end;
39993 var d = this.el.dom;
39994 if(d.setSelectionRange){
39995 d.setSelectionRange(start, end);
39996 }else if(d.createTextRange){
39997 var range = d.createTextRange();
39998 range.moveStart('character', start);
39999 range.moveEnd('character', end-v.length);
40002 doFocus = Ext.isGecko || Ext.isOpera;
40012 autoSize : function(){
40013 if(!this.grow || !this.rendered){
40017 this.metrics = Ext.util.TextMetrics.createInstance(this.el);
40020 var v = el.dom.value;
40021 var d = document.createElement('div');
40022 d.appendChild(document.createTextNode(v));
40027 var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + 10, this.growMin));
40028 this.el.setWidth(w);
40029 this.fireEvent('autosize', this, w);
40032 onDestroy: function(){
40033 if(this.validationTask){
40034 this.validationTask.cancel();
40035 this.validationTask = null;
40037 Ext.form.TextField.superclass.onDestroy.call(this);
40040 Ext.reg('textfield', Ext.form.TextField);
40042 Ext.form.TriggerField = Ext.extend(Ext.form.TextField, {
40046 defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
40054 wrapFocusClass: 'x-trigger-wrap-focus',
40056 autoSize: Ext.emptyFn,
40060 deferHeight : true,
40064 actionMode: 'wrap',
40066 defaultTriggerWidth: 17,
40069 onResize : function(w, h){
40070 Ext.form.TriggerField.superclass.onResize.call(this, w, h);
40071 var tw = this.getTriggerWidth();
40072 if(Ext.isNumber(w)){
40073 this.el.setWidth(w - tw);
40075 this.wrap.setWidth(this.el.getWidth() + tw);
40078 getTriggerWidth: function(){
40079 var tw = this.trigger.getWidth();
40080 if(!this.hideTrigger && !this.readOnly && tw === 0){
40081 tw = this.defaultTriggerWidth;
40087 alignErrorIcon : function(){
40089 this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
40094 onRender : function(ct, position){
40095 this.doc = Ext.isIE ? Ext.getBody() : Ext.getDoc();
40096 Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
40098 this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});
40099 this.trigger = this.wrap.createChild(this.triggerConfig ||
40100 {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.triggerClass});
40101 this.initTrigger();
40103 this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
40105 this.resizeEl = this.positionEl = this.wrap;
40108 getWidth: function() {
40109 return(this.el.getWidth() + this.trigger.getWidth());
40112 updateEditState: function(){
40114 if (this.readOnly) {
40115 this.el.dom.readOnly = true;
40116 this.el.addClass('x-trigger-noedit');
40117 this.mun(this.el, 'click', this.onTriggerClick, this);
40118 this.trigger.setDisplayed(false);
40120 if (!this.editable) {
40121 this.el.dom.readOnly = true;
40122 this.el.addClass('x-trigger-noedit');
40123 this.mon(this.el, 'click', this.onTriggerClick, this);
40125 this.el.dom.readOnly = false;
40126 this.el.removeClass('x-trigger-noedit');
40127 this.mun(this.el, 'click', this.onTriggerClick, this);
40129 this.trigger.setDisplayed(!this.hideTrigger);
40131 this.onResize(this.width || this.wrap.getWidth());
40136 setHideTrigger: function(hideTrigger){
40137 if(hideTrigger != this.hideTrigger){
40138 this.hideTrigger = hideTrigger;
40139 this.updateEditState();
40144 setEditable: function(editable){
40145 if(editable != this.editable){
40146 this.editable = editable;
40147 this.updateEditState();
40152 setReadOnly: function(readOnly){
40153 if(readOnly != this.readOnly){
40154 this.readOnly = readOnly;
40155 this.updateEditState();
40159 afterRender : function(){
40160 Ext.form.TriggerField.superclass.afterRender.call(this);
40161 this.updateEditState();
40165 initTrigger : function(){
40166 this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true});
40167 this.trigger.addClassOnOver('x-form-trigger-over');
40168 this.trigger.addClassOnClick('x-form-trigger-click');
40172 onDestroy : function(){
40173 Ext.destroy(this.trigger, this.wrap);
40174 if (this.mimicing){
40175 this.doc.un('mousedown', this.mimicBlur, this);
40178 Ext.form.TriggerField.superclass.onDestroy.call(this);
40182 onFocus : function(){
40183 Ext.form.TriggerField.superclass.onFocus.call(this);
40184 if(!this.mimicing){
40185 this.wrap.addClass(this.wrapFocusClass);
40186 this.mimicing = true;
40187 this.doc.on('mousedown', this.mimicBlur, this, {delay: 10});
40188 if(this.monitorTab){
40189 this.on('specialkey', this.checkTab, this);
40195 checkTab : function(me, e){
40196 if(e.getKey() == e.TAB){
40197 this.triggerBlur();
40202 onBlur : Ext.emptyFn,
40205 mimicBlur : function(e){
40206 if(!this.isDestroyed && !this.wrap.contains(e.target) && this.validateBlur(e)){
40207 this.triggerBlur();
40212 triggerBlur : function(){
40213 this.mimicing = false;
40214 this.doc.un('mousedown', this.mimicBlur, this);
40215 if(this.monitorTab && this.el){
40216 this.un('specialkey', this.checkTab, this);
40218 Ext.form.TriggerField.superclass.onBlur.call(this);
40220 this.wrap.removeClass(this.wrapFocusClass);
40224 beforeBlur : Ext.emptyFn,
40228 validateBlur : function(e){
40233 onTriggerClick : Ext.emptyFn
40241 Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
40246 initComponent : function(){
40247 Ext.form.TwinTriggerField.superclass.initComponent.call(this);
40249 this.triggerConfig = {
40250 tag:'span', cls:'x-form-twin-triggers', cn:[
40251 {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger1Class},
40252 {tag: "img", src: Ext.BLANK_IMAGE_URL, alt: "", cls: "x-form-trigger " + this.trigger2Class}
40256 getTrigger : function(index){
40257 return this.triggers[index];
40260 afterRender: function(){
40261 Ext.form.TwinTriggerField.superclass.afterRender.call(this);
40262 var triggers = this.triggers,
40264 len = triggers.length;
40266 for(; i < len; ++i){
40267 if(this['hideTrigger' + (i + 1)]){
40268 triggers[i].hide();
40274 initTrigger : function(){
40275 var ts = this.trigger.select('.x-form-trigger', true),
40276 triggerField = this;
40278 ts.each(function(t, all, index){
40279 var triggerIndex = 'Trigger'+(index+1);
40280 t.hide = function(){
40281 var w = triggerField.wrap.getWidth();
40282 this.dom.style.display = 'none';
40283 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
40284 triggerField['hidden' + triggerIndex] = true;
40286 t.show = function(){
40287 var w = triggerField.wrap.getWidth();
40288 this.dom.style.display = '';
40289 triggerField.el.setWidth(w-triggerField.trigger.getWidth());
40290 triggerField['hidden' + triggerIndex] = false;
40292 this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});
40293 t.addClassOnOver('x-form-trigger-over');
40294 t.addClassOnClick('x-form-trigger-click');
40296 this.triggers = ts.elements;
40299 getTriggerWidth: function(){
40301 Ext.each(this.triggers, function(t, index){
40302 var triggerIndex = 'Trigger' + (index + 1),
40304 if(w === 0 && !this['hidden' + triggerIndex]){
40305 tw += this.defaultTriggerWidth;
40314 onDestroy : function() {
40315 Ext.destroy(this.triggers);
40316 Ext.form.TwinTriggerField.superclass.onDestroy.call(this);
40320 onTrigger1Click : Ext.emptyFn,
40322 onTrigger2Click : Ext.emptyFn
40324 Ext.reg('trigger', Ext.form.TriggerField);
40326 Ext.form.TextArea = Ext.extend(Ext.form.TextField, {
40331 growAppend : ' \n ',
40333 enterIsSpecial : false,
40336 preventScrollbars: false,
40340 onRender : function(ct, position){
40342 this.defaultAutoCreate = {
40344 style:"width:100px;height:60px;",
40345 autocomplete: "off"
40348 Ext.form.TextArea.superclass.onRender.call(this, ct, position);
40350 this.textSizeEl = Ext.DomHelper.append(document.body, {
40351 tag: "pre", cls: "x-form-grow-sizer"
40353 if(this.preventScrollbars){
40354 this.el.setStyle("overflow", "hidden");
40356 this.el.setHeight(this.growMin);
40360 onDestroy : function(){
40361 Ext.removeNode(this.textSizeEl);
40362 Ext.form.TextArea.superclass.onDestroy.call(this);
40365 fireKey : function(e){
40366 if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
40367 this.fireEvent("specialkey", this, e);
40372 doAutoSize : function(e){
40373 return !e.isNavKeyPress() || e.getKey() == e.ENTER;
40377 filterValidation: function(e) {
40378 if(!e.isNavKeyPress() || (!this.enterIsSpecial && e.keyCode == e.ENTER)){
40379 this.validationTask.delay(this.validationDelay);
40384 autoSize: function(){
40385 if(!this.grow || !this.textSizeEl){
40389 v = Ext.util.Format.htmlEncode(el.dom.value),
40390 ts = this.textSizeEl,
40393 Ext.fly(ts).setWidth(this.el.getWidth());
40395 v = "  ";
40397 v += this.growAppend;
40399 v = v.replace(/\n/g, ' <br />');
40403 h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin));
40404 if(h != this.lastHeight){
40405 this.lastHeight = h;
40406 this.el.setHeight(h);
40407 this.fireEvent("autosize", this, h);
40411 Ext.reg('textarea', Ext.form.TextArea);
40412 Ext.form.NumberField = Ext.extend(Ext.form.TextField, {
40416 fieldClass: "x-form-field x-form-num-field",
40419 allowDecimals : true,
40422 decimalSeparator : ".",
40425 decimalPrecision : 2,
40428 allowNegative : true,
40431 minValue : Number.NEGATIVE_INFINITY,
40434 maxValue : Number.MAX_VALUE,
40437 minText : "The minimum value for this field is {0}",
40440 maxText : "The maximum value for this field is {0}",
40443 nanText : "{0} is not a valid number",
40446 baseChars : "0123456789",
40449 autoStripChars: false,
40452 initEvents : function() {
40453 var allowed = this.baseChars + '';
40454 if (this.allowDecimals) {
40455 allowed += this.decimalSeparator;
40457 if (this.allowNegative) {
40460 allowed = Ext.escapeRe(allowed);
40461 this.maskRe = new RegExp('[' + allowed + ']');
40462 if (this.autoStripChars) {
40463 this.stripCharsRe = new RegExp('[^' + allowed + ']', 'gi');
40466 Ext.form.NumberField.superclass.initEvents.call(this);
40470 getErrors: function(value) {
40471 var errors = Ext.form.NumberField.superclass.getErrors.apply(this, arguments);
40473 value = Ext.isDefined(value) ? value : this.processValue(this.getRawValue());
40475 if (value.length < 1) {
40479 value = String(value).replace(this.decimalSeparator, ".");
40482 errors.push(String.format(this.nanText, value));
40485 var num = this.parseValue(value);
40487 if (num < this.minValue) {
40488 errors.push(String.format(this.minText, this.minValue));
40491 if (num > this.maxValue) {
40492 errors.push(String.format(this.maxText, this.maxValue));
40498 getValue : function() {
40499 return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
40502 setValue : function(v) {
40503 v = this.fixPrecision(v);
40504 v = Ext.isNumber(v) ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
40505 v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
40506 return Ext.form.NumberField.superclass.setValue.call(this, v);
40510 setMinValue : function(value) {
40511 this.minValue = Ext.num(value, Number.NEGATIVE_INFINITY);
40515 setMaxValue : function(value) {
40516 this.maxValue = Ext.num(value, Number.MAX_VALUE);
40520 parseValue : function(value) {
40521 value = parseFloat(String(value).replace(this.decimalSeparator, "."));
40522 return isNaN(value) ? '' : value;
40526 fixPrecision : function(value) {
40527 var nan = isNaN(value);
40529 if (!this.allowDecimals || this.decimalPrecision == -1 || nan || !value) {
40530 return nan ? '' : value;
40533 return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
40536 beforeBlur : function() {
40537 var v = this.parseValue(this.getRawValue());
40539 if (!Ext.isEmpty(v)) {
40545 Ext.reg('numberfield', Ext.form.NumberField);
40547 Ext.form.DateField = Ext.extend(Ext.form.TriggerField, {
40551 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",
40553 disabledDaysText : "Disabled",
40555 disabledDatesText : "Disabled",
40557 minText : "The date in this field must be equal to or after {0}",
40559 maxText : "The date in this field must be equal to or before {0}",
40561 invalidText : "{0} is not a valid date - it must be in the format {1}",
40563 triggerClass : 'x-form-date-trigger',
40577 defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
40583 initTimeFormat: 'H',
40586 safeParse : function(value, format) {
40587 if (/[gGhH]/.test(format.replace(/(\\.)/g, ''))) {
40589 return Date.parseDate(value, format);
40592 var parsedDate = Date.parseDate(value + ' ' + this.initTime, format + ' ' + this.initTimeFormat);
40595 return parsedDate.clearTime();
40600 initComponent : function(){
40601 Ext.form.DateField.superclass.initComponent.call(this);
40608 if(Ext.isString(this.minValue)){
40609 this.minValue = this.parseDate(this.minValue);
40611 if(Ext.isString(this.maxValue)){
40612 this.maxValue = this.parseDate(this.maxValue);
40614 this.disabledDatesRE = null;
40615 this.initDisabledDays();
40618 initEvents: function() {
40619 Ext.form.DateField.superclass.initEvents.call(this);
40620 this.keyNav = new Ext.KeyNav(this.el, {
40621 "down": function(e) {
40622 this.onTriggerClick();
40631 initDisabledDays : function(){
40632 if(this.disabledDates){
40633 var dd = this.disabledDates,
40634 len = dd.length - 1,
40637 Ext.each(dd, function(d, i){
40638 re += Ext.isDate(d) ? '^' + Ext.escapeRe(d.dateFormat(this.format)) + '$' : dd[i];
40643 this.disabledDatesRE = new RegExp(re + ')');
40648 setDisabledDates : function(dd){
40649 this.disabledDates = dd;
40650 this.initDisabledDays();
40652 this.menu.picker.setDisabledDates(this.disabledDatesRE);
40657 setDisabledDays : function(dd){
40658 this.disabledDays = dd;
40660 this.menu.picker.setDisabledDays(dd);
40665 setMinValue : function(dt){
40666 this.minValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
40668 this.menu.picker.setMinDate(this.minValue);
40673 setMaxValue : function(dt){
40674 this.maxValue = (Ext.isString(dt) ? this.parseDate(dt) : dt);
40676 this.menu.picker.setMaxDate(this.maxValue);
40681 getErrors: function(value) {
40682 var errors = Ext.form.DateField.superclass.getErrors.apply(this, arguments);
40684 value = this.formatDate(value || this.processValue(this.getRawValue()));
40686 if (value.length < 1) {
40690 var svalue = value;
40691 value = this.parseDate(value);
40693 errors.push(String.format(this.invalidText, svalue, this.format));
40697 var time = value.getTime();
40698 if (this.minValue && time < this.minValue.clearTime().getTime()) {
40699 errors.push(String.format(this.minText, this.formatDate(this.minValue)));
40702 if (this.maxValue && time > this.maxValue.clearTime().getTime()) {
40703 errors.push(String.format(this.maxText, this.formatDate(this.maxValue)));
40706 if (this.disabledDays) {
40707 var day = value.getDay();
40709 for(var i = 0; i < this.disabledDays.length; i++) {
40710 if (day === this.disabledDays[i]) {
40711 errors.push(this.disabledDaysText);
40717 var fvalue = this.formatDate(value);
40718 if (this.disabledDatesRE && this.disabledDatesRE.test(fvalue)) {
40719 errors.push(String.format(this.disabledDatesText, fvalue));
40727 validateBlur : function(){
40728 return !this.menu || !this.menu.isVisible();
40732 getValue : function(){
40733 return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
40737 setValue : function(date){
40738 return Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
40742 parseDate : function(value) {
40743 if(!value || Ext.isDate(value)){
40747 var v = this.safeParse(value, this.format),
40748 af = this.altFormats,
40749 afa = this.altFormatsArray;
40752 afa = afa || af.split("|");
40754 for (var i = 0, len = afa.length; i < len && !v; i++) {
40755 v = this.safeParse(value, afa[i]);
40762 onDestroy : function(){
40763 Ext.destroy(this.menu, this.keyNav);
40764 Ext.form.DateField.superclass.onDestroy.call(this);
40768 formatDate : function(date){
40769 return Ext.isDate(date) ? date.dateFormat(this.format) : date;
40775 onTriggerClick : function(){
40779 if(this.menu == null){
40780 this.menu = new Ext.menu.DateMenu({
40781 hideOnClick: false,
40782 focusOnSelect: false
40786 Ext.apply(this.menu.picker, {
40787 minDate : this.minValue,
40788 maxDate : this.maxValue,
40789 disabledDatesRE : this.disabledDatesRE,
40790 disabledDatesText : this.disabledDatesText,
40791 disabledDays : this.disabledDays,
40792 disabledDaysText : this.disabledDaysText,
40793 format : this.format,
40794 showToday : this.showToday,
40795 startDay: this.startDay,
40796 minText : String.format(this.minText, this.formatDate(this.minValue)),
40797 maxText : String.format(this.maxText, this.formatDate(this.maxValue))
40799 this.menu.picker.setValue(this.getValue() || new Date());
40800 this.menu.show(this.el, "tl-bl?");
40801 this.menuEvents('on');
40805 menuEvents: function(method){
40806 this.menu[method]('select', this.onSelect, this);
40807 this.menu[method]('hide', this.onMenuHide, this);
40808 this.menu[method]('show', this.onFocus, this);
40811 onSelect: function(m, d){
40813 this.fireEvent('select', this, d);
40817 onMenuHide: function(){
40818 this.focus(false, 60);
40819 this.menuEvents('un');
40823 beforeBlur : function(){
40824 var v = this.parseDate(this.getRawValue());
40835 Ext.reg('datefield', Ext.form.DateField);
40837 Ext.form.DisplayField = Ext.extend(Ext.form.Field, {
40838 validationEvent : false,
40839 validateOnBlur : false,
40840 defaultAutoCreate : {tag: "div"},
40842 fieldClass : "x-form-display-field",
40847 initEvents : Ext.emptyFn,
40849 isValid : function(){
40853 validate : function(){
40857 getRawValue : function(){
40858 var v = this.rendered ? this.el.dom.innerHTML : Ext.value(this.value, '');
40859 if(v === this.emptyText){
40862 if(this.htmlEncode){
40863 v = Ext.util.Format.htmlDecode(v);
40868 getValue : function(){
40869 return this.getRawValue();
40872 getName: function() {
40876 setRawValue : function(v){
40877 if(this.htmlEncode){
40878 v = Ext.util.Format.htmlEncode(v);
40880 return this.rendered ? (this.el.dom.innerHTML = (Ext.isEmpty(v) ? '' : v)) : (this.value = v);
40883 setValue : function(v){
40884 this.setRawValue(v);
40895 Ext.reg('displayfield', Ext.form.DisplayField);
40897 Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
40905 defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
40915 selectedClass : 'x-combo-selected',
40919 triggerClass : 'x-form-arrow-trigger',
40923 listAlign : 'tl-bl?',
40929 triggerAction : 'query',
40941 selectOnFocus : false,
40943 queryParam : 'query',
40945 loadingText : 'Loading...',
40957 forceSelection : false,
40959 typeAheadDelay : 250,
40966 clearFilterOnReset : true,
40969 submitValue: undefined,
40974 initComponent : function(){
40975 Ext.form.ComboBox.superclass.initComponent.call(this);
40989 if(this.transform){
40990 var s = Ext.getDom(this.transform);
40991 if(!this.hiddenName){
40992 this.hiddenName = s.name;
40995 this.mode = 'local';
40996 var d = [], opts = s.options;
40997 for(var i = 0, len = opts.length;i < len; i++){
40999 value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttributeNode('value').specified) ? o.value : o.text;
41000 if(o.selected && Ext.isEmpty(this.value, true)) {
41001 this.value = value;
41003 d.push([value, o.text]);
41005 this.store = new Ext.data.ArrayStore({
41007 fields: ['value', 'text'],
41011 this.valueField = 'value';
41012 this.displayField = 'text';
41015 if(!this.lazyRender){
41016 this.target = true;
41017 this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
41018 this.render(this.el.parentNode, s);
41023 else if(this.store){
41024 this.store = Ext.StoreMgr.lookup(this.store);
41025 if(this.store.autoCreated){
41026 this.displayField = this.valueField = 'field1';
41027 if(!this.store.expandData){
41028 this.displayField = 'field2';
41030 this.mode = 'local';
41034 this.selectedIndex = -1;
41035 if(this.mode == 'local'){
41036 if(!Ext.isDefined(this.initialConfig.queryDelay)){
41037 this.queryDelay = 10;
41039 if(!Ext.isDefined(this.initialConfig.minChars)){
41046 onRender : function(ct, position){
41047 if(this.hiddenName && !Ext.isDefined(this.submitValue)){
41048 this.submitValue = false;
41050 Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
41051 if(this.hiddenName){
41052 this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
41053 id: (this.hiddenId || Ext.id())}, 'before', true);
41057 this.el.dom.setAttribute('autocomplete', 'off');
41060 if(!this.lazyInit){
41063 this.on('focus', this.initList, this, {single: true});
41068 initValue : function(){
41069 Ext.form.ComboBox.superclass.initValue.call(this);
41070 if(this.hiddenField){
41071 this.hiddenField.value =
41072 Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, '');
41076 getParentZIndex : function(){
41079 this.findParentBy(function(ct){
41080 zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10);
41087 getZIndex : function(listParent){
41088 listParent = listParent || Ext.getDom(this.getListParent() || Ext.getBody());
41089 var zindex = parseInt(Ext.fly(listParent).getStyle('z-index'), 10);
41091 zindex = this.getParentZIndex();
41093 return (zindex || 12000) + 5;
41097 initList : function(){
41099 var cls = 'x-combo-list',
41100 listParent = Ext.getDom(this.getListParent() || Ext.getBody());
41102 this.list = new Ext.Layer({
41103 parentEl: listParent,
41104 shadow: this.shadow,
41105 cls: [cls, this.listClass].join(' '),
41107 zindex: this.getZIndex(listParent)
41110 var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
41111 this.list.setSize(lw, 0);
41112 this.list.swallowEvent('mousewheel');
41113 this.assetHeight = 0;
41114 if(this.syncFont !== false){
41115 this.list.setStyle('font-size', this.el.getStyle('font-size'));
41118 this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
41119 this.assetHeight += this.header.getHeight();
41122 this.innerList = this.list.createChild({cls:cls+'-inner'});
41123 this.mon(this.innerList, 'mouseover', this.onViewOver, this);
41124 this.mon(this.innerList, 'mousemove', this.onViewMove, this);
41125 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
41128 this.footer = this.list.createChild({cls:cls+'-ft'});
41129 this.pageTb = new Ext.PagingToolbar({
41131 pageSize: this.pageSize,
41132 renderTo:this.footer
41134 this.assetHeight += this.footer.getHeight();
41139 this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
41144 this.view = new Ext.DataView({
41145 applyTo: this.innerList,
41147 singleSelect: true,
41148 selectedClass: this.selectedClass,
41149 itemSelector: this.itemSelector || '.' + cls + '-item',
41150 emptyText: this.listEmptyText,
41151 deferEmptyText: false
41154 this.mon(this.view, {
41155 containerclick : this.onViewClick,
41156 click : this.onViewClick,
41160 this.bindStore(this.store, true);
41162 if(this.resizable){
41163 this.resizer = new Ext.Resizable(this.list, {
41164 pinned:true, handles:'se'
41166 this.mon(this.resizer, 'resize', function(r, w, h){
41167 this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
41168 this.listWidth = w;
41169 this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
41170 this.restrictHeight();
41173 this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
41179 getListParent : function() {
41180 return document.body;
41184 getStore : function(){
41189 bindStore : function(store, initial){
41190 if(this.store && !initial){
41191 if(this.store !== store && this.store.autoDestroy){
41192 this.store.destroy();
41194 this.store.un('beforeload', this.onBeforeLoad, this);
41195 this.store.un('load', this.onLoad, this);
41196 this.store.un('exception', this.collapse, this);
41201 this.view.bindStore(null);
41204 this.pageTb.bindStore(null);
41210 this.lastQuery = null;
41212 this.pageTb.bindStore(store);
41216 this.store = Ext.StoreMgr.lookup(store);
41219 beforeload: this.onBeforeLoad,
41221 exception: this.collapse
41225 this.view.bindStore(store);
41230 reset : function(){
41231 if(this.clearFilterOnReset && this.mode == 'local'){
41232 this.store.clearFilter();
41234 Ext.form.ComboBox.superclass.reset.call(this);
41238 initEvents : function(){
41239 Ext.form.ComboBox.superclass.initEvents.call(this);
41242 this.keyNav = new Ext.KeyNav(this.el, {
41243 "up" : function(e){
41244 this.inKeyMode = true;
41248 "down" : function(e){
41249 if(!this.isExpanded()){
41250 this.onTriggerClick();
41252 this.inKeyMode = true;
41257 "enter" : function(e){
41258 this.onViewClick();
41261 "esc" : function(e){
41265 "tab" : function(e){
41266 if (this.forceSelection === true) {
41269 this.onViewClick(false);
41276 doRelay : function(e, h, hname){
41277 if(hname == 'down' || this.scope.isExpanded()){
41279 var relay = Ext.KeyNav.prototype.doRelay.apply(this, arguments);
41280 if(!Ext.isIE && Ext.EventManager.useKeydown){
41282 this.scope.fireKey(e);
41289 forceKeyDown : true,
41290 defaultEventAction: 'stopEvent'
41292 this.queryDelay = Math.max(this.queryDelay || 10,
41293 this.mode == 'local' ? 10 : 250);
41294 this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
41295 if(this.typeAhead){
41296 this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
41298 if(!this.enableKeyEvents){
41299 this.mon(this.el, 'keyup', this.onKeyUp, this);
41305 onDestroy : function(){
41307 this.dqTask.cancel();
41308 this.dqTask = null;
41310 this.bindStore(null);
41317 Ext.destroyMembers(this, 'hiddenField');
41318 Ext.form.ComboBox.superclass.onDestroy.call(this);
41322 fireKey : function(e){
41323 if (!this.isExpanded()) {
41324 Ext.form.ComboBox.superclass.fireKey.call(this, e);
41329 onResize : function(w, h){
41330 Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
41331 if(!isNaN(w) && this.isVisible() && this.list){
41334 this.bufferSize = w;
41338 doResize: function(w){
41339 if(!Ext.isDefined(this.listWidth)){
41340 var lw = Math.max(w, this.minListWidth);
41341 this.list.setWidth(lw);
41342 this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
41347 onEnable : function(){
41348 Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
41349 if(this.hiddenField){
41350 this.hiddenField.disabled = false;
41355 onDisable : function(){
41356 Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
41357 if(this.hiddenField){
41358 this.hiddenField.disabled = true;
41363 onBeforeLoad : function(){
41364 if(!this.hasFocus){
41367 this.innerList.update(this.loadingText ?
41368 '<div class="loading-indicator">'+this.loadingText+'</div>' : '');
41369 this.restrictHeight();
41370 this.selectedIndex = -1;
41374 onLoad : function(){
41375 if(!this.hasFocus){
41378 if(this.store.getCount() > 0 || this.listEmptyText){
41380 this.restrictHeight();
41381 if(this.lastQuery == this.allQuery){
41383 this.el.dom.select();
41386 if(this.autoSelect !== false && !this.selectByValue(this.value, true)){
41387 this.select(0, true);
41390 if(this.autoSelect !== false){
41393 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
41394 this.taTask.delay(this.typeAheadDelay);
41404 onTypeAhead : function(){
41405 if(this.store.getCount() > 0){
41406 var r = this.store.getAt(0);
41407 var newValue = r.data[this.displayField];
41408 var len = newValue.length;
41409 var selStart = this.getRawValue().length;
41410 if(selStart != len){
41411 this.setRawValue(newValue);
41412 this.selectText(selStart, newValue.length);
41418 assertValue : function(){
41419 var val = this.getRawValue(),
41420 rec = this.findRecord(this.displayField, val);
41422 if(!rec && this.forceSelection){
41423 if(val.length > 0 && val != this.emptyText){
41424 this.el.dom.value = Ext.value(this.lastSelectionText, '');
41425 this.applyEmptyText();
41434 if (val == rec.get(this.displayField) && this.value == rec.get(this.valueField)){
41437 val = rec.get(this.valueField || this.displayField);
41439 this.setValue(val);
41444 onSelect : function(record, index){
41445 if(this.fireEvent('beforeselect', this, record, index) !== false){
41446 this.setValue(record.data[this.valueField || this.displayField]);
41448 this.fireEvent('select', this, record, index);
41453 getName: function(){
41454 var hf = this.hiddenField;
41455 return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this);
41459 getValue : function(){
41460 if(this.valueField){
41461 return Ext.isDefined(this.value) ? this.value : '';
41463 return Ext.form.ComboBox.superclass.getValue.call(this);
41468 clearValue : function(){
41469 if(this.hiddenField){
41470 this.hiddenField.value = '';
41472 this.setRawValue('');
41473 this.lastSelectionText = '';
41474 this.applyEmptyText();
41479 setValue : function(v){
41481 if(this.valueField){
41482 var r = this.findRecord(this.valueField, v);
41484 text = r.data[this.displayField];
41485 }else if(Ext.isDefined(this.valueNotFoundText)){
41486 text = this.valueNotFoundText;
41489 this.lastSelectionText = text;
41490 if(this.hiddenField){
41491 this.hiddenField.value = Ext.value(v, '');
41493 Ext.form.ComboBox.superclass.setValue.call(this, text);
41499 findRecord : function(prop, value){
41501 if(this.store.getCount() > 0){
41502 this.store.each(function(r){
41503 if(r.data[prop] == value){
41513 onViewMove : function(e, t){
41514 this.inKeyMode = false;
41518 onViewOver : function(e, t){
41519 if(this.inKeyMode){
41522 var item = this.view.findItemFromChild(t);
41524 var index = this.view.indexOf(item);
41525 this.select(index, false);
41530 onViewClick : function(doFocus){
41531 var index = this.view.getSelectedIndexes()[0],
41533 r = s.getAt(index);
41535 this.onSelect(r, index);
41539 if(doFocus !== false){
41546 restrictHeight : function(){
41547 this.innerList.dom.style.height = '';
41548 var inner = this.innerList.dom,
41549 pad = this.list.getFrameWidth('tb') + (this.resizable ? this.handleHeight : 0) + this.assetHeight,
41550 h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight),
41551 ha = this.getPosition()[1]-Ext.getBody().getScroll().top,
41552 hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height,
41553 space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;
41555 h = Math.min(h, space, this.maxHeight);
41557 this.innerList.setHeight(h);
41558 this.list.beginUpdate();
41559 this.list.setHeight(h+pad);
41560 this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
41561 this.list.endUpdate();
41565 isExpanded : function(){
41566 return this.list && this.list.isVisible();
41570 selectByValue : function(v, scrollIntoView){
41571 if(!Ext.isEmpty(v, true)){
41572 var r = this.findRecord(this.valueField || this.displayField, v);
41574 this.select(this.store.indexOf(r), scrollIntoView);
41582 select : function(index, scrollIntoView){
41583 this.selectedIndex = index;
41584 this.view.select(index);
41585 if(scrollIntoView !== false){
41586 var el = this.view.getNode(index);
41588 this.innerList.scrollChildIntoView(el, false);
41595 selectNext : function(){
41596 var ct = this.store.getCount();
41598 if(this.selectedIndex == -1){
41600 }else if(this.selectedIndex < ct-1){
41601 this.select(this.selectedIndex+1);
41607 selectPrev : function(){
41608 var ct = this.store.getCount();
41610 if(this.selectedIndex == -1){
41612 }else if(this.selectedIndex !== 0){
41613 this.select(this.selectedIndex-1);
41619 onKeyUp : function(e){
41620 var k = e.getKey();
41621 if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){
41624 this.dqTask.delay(this.queryDelay);
41626 Ext.form.ComboBox.superclass.onKeyUp.call(this, e);
41630 validateBlur : function(){
41631 return !this.list || !this.list.isVisible();
41635 initQuery : function(){
41636 this.doQuery(this.getRawValue());
41640 beforeBlur : function(){
41641 this.assertValue();
41645 postBlur : function(){
41646 Ext.form.ComboBox.superclass.postBlur.call(this);
41648 this.inKeyMode = false;
41652 doQuery : function(q, forceAll){
41653 q = Ext.isEmpty(q) ? '' : q;
41656 forceAll: forceAll,
41660 if(this.fireEvent('beforequery', qe)===false || qe.cancel){
41664 forceAll = qe.forceAll;
41665 if(forceAll === true || (q.length >= this.minChars)){
41666 if(this.lastQuery !== q){
41667 this.lastQuery = q;
41668 if(this.mode == 'local'){
41669 this.selectedIndex = -1;
41671 this.store.clearFilter();
41673 this.store.filter(this.displayField, q);
41677 this.store.baseParams[this.queryParam] = q;
41679 params: this.getParams(q)
41684 this.selectedIndex = -1;
41691 getParams : function(q){
41693 paramNames = this.store.paramNames;
41695 params[paramNames.start] = 0;
41696 params[paramNames.limit] = this.pageSize;
41702 collapse : function(){
41703 if(!this.isExpanded()){
41707 Ext.getDoc().un('mousewheel', this.collapseIf, this);
41708 Ext.getDoc().un('mousedown', this.collapseIf, this);
41709 this.fireEvent('collapse', this);
41713 collapseIf : function(e){
41714 if(!this.isDestroyed && !e.within(this.wrap) && !e.within(this.list)){
41720 expand : function(){
41721 if(this.isExpanded() || !this.hasFocus){
41725 if(this.title || this.pageSize){
41726 this.assetHeight = 0;
41728 this.assetHeight += this.header.getHeight();
41731 this.assetHeight += this.footer.getHeight();
41735 if(this.bufferSize){
41736 this.doResize(this.bufferSize);
41737 delete this.bufferSize;
41739 this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
41742 this.list.setZIndex(this.getZIndex());
41745 this.innerList.setOverflow('auto');
41747 this.mon(Ext.getDoc(), {
41749 mousewheel: this.collapseIf,
41750 mousedown: this.collapseIf
41752 this.fireEvent('expand', this);
41758 onTriggerClick : function(){
41759 if(this.readOnly || this.disabled){
41762 if(this.isExpanded()){
41767 if(this.triggerAction == 'all') {
41768 this.doQuery(this.allQuery, true);
41770 this.doQuery(this.getRawValue());
41782 Ext.reg('combo', Ext.form.ComboBox);
41784 Ext.form.Checkbox = Ext.extend(Ext.form.Field, {
41786 focusClass : undefined,
41788 fieldClass : 'x-form-field',
41792 boxLabel: ' ',
41794 defaultAutoCreate : { tag: 'input', type: 'checkbox', autocomplete: 'off'},
41801 actionMode : 'wrap',
41804 initComponent : function(){
41805 Ext.form.Checkbox.superclass.initComponent.call(this);
41813 onResize : function(){
41814 Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
41815 if(!this.boxLabel && !this.fieldLabel){
41816 this.el.alignTo(this.wrap, 'c-c');
41821 initEvents : function(){
41822 Ext.form.Checkbox.superclass.initEvents.call(this);
41823 this.mon(this.el, {
41825 click: this.onClick,
41826 change: this.onClick
41831 markInvalid : Ext.emptyFn,
41833 clearInvalid : Ext.emptyFn,
41836 onRender : function(ct, position){
41837 Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
41838 if(this.inputValue !== undefined){
41839 this.el.dom.value = this.inputValue;
41841 this.wrap = this.el.wrap({cls: 'x-form-check-wrap'});
41843 this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
41846 this.setValue(true);
41848 this.checked = this.el.dom.checked;
41851 if (Ext.isIE && !Ext.isStrict) {
41852 this.wrap.repaint();
41854 this.resizeEl = this.positionEl = this.wrap;
41858 onDestroy : function(){
41859 Ext.destroy(this.wrap);
41860 Ext.form.Checkbox.superclass.onDestroy.call(this);
41864 initValue : function() {
41865 this.originalValue = this.getValue();
41869 getValue : function(){
41871 return this.el.dom.checked;
41873 return this.checked;
41877 onClick : function(){
41878 if(this.el.dom.checked != this.checked){
41879 this.setValue(this.el.dom.checked);
41884 setValue : function(v){
41885 var checked = this.checked,
41886 inputVal = this.inputValue;
41888 this.checked = (v === true || v === 'true' || v == '1' || (inputVal ? v == inputVal : String(v).toLowerCase() == 'on'));
41890 this.el.dom.checked = this.checked;
41891 this.el.dom.defaultChecked = this.checked;
41893 if(checked != this.checked){
41894 this.fireEvent('check', this, this.checked);
41896 this.handler.call(this.scope || this, this, this.checked);
41902 Ext.reg('checkbox', Ext.form.Checkbox);
41904 Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
41913 blankText : "You must select at least one item in this group",
41916 defaultType : 'checkbox',
41919 groupCls : 'x-form-check-group',
41922 initComponent: function(){
41927 this.on('change', this.validate, this);
41928 Ext.form.CheckboxGroup.superclass.initComponent.call(this);
41932 onRender : function(ct, position){
41938 cls: this.groupCls,
41941 bufferResize: false
41944 xtype: 'container',
41945 defaultType: this.defaultType,
41953 if(this.items[0].items){
41957 Ext.apply(panelCfg, {
41958 layoutConfig: {columns: this.items.length},
41959 defaults: this.defaults,
41962 for(var i=0, len=this.items.length; i<len; i++){
41963 Ext.applyIf(this.items[i], colCfg);
41971 var numCols, cols = [];
41973 if(typeof this.columns == 'string'){
41974 this.columns = this.items.length;
41976 if(!Ext.isArray(this.columns)){
41978 for(var i=0; i<this.columns; i++){
41979 cs.push((100/this.columns)*.01);
41984 numCols = this.columns.length;
41987 for(var i=0; i<numCols; i++){
41988 var cc = Ext.apply({items:[]}, colCfg);
41989 cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
41991 cc.defaults = Ext.apply(cc.defaults || {}, this.defaults);
41998 var rows = Math.ceil(this.items.length / numCols), ri = 0;
41999 for(var i=0, len=this.items.length; i<len; i++){
42000 if(i>0 && i%rows==0){
42003 if(this.items[i].fieldLabel){
42004 this.items[i].hideLabel = false;
42006 cols[ri].items.push(this.items[i]);
42009 for(var i=0, len=this.items.length; i<len; i++){
42010 var ci = i % numCols;
42011 if(this.items[i].fieldLabel){
42012 this.items[i].hideLabel = false;
42014 cols[ci].items.push(this.items[i]);
42018 Ext.apply(panelCfg, {
42019 layoutConfig: {columns: numCols},
42024 this.panel = new Ext.Container(panelCfg);
42025 this.panel.ownerCt = this;
42026 this.el = this.panel.getEl();
42028 if(this.forId && this.itemCls){
42029 var l = this.el.up(this.itemCls).child('label', true);
42031 l.setAttribute('htmlFor', this.forId);
42035 var fields = this.panel.findBy(function(c){
42036 return c.isFormField;
42039 this.items = new Ext.util.MixedCollection();
42040 this.items.addAll(fields);
42042 Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);
42045 initValue : function(){
42047 this.setValue.apply(this, this.buffered ? this.value : [this.value]);
42048 delete this.buffered;
42053 afterRender : function(){
42054 Ext.form.CheckboxGroup.superclass.afterRender.call(this);
42055 this.eachItem(function(item){
42056 item.on('check', this.fireChecked, this);
42057 item.inGroup = true;
42062 doLayout: function(){
42065 this.panel.forceLayout = this.ownerCt.forceLayout;
42066 this.panel.doLayout();
42071 fireChecked: function(){
42073 this.eachItem(function(item){
42078 this.fireEvent('change', this, arr);
42082 getErrors: function() {
42083 var errors = Ext.form.CheckboxGroup.superclass.getErrors.apply(this, arguments);
42085 if (!this.allowBlank) {
42088 this.eachItem(function(f){
42090 return (blank = false);
42094 if (blank) errors.push(this.blankText);
42101 isDirty: function(){
42103 if (this.disabled || !this.rendered) {
42109 this.eachItem(function(item){
42110 if(item.isDirty()){
42120 setReadOnly : function(readOnly){
42122 this.eachItem(function(item){
42123 item.setReadOnly(readOnly);
42126 this.readOnly = readOnly;
42130 onDisable : function(){
42131 this.eachItem(function(item){
42137 onEnable : function(){
42138 this.eachItem(function(item){
42144 onResize : function(w, h){
42145 this.panel.setSize(w, h);
42146 this.panel.doLayout();
42150 reset : function(){
42151 if (this.originalValue) {
42153 this.eachItem(function(c){
42156 c.originalValue = c.getValue();
42161 this.resetOriginal = true;
42162 this.setValue(this.originalValue);
42163 delete this.resetOriginal;
42165 this.eachItem(function(c){
42174 this.clearInvalid();
42175 }).defer(50, this);
42179 setValue: function(){
42181 this.onSetValue.apply(this, arguments);
42183 this.buffered = true;
42184 this.value = arguments;
42190 onSetValue: function(id, value){
42191 if(arguments.length == 1){
42192 if(Ext.isArray(id)){
42193 Ext.each(id, function(val, idx){
42194 if (Ext.isObject(val) && val.setValue){
42195 val.setValue(true);
42196 if (this.resetOriginal === true) {
42197 val.originalValue = val.getValue();
42200 var item = this.items.itemAt(idx);
42202 item.setValue(val);
42206 }else if(Ext.isObject(id)){
42209 var f = this.getBox(i);
42215 this.setValueForItem(id);
42218 var f = this.getBox(id);
42226 beforeDestroy: function(){
42227 Ext.destroy(this.panel);
42228 if (!this.rendered) {
42229 Ext.destroy(this.items);
42231 Ext.form.CheckboxGroup.superclass.beforeDestroy.call(this);
42235 setValueForItem : function(val){
42236 val = String(val).split(',');
42237 this.eachItem(function(item){
42238 if(val.indexOf(item.inputValue)> -1){
42239 item.setValue(true);
42245 getBox : function(id){
42247 this.eachItem(function(f){
42248 if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){
42257 getValue : function(){
42259 this.eachItem(function(item){
42268 eachItem: function(fn, scope) {
42269 if(this.items && this.items.each){
42270 this.items.each(fn, scope || this);
42277 getRawValue : Ext.emptyFn,
42280 setRawValue : Ext.emptyFn
42284 Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);
42286 Ext.form.CompositeField = Ext.extend(Ext.form.Field, {
42289 defaultMargins: '0 5 0 0',
42292 skipLastItemMargin: true,
42298 combineErrors: true,
42301 labelConnector: ', ',
42307 initComponent: function() {
42309 items = this.items,
42312 for (var i=0, j = items.length; i < j; i++) {
42315 labels.push(item.fieldLabel);
42318 Ext.applyIf(item, this.defaults);
42321 if (!(i == j - 1 && this.skipLastItemMargin)) {
42322 Ext.applyIf(item, {margins: this.defaultMargins});
42326 this.fieldLabel = this.fieldLabel || this.buildLabel(labels);
42329 this.fieldErrors = new Ext.util.MixedCollection(true, function(item) {
42333 this.fieldErrors.on({
42335 add : this.updateInvalidMark,
42336 remove : this.updateInvalidMark,
42337 replace: this.updateInvalidMark
42340 Ext.form.CompositeField.superclass.initComponent.apply(this, arguments);
42342 this.innerCt = new Ext.Container({
42344 items : this.items,
42345 cls : 'x-form-composite',
42346 defaultMargins: '0 3 0 0'
42349 var fields = this.innerCt.findBy(function(c) {
42350 return c.isFormField;
42354 this.items = new Ext.util.MixedCollection();
42355 this.items.addAll(fields);
42360 onRender: function(ct, position) {
42363 var innerCt = this.innerCt;
42364 innerCt.render(ct);
42366 this.el = innerCt.getEl();
42370 if (this.combineErrors) {
42371 this.eachItem(function(field) {
42373 markInvalid : this.onFieldMarkInvalid.createDelegate(this, [field], 0),
42374 clearInvalid: this.onFieldClearInvalid.createDelegate(this, [field], 0)
42380 var l = this.el.parent().parent().child('label', true);
42382 l.setAttribute('for', this.items.items[0].id);
42386 Ext.form.CompositeField.superclass.onRender.apply(this, arguments);
42390 onFieldMarkInvalid: function(field, message) {
42391 var name = field.getName(),
42394 errorName: field.fieldLabel || name,
42398 this.fieldErrors.replace(name, error);
42400 field.el.addClass(field.invalidClass);
42404 onFieldClearInvalid: function(field) {
42405 this.fieldErrors.removeKey(field.getName());
42407 field.el.removeClass(field.invalidClass);
42411 updateInvalidMark: function() {
42412 var ieStrict = Ext.isIE6 && Ext.isStrict;
42414 if (this.fieldErrors.length == 0) {
42415 this.clearInvalid();
42419 this.clearInvalid.defer(50, this);
42422 var message = this.buildCombinedErrorMessage(this.fieldErrors.items);
42425 this.markInvalid(message);
42429 this.markInvalid(message);
42435 validateValue: function() {
42438 this.eachItem(function(field) {
42439 if (!field.isValid()) valid = false;
42446 buildCombinedErrorMessage: function(errors) {
42450 for (var i = 0, j = errors.length; i < j; i++) {
42453 combined.push(String.format("{0}: {1}", error.errorName, error.error));
42456 return combined.join("<br />");
42460 sortErrors: function() {
42461 var fields = this.items;
42463 this.fieldErrors.sort("ASC", function(a, b) {
42464 var findByName = function(key) {
42465 return function(field) {
42466 return field.getName() == key;
42470 var aIndex = fields.findIndexBy(findByName(a.field)),
42471 bIndex = fields.findIndexBy(findByName(b.field));
42473 return aIndex < bIndex ? -1 : 1;
42478 reset: function() {
42479 this.eachItem(function(item) {
42486 this.clearInvalid();
42487 }).defer(50, this);
42491 clearInvalidChildren: function() {
42492 this.eachItem(function(item) {
42493 item.clearInvalid();
42498 buildLabel: function(segments) {
42499 return Ext.clean(segments).join(this.labelConnector);
42503 isDirty: function(){
42505 if (this.disabled || !this.rendered) {
42510 this.eachItem(function(item){
42511 if(item.isDirty()){
42520 eachItem: function(fn, scope) {
42521 if(this.items && this.items.each){
42522 this.items.each(fn, scope || this);
42527 onResize: function(adjWidth, adjHeight, rawWidth, rawHeight) {
42528 var innerCt = this.innerCt;
42530 if (this.rendered && innerCt.rendered) {
42531 innerCt.setSize(adjWidth, adjHeight);
42534 Ext.form.CompositeField.superclass.onResize.apply(this, arguments);
42538 doLayout: function(shallow, force) {
42539 if (this.rendered) {
42540 var innerCt = this.innerCt;
42542 innerCt.forceLayout = this.ownerCt.forceLayout;
42543 innerCt.doLayout(shallow, force);
42548 beforeDestroy: function(){
42549 Ext.destroy(this.innerCt);
42551 Ext.form.CompositeField.superclass.beforeDestroy.call(this);
42555 setReadOnly : function(readOnly) {
42556 if (readOnly == undefined) {
42559 readOnly = !!readOnly;
42562 this.eachItem(function(item){
42563 item.setReadOnly(readOnly);
42566 this.readOnly = readOnly;
42569 onShow : function() {
42570 Ext.form.CompositeField.superclass.onShow.call(this);
42575 onDisable : function(){
42576 this.eachItem(function(item){
42582 onEnable : function(){
42583 this.eachItem(function(item){
42589 Ext.reg('compositefield', Ext.form.CompositeField);
42590 Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
42591 inputType: 'radio',
42594 markInvalid : Ext.emptyFn,
42596 clearInvalid : Ext.emptyFn,
42599 getGroupValue : function(){
42600 var p = this.el.up('form') || Ext.getBody();
42601 var c = p.child('input[name='+this.el.dom.name+']:checked', true);
42602 return c ? c.value : null;
42606 setValue : function(v){
42610 if (typeof v == 'boolean') {
42611 Ext.form.Radio.superclass.setValue.call(this, v);
42612 } else if (this.rendered) {
42613 checkEl = this.getCheckEl();
42614 radio = checkEl.child('input[name=' + this.el.dom.name + '][value=' + v + ']', true);
42616 Ext.getCmp(radio.id).setValue(true);
42619 if(this.rendered && this.checked){
42620 checkEl = checkEl || this.getCheckEl();
42621 els = this.getCheckEl().select('input[name=' + this.el.dom.name + ']');
42622 els.each(function(el){
42623 if(el.dom.id != this.id){
42624 Ext.getCmp(el.dom.id).setValue(false);
42632 getCheckEl: function(){
42634 return this.el.up('.x-form-radio-group');
42636 return this.el.up('form') || Ext.getBody();
42639 Ext.reg('radio', Ext.form.Radio);
42641 Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, {
42646 blankText : 'You must select one item in this group',
42649 defaultType : 'radio',
42652 groupCls : 'x-form-radio-group',
42657 getValue : function(){
42659 this.eachItem(function(item){
42669 onSetValue : function(id, value){
42670 if(arguments.length > 1){
42671 var f = this.getBox(id);
42675 this.eachItem(function(item){
42677 item.setValue(false);
42683 this.setValueForItem(id);
42687 setValueForItem : function(val){
42688 val = String(val).split(',')[0];
42689 this.eachItem(function(item){
42690 item.setValue(val == item.inputValue);
42695 fireChecked : function(){
42696 if(!this.checkTask){
42697 this.checkTask = new Ext.util.DelayedTask(this.bufferChecked, this);
42699 this.checkTask.delay(10);
42703 bufferChecked : function(){
42705 this.eachItem(function(item){
42711 this.fireEvent('change', this, out);
42714 onDestroy : function(){
42715 if(this.checkTask){
42716 this.checkTask.cancel();
42717 this.checkTask = null;
42719 Ext.form.RadioGroup.superclass.onDestroy.call(this);
42724 Ext.reg('radiogroup', Ext.form.RadioGroup);
42726 Ext.form.Hidden = Ext.extend(Ext.form.Field, {
42728 inputType : 'hidden',
42730 shouldLayout: false,
42733 onRender : function(){
42734 Ext.form.Hidden.superclass.onRender.apply(this, arguments);
42738 initEvents : function(){
42739 this.originalValue = this.getValue();
42743 setSize : Ext.emptyFn,
42744 setWidth : Ext.emptyFn,
42745 setHeight : Ext.emptyFn,
42746 setPosition : Ext.emptyFn,
42747 setPagePosition : Ext.emptyFn,
42748 markInvalid : Ext.emptyFn,
42749 clearInvalid : Ext.emptyFn
42751 Ext.reg('hidden', Ext.form.Hidden);
42752 Ext.form.BasicForm = Ext.extend(Ext.util.Observable, {
42754 constructor: function(el, config){
42755 Ext.apply(this, config);
42756 if(Ext.isString(this.paramOrder)){
42757 this.paramOrder = this.paramOrder.split(/[\s,|]/);
42760 this.items = new Ext.util.MixedCollection(false, function(o){
42761 return o.getItemId();
42775 Ext.form.BasicForm.superclass.constructor.call(this);
42790 paramOrder: undefined,
42793 paramsAsHash: false,
42796 waitTitle: 'Please Wait...',
42799 activeAction : null,
42802 trackResetOnLoad : false,
42808 initEl : function(el){
42809 this.el = Ext.get(el);
42810 this.id = this.el.id || Ext.id();
42811 if(!this.standardSubmit){
42812 this.el.on('submit', this.onSubmit, this);
42814 this.el.addClass('x-form');
42823 onSubmit : function(e){
42828 destroy: function(bound){
42829 if(bound !== true){
42830 this.items.each(function(f){
42833 Ext.destroy(this.el);
42835 this.items.clear();
42836 this.purgeListeners();
42840 isValid : function(){
42842 this.items.each(function(f){
42851 isDirty : function(){
42853 this.items.each(function(f){
42863 doAction : function(action, options){
42864 if(Ext.isString(action)){
42865 action = new Ext.form.Action.ACTION_TYPES[action](this, options);
42867 if(this.fireEvent('beforeaction', this, action) !== false){
42868 this.beforeAction(action);
42869 action.run.defer(100, action);
42875 submit : function(options){
42876 options = options || {};
42877 if(this.standardSubmit){
42878 var v = options.clientValidation === false || this.isValid();
42880 var el = this.el.dom;
42881 if(this.url && Ext.isEmpty(el.action)){
42882 el.action = this.url;
42888 var submitAction = String.format('{0}submit', this.api ? 'direct' : '');
42889 this.doAction(submitAction, options);
42894 load : function(options){
42895 var loadAction = String.format('{0}load', this.api ? 'direct' : '');
42896 this.doAction(loadAction, options);
42901 updateRecord : function(record){
42902 record.beginEdit();
42903 var fs = record.fields;
42904 fs.each(function(f){
42905 var field = this.findField(f.name);
42907 var value = field.getValue();
42908 if ( value.getGroupValue ) {
42909 value = value.getGroupValue();
42910 } else if ( field.eachItem ) {
42912 field.eachItem(function(item){
42913 value.push(item.getValue());
42916 record.set(f.name, value);
42924 loadRecord : function(record){
42925 this.setValues(record.data);
42930 beforeAction : function(action){
42932 this.items.each(function(f){
42933 if(f.isFormField && f.syncValue){
42937 var o = action.options;
42939 if(this.waitMsgTarget === true){
42940 this.el.mask(o.waitMsg, 'x-mask-loading');
42941 }else if(this.waitMsgTarget){
42942 this.waitMsgTarget = Ext.get(this.waitMsgTarget);
42943 this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
42945 Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle);
42951 afterAction : function(action, success){
42952 this.activeAction = null;
42953 var o = action.options;
42955 if(this.waitMsgTarget === true){
42957 }else if(this.waitMsgTarget){
42958 this.waitMsgTarget.unmask();
42960 Ext.MessageBox.updateProgress(1);
42961 Ext.MessageBox.hide();
42968 Ext.callback(o.success, o.scope, [this, action]);
42969 this.fireEvent('actioncomplete', this, action);
42971 Ext.callback(o.failure, o.scope, [this, action]);
42972 this.fireEvent('actionfailed', this, action);
42977 findField : function(id) {
42978 var field = this.items.get(id);
42980 if (!Ext.isObject(field)) {
42982 var findMatchingField = function(f) {
42983 if (f.isFormField) {
42984 if (f.dataIndex == id || f.id == id || f.getName() == id) {
42987 } else if (f.isComposite) {
42988 return f.items.each(findMatchingField);
42989 } else if (f instanceof Ext.form.CheckboxGroup && f.rendered) {
42990 return f.eachItem(findMatchingField);
42995 this.items.each(findMatchingField);
42997 return field || null;
43002 markInvalid : function(errors){
43003 if (Ext.isArray(errors)) {
43004 for(var i = 0, len = errors.length; i < len; i++){
43005 var fieldError = errors[i];
43006 var f = this.findField(fieldError.id);
43008 f.markInvalid(fieldError.msg);
43014 if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){
43015 field.markInvalid(errors[id]);
43024 setValues : function(values){
43025 if(Ext.isArray(values)){
43026 for(var i = 0, len = values.length; i < len; i++){
43028 var f = this.findField(v.id);
43030 f.setValue(v.value);
43031 if(this.trackResetOnLoad){
43032 f.originalValue = f.getValue();
43039 if(!Ext.isFunction(values[id]) && (field = this.findField(id))){
43040 field.setValue(values[id]);
43041 if(this.trackResetOnLoad){
43042 field.originalValue = field.getValue();
43051 getValues : function(asString){
43052 var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
43053 if(asString === true){
43056 return Ext.urlDecode(fs);
43060 getFieldValues : function(dirtyOnly){
43065 this.items.each(function(f) {
43066 if (!f.disabled && (dirtyOnly !== true || f.isDirty())) {
43069 val = f.getValue();
43071 if(Ext.isDefined(key)){
43072 if(Ext.isArray(key)){
43086 clearInvalid : function(){
43087 this.items.each(function(f){
43094 reset : function(){
43095 this.items.each(function(f){
43103 this.items.addAll(Array.prototype.slice.call(arguments, 0));
43108 remove : function(field){
43109 this.items.remove(field);
43114 cleanDestroyed : function() {
43115 this.items.filterBy(function(o) { return !!o.isDestroyed; }).each(this.remove, this);
43119 render : function(){
43120 this.items.each(function(f){
43121 if(f.isFormField && !f.rendered && document.getElementById(f.id)){
43122 f.applyToMarkup(f.id);
43129 applyToFields : function(o){
43130 this.items.each(function(f){
43137 applyIfToFields : function(o){
43138 this.items.each(function(f){
43144 callFieldMethod : function(fnName, args){
43146 this.items.each(function(f){
43147 if(Ext.isFunction(f[fnName])){
43148 f[fnName].apply(f, args);
43156 Ext.BasicForm = Ext.form.BasicForm;
43158 Ext.FormPanel = Ext.extend(Ext.Panel, {
43169 minButtonWidth : 75,
43172 labelAlign : 'left',
43175 monitorValid : false,
43184 initComponent : function(){
43185 this.form = this.createForm();
43186 Ext.FormPanel.superclass.initComponent.call(this);
43190 cls: this.baseCls + '-body',
43191 method : this.method || 'POST',
43192 id : this.formId || Ext.id()
43194 if(this.fileUpload) {
43195 this.bodyCfg.enctype = 'multipart/form-data';
43204 this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
43208 createForm : function(){
43209 var config = Ext.applyIf({listeners: {}}, this.initialConfig);
43210 return new Ext.form.BasicForm(null, config);
43214 initFields : function(){
43216 var formPanel = this;
43217 var fn = function(c){
43218 if(formPanel.isField(c)){
43220 }else if(c.findBy && c != formPanel){
43221 formPanel.applySettings(c);
43223 if(c.items && c.items.each){
43224 c.items.each(fn, this);
43228 this.items.each(fn, this);
43232 applySettings: function(c){
43233 var ct = c.ownerCt;
43235 labelAlign: ct.labelAlign,
43236 labelWidth: ct.labelWidth,
43237 itemCls: ct.itemCls
43242 getLayoutTarget : function(){
43243 return this.form.el;
43247 getForm : function(){
43252 onRender : function(ct, position){
43254 Ext.FormPanel.superclass.onRender.call(this, ct, position);
43255 this.form.initEl(this.body);
43259 beforeDestroy : function(){
43260 this.stopMonitoring();
43261 this.form.destroy(true);
43262 Ext.FormPanel.superclass.beforeDestroy.call(this);
43266 isField : function(c) {
43267 return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid;
43271 initEvents : function(){
43272 Ext.FormPanel.superclass.initEvents.call(this);
43276 add: this.onAddEvent,
43277 remove: this.onRemoveEvent
43279 if(this.monitorValid){
43280 this.startMonitoring();
43285 onAdd: function(c){
43286 Ext.FormPanel.superclass.onAdd.call(this, c);
43287 this.processAdd(c);
43291 onAddEvent: function(ct, c){
43293 this.processAdd(c);
43298 processAdd : function(c){
43300 if(this.isField(c)){
43303 }else if(c.findBy){
43304 this.applySettings(c);
43305 this.form.add.apply(this.form, c.findBy(this.isField));
43310 onRemove: function(c){
43311 Ext.FormPanel.superclass.onRemove.call(this, c);
43312 this.processRemove(c);
43315 onRemoveEvent: function(ct, c){
43317 this.processRemove(c);
43322 processRemove: function(c){
43323 if(!this.destroying){
43325 if(this.isField(c)){
43326 this.form.remove(c);
43328 }else if (c.findBy){
43329 Ext.each(c.findBy(this.isField), this.form.remove, this.form);
43331 this.form.cleanDestroyed();
43337 startMonitoring : function(){
43338 if(!this.validTask){
43339 this.validTask = new Ext.util.TaskRunner();
43340 this.validTask.start({
43341 run : this.bindHandler,
43342 interval : this.monitorPoll || 200,
43349 stopMonitoring : function(){
43350 if(this.validTask){
43351 this.validTask.stopAll();
43352 this.validTask = null;
43358 this.form.load.apply(this.form, arguments);
43362 onDisable : function(){
43363 Ext.FormPanel.superclass.onDisable.call(this);
43365 this.form.items.each(function(){
43372 onEnable : function(){
43373 Ext.FormPanel.superclass.onEnable.call(this);
43375 this.form.items.each(function(){
43382 bindHandler : function(){
43384 this.form.items.each(function(f){
43385 if(!f.isValid(true)){
43391 var fitems = this.fbar.items.items;
43392 for(var i = 0, len = fitems.length; i < len; i++){
43393 var btn = fitems[i];
43394 if(btn.formBind === true && btn.disabled === valid){
43395 btn.setDisabled(!valid);
43399 this.fireEvent('clientvalidation', this, valid);
43402 Ext.reg('form', Ext.FormPanel);
43404 Ext.form.FormPanel = Ext.FormPanel;
43406 Ext.form.FieldSet = Ext.extend(Ext.Panel, {
43413 baseCls : 'x-fieldset',
43417 animCollapse : false,
43420 onRender : function(ct, position){
43422 this.el = document.createElement('fieldset');
43423 this.el.id = this.id;
43424 if (this.title || this.header || this.checkboxToggle) {
43425 this.el.appendChild(document.createElement('legend')).className = this.baseCls + '-header';
43429 Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
43431 if(this.checkboxToggle){
43432 var o = typeof this.checkboxToggle == 'object' ?
43433 this.checkboxToggle :
43434 {tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
43435 this.checkbox = this.header.insertFirst(o);
43436 this.checkbox.dom.checked = !this.collapsed;
43437 this.mon(this.checkbox, 'click', this.onCheckClick, this);
43442 onCollapse : function(doAnim, animArg){
43444 this.checkbox.dom.checked = false;
43446 Ext.form.FieldSet.superclass.onCollapse.call(this, doAnim, animArg);
43451 onExpand : function(doAnim, animArg){
43453 this.checkbox.dom.checked = true;
43455 Ext.form.FieldSet.superclass.onExpand.call(this, doAnim, animArg);
43459 onCheckClick : function(){
43460 this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
43498 Ext.reg('fieldset', Ext.form.FieldSet);
43500 Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
43502 enableFormat : true,
43504 enableFontSize : true,
43506 enableColors : true,
43508 enableAlignments : true,
43510 enableLists : true,
43512 enableSourceEdit : true,
43514 enableLinks : true,
43518 createLinkText : 'Please enter the URL for the link:',
43520 defaultLinkValue : 'http:/'+'/',
43529 defaultFont: 'tahoma',
43531 defaultValue: (Ext.isOpera || Ext.isIE6) ? ' ' : '​',
43534 actionMode: 'wrap',
43535 validationEvent : false,
43537 initialized : false,
43539 sourceEditMode : false,
43540 onFocus : Ext.emptyFn,
43542 hideMode:'offsets',
43543 defaultAutoCreate : {
43545 style:"width:500px;height:300px;",
43546 autocomplete: "off"
43550 initComponent : function(){
43567 Ext.form.HtmlEditor.superclass.initComponent.call(this);
43571 createFontOptions : function(){
43572 var buf = [], fs = this.fontFamilies, ff, lc;
43573 for(var i = 0, len = fs.length; i< len; i++){
43575 lc = ff.toLowerCase();
43577 '<option value="',lc,'" style="font-family:',ff,';"',
43578 (this.defaultFont == lc ? ' selected="true">' : '>'),
43583 return buf.join('');
43587 createToolbar : function(editor){
43589 var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
43592 function btn(id, toggle, handler){
43595 cls : 'x-btn-icon',
43596 iconCls: 'x-edit-'+id,
43597 enableToggle:toggle !== false,
43599 handler:handler||editor.relayBtnCmd,
43600 clickEvent:'mousedown',
43601 tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
43602 overflowText: editor.buttonTips[id].title || undefined,
43608 if(this.enableFont && !Ext.isSafari2){
43609 var fontSelectItem = new Ext.Toolbar.Item({
43612 cls:'x-font-select',
43613 html: this.createFontOptions()
43623 if(this.enableFormat){
43631 if(this.enableFontSize){
43634 btn('increasefontsize', false, this.adjustFont),
43635 btn('decreasefontsize', false, this.adjustFont)
43639 if(this.enableColors){
43642 itemId:'forecolor',
43644 iconCls: 'x-edit-forecolor',
43645 clickEvent:'mousedown',
43646 tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
43648 menu : new Ext.menu.ColorMenu({
43649 allowReselect: true,
43650 focus: Ext.emptyFn,
43655 select: function(cp, color){
43656 this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
43660 clickEvent:'mousedown'
43663 itemId:'backcolor',
43665 iconCls: 'x-edit-backcolor',
43666 clickEvent:'mousedown',
43667 tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
43669 menu : new Ext.menu.ColorMenu({
43670 focus: Ext.emptyFn,
43673 allowReselect: true,
43676 select: function(cp, color){
43678 this.execCmd('useCSS', false);
43679 this.execCmd('hilitecolor', color);
43680 this.execCmd('useCSS', true);
43683 this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
43688 clickEvent:'mousedown'
43694 if(this.enableAlignments){
43697 btn('justifyleft'),
43698 btn('justifycenter'),
43699 btn('justifyright')
43703 if(!Ext.isSafari2){
43704 if(this.enableLinks){
43707 btn('createlink', false, this.createLink)
43711 if(this.enableLists){
43714 btn('insertorderedlist'),
43715 btn('insertunorderedlist')
43718 if(this.enableSourceEdit){
43721 btn('sourceedit', true, function(btn){
43722 this.toggleSourceEdit(!this.sourceEditMode);
43729 var tb = new Ext.Toolbar({
43730 renderTo: this.wrap.dom.firstChild,
43734 if (fontSelectItem) {
43735 this.fontSelect = fontSelectItem.el;
43737 this.mon(this.fontSelect, 'change', function(){
43738 var font = this.fontSelect.dom.value;
43739 this.relayCmd('fontname', font);
43745 this.mon(tb.el, 'click', function(e){
43746 e.preventDefault();
43750 this.tb.doLayout();
43753 onDisable: function(){
43755 Ext.form.HtmlEditor.superclass.onDisable.call(this);
43758 onEnable: function(){
43759 this.wrap.unmask();
43760 Ext.form.HtmlEditor.superclass.onEnable.call(this);
43763 setReadOnly: function(readOnly){
43765 Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
43766 if(this.initialized){
43768 this.getEditorBody().contentEditable = !readOnly;
43770 this.setDesignMode(!readOnly);
43772 var bd = this.getEditorBody();
43774 bd.style.cursor = this.readOnly ? 'default' : 'text';
43776 this.disableItems(readOnly);
43781 getDocMarkup : function(){
43782 var h = Ext.fly(this.iframe).getHeight() - this.iframePad * 2;
43783 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);
43787 getEditorBody : function(){
43788 var doc = this.getDoc();
43789 return doc.body || doc.documentElement;
43793 getDoc : function(){
43794 return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
43798 getWin : function(){
43799 return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
43803 onRender : function(ct, position){
43804 Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
43805 this.el.dom.style.border = '0 none';
43806 this.el.dom.setAttribute('tabIndex', -1);
43807 this.el.addClass('x-hidden');
43809 this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;');
43811 this.wrap = this.el.wrap({
43812 cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
43815 this.createToolbar(this);
43817 this.disableItems(true);
43819 this.tb.doLayout();
43821 this.createIFrame();
43824 var sz = this.el.getSize();
43825 this.setSize(sz.width, this.height || sz.height);
43827 this.resizeEl = this.positionEl = this.wrap;
43830 createIFrame: function(){
43831 var iframe = document.createElement('iframe');
43832 iframe.name = Ext.id();
43833 iframe.frameBorder = '0';
43834 iframe.style.overflow = 'auto';
43835 iframe.src = Ext.SSL_SECURE_URL;
43837 this.wrap.dom.appendChild(iframe);
43838 this.iframe = iframe;
43840 this.monitorTask = Ext.TaskMgr.start({
43841 run: this.checkDesignMode,
43847 initFrame : function(){
43848 Ext.TaskMgr.stop(this.monitorTask);
43849 var doc = this.getDoc();
43850 this.win = this.getWin();
43853 doc.write(this.getDocMarkup());
43858 var doc = this.getDoc();
43859 if(doc.body || doc.readyState == 'complete'){
43860 Ext.TaskMgr.stop(task);
43861 this.setDesignMode(true);
43862 this.initEditor.defer(10, this);
43869 Ext.TaskMgr.start(task);
43873 checkDesignMode : function(){
43874 if(this.wrap && this.wrap.dom.offsetWidth){
43875 var doc = this.getDoc();
43879 if(!doc.editorInitialized || this.getDesignMode() != 'on'){
43886 setDesignMode : function(mode){
43887 var doc = this.getDoc();
43892 doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off';
43898 getDesignMode : function(){
43899 var doc = this.getDoc();
43900 if(!doc){ return ''; }
43901 return String(doc.designMode).toLowerCase();
43905 disableItems: function(disabled){
43906 if(this.fontSelect){
43907 this.fontSelect.dom.disabled = disabled;
43909 this.tb.items.each(function(item){
43910 if(item.getItemId() != 'sourceedit'){
43911 item.setDisabled(disabled);
43917 onResize : function(w, h){
43918 Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
43919 if(this.el && this.iframe){
43920 if(Ext.isNumber(w)){
43921 var aw = w - this.wrap.getFrameWidth('lr');
43922 this.el.setWidth(aw);
43923 this.tb.setWidth(aw);
43924 this.iframe.style.width = Math.max(aw, 0) + 'px';
43926 if(Ext.isNumber(h)){
43927 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
43928 this.el.setHeight(ah);
43929 this.iframe.style.height = Math.max(ah, 0) + 'px';
43930 var bd = this.getEditorBody();
43932 bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
43939 toggleSourceEdit : function(sourceEditMode){
43943 if (sourceEditMode === undefined) {
43944 sourceEditMode = !this.sourceEditMode;
43946 this.sourceEditMode = sourceEditMode === true;
43947 var btn = this.tb.getComponent('sourceedit');
43949 if (btn.pressed !== this.sourceEditMode) {
43950 btn.toggle(this.sourceEditMode);
43951 if (!btn.xtbHidden) {
43955 if (this.sourceEditMode) {
43957 this.previousSize = this.getSize();
43959 iframeHeight = Ext.get(this.iframe).getHeight();
43961 this.disableItems(true);
43963 this.iframe.className = 'x-hidden';
43964 this.el.removeClass('x-hidden');
43965 this.el.dom.removeAttribute('tabIndex');
43967 this.el.dom.style.height = iframeHeight + 'px';
43970 elHeight = parseInt(this.el.dom.style.height, 10);
43971 if (this.initialized) {
43972 this.disableItems(this.readOnly);
43975 this.iframe.className = '';
43976 this.el.addClass('x-hidden');
43977 this.el.dom.setAttribute('tabIndex', -1);
43980 this.setSize(this.previousSize);
43981 delete this.previousSize;
43982 this.iframe.style.height = elHeight + 'px';
43984 this.fireEvent('editmodechange', this, this.sourceEditMode);
43988 createLink : function() {
43989 var url = prompt(this.createLinkText, this.defaultLinkValue);
43990 if(url && url != 'http:/'+'/'){
43991 this.relayCmd('createlink', url);
43996 initEvents : function(){
43997 this.originalValue = this.getValue();
44001 markInvalid : Ext.emptyFn,
44004 clearInvalid : Ext.emptyFn,
44007 setValue : function(v){
44008 Ext.form.HtmlEditor.superclass.setValue.call(this, v);
44014 cleanHtml: function(html) {
44015 html = String(html);
44017 html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
44021 if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){
44022 html = html.substring(1);
44028 syncValue : function(){
44029 if(this.initialized){
44030 var bd = this.getEditorBody();
44031 var html = bd.innerHTML;
44033 var bs = bd.getAttribute('style');
44034 var m = bs.match(/text-align:(.*?);/i);
44036 html = '<div style="'+m[0]+'">' + html + '</div>';
44039 html = this.cleanHtml(html);
44040 if(this.fireEvent('beforesync', this, html) !== false){
44041 this.el.dom.value = html;
44042 this.fireEvent('sync', this, html);
44048 getValue : function() {
44049 this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
44050 return Ext.form.HtmlEditor.superclass.getValue.call(this);
44054 pushValue : function(){
44055 if(this.initialized){
44056 var v = this.el.dom.value;
44057 if(!this.activated && v.length < 1){
44058 v = this.defaultValue;
44060 if(this.fireEvent('beforepush', this, v) !== false){
44061 this.getEditorBody().innerHTML = v;
44064 this.setDesignMode(false);
44065 this.setDesignMode(true);
44067 this.fireEvent('push', this, v);
44074 deferFocus : function(){
44075 this.focus.defer(10, this);
44079 focus : function(){
44080 if(this.win && !this.sourceEditMode){
44088 initEditor : function(){
44091 var dbody = this.getEditorBody(),
44092 ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'),
44096 ss['background-attachment'] = 'fixed';
44097 dbody.bgProperties = 'fixed';
44099 Ext.DomHelper.applyStyles(dbody, ss);
44101 doc = this.getDoc();
44105 Ext.EventManager.removeAll(doc);
44110 fn = this.onEditorEvent.createDelegate(this);
44111 Ext.EventManager.on(doc, {
44120 Ext.EventManager.on(doc, 'keypress', this.applyCommand, this);
44122 if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
44123 Ext.EventManager.on(doc, 'keydown', this.fixKeys, this);
44125 doc.editorInitialized = true;
44126 this.initialized = true;
44128 this.setReadOnly(this.readOnly);
44129 this.fireEvent('initialize', this);
44134 beforeDestroy : function(){
44135 if(this.monitorTask){
44136 Ext.TaskMgr.stop(this.monitorTask);
44139 Ext.destroy(this.tb);
44140 var doc = this.getDoc();
44143 Ext.EventManager.removeAll(doc);
44144 for (var prop in doc){
44150 this.wrap.dom.innerHTML = '';
44151 this.wrap.remove();
44154 Ext.form.HtmlEditor.superclass.beforeDestroy.call(this);
44158 onFirstFocus : function(){
44159 this.activated = true;
44160 this.disableItems(this.readOnly);
44163 var s = this.win.getSelection();
44164 if(!s.focusNode || s.focusNode.nodeType != 3){
44165 var r = s.getRangeAt(0);
44166 r.selectNodeContents(this.getEditorBody());
44171 this.execCmd('useCSS', true);
44172 this.execCmd('styleWithCSS', false);
44175 this.fireEvent('activate', this);
44179 adjustFont: function(btn){
44180 var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1,
44181 doc = this.getDoc(),
44182 v = parseInt(doc.queryCommandValue('FontSize') || 2, 10);
44183 if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){
44199 v = v.constrain(1, 6);
44204 v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
44206 this.execCmd('FontSize', v);
44210 onEditorEvent : function(e){
44211 this.updateToolbar();
44216 updateToolbar: function(){
44222 if(!this.activated){
44223 this.onFirstFocus();
44227 var btns = this.tb.items.map,
44228 doc = this.getDoc();
44230 if(this.enableFont && !Ext.isSafari2){
44231 var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
44232 if(name != this.fontSelect.dom.value){
44233 this.fontSelect.dom.value = name;
44236 if(this.enableFormat){
44237 btns.bold.toggle(doc.queryCommandState('bold'));
44238 btns.italic.toggle(doc.queryCommandState('italic'));
44239 btns.underline.toggle(doc.queryCommandState('underline'));
44241 if(this.enableAlignments){
44242 btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
44243 btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
44244 btns.justifyright.toggle(doc.queryCommandState('justifyright'));
44246 if(!Ext.isSafari2 && this.enableLists){
44247 btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
44248 btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
44251 Ext.menu.MenuMgr.hideAll();
44257 relayBtnCmd : function(btn){
44258 this.relayCmd(btn.getItemId());
44262 relayCmd : function(cmd, value){
44265 this.execCmd(cmd, value);
44266 this.updateToolbar();
44267 }).defer(10, this);
44271 execCmd : function(cmd, value){
44272 var doc = this.getDoc();
44273 doc.execCommand(cmd, false, value === undefined ? null : value);
44278 applyCommand : function(e){
44280 var c = e.getCharCode(), cmd;
44282 c = String.fromCharCode(c);
44298 e.preventDefault();
44305 insertAtCursor : function(text){
44306 if(!this.activated){
44311 var doc = this.getDoc(),
44312 r = doc.selection.createRange();
44320 this.execCmd('InsertHTML', text);
44326 fixKeys : function(){
44328 return function(e){
44329 var k = e.getKey(),
44330 doc = this.getDoc(),
44334 r = doc.selection.createRange();
44337 r.pasteHTML(' ');
44340 }else if(k == e.ENTER){
44341 r = doc.selection.createRange();
44343 var target = r.parentElement();
44344 if(!target || target.tagName.toLowerCase() != 'li'){
44346 r.pasteHTML('<br />');
44353 }else if(Ext.isOpera){
44354 return function(e){
44355 var k = e.getKey();
44359 this.execCmd('InsertHTML',' ');
44363 }else if(Ext.isWebKit){
44364 return function(e){
44365 var k = e.getKey();
44368 this.execCmd('InsertText','\t');
44370 }else if(k == e.ENTER){
44372 this.execCmd('InsertHtml','<br /><br />');
44380 getToolbar : function(){
44387 title: 'Bold (Ctrl+B)',
44388 text: 'Make the selected text bold.',
44389 cls: 'x-html-editor-tip'
44392 title: 'Italic (Ctrl+I)',
44393 text: 'Make the selected text italic.',
44394 cls: 'x-html-editor-tip'
44397 title: 'Underline (Ctrl+U)',
44398 text: 'Underline the selected text.',
44399 cls: 'x-html-editor-tip'
44401 increasefontsize : {
44402 title: 'Grow Text',
44403 text: 'Increase the font size.',
44404 cls: 'x-html-editor-tip'
44406 decreasefontsize : {
44407 title: 'Shrink Text',
44408 text: 'Decrease the font size.',
44409 cls: 'x-html-editor-tip'
44412 title: 'Text Highlight Color',
44413 text: 'Change the background color of the selected text.',
44414 cls: 'x-html-editor-tip'
44417 title: 'Font Color',
44418 text: 'Change the color of the selected text.',
44419 cls: 'x-html-editor-tip'
44422 title: 'Align Text Left',
44423 text: 'Align text to the left.',
44424 cls: 'x-html-editor-tip'
44427 title: 'Center Text',
44428 text: 'Center text in the editor.',
44429 cls: 'x-html-editor-tip'
44432 title: 'Align Text Right',
44433 text: 'Align text to the right.',
44434 cls: 'x-html-editor-tip'
44436 insertunorderedlist : {
44437 title: 'Bullet List',
44438 text: 'Start a bulleted list.',
44439 cls: 'x-html-editor-tip'
44441 insertorderedlist : {
44442 title: 'Numbered List',
44443 text: 'Start a numbered list.',
44444 cls: 'x-html-editor-tip'
44447 title: 'Hyperlink',
44448 text: 'Make the selected text a hyperlink.',
44449 cls: 'x-html-editor-tip'
44452 title: 'Source Edit',
44453 text: 'Switch to source editing mode.',
44454 cls: 'x-html-editor-tip'
44493 Ext.reg('htmleditor', Ext.form.HtmlEditor);
44495 Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
44497 minValue : undefined,
44499 maxValue : undefined,
44501 minText : "The time in this field must be equal to or after {0}",
44503 maxText : "The time in this field must be equal to or before {0}",
44505 invalidText : "{0} is not a valid time",
44509 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",
44516 triggerAction: 'all',
44523 initDate: '1/1/2008',
44525 initDateFormat: 'j/n/Y',
44528 initComponent : function(){
44529 if(Ext.isDefined(this.minValue)){
44530 this.setMinValue(this.minValue, true);
44532 if(Ext.isDefined(this.maxValue)){
44533 this.setMaxValue(this.maxValue, true);
44536 this.generateStore(true);
44538 Ext.form.TimeField.superclass.initComponent.call(this);
44542 setMinValue: function(value, initial){
44543 this.setLimit(value, true, initial);
44548 setMaxValue: function(value, initial){
44549 this.setLimit(value, false, initial);
44554 generateStore: function(initial){
44555 var min = this.minValue || new Date(this.initDate).clearTime(),
44556 max = this.maxValue || new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1),
44560 times.push(min.dateFormat(this.format));
44561 min = min.add('mi', this.increment);
44563 this.bindStore(times, initial);
44567 setLimit: function(value, isMin, initial){
44569 if(Ext.isString(value)){
44570 d = this.parseDate(value);
44571 }else if(Ext.isDate(value)){
44575 var val = new Date(this.initDate).clearTime();
44576 val.setHours(d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds());
44577 this[isMin ? 'minValue' : 'maxValue'] = val;
44579 this.generateStore();
44585 getValue : function(){
44586 var v = Ext.form.TimeField.superclass.getValue.call(this);
44587 return this.formatDate(this.parseDate(v)) || '';
44591 setValue : function(value){
44592 return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
44596 validateValue : Ext.form.DateField.prototype.validateValue,
44598 formatDate : Ext.form.DateField.prototype.formatDate,
44600 parseDate: function(value) {
44601 if (!value || Ext.isDate(value)) {
44605 var id = this.initDate + ' ',
44606 idf = this.initDateFormat + ' ',
44607 v = Date.parseDate(id + value, idf + this.format),
44608 af = this.altFormats;
44611 if (!this.altFormatsArray) {
44612 this.altFormatsArray = af.split("|");
44614 for (var i = 0, afa = this.altFormatsArray, len = afa.length; i < len && !v; i++) {
44615 v = Date.parseDate(id + value, idf + afa[i]);
44622 Ext.reg('timefield', Ext.form.TimeField);
44623 Ext.form.SliderField = Ext.extend(Ext.form.Field, {
44632 actionMode: 'wrap',
44635 initComponent : function() {
44636 var cfg = Ext.copyTo({
44637 id: this.id + '-slider'
44638 }, this.initialConfig, ['vertical', 'minValue', 'maxValue', 'decimalPrecision', 'keyIncrement', 'increment', 'clickToChange', 'animate']);
44641 if (this.useTips) {
44642 var plug = this.tipText ? {getText: this.tipText} : {};
44643 cfg.plugins = [new Ext.slider.Tip(plug)];
44645 this.slider = new Ext.Slider(cfg);
44646 Ext.form.SliderField.superclass.initComponent.call(this);
44650 onRender : function(ct, position){
44651 this.autoCreate = {
44657 Ext.form.SliderField.superclass.onRender.call(this, ct, position);
44658 this.wrap = this.el.wrap({cls: 'x-form-field-wrap'});
44659 this.resizeEl = this.positionEl = this.wrap;
44660 this.slider.render(this.wrap);
44664 onResize : function(w, h, aw, ah){
44665 Ext.form.SliderField.superclass.onResize.call(this, w, h, aw, ah);
44666 this.slider.setSize(w, h);
44670 initEvents : function(){
44671 Ext.form.SliderField.superclass.initEvents.call(this);
44672 this.slider.on('change', this.onChange, this);
44676 onChange : function(slider, v){
44677 this.setValue(v, undefined, true);
44681 onEnable : function(){
44682 Ext.form.SliderField.superclass.onEnable.call(this);
44683 this.slider.enable();
44687 onDisable : function(){
44688 Ext.form.SliderField.superclass.onDisable.call(this);
44689 this.slider.disable();
44693 beforeDestroy : function(){
44694 Ext.destroy(this.slider);
44695 Ext.form.SliderField.superclass.beforeDestroy.call(this);
44699 alignErrorIcon : function(){
44700 this.errorIcon.alignTo(this.slider.el, 'tl-tr', [2, 0]);
44704 setMinValue : function(v){
44705 this.slider.setMinValue(v);
44710 setMaxValue : function(v){
44711 this.slider.setMaxValue(v);
44716 setValue : function(v, animate, silent){
44720 this.slider.setValue(v, animate);
44722 return Ext.form.SliderField.superclass.setValue.call(this, this.slider.getValue());
44726 getValue : function(){
44727 return this.slider.getValue();
44731 Ext.reg('sliderfield', Ext.form.SliderField);
44732 Ext.form.Label = Ext.extend(Ext.BoxComponent, {
44738 onRender : function(ct, position){
44740 this.el = document.createElement('label');
44741 this.el.id = this.getId();
44742 this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
44744 this.el.setAttribute('for', this.forId);
44747 Ext.form.Label.superclass.onRender.call(this, ct, position);
44751 setText : function(t, encode){
44752 var e = encode === false;
44753 this[!e ? 'text' : 'html'] = t;
44754 delete this[e ? 'text' : 'html'];
44756 this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;
44762 Ext.reg('label', Ext.form.Label);
44763 Ext.form.Action = function(form, options){
44765 this.options = options || {};
44769 Ext.form.Action.CLIENT_INVALID = 'client';
44771 Ext.form.Action.SERVER_INVALID = 'server';
44773 Ext.form.Action.CONNECT_FAILURE = 'connect';
44775 Ext.form.Action.LOAD_FAILURE = 'load';
44777 Ext.form.Action.prototype = {
44798 run : function(options){
44803 success : function(response){
44808 handleResponse : function(response){
44813 failure : function(response){
44814 this.response = response;
44815 this.failureType = Ext.form.Action.CONNECT_FAILURE;
44816 this.form.afterAction(this, false);
44822 processResponse : function(response){
44823 this.response = response;
44824 if(!response.responseText && !response.responseXML){
44827 this.result = this.handleResponse(response);
44828 return this.result;
44832 getUrl : function(appendParams){
44833 var url = this.options.url || this.form.url || this.form.el.dom.action;
44835 var p = this.getParams();
44837 url = Ext.urlAppend(url, p);
44844 getMethod : function(){
44845 return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
44849 getParams : function(){
44850 var bp = this.form.baseParams;
44851 var p = this.options.params;
44853 if(typeof p == "object"){
44854 p = Ext.urlEncode(Ext.applyIf(p, bp));
44855 }else if(typeof p == 'string' && bp){
44856 p += '&' + Ext.urlEncode(bp);
44859 p = Ext.urlEncode(bp);
44865 createCallback : function(opts){
44866 var opts = opts || {};
44868 success: this.success,
44869 failure: this.failure,
44871 timeout: (opts.timeout*1000) || (this.form.timeout*1000),
44872 upload: this.form.fileUpload ? this.success : undefined
44878 Ext.form.Action.Submit = function(form, options){
44879 Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
44882 Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
44889 var o = this.options,
44890 method = this.getMethod(),
44891 isGet = method == 'GET';
44892 if(o.clientValidation === false || this.form.isValid()){
44893 if (o.submitEmptyText === false) {
44894 var fields = this.form.items,
44896 setupEmptyFields = function(f){
44897 if (f.el.getValue() == f.emptyText) {
44898 emptyFields.push(f);
44899 f.el.dom.value = "";
44901 if(f.isComposite && f.rendered){
44902 f.items.each(setupEmptyFields);
44906 fields.each(setupEmptyFields);
44908 Ext.Ajax.request(Ext.apply(this.createCallback(o), {
44909 form:this.form.el.dom,
44910 url:this.getUrl(isGet),
44912 headers: o.headers,
44913 params:!isGet ? this.getParams() : null,
44914 isUpload: this.form.fileUpload
44916 if (o.submitEmptyText === false) {
44917 Ext.each(emptyFields, function(f) {
44918 if (f.applyEmptyText) {
44919 f.applyEmptyText();
44923 }else if (o.clientValidation !== false){
44924 this.failureType = Ext.form.Action.CLIENT_INVALID;
44925 this.form.afterAction(this, false);
44930 success : function(response){
44931 var result = this.processResponse(response);
44932 if(result === true || result.success){
44933 this.form.afterAction(this, true);
44937 this.form.markInvalid(result.errors);
44939 this.failureType = Ext.form.Action.SERVER_INVALID;
44940 this.form.afterAction(this, false);
44944 handleResponse : function(response){
44945 if(this.form.errorReader){
44946 var rs = this.form.errorReader.read(response);
44949 for(var i = 0, len = rs.records.length; i < len; i++) {
44950 var r = rs.records[i];
44951 errors[i] = r.data;
44954 if(errors.length < 1){
44958 success : rs.success,
44962 return Ext.decode(response.responseText);
44968 Ext.form.Action.Load = function(form, options){
44969 Ext.form.Action.Load.superclass.constructor.call(this, form, options);
44970 this.reader = this.form.reader;
44973 Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
44979 Ext.Ajax.request(Ext.apply(
44980 this.createCallback(this.options), {
44981 method:this.getMethod(),
44982 url:this.getUrl(false),
44983 headers: this.options.headers,
44984 params:this.getParams()
44989 success : function(response){
44990 var result = this.processResponse(response);
44991 if(result === true || !result.success || !result.data){
44992 this.failureType = Ext.form.Action.LOAD_FAILURE;
44993 this.form.afterAction(this, false);
44996 this.form.clearInvalid();
44997 this.form.setValues(result.data);
44998 this.form.afterAction(this, true);
45002 handleResponse : function(response){
45003 if(this.form.reader){
45004 var rs = this.form.reader.read(response);
45005 var data = rs.records && rs.records[0] ? rs.records[0].data : null;
45007 success : rs.success,
45011 return Ext.decode(response.responseText);
45018 Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {
45019 constructor: function(form, opts) {
45020 Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);
45022 type : 'directload',
45025 var args = this.getParams();
45026 args.push(this.success, this);
45027 this.form.api.load.apply(window, args);
45030 getParams : function() {
45031 var buf = [], o = {};
45032 var bp = this.form.baseParams;
45033 var p = this.options.params;
45034 Ext.apply(o, p, bp);
45035 var paramOrder = this.form.paramOrder;
45037 for(var i = 0, len = paramOrder.length; i < len; i++){
45038 buf.push(o[paramOrder[i]]);
45040 }else if(this.form.paramsAsHash){
45048 processResponse : function(result) {
45049 this.result = result;
45053 success : function(response, trans){
45054 if(trans.type == Ext.Direct.exceptions.SERVER){
45057 Ext.form.Action.DirectLoad.superclass.success.call(this, response);
45062 Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {
45063 constructor : function(form, opts) {
45064 Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);
45066 type : 'directsubmit',
45069 var o = this.options;
45070 if(o.clientValidation === false || this.form.isValid()){
45073 this.success.params = this.getParams();
45074 this.form.api.submit(this.form.el.dom, this.success, this);
45075 }else if (o.clientValidation !== false){
45076 this.failureType = Ext.form.Action.CLIENT_INVALID;
45077 this.form.afterAction(this, false);
45081 getParams : function() {
45083 var bp = this.form.baseParams;
45084 var p = this.options.params;
45085 Ext.apply(o, p, bp);
45091 processResponse : function(result) {
45092 this.result = result;
45096 success : function(response, trans){
45097 if(trans.type == Ext.Direct.exceptions.SERVER){
45100 Ext.form.Action.DirectSubmit.superclass.success.call(this, response);
45104 Ext.form.Action.ACTION_TYPES = {
45105 'load' : Ext.form.Action.Load,
45106 'submit' : Ext.form.Action.Submit,
45107 'directload' : Ext.form.Action.DirectLoad,
45108 'directsubmit' : Ext.form.Action.DirectSubmit
45111 Ext.form.VTypes = function(){
45113 var alpha = /^[a-zA-Z_]+$/,
45114 alphanum = /^[a-zA-Z0-9_]+$/,
45115 email = /^(\w+)([\-+.][\w]+)*@(\w[\-\w]*\.){1,5}([A-Za-z]){2,6}$/,
45116 url = /(((^https?)|(^ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
45121 'email' : function(v){
45122 return email.test(v);
45125 'emailText' : 'This field should be an e-mail address in the format "user@example.com"',
45127 'emailMask' : /[a-z0-9_\.\-@\+]/i,
45130 'url' : function(v){
45131 return url.test(v);
45134 'urlText' : 'This field should be a URL in the format "http:/'+'/www.example.com"',
45137 'alpha' : function(v){
45138 return alpha.test(v);
45141 'alphaText' : 'This field should only contain letters and _',
45143 'alphaMask' : /[a-z_]/i,
45146 'alphanum' : function(v){
45147 return alphanum.test(v);
45150 'alphanumText' : 'This field should only contain letters, numbers and _',
45152 'alphanumMask' : /[a-z0-9_]/i
45156 Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
45158 autoExpandColumn : false,
45161 autoExpandMax : 1000,
45164 autoExpandMin : 50,
45167 columnLines : false,
45174 ddText : '{0} selected row{1}',
45177 deferRowRender : true,
45182 enableColumnHide : true,
45185 enableColumnMove : true,
45188 enableDragDrop : false,
45191 enableHdMenu : true,
45199 minColumnWidth : 25,
45205 stripeRows : false,
45208 trackMouseOver : true,
45211 stateEvents : ['columnmove', 'columnresize', 'sortchange', 'groupchange'],
45228 initComponent : function() {
45229 Ext.grid.GridPanel.superclass.initComponent.call(this);
45231 if (this.columnLines) {
45232 this.cls = (this.cls || '') + ' x-grid-with-col-lines';
45236 this.autoScroll = false;
45237 this.autoWidth = false;
45239 if(Ext.isArray(this.columns)){
45240 this.colModel = new Ext.grid.ColumnModel(this.columns);
45241 delete this.columns;
45246 this.store = this.ds;
45250 this.colModel = this.cm;
45254 this.selModel = this.sm;
45257 this.store = Ext.StoreMgr.lookup(this.store);
45292 'rowbodymousedown',
45295 'containermousedown',
45316 'containerdblclick',
45328 'headercontextmenu',
45330 'groupcontextmenu',
45332 'containercontextmenu',
45334 'rowbodycontextmenu',
45353 onRender : function(ct, position){
45354 Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
45356 var c = this.getGridEl();
45358 this.el.addClass('x-grid-panel');
45362 mousedown: this.onMouseDown,
45363 click: this.onClick,
45364 dblclick: this.onDblClick,
45365 contextmenu: this.onContextMenu
45368 this.relayEvents(c, ['mousedown','mouseup','mouseover','mouseout','keypress', 'keydown']);
45370 var view = this.getView();
45373 this.getSelectionModel().init(this);
45377 initEvents : function(){
45378 Ext.grid.GridPanel.superclass.initEvents.call(this);
45381 this.loadMask = new Ext.LoadMask(this.bwrap,
45382 Ext.apply({store:this.store}, this.loadMask));
45386 initStateEvents : function(){
45387 Ext.grid.GridPanel.superclass.initStateEvents.call(this);
45388 this.mon(this.colModel, 'hiddenchange', this.saveState, this, {delay: 100});
45391 applyState : function(state){
45392 var cm = this.colModel,
45393 cs = state.columns,
45394 store = this.store,
45400 for(var i = 0, len = cs.length; i < len; i++){
45402 c = cm.getColumnById(s.id);
45404 cm.setState(s.id, {
45408 oldIndex = cm.getIndexById(s.id);
45410 cm.moveColumn(oldIndex, i);
45418 store[store.remoteSort ? 'setDefaultSort' : 'sort'](s.field, s.direction);
45425 store.clearGrouping();
45430 var o = Ext.apply({}, state);
45433 Ext.grid.GridPanel.superclass.applyState.call(this, o);
45436 getState : function(){
45437 var o = {columns: []},
45438 store = this.store,
45442 for(var i = 0, c; (c = this.colModel.config[i]); i++){
45448 o.columns[i].hidden = true;
45452 ss = store.getSortState();
45456 if(store.getGroupState){
45457 gs = store.getGroupState();
45467 afterRender : function(){
45468 Ext.grid.GridPanel.superclass.afterRender.call(this);
45470 this.on('bodyresize', v.layout, v);
45472 if(this.deferRowRender){
45473 if (!this.deferRowRenderTask){
45474 this.deferRowRenderTask = new Ext.util.DelayedTask(v.afterRender, this.view);
45476 this.deferRowRenderTask.delay(10);
45480 this.viewReady = true;
45484 reconfigure : function(store, colModel){
45485 var rendered = this.rendered;
45488 this.loadMask.destroy();
45489 this.loadMask = new Ext.LoadMask(this.bwrap,
45490 Ext.apply({}, {store:store}, this.initialConfig.loadMask));
45494 this.view.initData(store, colModel);
45496 this.store = store;
45497 this.colModel = colModel;
45499 this.view.refresh(true);
45501 this.fireEvent('reconfigure', this, store, colModel);
45505 onDestroy : function(){
45506 if (this.deferRowRenderTask && this.deferRowRenderTask.cancel){
45507 this.deferRowRenderTask.cancel();
45510 Ext.destroy(this.view, this.loadMask);
45511 }else if(this.store && this.store.autoDestroy){
45512 this.store.destroy();
45514 Ext.destroy(this.colModel, this.selModel);
45515 this.store = this.selModel = this.colModel = this.view = this.loadMask = null;
45516 Ext.grid.GridPanel.superclass.onDestroy.call(this);
45520 processEvent : function(name, e){
45521 this.view.processEvent(name, e);
45525 onClick : function(e){
45526 this.processEvent('click', e);
45530 onMouseDown : function(e){
45531 this.processEvent('mousedown', e);
45535 onContextMenu : function(e, t){
45536 this.processEvent('contextmenu', e);
45540 onDblClick : function(e){
45541 this.processEvent('dblclick', e);
45545 walkCells : function(row, col, step, fn, scope){
45546 var cm = this.colModel,
45547 clen = cm.getColumnCount(),
45549 rlen = ds.getCount(),
45563 if(fn.call(scope || this, row, col, cm) === true){
45581 if(fn.call(scope || this, row, col, cm) === true){
45593 getGridEl : function(){
45598 stopEditing : Ext.emptyFn,
45601 getSelectionModel : function(){
45602 if(!this.selModel){
45603 this.selModel = new Ext.grid.RowSelectionModel(
45604 this.disableSelection ? {selectRow: Ext.emptyFn} : null);
45606 return this.selModel;
45610 getStore : function(){
45615 getColumnModel : function(){
45616 return this.colModel;
45620 getView : function() {
45622 this.view = new Ext.grid.GridView(this.viewConfig);
45628 getDragDropText : function(){
45629 var count = this.selModel.getCount();
45630 return String.format(this.ddText, count, count == 1 ? '' : 's');
45684 Ext.reg('grid', Ext.grid.GridPanel);
45685 Ext.grid.PivotGrid = Ext.extend(Ext.grid.GridPanel, {
45691 renderer: undefined,
45700 initComponent: function() {
45701 Ext.grid.PivotGrid.superclass.initComponent.apply(this, arguments);
45706 this.enableColumnResize = false;
45708 this.viewConfig = Ext.apply(this.viewConfig || {}, {
45714 this.colModel = new Ext.grid.ColumnModel({});
45718 getAggregator: function() {
45719 if (typeof this.aggregator == 'string') {
45720 return Ext.grid.PivotAggregatorMgr.types[this.aggregator];
45722 return this.aggregator;
45727 setAggregator: function(aggregator) {
45728 this.aggregator = aggregator;
45732 setMeasure: function(measure) {
45733 this.measure = measure;
45737 setLeftAxis: function(axis, refresh) {
45739 this.leftAxis = axis;
45742 this.view.refresh();
45747 setTopAxis: function(axis, refresh) {
45749 this.topAxis = axis;
45752 this.view.refresh();
45757 initAxes: function() {
45758 var PivotAxis = Ext.grid.PivotAxis;
45760 if (!(this.leftAxis instanceof PivotAxis)) {
45761 this.setLeftAxis(new PivotAxis({
45762 orientation: 'vertical',
45763 dimensions : this.leftAxis || [],
45768 if (!(this.topAxis instanceof PivotAxis)) {
45769 this.setTopAxis(new PivotAxis({
45770 orientation: 'horizontal',
45771 dimensions : this.topAxis || [],
45778 extractData: function() {
45779 var records = this.store.data.items,
45780 recCount = records.length,
45784 if (recCount == 0) {
45788 var leftTuples = this.leftAxis.getTuples(),
45789 leftCount = leftTuples.length,
45790 topTuples = this.topAxis.getTuples(),
45791 topCount = topTuples.length,
45792 aggregator = this.getAggregator();
45794 for (i = 0; i < recCount; i++) {
45795 record = records[i];
45797 for (j = 0; j < leftCount; j++) {
45798 cells[j] = cells[j] || [];
45800 if (leftTuples[j].matcher(record) === true) {
45801 for (k = 0; k < topCount; k++) {
45802 cells[j][k] = cells[j][k] || [];
45804 if (topTuples[k].matcher(record)) {
45805 cells[j][k].push(record);
45812 var rowCount = cells.length,
45815 for (i = 0; i < rowCount; i++) {
45817 colCount = row.length;
45819 for (j = 0; j < colCount; j++) {
45820 cells[i][j] = aggregator(cells[i][j], this.measure);
45828 getView: function() {
45830 this.view = new Ext.grid.PivotGridView(this.viewConfig);
45837 Ext.reg('pivotgrid', Ext.grid.PivotGrid);
45840 Ext.grid.PivotAggregatorMgr = new Ext.AbstractManager();
45842 Ext.grid.PivotAggregatorMgr.registerType('sum', function(records, measure) {
45843 var length = records.length,
45847 for (i = 0; i < length; i++) {
45848 total += records[i].get(measure);
45854 Ext.grid.PivotAggregatorMgr.registerType('avg', function(records, measure) {
45855 var length = records.length,
45859 for (i = 0; i < length; i++) {
45860 total += records[i].get(measure);
45863 return (total / length) || 'n/a';
45866 Ext.grid.PivotAggregatorMgr.registerType('min', function(records, measure) {
45868 length = records.length,
45871 for (i = 0; i < length; i++) {
45872 data.push(records[i].get(measure));
45875 return Math.min.apply(this, data) || 'n/a';
45878 Ext.grid.PivotAggregatorMgr.registerType('max', function(records, measure) {
45880 length = records.length,
45883 for (i = 0; i < length; i++) {
45884 data.push(records[i].get(measure));
45887 return Math.max.apply(this, data) || 'n/a';
45890 Ext.grid.PivotAggregatorMgr.registerType('count', function(records, measure) {
45891 return records.length;
45893 Ext.grid.GridView = Ext.extend(Ext.util.Observable, {
45905 deferEmptyText : true,
45908 scrollOffset : undefined,
45917 sortClasses : ['sort-asc', 'sort-desc'],
45920 sortAscText : 'Sort Ascending',
45923 sortDescText : 'Sort Descending',
45926 columnsText : 'Columns',
45929 selectedRowClass : 'x-grid3-row-selected',
45933 tdClass : 'x-grid3-cell',
45934 hdCls : 'x-grid3-hd',
45941 cellSelectorDepth : 4,
45944 rowSelectorDepth : 10,
45947 rowBodySelectorDepth : 10,
45950 cellSelector : 'td.x-grid3-cell',
45953 rowSelector : 'div.x-grid3-row',
45956 rowBodySelector : 'div.x-grid3-row-body',
45959 firstRowCls: 'x-grid3-row-first',
45960 lastRowCls: 'x-grid3-row-last',
45961 rowClsRe: /(?:^|\s+)x-grid3-row-(first|last|alt)(?:\s+|$)/g,
45964 headerMenuOpenCls: 'x-grid3-hd-menu-open',
45967 rowOverCls: 'x-grid3-row-over',
45969 constructor : function(config) {
45970 Ext.apply(this, config);
45975 'beforerowremoved',
45978 'beforerowsinserted',
45996 Ext.grid.GridView.superclass.constructor.call(this);
46002 masterTpl: new Ext.Template(
46003 '<div class="x-grid3" hidefocus="true">',
46004 '<div class="x-grid3-viewport">',
46005 '<div class="x-grid3-header">',
46006 '<div class="x-grid3-header-inner">',
46007 '<div class="x-grid3-header-offset" style="{ostyle}">{header}</div>',
46009 '<div class="x-clear"></div>',
46011 '<div class="x-grid3-scroller">',
46012 '<div class="x-grid3-body" style="{bstyle}">{body}</div>',
46013 '<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
46016 '<div class="x-grid3-resize-marker"> </div>',
46017 '<div class="x-grid3-resize-proxy"> </div>',
46022 headerTpl: new Ext.Template(
46023 '<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
46025 '<tr class="x-grid3-hd-row">{cells}</tr>',
46031 bodyTpl: new Ext.Template('{rows}'),
46034 cellTpl: new Ext.Template(
46035 '<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
46036 '<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
46041 initTemplates : function() {
46042 var templates = this.templates || {},
46045 headerCellTpl = new Ext.Template(
46046 '<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}">',
46047 '<div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">',
46048 this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
46050 '<img alt="" class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
46056 '<tr class="x-grid3-row-body-tr" style="{bodyStyle}">',
46057 '<td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on">',
46058 '<div class="x-grid3-row-body">{body}</div>',
46064 '<table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
46066 '<tr>{cells}</tr>',
46067 this.enableRowBody ? rowBodyText : '',
46072 Ext.applyIf(templates, {
46073 hcell : headerCellTpl,
46074 cell : this.cellTpl,
46075 body : this.bodyTpl,
46076 header : this.headerTpl,
46077 master : this.masterTpl,
46078 row : new Ext.Template('<div class="x-grid3-row {alt}" style="{tstyle}">' + innerText + '</div>'),
46079 rowInner: new Ext.Template(innerText)
46082 for (name in templates) {
46083 template = templates[name];
46085 if (template && Ext.isFunction(template.compile) && !template.compiled) {
46086 template.disableFormats = true;
46087 template.compile();
46091 this.templates = templates;
46092 this.colRe = new RegExp('x-grid3-td-([^\\s]+)', '');
46096 fly : function(el) {
46097 if (!this._flyweight) {
46098 this._flyweight = new Ext.Element.Flyweight(document.body);
46100 this._flyweight.dom = el;
46101 return this._flyweight;
46105 getEditorParent : function() {
46106 return this.scroller.dom;
46110 initElements : function() {
46111 var Element = Ext.Element,
46112 el = Ext.get(this.grid.getGridEl().dom.firstChild),
46113 mainWrap = new Element(el.child('div.x-grid3-viewport')),
46114 mainHd = new Element(mainWrap.child('div.x-grid3-header')),
46115 scroller = new Element(mainWrap.child('div.x-grid3-scroller'));
46117 if (this.grid.hideHeaders) {
46118 mainHd.setDisplayed(false);
46121 if (this.forceFit) {
46122 scroller.setStyle('overflow-x', 'hidden');
46129 mainWrap: mainWrap,
46130 scroller: scroller,
46132 innerHd : mainHd.child('div.x-grid3-header-inner').dom,
46133 mainBody: new Element(Element.fly(scroller).child('div.x-grid3-body')),
46134 focusEl : new Element(Element.fly(scroller).child('a')),
46136 resizeMarker: new Element(el.child('div.x-grid3-resize-marker')),
46137 resizeProxy : new Element(el.child('div.x-grid3-resize-proxy'))
46140 this.focusEl.swallowEvent('click', true);
46144 getRows : function() {
46145 return this.hasRows() ? this.mainBody.dom.childNodes : [];
46151 findCell : function(el) {
46155 return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth);
46159 findCellIndex : function(el, requiredCls) {
46160 var cell = this.findCell(el),
46164 hasCls = this.fly(cell).hasClass(requiredCls);
46165 if (!requiredCls || hasCls) {
46166 return this.getCellIndex(cell);
46173 getCellIndex : function(el) {
46175 var match = el.className.match(this.colRe);
46177 if (match && match[1]) {
46178 return this.cm.getIndexById(match[1]);
46185 findHeaderCell : function(el) {
46186 var cell = this.findCell(el);
46187 return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
46191 findHeaderIndex : function(el){
46192 return this.findCellIndex(el, this.hdCls);
46196 findRow : function(el) {
46200 return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth);
46204 findRowIndex : function(el) {
46205 var row = this.findRow(el);
46206 return row ? row.rowIndex : false;
46210 findRowBody : function(el) {
46215 return this.fly(el).findParent(this.rowBodySelector, this.rowBodySelectorDepth);
46221 getRow : function(row) {
46222 return this.getRows()[row];
46226 getCell : function(row, col) {
46227 return Ext.fly(this.getRow(row)).query(this.cellSelector)[col];
46231 getHeaderCell : function(index) {
46232 return this.mainHd.dom.getElementsByTagName('td')[index];
46238 addRowClass : function(rowId, cls) {
46239 var row = this.getRow(rowId);
46241 this.fly(row).addClass(cls);
46246 removeRowClass : function(row, cls) {
46247 var r = this.getRow(row);
46249 this.fly(r).removeClass(cls);
46254 removeRow : function(row) {
46255 Ext.removeNode(this.getRow(row));
46256 this.syncFocusEl(row);
46260 removeRows : function(firstRow, lastRow) {
46261 var bd = this.mainBody.dom,
46264 for (rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
46265 Ext.removeNode(bd.childNodes[firstRow]);
46268 this.syncFocusEl(firstRow);
46274 getScrollState : function() {
46275 var sb = this.scroller.dom;
46278 left: sb.scrollLeft,
46284 restoreScroll : function(state) {
46285 var sb = this.scroller.dom;
46286 sb.scrollLeft = state.left;
46287 sb.scrollTop = state.top;
46291 scrollToTop : function() {
46292 var dom = this.scroller.dom;
46295 dom.scrollLeft = 0;
46299 syncScroll : function() {
46300 this.syncHeaderScroll();
46301 var mb = this.scroller.dom;
46302 this.grid.fireEvent('bodyscroll', mb.scrollLeft, mb.scrollTop);
46306 syncHeaderScroll : function() {
46307 var innerHd = this.innerHd,
46308 scrollLeft = this.scroller.dom.scrollLeft;
46310 innerHd.scrollLeft = scrollLeft;
46311 innerHd.scrollLeft = scrollLeft;
46315 updateSortIcon : function(col, dir) {
46316 var sortClasses = this.sortClasses,
46317 sortClass = sortClasses[dir == "DESC" ? 1 : 0],
46318 headers = this.mainHd.select('td').removeClass(sortClasses);
46320 headers.item(col).addClass(sortClass);
46324 updateAllColumnWidths : function() {
46325 var totalWidth = this.getTotalWidth(),
46326 colCount = this.cm.getColumnCount(),
46327 rows = this.getRows(),
46328 rowCount = rows.length,
46330 row, rowFirstChild, trow, i, j;
46332 for (i = 0; i < colCount; i++) {
46333 widths[i] = this.getColumnWidth(i);
46334 this.getHeaderCell(i).style.width = widths[i];
46337 this.updateHeaderWidth();
46339 for (i = 0; i < rowCount; i++) {
46341 row.style.width = totalWidth;
46342 rowFirstChild = row.firstChild;
46344 if (rowFirstChild) {
46345 rowFirstChild.style.width = totalWidth;
46346 trow = rowFirstChild.rows[0];
46348 for (j = 0; j < colCount; j++) {
46349 trow.childNodes[j].style.width = widths[j];
46354 this.onAllColumnWidthsUpdated(widths, totalWidth);
46358 updateColumnWidth : function(column, width) {
46359 var columnWidth = this.getColumnWidth(column),
46360 totalWidth = this.getTotalWidth(),
46361 headerCell = this.getHeaderCell(column),
46362 nodes = this.getRows(),
46363 nodeCount = nodes.length,
46364 row, i, firstChild;
46366 this.updateHeaderWidth();
46367 headerCell.style.width = columnWidth;
46369 for (i = 0; i < nodeCount; i++) {
46371 firstChild = row.firstChild;
46373 row.style.width = totalWidth;
46375 firstChild.style.width = totalWidth;
46376 firstChild.rows[0].childNodes[column].style.width = columnWidth;
46380 this.onColumnWidthUpdated(column, columnWidth, totalWidth);
46384 updateColumnHidden : function(col, hidden) {
46385 var totalWidth = this.getTotalWidth(),
46386 display = hidden ? 'none' : '',
46387 headerCell = this.getHeaderCell(col),
46388 nodes = this.getRows(),
46389 nodeCount = nodes.length,
46390 row, rowFirstChild, i;
46392 this.updateHeaderWidth();
46393 headerCell.style.display = display;
46395 for (i = 0; i < nodeCount; i++) {
46397 row.style.width = totalWidth;
46398 rowFirstChild = row.firstChild;
46400 if (rowFirstChild) {
46401 rowFirstChild.style.width = totalWidth;
46402 rowFirstChild.rows[0].childNodes[col].style.display = display;
46406 this.onColumnHiddenUpdated(col, hidden, totalWidth);
46407 delete this.lastViewWidth;
46412 doRender : function(columns, records, store, startRow, colCount, stripe) {
46413 var templates = this.templates,
46414 cellTemplate = templates.cell,
46415 rowTemplate = templates.row,
46416 last = colCount - 1,
46417 tstyle = 'width:' + this.getTotalWidth() + ';',
46421 rowParams = {tstyle: tstyle},
46423 len = records.length,
46426 record, i, j, rowIndex;
46429 for (j = 0; j < len; j++) {
46430 record = records[j];
46433 rowIndex = j + startRow;
46436 for (i = 0; i < colCount; i++) {
46437 column = columns[i];
46439 meta.id = column.id;
46440 meta.css = i === 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
46441 meta.attr = meta.cellAttr = '';
46442 meta.style = column.style;
46443 meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
46445 if (Ext.isEmpty(meta.value)) {
46446 meta.value = ' ';
46449 if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
46450 meta.css += ' x-grid3-dirty-cell';
46453 colBuffer[colBuffer.length] = cellTemplate.apply(meta);
46458 if (stripe && ((rowIndex + 1) % 2 === 0)) {
46459 alt[0] = 'x-grid3-row-alt';
46462 if (record.dirty) {
46463 alt[1] = ' x-grid3-dirty-row';
46466 rowParams.cols = colCount;
46468 if (this.getRowClass) {
46469 alt[2] = this.getRowClass(record, rowIndex, rowParams, store);
46472 rowParams.alt = alt.join(' ');
46473 rowParams.cells = colBuffer.join('');
46475 rowBuffer[rowBuffer.length] = rowTemplate.apply(rowParams);
46478 return rowBuffer.join('');
46482 processRows : function(startRow, skipStripe) {
46483 if (!this.ds || this.ds.getCount() < 1) {
46487 var rows = this.getRows(),
46488 length = rows.length,
46491 skipStripe = skipStripe || !this.grid.stripeRows;
46492 startRow = startRow || 0;
46494 for (i = 0; i < length; i++) {
46499 row.className = row.className.replace(this.rowClsRe, ' ');
46500 if ((i + 1) % 2 === 0){
46501 row.className += ' x-grid3-row-alt';
46508 if (startRow === 0) {
46509 Ext.fly(rows[0]).addClass(this.firstRowCls);
46512 Ext.fly(rows[length - 1]).addClass(this.lastRowCls);
46516 afterRender : function() {
46517 if (!this.ds || !this.cm) {
46521 this.mainBody.dom.innerHTML = this.renderBody() || ' ';
46522 this.processRows(0, true);
46524 if (this.deferEmptyText !== true) {
46525 this.applyEmptyText();
46528 this.grid.fireEvent('viewready', this.grid);
46532 afterRenderUI: function() {
46533 var grid = this.grid;
46535 this.initElements();
46538 Ext.fly(this.innerHd).on('click', this.handleHdDown, this);
46542 mouseover: this.handleHdOver,
46543 mouseout : this.handleHdOut,
46544 mousemove: this.handleHdMove
46547 this.scroller.on('scroll', this.syncScroll, this);
46549 if (grid.enableColumnResize !== false) {
46550 this.splitZone = new Ext.grid.GridView.SplitDragZone(grid, this.mainHd.dom);
46553 if (grid.enableColumnMove) {
46554 this.columnDrag = new Ext.grid.GridView.ColumnDragZone(grid, this.innerHd);
46555 this.columnDrop = new Ext.grid.HeaderDropZone(grid, this.mainHd.dom);
46558 if (grid.enableHdMenu !== false) {
46559 this.hmenu = new Ext.menu.Menu({id: grid.id + '-hctx'});
46561 {itemId:'asc', text: this.sortAscText, cls: 'xg-hmenu-sort-asc'},
46562 {itemId:'desc', text: this.sortDescText, cls: 'xg-hmenu-sort-desc'}
46565 if (grid.enableColumnHide !== false) {
46566 this.colMenu = new Ext.menu.Menu({id:grid.id + '-hcols-menu'});
46569 beforeshow: this.beforeColMenuShow,
46570 itemclick : this.handleHdMenuClick
46572 this.hmenu.add('-', {
46574 hideOnClick: false,
46575 text: this.columnsText,
46576 menu: this.colMenu,
46577 iconCls: 'x-cols-icon'
46581 this.hmenu.on('itemclick', this.handleHdMenuClick, this);
46584 if (grid.trackMouseOver) {
46587 mouseover: this.onRowOver,
46588 mouseout : this.onRowOut
46592 if (grid.enableDragDrop || grid.enableDrag) {
46593 this.dragZone = new Ext.grid.GridDragZone(grid, {
46594 ddGroup : grid.ddGroup || 'GridDD'
46598 this.updateHeaderSortState();
46602 renderUI : function() {
46603 var templates = this.templates;
46605 return templates.master.apply({
46606 body : templates.body.apply({rows:' '}),
46607 header: this.renderHeaders(),
46608 ostyle: 'width:' + this.getOffsetWidth() + ';',
46609 bstyle: 'width:' + this.getTotalWidth() + ';'
46614 processEvent : function(name, e) {
46615 var target = e.getTarget(),
46617 header = this.findHeaderIndex(target),
46618 row, cell, col, body;
46620 grid.fireEvent(name, e);
46622 if (header !== false) {
46623 grid.fireEvent('header' + name, grid, header, e);
46625 row = this.findRowIndex(target);
46630 if (row !== false) {
46631 cell = this.findCellIndex(target);
46632 if (cell !== false) {
46633 col = grid.colModel.getColumnAt(cell);
46634 if (grid.fireEvent('cell' + name, grid, row, cell, e) !== false) {
46635 if (!col || (col.processEvent && (col.processEvent(name, e, grid, row, cell) !== false))) {
46636 grid.fireEvent('row' + name, grid, row, e);
46640 if (grid.fireEvent('row' + name, grid, row, e) !== false) {
46641 (body = this.findRowBody(target)) && grid.fireEvent('rowbody' + name, grid, row, e);
46645 grid.fireEvent('container' + name, grid, e);
46651 layout : function(initial) {
46652 if (!this.mainBody) {
46656 var grid = this.grid,
46657 gridEl = grid.getGridEl(),
46658 gridSize = gridEl.getSize(true),
46659 gridWidth = gridSize.width,
46660 gridHeight = gridSize.height,
46661 scroller = this.scroller,
46662 scrollStyle, headerHeight, scrollHeight;
46664 if (gridWidth < 20 || gridHeight < 20) {
46668 if (grid.autoHeight) {
46669 scrollStyle = scroller.dom.style;
46670 scrollStyle.overflow = 'visible';
46672 if (Ext.isWebKit) {
46673 scrollStyle.position = 'static';
46676 this.el.setSize(gridWidth, gridHeight);
46678 headerHeight = this.mainHd.getHeight();
46679 scrollHeight = gridHeight - headerHeight;
46681 scroller.setSize(gridWidth, scrollHeight);
46683 if (this.innerHd) {
46684 this.innerHd.style.width = (gridWidth) + "px";
46688 if (this.forceFit || (initial === true && this.autoFill)) {
46689 if (this.lastViewWidth != gridWidth) {
46690 this.fitColumns(false, false);
46691 this.lastViewWidth = gridWidth;
46695 this.syncHeaderScroll();
46698 this.onLayout(gridWidth, scrollHeight);
46703 onLayout : function(vw, vh) {
46707 onColumnWidthUpdated : function(col, w, tw) {
46711 onAllColumnWidthsUpdated : function(ws, tw) {
46715 onColumnHiddenUpdated : function(col, hidden, tw) {
46719 updateColumnText : function(col, text) {
46723 afterMove : function(colIndex) {
46729 init : function(grid) {
46732 this.initTemplates();
46733 this.initData(grid.store, grid.colModel);
46738 getColumnId : function(index){
46739 return this.cm.getColumnId(index);
46743 getOffsetWidth : function() {
46744 return (this.cm.getTotalWidth() + this.getScrollOffset()) + 'px';
46748 getScrollOffset: function() {
46749 return Ext.num(this.scrollOffset, Ext.getScrollBarWidth());
46753 renderHeaders : function() {
46754 var colModel = this.cm,
46755 templates = this.templates,
46756 headerTpl = templates.hcell,
46758 colCount = colModel.getColumnCount(),
46759 last = colCount - 1,
46763 for (i = 0; i < colCount; i++) {
46765 cssCls = 'x-grid3-cell-first ';
46767 cssCls = i == last ? 'x-grid3-cell-last ' : '';
46771 id : colModel.getColumnId(i),
46772 value : colModel.getColumnHeader(i) || '',
46773 style : this.getColumnStyle(i, true),
46775 tooltip: this.getColumnTooltip(i)
46778 if (colModel.config[i].align == 'right') {
46779 properties.istyle = 'padding-right: 16px;';
46781 delete properties.istyle;
46784 cells[i] = headerTpl.apply(properties);
46787 return templates.header.apply({
46788 cells : cells.join(""),
46789 tstyle: String.format("width: {0};", this.getTotalWidth())
46794 getColumnTooltip : function(i) {
46795 var tooltip = this.cm.getColumnTooltip(i);
46797 if (Ext.QuickTips.isEnabled()) {
46798 return 'ext:qtip="' + tooltip + '"';
46800 return 'title="' + tooltip + '"';
46808 beforeUpdate : function() {
46809 this.grid.stopEditing(true);
46813 updateHeaders : function() {
46814 this.innerHd.firstChild.innerHTML = this.renderHeaders();
46816 this.updateHeaderWidth(false);
46820 updateHeaderWidth: function(updateMain) {
46821 var innerHdChild = this.innerHd.firstChild,
46822 totalWidth = this.getTotalWidth();
46824 innerHdChild.style.width = this.getOffsetWidth();
46825 innerHdChild.firstChild.style.width = totalWidth;
46827 if (updateMain !== false) {
46828 this.mainBody.dom.style.width = totalWidth;
46833 focusRow : function(row) {
46834 this.focusCell(row, 0, false);
46838 focusCell : function(row, col, hscroll) {
46839 this.syncFocusEl(this.ensureVisible(row, col, hscroll));
46841 var focusEl = this.focusEl;
46846 focusEl.focus.defer(1, focusEl);
46851 resolveCell : function(row, col, hscroll) {
46852 if (!Ext.isNumber(row)) {
46853 row = row.rowIndex;
46860 if (row < 0 || row >= this.ds.getCount()) {
46863 col = (col !== undefined ? col : 0);
46865 var rowEl = this.getRow(row),
46866 colModel = this.cm,
46867 colCount = colModel.getColumnCount(),
46870 if (!(hscroll === false && col === 0)) {
46871 while (col < colCount && colModel.isHidden(col)) {
46875 cellEl = this.getCell(row, col);
46878 return {row: rowEl, cell: cellEl};
46882 getResolvedXY : function(resolved) {
46887 var cell = resolved.cell,
46888 row = resolved.row;
46891 return Ext.fly(cell).getXY();
46893 return [this.el.getX(), Ext.fly(row).getY()];
46898 syncFocusEl : function(row, col, hscroll) {
46901 if (!Ext.isArray(xy)) {
46902 row = Math.min(row, Math.max(0, this.getRows().length-1));
46908 xy = this.getResolvedXY(this.resolveCell(row, col, hscroll));
46911 this.focusEl.setXY(xy || this.scroller.getXY());
46915 ensureVisible : function(row, col, hscroll) {
46916 var resolved = this.resolveCell(row, col, hscroll);
46918 if (!resolved || !resolved.row) {
46922 var rowEl = resolved.row,
46923 cellEl = resolved.cell,
46924 c = this.scroller.dom,
46927 stop = this.el.dom;
46929 while (p && p != stop) {
46930 ctop += p.offsetTop;
46931 p = p.offsetParent;
46934 ctop -= this.mainHd.dom.offsetHeight;
46935 stop = parseInt(c.scrollTop, 10);
46937 var cbot = ctop + rowEl.offsetHeight,
46938 ch = c.clientHeight,
46943 c.scrollTop = ctop;
46944 } else if(cbot > sbot) {
46945 c.scrollTop = cbot-ch;
46948 if (hscroll !== false) {
46949 var cleft = parseInt(cellEl.offsetLeft, 10),
46950 cright = cleft + cellEl.offsetWidth,
46951 sleft = parseInt(c.scrollLeft, 10),
46952 sright = sleft + c.clientWidth;
46954 if (cleft < sleft) {
46955 c.scrollLeft = cleft;
46956 } else if(cright > sright) {
46957 c.scrollLeft = cright-c.clientWidth;
46961 return this.getResolvedXY(resolved);
46965 insertRows : function(dm, firstRow, lastRow, isUpdate) {
46966 var last = dm.getCount() - 1;
46967 if( !isUpdate && firstRow === 0 && lastRow >= last) {
46968 this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
46970 this.fireEvent('rowsinserted', this, firstRow, lastRow);
46973 this.fireEvent('beforerowsinserted', this, firstRow, lastRow);
46975 var html = this.renderRows(firstRow, lastRow),
46976 before = this.getRow(firstRow);
46978 if(firstRow === 0){
46979 Ext.fly(this.getRow(0)).removeClass(this.firstRowCls);
46981 Ext.DomHelper.insertHtml('beforeBegin', before, html);
46983 var r = this.getRow(last - 1);
46985 Ext.fly(r).removeClass(this.lastRowCls);
46987 Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
46990 this.fireEvent('rowsinserted', this, firstRow, lastRow);
46991 this.processRows(firstRow);
46992 } else if (firstRow === 0 || firstRow >= last) {
46994 Ext.fly(this.getRow(firstRow)).addClass(firstRow === 0 ? this.firstRowCls : this.lastRowCls);
46997 this.syncFocusEl(firstRow);
47001 deleteRows : function(dm, firstRow, lastRow) {
47002 if (dm.getRowCount() < 1) {
47005 this.fireEvent('beforerowsdeleted', this, firstRow, lastRow);
47007 this.removeRows(firstRow, lastRow);
47009 this.processRows(firstRow);
47010 this.fireEvent('rowsdeleted', this, firstRow, lastRow);
47015 getColumnStyle : function(colIndex, isHeader) {
47016 var colModel = this.cm,
47017 colConfig = colModel.config,
47018 style = isHeader ? '' : colConfig[colIndex].css || '',
47019 align = colConfig[colIndex].align;
47021 style += String.format("width: {0};", this.getColumnWidth(colIndex));
47023 if (colModel.isHidden(colIndex)) {
47024 style += 'display: none; ';
47028 style += String.format("text-align: {0};", align);
47035 getColumnWidth : function(column) {
47036 var columnWidth = this.cm.getColumnWidth(column),
47037 borderWidth = this.borderWidth;
47039 if (Ext.isNumber(columnWidth)) {
47040 if (Ext.isBorderBox || (Ext.isWebKit && !Ext.isSafari2)) {
47041 return columnWidth + "px";
47043 return Math.max(columnWidth - borderWidth, 0) + "px";
47046 return columnWidth;
47051 getTotalWidth : function() {
47052 return this.cm.getTotalWidth() + 'px';
47056 fitColumns : function(preventRefresh, onlyExpand, omitColumn) {
47057 var grid = this.grid,
47058 colModel = this.cm,
47059 totalColWidth = colModel.getTotalWidth(false),
47060 gridWidth = this.getGridInnerWidth(),
47061 extraWidth = gridWidth - totalColWidth,
47065 colWidth, fraction, i;
47068 if (gridWidth < 20 || extraWidth === 0) {
47072 var visibleColCount = colModel.getColumnCount(true),
47073 totalColCount = colModel.getColumnCount(false),
47074 adjCount = visibleColCount - (Ext.isNumber(omitColumn) ? 1 : 0);
47076 if (adjCount === 0) {
47078 omitColumn = undefined;
47082 for (i = 0; i < totalColCount; i++) {
47083 if (!colModel.isFixed(i) && i !== omitColumn) {
47084 colWidth = colModel.getColumnWidth(i);
47085 columns.push(i, colWidth);
47087 if (!colModel.isHidden(i)) {
47094 fraction = (gridWidth - colModel.getTotalWidth()) / width;
47096 while (columns.length) {
47097 colWidth = columns.pop();
47100 colModel.setColumnWidth(i, Math.max(grid.minColumnWidth, Math.floor(colWidth + colWidth * fraction)), true);
47104 totalColWidth = colModel.getTotalWidth(false);
47106 if (totalColWidth > gridWidth) {
47107 var adjustCol = (adjCount == visibleColCount) ? extraCol : omitColumn,
47108 newWidth = Math.max(1, colModel.getColumnWidth(adjustCol) - (totalColWidth - gridWidth));
47110 colModel.setColumnWidth(adjustCol, newWidth, true);
47113 if (preventRefresh !== true) {
47114 this.updateAllColumnWidths();
47121 autoExpand : function(preventUpdate) {
47122 var grid = this.grid,
47123 colModel = this.cm,
47124 gridWidth = this.getGridInnerWidth(),
47125 totalColumnWidth = colModel.getTotalWidth(false),
47126 autoExpandColumn = grid.autoExpandColumn;
47128 if (!this.userResized && autoExpandColumn) {
47129 if (gridWidth != totalColumnWidth) {
47131 var colIndex = colModel.getIndexById(autoExpandColumn),
47132 currentWidth = colModel.getColumnWidth(colIndex),
47133 desiredWidth = gridWidth - totalColumnWidth + currentWidth,
47134 newWidth = Math.min(Math.max(desiredWidth, grid.autoExpandMin), grid.autoExpandMax);
47136 if (currentWidth != newWidth) {
47137 colModel.setColumnWidth(colIndex, newWidth, true);
47139 if (preventUpdate !== true) {
47140 this.updateColumnWidth(colIndex, newWidth);
47148 getGridInnerWidth: function() {
47149 return this.grid.getGridEl().getWidth(true) - this.getScrollOffset();
47153 getColumnData : function() {
47155 colModel = this.cm,
47156 colCount = colModel.getColumnCount(),
47157 fields = this.ds.fields,
47160 for (i = 0; i < colCount; i++) {
47161 name = colModel.getDataIndex(i);
47164 name : Ext.isDefined(name) ? name : (fields.get(i) ? fields.get(i).name : undefined),
47165 renderer: colModel.getRenderer(i),
47166 scope : colModel.getRendererScope(i),
47167 id : colModel.getColumnId(i),
47168 style : this.getColumnStyle(i)
47176 renderRows : function(startRow, endRow) {
47177 var grid = this.grid,
47178 store = grid.store,
47179 stripe = grid.stripeRows,
47180 colModel = grid.colModel,
47181 colCount = colModel.getColumnCount(),
47182 rowCount = store.getCount(),
47185 if (rowCount < 1) {
47189 startRow = startRow || 0;
47190 endRow = Ext.isDefined(endRow) ? endRow : rowCount - 1;
47191 records = store.getRange(startRow, endRow);
47193 return this.doRender(this.getColumnData(), records, store, startRow, colCount, stripe);
47197 renderBody : function(){
47198 var markup = this.renderRows() || ' ';
47199 return this.templates.body.apply({rows: markup});
47203 refreshRow: function(record) {
47204 var store = this.ds,
47205 colCount = this.cm.getColumnCount(),
47206 columns = this.getColumnData(),
47207 last = colCount - 1,
47208 cls = ['x-grid3-row'],
47210 tstyle: String.format("width: {0};", this.getTotalWidth())
47213 cellTpl = this.templates.cell,
47214 rowIndex, row, column, meta, css, i;
47216 if (Ext.isNumber(record)) {
47218 record = store.getAt(rowIndex);
47220 rowIndex = store.indexOf(record);
47224 if (!record || rowIndex < 0) {
47229 for (i = 0; i < colCount; i++) {
47230 column = columns[i];
47233 css = 'x-grid3-cell-first';
47235 css = (i == last) ? 'x-grid3-cell-last ' : '';
47240 style : column.style,
47246 meta.value = column.renderer.call(column.scope, record.data[column.name], meta, record, rowIndex, i, store);
47248 if (Ext.isEmpty(meta.value)) {
47249 meta.value = ' ';
47252 if (this.markDirty && record.dirty && typeof record.modified[column.name] != 'undefined') {
47253 meta.css += ' x-grid3-dirty-cell';
47256 colBuffer[i] = cellTpl.apply(meta);
47259 row = this.getRow(rowIndex);
47260 row.className = '';
47262 if (this.grid.stripeRows && ((rowIndex + 1) % 2 === 0)) {
47263 cls.push('x-grid3-row-alt');
47266 if (this.getRowClass) {
47267 rowParams.cols = colCount;
47268 cls.push(this.getRowClass(record, rowIndex, rowParams, store));
47271 this.fly(row).addClass(cls).setStyle(rowParams.tstyle);
47272 rowParams.cells = colBuffer.join("");
47273 row.innerHTML = this.templates.rowInner.apply(rowParams);
47275 this.fireEvent('rowupdated', this, rowIndex, record);
47279 refresh : function(headersToo) {
47280 this.fireEvent('beforerefresh', this);
47281 this.grid.stopEditing(true);
47283 var result = this.renderBody();
47284 this.mainBody.update(result).setWidth(this.getTotalWidth());
47285 if (headersToo === true) {
47286 this.updateHeaders();
47287 this.updateHeaderSortState();
47289 this.processRows(0, true);
47291 this.applyEmptyText();
47292 this.fireEvent('refresh', this);
47296 applyEmptyText : function() {
47297 if (this.emptyText && !this.hasRows()) {
47298 this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
47303 updateHeaderSortState : function() {
47304 var state = this.ds.getSortState();
47309 if (!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)) {
47310 this.grid.fireEvent('sortchange', this.grid, state);
47313 this.sortState = state;
47315 var sortColumn = this.cm.findColumnIndex(state.field);
47316 if (sortColumn != -1) {
47317 var sortDir = state.direction;
47318 this.updateSortIcon(sortColumn, sortDir);
47323 clearHeaderSortState : function() {
47324 if (!this.sortState) {
47327 this.grid.fireEvent('sortchange', this.grid, null);
47328 this.mainHd.select('td').removeClass(this.sortClasses);
47329 delete this.sortState;
47333 destroy : function() {
47336 gridEl = grid.getGridEl(),
47337 dragZone = me.dragZone,
47338 splitZone = me.splitZone,
47339 columnDrag = me.columnDrag,
47340 columnDrop = me.columnDrop,
47341 scrollToTopTask = me.scrollToTopTask,
47345 if (scrollToTopTask && scrollToTopTask.cancel) {
47346 scrollToTopTask.cancel();
47349 Ext.destroyMembers(me, 'colMenu', 'hmenu');
47351 me.initData(null, null);
47352 me.purgeListeners();
47354 Ext.fly(me.innerHd).un("click", me.handleHdDown, me);
47356 if (grid.enableColumnMove) {
47357 columnDragData = columnDrag.dragData;
47358 columnDragProxy = columnDrag.proxy;
47361 columnDragProxy.ghost,
47362 columnDragProxy.el,
47364 columnDrop.proxyTop,
47365 columnDrop.proxyBottom,
47366 columnDragData.ddel,
47367 columnDragData.header
47370 if (columnDragProxy.anim) {
47371 Ext.destroy(columnDragProxy.anim);
47374 delete columnDragProxy.ghost;
47375 delete columnDragData.ddel;
47376 delete columnDragData.header;
47377 columnDrag.destroy();
47379 delete Ext.dd.DDM.locationCache[columnDrag.id];
47380 delete columnDrag._domRef;
47382 delete columnDrop.proxyTop;
47383 delete columnDrop.proxyBottom;
47384 columnDrop.destroy();
47385 delete Ext.dd.DDM.locationCache["gridHeader" + gridEl.id];
47386 delete columnDrop._domRef;
47387 delete Ext.dd.DDM.ids[columnDrop.ddGroup];
47391 splitZone.destroy();
47392 delete splitZone._domRef;
47393 delete Ext.dd.DDM.ids["gridSplitters" + gridEl.id];
47396 Ext.fly(me.innerHd).removeAllListeners();
47397 Ext.removeNode(me.innerHd);
47415 delete grid.container;
47418 dragZone.destroy();
47421 Ext.dd.DDM.currentTarget = null;
47422 delete Ext.dd.DDM.locationCache[gridEl.id];
47424 Ext.EventManager.removeResizeListener(me.onWindowResize, me);
47428 onDenyColumnHide : function() {
47433 render : function() {
47434 if (this.autoFill) {
47435 var ct = this.grid.ownerCt;
47437 if (ct && ct.getLayout()) {
47438 ct.on('afterlayout', function() {
47439 this.fitColumns(true, true);
47440 this.updateHeaders();
47441 this.updateHeaderSortState();
47442 }, this, {single: true});
47444 } else if (this.forceFit) {
47445 this.fitColumns(true, false);
47446 } else if (this.grid.autoExpandColumn) {
47447 this.autoExpand(true);
47450 this.grid.getGridEl().dom.innerHTML = this.renderUI();
47452 this.afterRenderUI();
47458 initData : function(newStore, newColModel) {
47462 var oldStore = me.ds;
47464 oldStore.un('add', me.onAdd, me);
47465 oldStore.un('load', me.onLoad, me);
47466 oldStore.un('clear', me.onClear, me);
47467 oldStore.un('remove', me.onRemove, me);
47468 oldStore.un('update', me.onUpdate, me);
47469 oldStore.un('datachanged', me.onDataChange, me);
47471 if (oldStore !== newStore && oldStore.autoDestroy) {
47472 oldStore.destroy();
47481 remove : me.onRemove,
47482 update : me.onUpdate,
47483 clear : me.onClear,
47484 datachanged: me.onDataChange
47489 var oldColModel = me.cm;
47491 oldColModel.un('configchange', me.onColConfigChange, me);
47492 oldColModel.un('widthchange', me.onColWidthChange, me);
47493 oldColModel.un('headerchange', me.onHeaderChange, me);
47494 oldColModel.un('hiddenchange', me.onHiddenChange, me);
47495 oldColModel.un('columnmoved', me.onColumnMove, me);
47499 delete me.lastViewWidth;
47503 configchange: me.onColConfigChange,
47504 widthchange : me.onColWidthChange,
47505 headerchange: me.onHeaderChange,
47506 hiddenchange: me.onHiddenChange,
47507 columnmoved : me.onColumnMove
47512 me.cm = newColModel;
47516 onDataChange : function(){
47517 this.refresh(true);
47518 this.updateHeaderSortState();
47519 this.syncFocusEl(0);
47523 onClear : function() {
47525 this.syncFocusEl(0);
47529 onUpdate : function(store, record) {
47530 this.refreshRow(record);
47534 onAdd : function(store, records, index) {
47535 this.insertRows(store, index, index + (records.length-1));
47539 onRemove : function(store, record, index, isUpdate) {
47540 if (isUpdate !== true) {
47541 this.fireEvent('beforerowremoved', this, index, record);
47544 this.removeRow(index);
47546 if (isUpdate !== true) {
47547 this.processRows(index);
47548 this.applyEmptyText();
47549 this.fireEvent('rowremoved', this, index, record);
47554 onLoad : function() {
47556 if (!this.scrollToTopTask) {
47557 this.scrollToTopTask = new Ext.util.DelayedTask(this.scrollToTop, this);
47559 this.scrollToTopTask.delay(1);
47561 this.scrollToTop();
47566 onColWidthChange : function(cm, col, width) {
47567 this.updateColumnWidth(col, width);
47571 onHeaderChange : function(cm, col, text) {
47572 this.updateHeaders();
47576 onHiddenChange : function(cm, col, hidden) {
47577 this.updateColumnHidden(col, hidden);
47581 onColumnMove : function(cm, oldIndex, newIndex) {
47582 this.indexMap = null;
47583 this.refresh(true);
47584 this.restoreScroll(this.getScrollState());
47586 this.afterMove(newIndex);
47587 this.grid.fireEvent('columnmove', oldIndex, newIndex);
47591 onColConfigChange : function() {
47592 delete this.lastViewWidth;
47593 this.indexMap = null;
47594 this.refresh(true);
47599 initUI : function(grid) {
47600 grid.on('headerclick', this.onHeaderClick, this);
47604 initEvents : Ext.emptyFn,
47607 onHeaderClick : function(g, index) {
47608 if (this.headersDisabled || !this.cm.isSortable(index)) {
47611 g.stopEditing(true);
47612 g.store.sort(this.cm.getDataIndex(index));
47616 onRowOver : function(e, target) {
47617 var row = this.findRowIndex(target);
47619 if (row !== false) {
47620 this.addRowClass(row, this.rowOverCls);
47625 onRowOut : function(e, target) {
47626 var row = this.findRowIndex(target);
47628 if (row !== false && !e.within(this.getRow(row), true)) {
47629 this.removeRowClass(row, this.rowOverCls);
47634 onRowSelect : function(row) {
47635 this.addRowClass(row, this.selectedRowClass);
47639 onRowDeselect : function(row) {
47640 this.removeRowClass(row, this.selectedRowClass);
47644 onCellSelect : function(row, col) {
47645 var cell = this.getCell(row, col);
47647 this.fly(cell).addClass('x-grid3-cell-selected');
47652 onCellDeselect : function(row, col) {
47653 var cell = this.getCell(row, col);
47655 this.fly(cell).removeClass('x-grid3-cell-selected');
47660 handleWheel : function(e) {
47661 e.stopPropagation();
47665 onColumnSplitterMoved : function(cellIndex, width) {
47666 this.userResized = true;
47667 this.grid.colModel.setColumnWidth(cellIndex, width, true);
47669 if (this.forceFit) {
47670 this.fitColumns(true, false, cellIndex);
47671 this.updateAllColumnWidths();
47673 this.updateColumnWidth(cellIndex, width);
47674 this.syncHeaderScroll();
47677 this.grid.fireEvent('columnresize', cellIndex, width);
47681 beforeColMenuShow : function() {
47682 var colModel = this.cm,
47683 colCount = colModel.getColumnCount(),
47684 colMenu = this.colMenu,
47687 colMenu.removeAll();
47689 for (i = 0; i < colCount; i++) {
47690 if (colModel.config[i].hideable !== false) {
47691 colMenu.add(new Ext.menu.CheckItem({
47692 text : colModel.getColumnHeader(i),
47693 itemId : 'col-' + colModel.getColumnId(i),
47694 checked : !colModel.isHidden(i),
47695 disabled : colModel.config[i].hideable === false,
47703 handleHdMenuClick : function(item) {
47704 var store = this.ds,
47705 dataIndex = this.cm.getDataIndex(this.hdCtxIndex);
47707 switch (item.getItemId()) {
47709 store.sort(dataIndex, 'ASC');
47712 store.sort(dataIndex, 'DESC');
47715 this.handleHdMenuClickDefault(item);
47721 handleHdMenuClickDefault: function(item) {
47722 var colModel = this.cm,
47723 itemId = item.getItemId(),
47724 index = colModel.getIndexById(itemId.substr(4));
47727 if (item.checked && colModel.getColumnsBy(this.isHideableColumn, this).length <= 1) {
47728 this.onDenyColumnHide();
47731 colModel.setHidden(index, item.checked);
47736 handleHdDown : function(e, target) {
47737 if (Ext.fly(target).hasClass('x-grid3-hd-btn')) {
47740 var colModel = this.cm,
47741 header = this.findHeaderCell(target),
47742 index = this.getCellIndex(header),
47743 sortable = colModel.isSortable(index),
47745 menuItems = menu.items,
47746 menuCls = this.headerMenuOpenCls;
47748 this.hdCtxIndex = index;
47750 Ext.fly(header).addClass(menuCls);
47751 menuItems.get('asc').setDisabled(!sortable);
47752 menuItems.get('desc').setDisabled(!sortable);
47754 menu.on('hide', function() {
47755 Ext.fly(header).removeClass(menuCls);
47756 }, this, {single:true});
47758 menu.show(target, 'tl-bl?');
47763 handleHdMove : function(e) {
47764 var header = this.findHeaderCell(this.activeHdRef);
47766 if (header && !this.headersDisabled) {
47767 var handleWidth = this.splitHandleWidth || 5,
47768 activeRegion = this.activeHdRegion,
47769 headerStyle = header.style,
47770 colModel = this.cm,
47772 pageX = e.getPageX();
47774 if (this.grid.enableColumnResize !== false) {
47775 var activeHeaderIndex = this.activeHdIndex,
47776 previousVisible = this.getPreviousVisible(activeHeaderIndex),
47777 currentResizable = colModel.isResizable(activeHeaderIndex),
47778 previousResizable = previousVisible && colModel.isResizable(previousVisible),
47779 inLeftResizer = pageX - activeRegion.left <= handleWidth,
47780 inRightResizer = activeRegion.right - pageX <= (!this.activeHdBtn ? handleWidth : 2);
47782 if (inLeftResizer && previousResizable) {
47783 cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize';
47784 } else if (inRightResizer && currentResizable) {
47785 cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
47789 headerStyle.cursor = cursor;
47794 getPreviousVisible: function(index) {
47795 while (index > 0) {
47796 if (!this.cm.isHidden(index - 1)) {
47805 handleHdOver : function(e, target) {
47806 var header = this.findHeaderCell(target);
47808 if (header && !this.headersDisabled) {
47809 var fly = this.fly(header);
47811 this.activeHdRef = target;
47812 this.activeHdIndex = this.getCellIndex(header);
47813 this.activeHdRegion = fly.getRegion();
47815 if (!this.isMenuDisabled(this.activeHdIndex, fly)) {
47816 fly.addClass('x-grid3-hd-over');
47817 this.activeHdBtn = fly.child('.x-grid3-hd-btn');
47819 if (this.activeHdBtn) {
47820 this.activeHdBtn.dom.style.height = (header.firstChild.offsetHeight - 1) + 'px';
47827 handleHdOut : function(e, target) {
47828 var header = this.findHeaderCell(target);
47830 if (header && (!Ext.isIE || !e.within(header, true))) {
47831 this.activeHdRef = null;
47832 this.fly(header).removeClass('x-grid3-hd-over');
47833 header.style.cursor = '';
47838 isMenuDisabled: function(cellIndex, el) {
47839 return this.cm.isMenuDisabled(cellIndex);
47843 hasRows : function() {
47844 var fc = this.mainBody.dom.firstChild;
47845 return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';
47849 isHideableColumn : function(c) {
47854 bind : function(d, c) {
47855 this.initData(d, c);
47862 Ext.grid.GridView.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
47864 constructor: function(grid, hd){
47866 this.view = grid.getView();
47867 this.marker = this.view.resizeMarker;
47868 this.proxy = this.view.resizeProxy;
47869 Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
47870 'gridSplitters' + this.grid.getGridEl().id, {
47871 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
47873 this.scroll = false;
47874 this.hw = this.view.splitHandleWidth || 5;
47877 b4StartDrag : function(x, y){
47878 this.dragHeadersDisabled = this.view.headersDisabled;
47879 this.view.headersDisabled = true;
47880 var h = this.view.mainWrap.getHeight();
47881 this.marker.setHeight(h);
47882 this.marker.show();
47883 this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
47884 this.proxy.setHeight(h);
47885 var w = this.cm.getColumnWidth(this.cellIndex),
47886 minw = Math.max(w-this.grid.minColumnWidth, 0);
47887 this.resetConstraints();
47888 this.setXConstraint(minw, 1000);
47889 this.setYConstraint(0, 0);
47890 this.minX = x - minw;
47891 this.maxX = x + 1000;
47893 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
47896 allowHeaderDrag : function(e){
47900 handleMouseDown : function(e){
47901 var t = this.view.findHeaderCell(e.getTarget());
47902 if(t && this.allowHeaderDrag(e)){
47903 var xy = this.view.fly(t).getXY(),
47910 if((ex - x) <= this.hw){
47912 }else if((x+w) - ex <= this.hw){
47915 if(adjust !== false){
47916 this.cm = this.grid.colModel;
47917 var ci = this.view.getCellIndex(t);
47919 if (ci + adjust < 0) {
47922 while(this.cm.isHidden(ci+adjust)){
47929 this.cellIndex = ci+adjust;
47930 this.split = t.dom;
47931 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
47932 Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
47934 }else if(this.view.columnDrag){
47935 this.view.columnDrag.callHandleMouseDown(e);
47940 endDrag : function(e){
47941 this.marker.hide();
47943 endX = Math.max(this.minX, e.getPageX()),
47944 diff = endX - this.startPos,
47945 disabled = this.dragHeadersDisabled;
47947 v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
47948 setTimeout(function(){
47949 v.headersDisabled = disabled;
47953 autoOffset : function(){
47954 this.setDelta(0,0);
47958 Ext.grid.PivotGridView = Ext.extend(Ext.grid.GridView, {
47961 colHeaderCellCls: 'grid-hd-group-cell',
47969 getColumnHeaders: function() {
47970 return this.grid.topAxis.buildHeaders();;
47974 getRowHeaders: function() {
47975 return this.grid.leftAxis.buildHeaders();
47979 renderRows : function(startRow, endRow) {
47980 var grid = this.grid,
47981 rows = grid.extractData(),
47982 rowCount = rows.length,
47983 templates = this.templates,
47984 renderer = grid.renderer,
47985 hasRenderer = typeof renderer == 'function',
47986 getCellCls = this.getCellCls,
47987 hasGetCellCls = typeof getCellCls == 'function',
47988 cellTemplate = templates.cell,
47989 rowTemplate = templates.row,
47992 tstyle = 'width:' + this.getGridInnerWidth() + 'px;',
47993 colBuffer, column, i;
47995 startRow = startRow || 0;
47996 endRow = Ext.isDefined(endRow) ? endRow : rowCount - 1;
47998 for (i = 0; i < rowCount; i++) {
48000 colCount = row.length;
48003 rowIndex = startRow + i;
48006 for (j = 0; j < colCount; j++) {
48009 meta.css = j === 0 ? 'x-grid3-cell-first ' : (j == (colCount - 1) ? 'x-grid3-cell-last ' : '');
48010 meta.attr = meta.cellAttr = '';
48013 if (Ext.isEmpty(meta.value)) {
48014 meta.value = ' ';
48018 meta.value = renderer(meta.value);
48021 if (hasGetCellCls) {
48022 meta.css += getCellCls(meta.value) + ' ';
48025 colBuffer[colBuffer.length] = cellTemplate.apply(meta);
48028 rowBuffer[rowBuffer.length] = rowTemplate.apply({
48031 cells : colBuffer.join(""),
48036 return rowBuffer.join("");
48040 masterTpl: new Ext.Template(
48041 '<div class="x-grid3 x-pivotgrid" hidefocus="true">',
48042 '<div class="x-grid3-viewport">',
48043 '<div class="x-grid3-header">',
48044 '<div class="x-grid3-header-title"><span>{title}</span></div>',
48045 '<div class="x-grid3-header-inner">',
48046 '<div class="x-grid3-header-offset" style="{ostyle}"></div>',
48048 '<div class="x-clear"></div>',
48050 '<div class="x-grid3-scroller">',
48051 '<div class="x-grid3-row-headers"></div>',
48052 '<div class="x-grid3-body" style="{bstyle}">{body}</div>',
48053 '<a href="#" class="x-grid3-focus" tabIndex="-1"></a>',
48056 '<div class="x-grid3-resize-marker"> </div>',
48057 '<div class="x-grid3-resize-proxy"> </div>',
48062 initTemplates: function() {
48063 Ext.grid.PivotGridView.superclass.initTemplates.apply(this, arguments);
48065 var templates = this.templates || {};
48066 if (!templates.gcell) {
48067 templates.gcell = new Ext.XTemplate(
48068 '<td class="x-grid3-hd x-grid3-gcell x-grid3-td-{id} ux-grid-hd-group-row-{row} ' + this.colHeaderCellCls + '" style="{style}">',
48069 '<div {tooltip} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">',
48070 this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '', '{value}',
48076 this.templates = templates;
48077 this.hrowRe = new RegExp("ux-grid-hd-group-row-(\\d+)", "");
48081 initElements: function() {
48082 Ext.grid.PivotGridView.superclass.initElements.apply(this, arguments);
48085 this.rowHeadersEl = new Ext.Element(this.scroller.child('div.x-grid3-row-headers'));
48088 this.headerTitleEl = new Ext.Element(this.mainHd.child('div.x-grid3-header-title'));
48092 getGridInnerWidth: function() {
48093 var previousWidth = Ext.grid.PivotGridView.superclass.getGridInnerWidth.apply(this, arguments);
48095 return previousWidth - this.getTotalRowHeaderWidth();
48099 getTotalRowHeaderWidth: function() {
48100 var headers = this.getRowHeaders(),
48101 length = headers.length,
48105 for (i = 0; i< length; i++) {
48106 total += headers[i].width;
48113 getTotalColumnHeaderHeight: function() {
48114 return this.getColumnHeaders().length * 21;
48118 renderUI : function() {
48119 var templates = this.templates,
48120 innerWidth = this.getGridInnerWidth();
48122 return templates.master.apply({
48123 body : templates.body.apply({rows:' '}),
48124 ostyle: 'width:' + innerWidth + 'px',
48125 bstyle: 'width:' + innerWidth + 'px'
48130 onLayout: function(width, height) {
48131 Ext.grid.PivotGridView.superclass.onLayout.apply(this, arguments);
48133 var width = this.getGridInnerWidth();
48135 this.resizeColumnHeaders(width);
48136 this.resizeAllRows(width);
48140 refresh : function(headersToo) {
48141 this.fireEvent('beforerefresh', this);
48142 this.grid.stopEditing(true);
48144 var result = this.renderBody();
48145 this.mainBody.update(result).setWidth(this.getGridInnerWidth());
48146 if (headersToo === true) {
48147 this.updateHeaders();
48148 this.updateHeaderSortState();
48150 this.processRows(0, true);
48152 this.applyEmptyText();
48153 this.fireEvent('refresh', this);
48157 renderHeaders: Ext.emptyFn,
48160 fitColumns: Ext.emptyFn,
48163 resizeColumnHeaders: function(width) {
48164 var topAxis = this.grid.topAxis;
48166 if (topAxis.rendered) {
48167 topAxis.el.setWidth(width);
48172 resizeRowHeaders: function() {
48173 var rowHeaderWidth = this.getTotalRowHeaderWidth(),
48174 marginStyle = String.format("margin-left: {0}px;", rowHeaderWidth);
48176 this.rowHeadersEl.setWidth(rowHeaderWidth);
48177 this.mainBody.applyStyles(marginStyle);
48178 Ext.fly(this.innerHd).applyStyles(marginStyle);
48180 this.headerTitleEl.setWidth(rowHeaderWidth);
48181 this.headerTitleEl.setHeight(this.getTotalColumnHeaderHeight());
48185 resizeAllRows: function(width) {
48186 var rows = this.getRows(),
48187 length = rows.length,
48190 for (i = 0; i < length; i++) {
48191 Ext.fly(rows[i]).setWidth(width);
48192 Ext.fly(rows[i]).child('table').setWidth(width);
48197 updateHeaders: function() {
48198 this.renderGroupRowHeaders();
48199 this.renderGroupColumnHeaders();
48203 renderGroupRowHeaders: function() {
48204 var leftAxis = this.grid.leftAxis;
48206 this.resizeRowHeaders();
48207 leftAxis.rendered = false;
48208 leftAxis.render(this.rowHeadersEl);
48210 this.setTitle(this.title);
48214 setTitle: function(title) {
48215 this.headerTitleEl.child('span').dom.innerHTML = title;
48219 renderGroupColumnHeaders: function() {
48220 var topAxis = this.grid.topAxis;
48222 topAxis.rendered = false;
48223 topAxis.render(this.innerHd.firstChild);
48227 isMenuDisabled: function(cellIndex, el) {
48231 Ext.grid.PivotAxis = Ext.extend(Ext.Component, {
48233 orientation: 'horizontal',
48236 defaultHeaderWidth: 80,
48242 setDimensions: function(dimensions) {
48243 this.dimensions = dimensions;
48247 onRender: function(ct, position) {
48248 var rows = this.orientation == 'horizontal'
48249 ? this.renderHorizontalRows()
48250 : this.renderVerticalRows();
48252 this.el = Ext.DomHelper.overwrite(ct.dom, {tag: 'table', cn: rows}, true);
48256 renderHorizontalRows: function() {
48257 var headers = this.buildHeaders(),
48258 rowCount = headers.length,
48260 cells, cols, colCount, i, j;
48262 for (i = 0; i < rowCount; i++) {
48264 cols = headers[i].items;
48265 colCount = cols.length;
48267 for (j = 0; j < colCount; j++) {
48270 html: cols[j].header,
48271 colspan: cols[j].span
48285 renderVerticalRows: function() {
48286 var headers = this.buildHeaders(),
48287 colCount = headers.length,
48290 rowCount, col, row, colWidth, i, j;
48292 for (i = 0; i < colCount; i++) {
48294 colWidth = col.width || 80;
48295 rowCount = col.items.length;
48297 for (j = 0; j < rowCount; j++) {
48298 row = col.items[j];
48300 rowCells[row.start] = rowCells[row.start] || [];
48301 rowCells[row.start].push({
48305 width : Ext.isBorderBox ? colWidth : colWidth - this.paddingWidth
48310 rowCount = rowCells.length;
48311 for (i = 0; i < rowCount; i++) {
48322 getTuples: function() {
48323 var newStore = new Ext.data.Store({});
48325 newStore.data = this.store.data.clone();
48326 newStore.fields = this.store.fields;
48329 dimensions = this.dimensions,
48330 length = dimensions.length,
48333 for (i = 0; i < length; i++) {
48335 field : dimensions[i].dataIndex,
48336 direction: dimensions[i].direction || 'ASC'
48340 newStore.sort(sorters);
48342 var records = newStore.data.items,
48345 recData, hash, info, data, key;
48347 length = records.length;
48349 for (i = 0; i < length; i++) {
48350 info = this.getRecordInfo(records[i]);
48354 for (key in data) {
48355 hash += data[key] + '---';
48358 if (hashes.indexOf(hash) == -1) {
48364 newStore.destroy();
48370 getRecordInfo: function(record) {
48371 var dimensions = this.dimensions,
48372 length = dimensions.length,
48374 dimension, dataIndex, i;
48377 for (i = 0; i < length; i++) {
48378 dimension = dimensions[i];
48379 dataIndex = dimension.dataIndex;
48381 data[dataIndex] = record.get(dataIndex);
48386 var createMatcherFunction = function(data) {
48387 return function(record) {
48388 for (var dataIndex in data) {
48389 if (record.get(dataIndex) != data[dataIndex]) {
48400 matcher: createMatcherFunction(data)
48405 buildHeaders: function() {
48406 var tuples = this.getTuples(),
48407 rowCount = tuples.length,
48408 dimensions = this.dimensions,
48409 colCount = dimensions.length,
48411 tuple, rows, currentHeader, previousHeader, span, start, isLast, changed, i, j;
48413 for (i = 0; i < colCount; i++) {
48414 dimension = dimensions[i];
48419 for (j = 0; j < rowCount; j++) {
48421 isLast = j == (rowCount - 1);
48422 currentHeader = tuple.data[dimension.dataIndex];
48425 changed = previousHeader != undefined && previousHeader != currentHeader;
48426 if (i > 0 && j > 0) {
48427 changed = changed || tuple.data[dimensions[i-1].dataIndex] != tuples[j-1].data[dimensions[i-1].dataIndex];
48432 header: previousHeader,
48443 header: currentHeader,
48452 previousHeader = currentHeader;
48458 width: dimension.width || this.defaultHeaderWidth
48461 previousHeader = undefined;
48469 Ext.grid.HeaderDragZone = Ext.extend(Ext.dd.DragZone, {
48472 constructor : function(grid, hd, hd2){
48474 this.view = grid.getView();
48475 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
48476 Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
48478 this.setHandleElId(Ext.id(hd));
48479 this.setOuterHandleElId(Ext.id(hd2));
48481 this.scroll = false;
48484 getDragData : function(e){
48485 var t = Ext.lib.Event.getTarget(e),
48486 h = this.view.findHeaderCell(t);
48488 return {ddel: h.firstChild, header:h};
48493 onInitDrag : function(e){
48495 this.dragHeadersDisabled = this.view.headersDisabled;
48496 this.view.headersDisabled = true;
48497 var clone = this.dragData.ddel.cloneNode(true);
48498 clone.id = Ext.id();
48499 clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
48500 this.proxy.update(clone);
48504 afterValidDrop : function(){
48505 this.completeDrop();
48508 afterInvalidDrop : function(){
48509 this.completeDrop();
48512 completeDrop: function(){
48514 disabled = this.dragHeadersDisabled;
48515 setTimeout(function(){
48516 v.headersDisabled = disabled;
48523 Ext.grid.HeaderDropZone = Ext.extend(Ext.dd.DropZone, {
48524 proxyOffsets : [-4, -9],
48525 fly: Ext.Element.fly,
48527 constructor : function(grid, hd, hd2){
48529 this.view = grid.getView();
48531 this.proxyTop = Ext.DomHelper.append(document.body, {
48532 cls:"col-move-top", html:" "
48534 this.proxyBottom = Ext.DomHelper.append(document.body, {
48535 cls:"col-move-bottom", html:" "
48537 this.proxyTop.hide = this.proxyBottom.hide = function(){
48538 this.setLeftTop(-100,-100);
48539 this.setStyle("visibility", "hidden");
48541 this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
48544 Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
48547 getTargetFromEvent : function(e){
48548 var t = Ext.lib.Event.getTarget(e),
48549 cindex = this.view.findCellIndex(t);
48550 if(cindex !== false){
48551 return this.view.getHeaderCell(cindex);
48555 nextVisible : function(h){
48556 var v = this.view, cm = this.grid.colModel;
48559 if(!cm.isHidden(v.getCellIndex(h))){
48567 prevVisible : function(h){
48568 var v = this.view, cm = this.grid.colModel;
48571 if(!cm.isHidden(v.getCellIndex(h))){
48579 positionIndicator : function(h, n, e){
48580 var x = Ext.lib.Event.getPageX(e),
48581 r = Ext.lib.Dom.getRegion(n.firstChild),
48584 py = r.top + this.proxyOffsets[1];
48585 if((r.right - x) <= (r.right-r.left)/2){
48586 px = r.right+this.view.borderWidth;
48593 if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){
48597 px += this.proxyOffsets[0];
48598 this.proxyTop.setLeftTop(px, py);
48599 this.proxyTop.show();
48600 if(!this.bottomOffset){
48601 this.bottomOffset = this.view.mainHd.getHeight();
48603 this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
48604 this.proxyBottom.show();
48608 onNodeEnter : function(n, dd, e, data){
48609 if(data.header != n){
48610 this.positionIndicator(data.header, n, e);
48614 onNodeOver : function(n, dd, e, data){
48615 var result = false;
48616 if(data.header != n){
48617 result = this.positionIndicator(data.header, n, e);
48620 this.proxyTop.hide();
48621 this.proxyBottom.hide();
48623 return result ? this.dropAllowed : this.dropNotAllowed;
48626 onNodeOut : function(n, dd, e, data){
48627 this.proxyTop.hide();
48628 this.proxyBottom.hide();
48631 onNodeDrop : function(n, dd, e, data){
48632 var h = data.header;
48634 var cm = this.grid.colModel,
48635 x = Ext.lib.Event.getPageX(e),
48636 r = Ext.lib.Dom.getRegion(n.firstChild),
48637 pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before",
48638 oldIndex = this.view.getCellIndex(h),
48639 newIndex = this.view.getCellIndex(n);
48643 if(oldIndex < newIndex){
48646 cm.moveColumn(oldIndex, newIndex);
48653 Ext.grid.GridView.ColumnDragZone = Ext.extend(Ext.grid.HeaderDragZone, {
48655 constructor : function(grid, hd){
48656 Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
48657 this.proxy.el.addClass('x-grid3-col-dd');
48660 handleMouseDown : function(e){
48663 callHandleMouseDown : function(e){
48664 Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
48668 Ext.grid.SplitDragZone = Ext.extend(Ext.dd.DDProxy, {
48669 fly: Ext.Element.fly,
48671 constructor : function(grid, hd, hd2){
48673 this.view = grid.getView();
48674 this.proxy = this.view.resizeProxy;
48675 Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
48676 "gridSplitters" + this.grid.getGridEl().id, {
48677 dragElId : Ext.id(this.proxy.dom), resizeFrame:false
48679 this.setHandleElId(Ext.id(hd));
48680 this.setOuterHandleElId(Ext.id(hd2));
48681 this.scroll = false;
48684 b4StartDrag : function(x, y){
48685 this.view.headersDisabled = true;
48686 this.proxy.setHeight(this.view.mainWrap.getHeight());
48687 var w = this.cm.getColumnWidth(this.cellIndex);
48688 var minw = Math.max(w-this.grid.minColumnWidth, 0);
48689 this.resetConstraints();
48690 this.setXConstraint(minw, 1000);
48691 this.setYConstraint(0, 0);
48692 this.minX = x - minw;
48693 this.maxX = x + 1000;
48695 Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
48699 handleMouseDown : function(e){
48700 var ev = Ext.EventObject.setEvent(e);
48701 var t = this.fly(ev.getTarget());
48702 if(t.hasClass("x-grid-split")){
48703 this.cellIndex = this.view.getCellIndex(t.dom);
48704 this.split = t.dom;
48705 this.cm = this.grid.colModel;
48706 if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
48707 Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
48712 endDrag : function(e){
48713 this.view.headersDisabled = false;
48714 var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
48715 var diff = endX - this.startPos;
48716 this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
48719 autoOffset : function(){
48720 this.setDelta(0,0);
48723 Ext.grid.GridDragZone = function(grid, config){
48724 this.view = grid.getView();
48725 Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
48726 this.scroll = false;
48728 this.ddel = document.createElement('div');
48729 this.ddel.className = 'x-grid-dd-wrap';
48732 Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
48733 ddGroup : "GridDD",
48736 getDragData : function(e){
48737 var t = Ext.lib.Event.getTarget(e);
48738 var rowIndex = this.view.findRowIndex(t);
48739 if(rowIndex !== false){
48740 var sm = this.grid.selModel;
48741 if(!sm.isSelected(rowIndex) || e.hasModifier()){
48742 sm.handleMouseDown(this.grid, rowIndex, e);
48744 return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()};
48750 onInitDrag : function(e){
48751 var data = this.dragData;
48752 this.ddel.innerHTML = this.grid.getDragDropText();
48753 this.proxy.update(this.ddel);
48758 afterRepair : function(){
48759 this.dragging = false;
48763 getRepairXY : function(e, data){
48767 onEndDrag : function(data, e){
48771 onValidDrop : function(dd, e, id){
48776 beforeInvalidDrop : function(e, id){
48781 Ext.grid.ColumnModel = Ext.extend(Ext.util.Observable, {
48786 defaultSortable: false,
48792 constructor : function(config) {
48794 if (config.columns) {
48795 Ext.apply(this, config);
48796 this.setConfig(config.columns, true);
48798 this.setConfig(config, true);
48818 Ext.grid.ColumnModel.superclass.constructor.call(this);
48822 getColumnId : function(index) {
48823 return this.config[index].id;
48826 getColumnAt : function(index) {
48827 return this.config[index];
48831 setConfig : function(config, initial) {
48835 delete this.totalWidth;
48837 for (i = 0, len = this.config.length; i < len; i++) {
48838 c = this.config[i];
48848 this.defaults = Ext.apply({
48849 width: this.defaultWidth,
48850 sortable: this.defaultSortable
48853 this.config = config;
48856 for (i = 0, len = config.length; i < len; i++) {
48857 c = Ext.applyIf(config[i], this.defaults);
48860 if (Ext.isEmpty(c.id)) {
48865 var Cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
48870 this.lookup[c.id] = c;
48874 this.fireEvent('configchange', this);
48879 getColumnById : function(id) {
48880 return this.lookup[id];
48884 getIndexById : function(id) {
48885 for (var i = 0, len = this.config.length; i < len; i++) {
48886 if (this.config[i].id == id) {
48894 moveColumn : function(oldIndex, newIndex) {
48895 var config = this.config,
48896 c = config[oldIndex];
48898 config.splice(oldIndex, 1);
48899 config.splice(newIndex, 0, c);
48900 this.dataMap = null;
48901 this.fireEvent("columnmoved", this, oldIndex, newIndex);
48905 getColumnCount : function(visibleOnly) {
48906 var length = this.config.length,
48910 if (visibleOnly === true) {
48911 for (i = 0; i < length; i++) {
48912 if (!this.isHidden(i)) {
48924 getColumnsBy : function(fn, scope) {
48925 var config = this.config,
48926 length = config.length,
48930 for (i = 0; i < length; i++){
48933 if (fn.call(scope || this, c, i) === true) {
48934 result[result.length] = c;
48942 isSortable : function(col) {
48943 return !!this.config[col].sortable;
48947 isMenuDisabled : function(col) {
48948 return !!this.config[col].menuDisabled;
48952 getRenderer : function(col) {
48953 return this.config[col].renderer || Ext.grid.ColumnModel.defaultRenderer;
48956 getRendererScope : function(col) {
48957 return this.config[col].scope;
48961 setRenderer : function(col, fn) {
48962 this.config[col].renderer = fn;
48966 getColumnWidth : function(col) {
48967 var width = this.config[col].width;
48968 if(typeof width != 'number'){
48969 width = this.defaultWidth;
48975 setColumnWidth : function(col, width, suppressEvent) {
48976 this.config[col].width = width;
48977 this.totalWidth = null;
48979 if (!suppressEvent) {
48980 this.fireEvent("widthchange", this, col, width);
48985 getTotalWidth : function(includeHidden) {
48986 if (!this.totalWidth) {
48987 this.totalWidth = 0;
48988 for (var i = 0, len = this.config.length; i < len; i++) {
48989 if (includeHidden || !this.isHidden(i)) {
48990 this.totalWidth += this.getColumnWidth(i);
48994 return this.totalWidth;
48998 getColumnHeader : function(col) {
48999 return this.config[col].header;
49003 setColumnHeader : function(col, header) {
49004 this.config[col].header = header;
49005 this.fireEvent("headerchange", this, col, header);
49009 getColumnTooltip : function(col) {
49010 return this.config[col].tooltip;
49013 setColumnTooltip : function(col, tooltip) {
49014 this.config[col].tooltip = tooltip;
49018 getDataIndex : function(col) {
49019 return this.config[col].dataIndex;
49023 setDataIndex : function(col, dataIndex) {
49024 this.config[col].dataIndex = dataIndex;
49028 findColumnIndex : function(dataIndex) {
49029 var c = this.config;
49030 for(var i = 0, len = c.length; i < len; i++){
49031 if(c[i].dataIndex == dataIndex){
49039 isCellEditable : function(colIndex, rowIndex) {
49040 var c = this.config[colIndex],
49044 return !!(ed || (!Ext.isDefined(ed) && c.editor));
49048 getCellEditor : function(colIndex, rowIndex) {
49049 return this.config[colIndex].getCellEditor(rowIndex);
49053 setEditable : function(col, editable) {
49054 this.config[col].editable = editable;
49058 isHidden : function(colIndex) {
49059 return !!this.config[colIndex].hidden;
49063 isFixed : function(colIndex) {
49064 return !!this.config[colIndex].fixed;
49068 isResizable : function(colIndex) {
49069 return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
49073 setHidden : function(colIndex, hidden) {
49074 var c = this.config[colIndex];
49075 if(c.hidden !== hidden){
49077 this.totalWidth = null;
49078 this.fireEvent("hiddenchange", this, colIndex, hidden);
49083 setEditor : function(col, editor) {
49084 this.config[col].setEditor(editor);
49088 destroy : function() {
49089 var length = this.config.length,
49092 for (; i < length; i++){
49093 this.config[i].destroy();
49095 delete this.config;
49096 delete this.lookup;
49097 this.purgeListeners();
49101 setState : function(col, state) {
49102 state = Ext.applyIf(state, this.defaults);
49103 Ext.apply(this.config[col], state);
49108 Ext.grid.ColumnModel.defaultRenderer = function(value) {
49109 if (typeof value == "string" && value.length < 1) {
49114 Ext.grid.AbstractSelectionModel = Ext.extend(Ext.util.Observable, {
49117 constructor : function(){
49118 this.locked = false;
49119 Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
49123 init : function(grid){
49125 if(this.lockOnInit){
49126 delete this.lockOnInit;
49127 this.locked = false;
49136 this.locked = true;
49142 beforerefresh: this.sortUnLock,
49143 refresh: this.sortLock
49146 this.lockOnInit = true;
49152 sortLock : function() {
49153 this.locked = true;
49157 sortUnLock : function() {
49158 this.locked = false;
49162 unlock : function(){
49164 this.locked = false;
49171 gv.un('beforerefresh', this.sortUnLock, this);
49172 gv.un('refresh', this.sortLock, this);
49174 delete this.lockOnInit;
49180 isLocked : function(){
49181 return this.locked;
49184 destroy: function(){
49186 this.purgeListeners();
49189 Ext.grid.RowSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, {
49191 singleSelect : false,
49193 constructor : function(config){
49194 Ext.apply(this, config);
49195 this.selections = new Ext.util.MixedCollection(false, function(o){
49200 this.lastActive = false;
49212 Ext.grid.RowSelectionModel.superclass.constructor.call(this);
49217 initEvents : function(){
49219 if(!this.grid.enableDragDrop && !this.grid.enableDrag){
49220 this.grid.on('rowmousedown', this.handleMouseDown, this);
49223 this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
49224 up: this.onKeyPress,
49225 down: this.onKeyPress,
49229 this.grid.getView().on({
49231 refresh: this.onRefresh,
49232 rowupdated: this.onRowUpdated,
49233 rowremoved: this.onRemove
49237 onKeyPress : function(e, name){
49238 var up = name == 'up',
49239 method = up ? 'selectPrevious' : 'selectNext',
49242 if(!e.shiftKey || this.singleSelect){
49243 this[method](false);
49244 }else if(this.last !== false && this.lastActive !== false){
49246 this.selectRange(this.last, this.lastActive + add);
49247 this.grid.getView().focusRow(this.lastActive);
49248 if(last !== false){
49252 this.selectFirstRow();
49257 onRefresh : function(){
49258 var ds = this.grid.store,
49259 s = this.getSelections(),
49264 this.silent = true;
49265 this.clearSelections(true);
49266 for(; i < len; i++){
49268 if((index = ds.indexOfId(r.id)) != -1){
49269 this.selectRow(index, true);
49272 if(s.length != this.selections.getCount()){
49273 this.fireEvent('selectionchange', this);
49275 this.silent = false;
49279 onRemove : function(v, index, r){
49280 if(this.selections.remove(r) !== false){
49281 this.fireEvent('selectionchange', this);
49286 onRowUpdated : function(v, index, r){
49287 if(this.isSelected(r)){
49288 v.onRowSelect(index);
49293 selectRecords : function(records, keepExisting){
49295 this.clearSelections();
49297 var ds = this.grid.store,
49299 len = records.length;
49300 for(; i < len; i++){
49301 this.selectRow(ds.indexOf(records[i]), true);
49306 getCount : function(){
49307 return this.selections.length;
49311 selectFirstRow : function(){
49316 selectLastRow : function(keepExisting){
49317 this.selectRow(this.grid.store.getCount() - 1, keepExisting);
49321 selectNext : function(keepExisting){
49322 if(this.hasNext()){
49323 this.selectRow(this.last+1, keepExisting);
49324 this.grid.getView().focusRow(this.last);
49331 selectPrevious : function(keepExisting){
49332 if(this.hasPrevious()){
49333 this.selectRow(this.last-1, keepExisting);
49334 this.grid.getView().focusRow(this.last);
49341 hasNext : function(){
49342 return this.last !== false && (this.last+1) < this.grid.store.getCount();
49346 hasPrevious : function(){
49347 return !!this.last;
49352 getSelections : function(){
49353 return [].concat(this.selections.items);
49357 getSelected : function(){
49358 return this.selections.itemAt(0);
49362 each : function(fn, scope){
49363 var s = this.getSelections(),
49367 for(; i < len; i++){
49368 if(fn.call(scope || this, s[i], i) === false){
49376 clearSelections : function(fast){
49377 if(this.isLocked()){
49381 var ds = this.grid.store,
49382 s = this.selections;
49383 s.each(function(r){
49384 this.deselectRow(ds.indexOfId(r.id));
49388 this.selections.clear();
49395 selectAll : function(){
49396 if(this.isLocked()){
49399 this.selections.clear();
49400 for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
49401 this.selectRow(i, true);
49406 hasSelection : function(){
49407 return this.selections.length > 0;
49411 isSelected : function(index){
49412 var r = Ext.isNumber(index) ? this.grid.store.getAt(index) : index;
49413 return (r && this.selections.key(r.id) ? true : false);
49417 isIdSelected : function(id){
49418 return (this.selections.key(id) ? true : false);
49422 handleMouseDown : function(g, rowIndex, e){
49423 if(e.button !== 0 || this.isLocked()){
49426 var view = this.grid.getView();
49427 if(e.shiftKey && !this.singleSelect && this.last !== false){
49428 var last = this.last;
49429 this.selectRange(last, rowIndex, e.ctrlKey);
49431 view.focusRow(rowIndex);
49433 var isSelected = this.isSelected(rowIndex);
49434 if(e.ctrlKey && isSelected){
49435 this.deselectRow(rowIndex);
49436 }else if(!isSelected || this.getCount() > 1){
49437 this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
49438 view.focusRow(rowIndex);
49444 selectRows : function(rows, keepExisting){
49446 this.clearSelections();
49448 for(var i = 0, len = rows.length; i < len; i++){
49449 this.selectRow(rows[i], true);
49454 selectRange : function(startRow, endRow, keepExisting){
49456 if(this.isLocked()){
49460 this.clearSelections();
49462 if(startRow <= endRow){
49463 for(i = startRow; i <= endRow; i++){
49464 this.selectRow(i, true);
49467 for(i = startRow; i >= endRow; i--){
49468 this.selectRow(i, true);
49474 deselectRange : function(startRow, endRow, preventViewNotify){
49475 if(this.isLocked()){
49478 for(var i = startRow; i <= endRow; i++){
49479 this.deselectRow(i, preventViewNotify);
49484 selectRow : function(index, keepExisting, preventViewNotify){
49485 if(this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))){
49488 var r = this.grid.store.getAt(index);
49489 if(r && this.fireEvent('beforerowselect', this, index, keepExisting, r) !== false){
49490 if(!keepExisting || this.singleSelect){
49491 this.clearSelections();
49493 this.selections.add(r);
49494 this.last = this.lastActive = index;
49495 if(!preventViewNotify){
49496 this.grid.getView().onRowSelect(index);
49499 this.fireEvent('rowselect', this, index, r);
49500 this.fireEvent('selectionchange', this);
49506 deselectRow : function(index, preventViewNotify){
49507 if(this.isLocked()){
49510 if(this.last == index){
49513 if(this.lastActive == index){
49514 this.lastActive = false;
49516 var r = this.grid.store.getAt(index);
49518 this.selections.remove(r);
49519 if(!preventViewNotify){
49520 this.grid.getView().onRowDeselect(index);
49522 this.fireEvent('rowdeselect', this, index, r);
49523 this.fireEvent('selectionchange', this);
49528 acceptsNav : function(row, col, cm){
49529 return !cm.isHidden(col) && cm.isCellEditable(col, row);
49533 onEditorKey : function(field, e){
49534 var k = e.getKey(),
49538 ed = g.activeEditor,
49539 shift = e.shiftKey,
49546 newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
49548 newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
49550 }else if(k == e.ENTER){
49551 if(this.moveEditorOnEnter !== false){
49553 newCell = g.walkCells(last.row - 1, last.col, -1, this.acceptsNav, this);
49555 newCell = g.walkCells(last.row + 1, last.col, 1, this.acceptsNav, this);
49567 if(g.isEditor && g.editing){
49568 ae = g.activeEditor;
49569 if(ae && ae.field.triggerBlur){
49571 ae.field.triggerBlur();
49574 g.startEditing(r, c);
49578 destroy : function(){
49579 Ext.destroy(this.rowNav);
49580 this.rowNav = null;
49581 Ext.grid.RowSelectionModel.superclass.destroy.call(this);
49584 Ext.grid.Column = Ext.extend(Ext.util.Observable, {
49611 constructor : function(config){
49612 Ext.apply(this, config);
49614 if(Ext.isString(this.renderer)){
49615 this.renderer = Ext.util.Format[this.renderer];
49616 }else if(Ext.isObject(this.renderer)){
49617 this.scope = this.renderer.scope;
49618 this.renderer = this.renderer.fn;
49624 var ed = this.editor;
49625 delete this.editor;
49626 this.setEditor(ed);
49637 Ext.grid.Column.superclass.constructor.call(this);
49641 processEvent : function(name, e, grid, rowIndex, colIndex){
49642 return this.fireEvent(name, this, grid, rowIndex, e);
49646 destroy: function() {
49647 if(this.setEditor){
49648 this.setEditor(null);
49650 this.purgeListeners();
49654 renderer : function(value){
49659 getEditor: function(rowIndex){
49660 return this.editable !== false ? this.editor : null;
49664 setEditor : function(editor){
49665 var ed = this.editor;
49668 ed.gridEditor.destroy();
49669 delete ed.gridEditor;
49674 this.editor = null;
49677 if(!editor.isXType){
49678 editor = Ext.create(editor, 'textfield');
49680 this.editor = editor;
49685 getCellEditor: function(rowIndex){
49686 var ed = this.getEditor(rowIndex);
49689 if(!ed.gridEditor){
49690 ed.gridEditor = new Ext.grid.GridEditor(ed);
49692 ed = ed.gridEditor;
49700 Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {
49704 falseText: 'false',
49706 undefinedText: ' ',
49708 constructor: function(cfg){
49709 Ext.grid.BooleanColumn.superclass.constructor.call(this, cfg);
49710 var t = this.trueText, f = this.falseText, u = this.undefinedText;
49711 this.renderer = function(v){
49712 if(v === undefined){
49715 if(!v || v === 'false'){
49724 Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, {
49726 format : '0,000.00',
49727 constructor: function(cfg){
49728 Ext.grid.NumberColumn.superclass.constructor.call(this, cfg);
49729 this.renderer = Ext.util.Format.numberRenderer(this.format);
49734 Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, {
49737 constructor: function(cfg){
49738 Ext.grid.DateColumn.superclass.constructor.call(this, cfg);
49739 this.renderer = Ext.util.Format.dateRenderer(this.format);
49744 Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {
49746 constructor: function(cfg){
49747 Ext.grid.TemplateColumn.superclass.constructor.call(this, cfg);
49748 var tpl = (!Ext.isPrimitive(this.tpl) && this.tpl.compile) ? this.tpl : new Ext.XTemplate(this.tpl);
49749 this.renderer = function(value, p, r){
49750 return tpl.apply(r.data);
49757 Ext.grid.ActionColumn = Ext.extend(Ext.grid.Column, {
49768 actionIdRe: /x-action-col-(\d+)/,
49773 constructor: function(cfg) {
49775 items = cfg.items || (me.items = [me]),
49780 Ext.grid.ActionColumn.superclass.constructor.call(me, cfg);
49784 me.renderer = function(v, meta) {
49786 v = Ext.isFunction(cfg.renderer) ? cfg.renderer.apply(this, arguments)||'' : '';
49788 meta.css += ' x-action-col-cell';
49789 for (i = 0; i < l; i++) {
49791 v += '<img alt="' + me.altText + '" src="' + (item.icon || Ext.BLANK_IMAGE_URL) +
49792 '" class="x-action-col-icon x-action-col-' + String(i) + ' ' + (item.iconCls || '') +
49793 ' ' + (Ext.isFunction(item.getClass) ? item.getClass.apply(item.scope||this.scope||this, arguments) : '') + '"' +
49794 ((item.tooltip) ? ' ext:qtip="' + item.tooltip + '"' : '') + ' />';
49800 destroy: function() {
49802 delete this.renderer;
49803 return Ext.grid.ActionColumn.superclass.destroy.apply(this, arguments);
49807 processEvent : function(name, e, grid, rowIndex, colIndex){
49808 var m = e.getTarget().className.match(this.actionIdRe),
49810 if (m && (item = this.items[parseInt(m[1], 10)])) {
49811 if (name == 'click') {
49812 (fn = item.handler || this.handler) && fn.call(item.scope||this.scope||this, grid, rowIndex, colIndex, item, e);
49813 } else if ((name == 'mousedown') && (item.stopSelection !== false)) {
49817 return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments);
49822 Ext.grid.Column.types = {
49823 gridcolumn : Ext.grid.Column,
49824 booleancolumn: Ext.grid.BooleanColumn,
49825 numbercolumn: Ext.grid.NumberColumn,
49826 datecolumn: Ext.grid.DateColumn,
49827 templatecolumn: Ext.grid.TemplateColumn,
49828 actioncolumn: Ext.grid.ActionColumn
49830 Ext.grid.RowNumberer = Ext.extend(Object, {
49838 constructor : function(config){
49839 Ext.apply(this, config);
49841 this.renderer = this.renderer.createDelegate(this);
49851 rowspan: undefined,
49854 renderer : function(v, p, record, rowIndex){
49856 p.cellAttr = 'rowspan="'+this.rowspan+'"';
49861 Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
49865 header : '<div class="x-grid3-hd-checker"> </div>',
49872 menuDisabled : true,
49879 constructor : function(){
49880 Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments);
49881 if(this.checkOnly){
49882 this.handleMouseDown = Ext.emptyFn;
49887 initEvents : function(){
49888 Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
49889 this.grid.on('render', function(){
49890 Ext.fly(this.grid.getView().innerHd).on('mousedown', this.onHdMouseDown, this);
49895 processEvent : function(name, e, grid, rowIndex, colIndex){
49896 if (name == 'mousedown') {
49897 this.onMouseDown(e, e.getTarget());
49900 return Ext.grid.Column.prototype.processEvent.apply(this, arguments);
49905 onMouseDown : function(e, t){
49906 if(e.button === 0 && t.className == 'x-grid3-row-checker'){
49908 var row = e.getTarget('.x-grid3-row');
49910 var index = row.rowIndex;
49911 if(this.isSelected(index)){
49912 this.deselectRow(index);
49914 this.selectRow(index, true);
49915 this.grid.getView().focusRow(index);
49922 onHdMouseDown : function(e, t) {
49923 if(t.className == 'x-grid3-hd-checker'){
49925 var hd = Ext.fly(t.parentNode);
49926 var isChecked = hd.hasClass('x-grid3-hd-checker-on');
49928 hd.removeClass('x-grid3-hd-checker-on');
49929 this.clearSelections();
49931 hd.addClass('x-grid3-hd-checker-on');
49938 renderer : function(v, p, record){
49939 return '<div class="x-grid3-row-checker"> </div>';
49942 Ext.grid.CellSelectionModel = Ext.extend(Ext.grid.AbstractSelectionModel, {
49944 constructor : function(config){
49945 Ext.apply(this, config);
49947 this.selection = null;
49951 "beforecellselect",
49958 Ext.grid.CellSelectionModel.superclass.constructor.call(this);
49962 initEvents : function(){
49963 this.grid.on('cellmousedown', this.handleMouseDown, this);
49964 this.grid.on(Ext.EventManager.getKeyEvent(), this.handleKeyDown, this);
49965 this.grid.getView().on({
49967 refresh: this.onViewChange,
49968 rowupdated: this.onRowUpdated,
49969 beforerowremoved: this.clearSelections,
49970 beforerowsinserted: this.clearSelections
49972 if(this.grid.isEditor){
49973 this.grid.on('beforeedit', this.beforeEdit, this);
49978 beforeEdit : function(e){
49979 this.select(e.row, e.column, false, true, e.record);
49983 onRowUpdated : function(v, index, r){
49984 if(this.selection && this.selection.record == r){
49985 v.onCellSelect(index, this.selection.cell[1]);
49990 onViewChange : function(){
49991 this.clearSelections(true);
49995 getSelectedCell : function(){
49996 return this.selection ? this.selection.cell : null;
50000 clearSelections : function(preventNotify){
50001 var s = this.selection;
50003 if(preventNotify !== true){
50004 this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
50006 this.selection = null;
50007 this.fireEvent("selectionchange", this, null);
50012 hasSelection : function(){
50013 return this.selection ? true : false;
50017 handleMouseDown : function(g, row, cell, e){
50018 if(e.button !== 0 || this.isLocked()){
50021 this.select(row, cell);
50025 select : function(rowIndex, colIndex, preventViewNotify, preventFocus, r){
50026 if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
50027 this.clearSelections();
50028 r = r || this.grid.store.getAt(rowIndex);
50031 cell : [rowIndex, colIndex]
50033 if(!preventViewNotify){
50034 var v = this.grid.getView();
50035 v.onCellSelect(rowIndex, colIndex);
50036 if(preventFocus !== true){
50037 v.focusCell(rowIndex, colIndex);
50040 this.fireEvent("cellselect", this, rowIndex, colIndex);
50041 this.fireEvent("selectionchange", this, this.selection);
50046 isSelectable : function(rowIndex, colIndex, cm){
50047 return !cm.isHidden(colIndex);
50051 onEditorKey: function(field, e){
50052 if(e.getKey() == e.TAB){
50053 this.handleKeyDown(e);
50058 handleKeyDown : function(e){
50059 if(!e.isNavKeyPress()){
50063 var k = e.getKey(),
50065 s = this.selection,
50067 walk = function(row, col, step){
50068 return g.walkCells(
50072 g.isEditor && g.editing ? sm.acceptsNav : sm.isSelectable,
50076 cell, newCell, r, c, ae;
50091 cell = walk(0, 0, 1);
50093 this.select(cell[0], cell[1]);
50105 newCell = walk(r, c - 1, -1);
50107 newCell = walk(r, c + 1, 1);
50111 newCell = walk(r + 1, c, 1);
50114 newCell = walk(r - 1, c, -1);
50117 newCell = walk(r, c + 1, 1);
50120 newCell = walk(r, c - 1, -1);
50123 if (g.isEditor && !g.editing) {
50124 g.startEditing(r, c);
50137 if(g.isEditor && g.editing){
50138 ae = g.activeEditor;
50139 if(ae && ae.field.triggerBlur){
50141 ae.field.triggerBlur();
50143 g.startEditing(r, c);
50148 acceptsNav : function(row, col, cm){
50149 return !cm.isHidden(col) && cm.isCellEditable(col, row);
50152 Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
50157 forceValidation: false,
50165 autoEncode : false,
50169 trackMouseOver: false,
50172 initComponent : function(){
50173 Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
50175 if(!this.selModel){
50177 this.selModel = new Ext.grid.CellSelectionModel();
50180 this.activeEditor = null;
50193 initEvents : function(){
50194 Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
50196 this.getGridEl().on('mousewheel', this.stopEditing.createDelegate(this, [true]), this);
50197 this.on('columnresize', this.stopEditing, this, [true]);
50199 if(this.clicksToEdit == 1){
50200 this.on("cellclick", this.onCellDblClick, this);
50202 var view = this.getView();
50203 if(this.clicksToEdit == 'auto' && view.mainBody){
50204 view.mainBody.on('mousedown', this.onAutoEditClick, this);
50206 this.on('celldblclick', this.onCellDblClick, this);
50210 onResize : function(){
50211 Ext.grid.EditorGridPanel.superclass.onResize.apply(this, arguments);
50212 var ae = this.activeEditor;
50213 if(this.editing && ae){
50219 onCellDblClick : function(g, row, col){
50220 this.startEditing(row, col);
50224 onAutoEditClick : function(e, t){
50225 if(e.button !== 0){
50228 var row = this.view.findRowIndex(t),
50229 col = this.view.findCellIndex(t);
50230 if(row !== false && col !== false){
50231 this.stopEditing();
50232 if(this.selModel.getSelectedCell){
50233 var sc = this.selModel.getSelectedCell();
50234 if(sc && sc[0] === row && sc[1] === col){
50235 this.startEditing(row, col);
50238 if(this.selModel.isSelected(row)){
50239 this.startEditing(row, col);
50246 onEditComplete : function(ed, value, startValue){
50247 this.editing = false;
50248 this.lastActiveEditor = this.activeEditor;
50249 this.activeEditor = null;
50252 field = this.colModel.getDataIndex(ed.col);
50253 value = this.postEditValue(value, startValue, r, field);
50254 if(this.forceValidation === true || String(value) !== String(startValue)){
50259 originalValue: startValue,
50265 if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){
50266 r.set(field, e.value);
50268 this.fireEvent("afteredit", e);
50271 this.view.focusCell(ed.row, ed.col);
50275 startEditing : function(row, col){
50276 this.stopEditing();
50277 if(this.colModel.isCellEditable(col, row)){
50278 this.view.ensureVisible(row, col, true);
50279 var r = this.store.getAt(row),
50280 field = this.colModel.getDataIndex(col),
50285 value: r.data[field],
50290 if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
50291 this.editing = true;
50292 var ed = this.colModel.getCellEditor(col, row);
50297 ed.parentEl = this.view.getEditorParent(ed);
50302 c.field.focus(false, true);
50307 specialkey: function(field, e){
50308 this.getSelectionModel().onEditorKey(field, e);
50310 complete: this.onEditComplete,
50311 canceledit: this.stopEditing.createDelegate(this, [true])
50323 this.activeEditor = ed;
50326 ed.selectSameEditor = (this.activeEditor == this.lastActiveEditor);
50327 var v = this.preEditValue(r, field);
50328 ed.startEdit(this.view.getCell(row, col).firstChild, Ext.isDefined(v) ? v : '');
50332 delete ed.selectSameEditor;
50339 preEditValue : function(r, field){
50340 var value = r.data[field];
50341 return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlDecode(value) : value;
50345 postEditValue : function(value, originalValue, r, field){
50346 return this.autoEncode && Ext.isString(value) ? Ext.util.Format.htmlEncode(value) : value;
50350 stopEditing : function(cancel){
50353 var ae = this.lastActiveEditor = this.activeEditor;
50355 ae[cancel === true ? 'cancelEdit' : 'completeEdit']();
50356 this.view.focusCell(ae.row, ae.col);
50358 this.activeEditor = null;
50360 this.editing = false;
50363 Ext.reg('editorgrid', Ext.grid.EditorGridPanel);
50365 Ext.grid.GridEditor = function(field, config){
50366 Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
50367 field.monitorTab = false;
50370 Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
50371 alignment: "tl-tl",
50374 cls: "x-small-editor x-grid-editor",
50378 Ext.grid.PropertyRecord = Ext.data.Record.create([
50379 {name:'name',type:'string'}, 'value'
50383 Ext.grid.PropertyStore = Ext.extend(Ext.util.Observable, {
50385 constructor : function(grid, source){
50387 this.store = new Ext.data.Store({
50388 recordType : Ext.grid.PropertyRecord
50390 this.store.on('update', this.onUpdate, this);
50392 this.setSource(source);
50394 Ext.grid.PropertyStore.superclass.constructor.call(this);
50398 setSource : function(o){
50400 this.store.removeAll();
50403 if(this.isEditableValue(o[k])){
50404 data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
50407 this.store.loadRecords({records: data}, {}, true);
50411 onUpdate : function(ds, record, type){
50412 if(type == Ext.data.Record.EDIT){
50413 var v = record.data.value;
50414 var oldValue = record.modified.value;
50415 if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
50416 this.source[record.id] = v;
50418 this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
50426 getProperty : function(row){
50427 return this.store.getAt(row);
50431 isEditableValue: function(val){
50432 return Ext.isPrimitive(val) || Ext.isDate(val);
50436 setValue : function(prop, value, create){
50437 var r = this.getRec(prop);
50439 r.set('value', value);
50440 this.source[prop] = value;
50443 this.source[prop] = value;
50444 r = new Ext.grid.PropertyRecord({name: prop, value: value}, prop);
50451 remove : function(prop){
50452 var r = this.getRec(prop);
50454 this.store.remove(r);
50455 delete this.source[prop];
50460 getRec : function(prop){
50461 return this.store.getById(prop);
50465 getSource : function(){
50466 return this.source;
50471 Ext.grid.PropertyColumnModel = Ext.extend(Ext.grid.ColumnModel, {
50474 valueText : 'Value',
50475 dateFormat : 'm/j/Y',
50477 falseText: 'false',
50479 constructor : function(grid, store){
50484 g.PropertyColumnModel.superclass.constructor.call(this, [
50485 {header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
50486 {header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
50488 this.store = store;
50490 var bfield = new f.Field({
50491 autoCreate: {tag: 'select', children: [
50492 {tag: 'option', value: 'true', html: this.trueText},
50493 {tag: 'option', value: 'false', html: this.falseText}
50495 getValue : function(){
50496 return this.el.dom.value == 'true';
50500 'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
50501 'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
50502 'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
50503 'boolean' : new g.GridEditor(bfield, {
50507 this.renderCellDelegate = this.renderCell.createDelegate(this);
50508 this.renderPropDelegate = this.renderProp.createDelegate(this);
50512 renderDate : function(dateVal){
50513 return dateVal.dateFormat(this.dateFormat);
50517 renderBool : function(bVal){
50518 return this[bVal ? 'trueText' : 'falseText'];
50522 isCellEditable : function(colIndex, rowIndex){
50523 return colIndex == 1;
50527 getRenderer : function(col){
50529 this.renderCellDelegate : this.renderPropDelegate;
50533 renderProp : function(v){
50534 return this.getPropertyName(v);
50538 renderCell : function(val, meta, rec){
50539 var renderer = this.grid.customRenderers[rec.get('name')];
50541 return renderer.apply(this, arguments);
50544 if(Ext.isDate(val)){
50545 rv = this.renderDate(val);
50546 }else if(typeof val == 'boolean'){
50547 rv = this.renderBool(val);
50549 return Ext.util.Format.htmlEncode(rv);
50553 getPropertyName : function(name){
50554 var pn = this.grid.propertyNames;
50555 return pn && pn[name] ? pn[name] : name;
50559 getCellEditor : function(colIndex, rowIndex){
50560 var p = this.store.getProperty(rowIndex),
50562 val = p.data.value;
50563 if(this.grid.customEditors[n]){
50564 return this.grid.customEditors[n];
50566 if(Ext.isDate(val)){
50567 return this.editors.date;
50568 }else if(typeof val == 'number'){
50569 return this.editors.number;
50570 }else if(typeof val == 'boolean'){
50571 return this.editors['boolean'];
50573 return this.editors.string;
50578 destroy : function(){
50579 Ext.grid.PropertyColumnModel.superclass.destroy.call(this);
50580 this.destroyEditors(this.editors);
50581 this.destroyEditors(this.grid.customEditors);
50584 destroyEditors: function(editors){
50585 for(var ed in editors){
50586 Ext.destroy(editors[ed]);
50592 Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
50600 enableColumnMove:false,
50602 trackMouseOver: false,
50604 enableHdMenu : false,
50610 initComponent : function(){
50611 this.customRenderers = this.customRenderers || {};
50612 this.customEditors = this.customEditors || {};
50613 this.lastEditRow = null;
50614 var store = new Ext.grid.PropertyStore(this);
50615 this.propStore = store;
50616 var cm = new Ext.grid.PropertyColumnModel(this, store);
50617 store.store.sort('name', 'ASC');
50620 'beforepropertychange',
50625 this.ds = store.store;
50626 Ext.grid.PropertyGrid.superclass.initComponent.call(this);
50628 this.mon(this.selModel, 'beforecellselect', function(sm, rowIndex, colIndex){
50629 if(colIndex === 0){
50630 this.startEditing.defer(200, this, [rowIndex, 1]);
50637 onRender : function(){
50638 Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
50640 this.getGridEl().addClass('x-props-grid');
50644 afterRender: function(){
50645 Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
50647 this.setSource(this.source);
50652 setSource : function(source){
50653 this.propStore.setSource(source);
50657 getSource : function(){
50658 return this.propStore.getSource();
50662 setProperty : function(prop, value, create){
50663 this.propStore.setValue(prop, value, create);
50667 removeProperty : function(prop){
50668 this.propStore.remove(prop);
50676 Ext.reg("propertygrid", Ext.grid.PropertyGrid);
50678 Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
50681 groupByText : 'Group By This Field',
50683 showGroupsText : 'Show in Groups',
50685 hideGroupedColumn : false,
50687 showGroupName : true,
50689 startCollapsed : false,
50691 enableGrouping : true,
50693 enableGroupingMenu : true,
50695 enableNoGroups : true,
50697 emptyGroupText : '(None)',
50701 groupTextTpl : '{text}',
50704 groupMode: 'value',
50709 cancelEditOnToggle: true,
50712 initTemplates : function(){
50713 Ext.grid.GroupingView.superclass.initTemplates.call(this);
50716 var sm = this.grid.getSelectionModel();
50717 sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
50718 this.onBeforeRowSelect, this);
50720 if(!this.startGroup){
50721 this.startGroup = new Ext.XTemplate(
50722 '<div id="{groupId}" class="x-grid-group {cls}">',
50723 '<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div class="x-grid-group-title">', this.groupTextTpl ,'</div></div>',
50724 '<div id="{groupId}-bd" class="x-grid-group-body">'
50727 this.startGroup.compile();
50729 if (!this.endGroup) {
50730 this.endGroup = '</div></div>';
50735 findGroup : function(el){
50736 return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
50740 getGroups : function(){
50741 return this.hasRows() ? this.mainBody.dom.childNodes : [];
50745 onAdd : function(ds, records, index) {
50746 if (this.canGroup() && !this.ignoreAdd) {
50747 var ss = this.getScrollState();
50748 this.fireEvent('beforerowsinserted', ds, index, index + (records.length-1));
50750 this.restoreScroll(ss);
50751 this.fireEvent('rowsinserted', ds, index, index + (records.length-1));
50752 } else if (!this.canGroup()) {
50753 Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
50758 onRemove : function(ds, record, index, isUpdate){
50759 Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);
50760 var g = document.getElementById(record._groupId);
50761 if(g && g.childNodes[1].childNodes.length < 1){
50764 this.applyEmptyText();
50768 refreshRow : function(record){
50769 if(this.ds.getCount()==1){
50772 this.isUpdating = true;
50773 Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);
50774 this.isUpdating = false;
50779 beforeMenuShow : function(){
50780 var item, items = this.hmenu.items, disabled = this.cm.config[this.hdCtxIndex].groupable === false;
50781 if((item = items.get('groupBy'))){
50782 item.setDisabled(disabled);
50784 if((item = items.get('showGroups'))){
50785 item.setDisabled(disabled);
50786 item.setChecked(this.canGroup(), true);
50791 renderUI : function(){
50792 var markup = Ext.grid.GroupingView.superclass.renderUI.call(this);
50794 if(this.enableGroupingMenu && this.hmenu){
50795 this.hmenu.add('-',{
50797 text: this.groupByText,
50798 handler: this.onGroupByClick,
50800 iconCls:'x-group-by-icon'
50802 if(this.enableNoGroups){
50804 itemId:'showGroups',
50805 text: this.showGroupsText,
50807 checkHandler: this.onShowGroupsClick,
50811 this.hmenu.on('beforeshow', this.beforeMenuShow, this);
50816 processEvent: function(name, e){
50817 Ext.grid.GroupingView.superclass.processEvent.call(this, name, e);
50818 var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
50821 var field = this.getGroupField(),
50822 prefix = this.getPrefix(field),
50823 groupValue = hd.id.substring(prefix.length),
50824 emptyRe = new RegExp('gp-' + Ext.escapeRe(field) + '--hd');
50827 groupValue = groupValue.substr(0, groupValue.length - 3);
50830 if(groupValue || emptyRe.test(hd.id)){
50831 this.grid.fireEvent('group' + name, this.grid, field, groupValue, e);
50833 if(name == 'mousedown' && e.button == 0){
50834 this.toggleGroup(hd.parentNode);
50841 onGroupByClick : function(){
50842 this.enableGrouping = true;
50843 this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
50844 this.grid.fireEvent('groupchange', this, this.grid.store.getGroupState());
50845 this.beforeMenuShow();
50850 onShowGroupsClick : function(mi, checked){
50851 this.enableGrouping = checked;
50853 this.onGroupByClick();
50855 this.grid.store.clearGrouping();
50856 this.grid.fireEvent('groupchange', this, null);
50861 toggleRowIndex : function(rowIndex, expanded){
50862 if(!this.canGroup()){
50865 var row = this.getRow(rowIndex);
50867 this.toggleGroup(this.findGroup(row), expanded);
50872 toggleGroup : function(group, expanded){
50873 var gel = Ext.get(group);
50874 expanded = Ext.isDefined(expanded) ? expanded : gel.hasClass('x-grid-group-collapsed');
50875 if(this.state[gel.id] !== expanded){
50876 if (this.cancelEditOnToggle !== false) {
50877 this.grid.stopEditing(true);
50879 this.state[gel.id] = expanded;
50880 gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
50885 toggleAllGroups : function(expanded){
50886 var groups = this.getGroups();
50887 for(var i = 0, len = groups.length; i < len; i++){
50888 this.toggleGroup(groups[i], expanded);
50893 expandAllGroups : function(){
50894 this.toggleAllGroups(true);
50898 collapseAllGroups : function(){
50899 this.toggleAllGroups(false);
50903 getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
50904 var column = this.cm.config[colIndex],
50905 g = groupRenderer ? groupRenderer.call(column.scope, v, {}, r, rowIndex, colIndex, ds) : String(v);
50906 if(g === '' || g === ' '){
50907 g = column.emptyGroupText || this.emptyGroupText;
50913 getGroupField : function(){
50914 return this.grid.store.getGroupState();
50918 afterRender : function(){
50919 if(!this.ds || !this.cm){
50922 Ext.grid.GroupingView.superclass.afterRender.call(this);
50923 if(this.grid.deferRowRender){
50924 this.updateGroupWidths();
50928 afterRenderUI: function () {
50929 Ext.grid.GroupingView.superclass.afterRenderUI.call(this);
50931 if (this.enableGroupingMenu && this.hmenu) {
50932 this.hmenu.add('-',{
50934 text: this.groupByText,
50935 handler: this.onGroupByClick,
50937 iconCls:'x-group-by-icon'
50940 if (this.enableNoGroups) {
50942 itemId:'showGroups',
50943 text: this.showGroupsText,
50945 checkHandler: this.onShowGroupsClick,
50950 this.hmenu.on('beforeshow', this.beforeMenuShow, this);
50955 renderRows : function(){
50956 var groupField = this.getGroupField();
50957 var eg = !!groupField;
50959 if(this.hideGroupedColumn) {
50960 var colIndex = this.cm.findColumnIndex(groupField),
50961 hasLastGroupField = Ext.isDefined(this.lastGroupField);
50962 if(!eg && hasLastGroupField){
50963 this.mainBody.update('');
50964 this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
50965 delete this.lastGroupField;
50966 }else if (eg && !hasLastGroupField){
50967 this.lastGroupField = groupField;
50968 this.cm.setHidden(colIndex, true);
50969 }else if (eg && hasLastGroupField && groupField !== this.lastGroupField) {
50970 this.mainBody.update('');
50971 var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
50972 this.cm.setHidden(oldIndex, false);
50973 this.lastGroupField = groupField;
50974 this.cm.setHidden(colIndex, true);
50977 return Ext.grid.GroupingView.superclass.renderRows.apply(
50982 doRender : function(cs, rs, ds, startRow, colCount, stripe){
50987 if(!this.canGroup() || this.isUpdating){
50988 return Ext.grid.GroupingView.superclass.doRender.apply(this, arguments);
50991 var groupField = this.getGroupField(),
50992 colIndex = this.cm.findColumnIndex(groupField),
50994 gstyle = 'width:' + this.getTotalWidth() + ';',
50995 cfg = this.cm.config[colIndex],
50996 groupRenderer = cfg.groupRenderer || cfg.renderer,
50997 prefix = this.showGroupName ? (cfg.groupName || cfg.header)+': ' : '',
50999 curGroup, i, len, gid;
51001 for(i = 0, len = rs.length; i < len; i++){
51002 var rowIndex = startRow + i,
51004 gvalue = r.data[groupField];
51006 g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
51007 if(!curGroup || curGroup.group != g){
51008 gid = this.constructId(gvalue, groupField, colIndex);
51011 this.state[gid] = !(Ext.isDefined(this.state[gid]) ? !this.state[gid] : this.startCollapsed);
51017 startRow: rowIndex,
51019 cls: this.state[gid] ? '' : 'x-grid-group-collapsed',
51022 groups.push(curGroup);
51024 curGroup.rs.push(r);
51030 for(i = 0, len = groups.length; i < len; i++){
51032 this.doGroupStart(buf, g, cs, ds, colCount);
51033 buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
51034 this, cs, g.rs, ds, g.startRow, colCount, stripe);
51036 this.doGroupEnd(buf, g, cs, ds, colCount);
51038 return buf.join('');
51042 getGroupId : function(value){
51043 var field = this.getGroupField();
51044 return this.constructId(value, field, this.cm.findColumnIndex(field));
51048 constructId : function(value, field, idx){
51049 var cfg = this.cm.config[idx],
51050 groupRenderer = cfg.groupRenderer || cfg.renderer,
51051 val = (this.groupMode == 'value') ? value : this.getGroup(value, {data:{}}, groupRenderer, 0, idx, this.ds);
51053 return this.getPrefix(field) + Ext.util.Format.htmlEncode(val);
51057 canGroup : function(){
51058 return this.enableGrouping && !!this.getGroupField();
51062 getPrefix: function(field){
51063 return this.grid.getGridEl().id + '-gp-' + field + '-';
51067 doGroupStart : function(buf, g, cs, ds, colCount){
51068 buf[buf.length] = this.startGroup.apply(g);
51072 doGroupEnd : function(buf, g, cs, ds, colCount){
51073 buf[buf.length] = this.endGroup;
51077 getRows : function(){
51078 if(!this.canGroup()){
51079 return Ext.grid.GroupingView.superclass.getRows.call(this);
51082 gs = this.getGroups(),
51088 for(; i < len; ++i){
51089 g = gs[i].childNodes[1];
51092 for(j = 0, jlen = g.length; j < jlen; ++j){
51093 r[r.length] = g[j];
51101 updateGroupWidths : function(){
51102 if(!this.canGroup() || !this.hasRows()){
51105 var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.getScrollOffset()) +'px';
51106 var gs = this.getGroups();
51107 for(var i = 0, len = gs.length; i < len; i++){
51108 gs[i].firstChild.style.width = tw;
51113 onColumnWidthUpdated : function(col, w, tw){
51114 Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this, col, w, tw);
51115 this.updateGroupWidths();
51119 onAllColumnWidthsUpdated : function(ws, tw){
51120 Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this, ws, tw);
51121 this.updateGroupWidths();
51125 onColumnHiddenUpdated : function(col, hidden, tw){
51126 Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this, col, hidden, tw);
51127 this.updateGroupWidths();
51131 onLayout : function(){
51132 this.updateGroupWidths();
51136 onBeforeRowSelect : function(sm, rowIndex){
51137 this.toggleRowIndex(rowIndex, true);
51141 Ext.grid.GroupingView.GROUP_ID = 1000;