2
* Ext JS Library 3.0 RC2
3
* Copyright(c) 2006-2009, Ext JS, LLC.
6
* http://extjs.com/license
10
Ext.DomHelper = function(){
11
var tempTableEl = null,
12
emptyTags = /^(?:br|frame|hr|img|input|link|meta|range|spacer|wbr|area|param|col)$/i,
13
tableRe = /^table|tbody|tr|td$/i,
15
// kill repeat to save bytes
16
afterbegin = "afterbegin",
17
afterend = "afterend",
18
beforebegin = "beforebegin",
19
beforeend = "beforeend",
28
function doInsert(el, o, returnElement, pos, sibling, append){
29
var newNode = pub.insertHtml(pos, Ext.getDom(el), createHtml(o));
30
return returnElement ? Ext.get(newNode, true) : newNode;
33
// build as innerHTML where available
34
function createHtml(o){
42
if(typeof o == 'string'){
44
} else if (Ext.isArray(o)) {
45
Ext.each(o, function(v) {
49
b += "<" + (o.tag = o.tag || "div");
52
if (!/tag|children|cn|html$/i.test(attr) && !Ext.isFunction(val)) {
53
if (Ext.isObject(val)) {
54
b += " " + attr + "='";
57
b += !Ext.isFunction(keyVal) ? key + ":" + keyVal + ";" : "";
61
b += " " + ({cls : "class", htmlFor : "for"}[attr] || attr) + "='" + val + "'";
65
// Now either just close the tag or try to add children and close the tag.
66
if (emptyTags.test(o.tag)) {
70
if (cn = o.children || o.cn) {
75
b += "</" + o.tag + ">";
81
function ieTable(depth, s, h, e){
82
tempTableEl.innerHTML = [s, h, e].join('');
92
function insertIntoTable(tag, where, el, html) {
96
tempTableEl = tempTableEl || document.createElement('div');
98
if(tag == 'td' && (where == afterbegin || where == beforeend) ||
99
!/td|tr|tbody/i.test(tag) && (where == beforebegin || where == afterend)) {
102
before = where == beforebegin ? el :
103
where == afterend ? el.nextSibling :
104
where == afterbegin ? el.firstChild : null;
106
if (where == beforebegin || where == afterend) {
110
if (tag == 'td' || (tag == "tr" && (where == beforeend || where == afterbegin))) {
111
node = ieTable(4, trs, html, tre);
112
} else if ((tag == "tbody" && (where == beforeend || where == afterbegin)) ||
113
(tag == "tr" && (where == beforebegin || where == afterend))) {
114
node = ieTable(3, tbs, html, tbe);
116
node = ieTable(2, ts, html, te);
118
el.insertBefore(node, before);
125
markup : function(o){
126
return createHtml(o);
130
insertHtml : function(where, el, html){
139
where = where.toLowerCase();
140
// add these here because they are used in both branches of the condition.
141
hash[beforebegin] = ['BeforeBegin', 'previousSibling'];
142
hash[afterend] = ['AfterEnd', 'nextSibling'];
144
if (el.insertAdjacentHTML) {
145
if(tableRe.test(el.tagName) && (rs = insertIntoTable(el.tagName.toLowerCase(), where, el, html))){
148
// add these two to the hash.
149
hash[afterbegin] = ['AfterBegin', 'firstChild'];
150
hash[beforeend] = ['BeforeEnd', 'lastChild'];
151
if (hashVal = hash[where]) {
152
el.insertAdjacentHTML(hashVal[0], html);
153
return el[hashVal[1]];
156
range = el.ownerDocument.createRange();
157
setStart = "setStart" + (/end/i.test(where) ? "After" : "Before");
160
frag = range.createContextualFragment(html);
161
el.parentNode.insertBefore(frag, where == beforebegin ? el : el.nextSibling);
162
return el[(where == beforebegin ? "previous" : "next") + "Sibling"];
164
rangeEl = (where == afterbegin ? "first" : "last") + "Child";
166
range[setStart](el[rangeEl]);
167
frag = range.createContextualFragment(html);
168
where == afterbegin ? el.insertBefore(frag, el.firstChild) : el.appendChild(frag);
175
throw 'Illegal insertion point -> "' + where + '"';
179
insertBefore : function(el, o, returnElement){
180
return doInsert(el, o, returnElement, beforebegin);
184
insertAfter : function(el, o, returnElement){
185
return doInsert(el, o, returnElement, afterend, "nextSibling");
189
insertFirst : function(el, o, returnElement){
190
return doInsert(el, o, returnElement, afterbegin, "firstChild");
194
append : function(el, o, returnElement){
195
return doInsert(el, o, returnElement, beforeend, "", true);
199
overwrite : function(el, o, returnElement){
201
el.innerHTML = createHtml(o);
202
return returnElement ? Ext.get(el.firstChild) : el.firstChild;
205
createHtml : createHtml
210
Ext.apply(Ext.DomHelper,
213
afterbegin = "afterbegin",
214
afterend = "afterend",
215
beforebegin = "beforebegin",
216
beforeend = "beforeend";
219
function doInsert(el, o, returnElement, pos, sibling, append){
223
newNode = createDom(o, null);
225
el.appendChild(newNode);
227
(sibling == "firstChild" ? el : el.parentNode).insertBefore(newNode, el[sibling] || el);
230
newNode = Ext.DomHelper.insertHtml(pos, el, Ext.DomHelper.createHtml(o));
232
return returnElement ? Ext.get(newNode, true) : newNode;
237
function createDom(o, parentNode){
245
if (Ext.isArray(o)) { // Allow Arrays of siblings to be inserted
246
el = doc.createDocumentFragment(); // in one shot using a DocumentFragment
247
Ext.each(o, function(v) {
250
} else if (typeof o == "string") { // Allow a string as a child spec.
251
el = doc.createTextNode(o);
253
el = doc.createElement( o.tag || 'div' );
254
useSet = !!el.setAttribute; // In IE some elements don't have setAttribute
257
if(["tag", "children", "cn", "html", "style"].indexOf(attr) == -1 || !Ext.isFunction(val)) {
261
useSet ? el.setAttribute(attr, val) : el[attr] = val;
265
pub.applyStyles(el, o.style);
267
if (cn = o.children || o.cn) {
270
el.innerHTML = o.html;
274
parentNode.appendChild(el);
281
createTemplate : function(o){
282
var html = Ext.DomHelper.createHtml(o);
283
return new Ext.Template(html);
290
applyStyles : function(el, styles){
297
if(Ext.isFunction(styles)){
298
styles = styles.call();
300
if(typeof styles == "string"){
301
styles = styles.trim().split(/\s*(?::|;)\s*/);
302
for(len = styles.length; i < len;){
303
el.setStyle(styles[i++], styles[i++]);
305
}else if (Ext.isObject(styles)){
312
insertBefore : function(el, o, returnElement){
313
return doInsert(el, o, returnElement, beforebegin);
317
insertAfter : function(el, o, returnElement){
318
return doInsert(el, o, returnElement, afterend, "nextSibling");
322
insertFirst : function(el, o, returnElement){
323
return doInsert(el, o, returnElement, afterbegin, "firstChild");
327
append: function(el, o, returnElement){
328
return doInsert(el, o, returnElement, beforeend, "", true);
337
Ext.Template = function(html){
342
if (Ext.isArray(html)) {
343
html = html.join("");
344
} else if (a.length > 1) {
345
Ext.each(a, function(v) {
346
if (Ext.isObject(v)) {
361
Ext.Template.prototype = {
363
applyTemplate : function(values){
367
me.compiled(values) :
368
me.html.replace(me.re, function(m, name){
369
return values[name] !== undefined ? values[name] : "";
374
set : function(html, compile){
378
return compile ? me.compile() : me;
382
re : /\{([\w-]+)\}/g,
385
compile : function(){
387
sep = Ext.isGecko ? "+" : ",";
389
function fn(m, name){
390
name = "values['" + name + "']";
391
return "'"+ sep + '(' + name + " == undefined ? '' : " + name + ')' + sep + "'";
394
eval("this.compiled = function(values){ return " + (Ext.isGecko ? "'" : "['") +
395
me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
396
(Ext.isGecko ? "';};" : "'].join('');};"));
401
insertFirst: function(el, values, returnElement){
402
return this.doInsert('afterBegin', el, values, returnElement);
406
insertBefore: function(el, values, returnElement){
407
return this.doInsert('beforeBegin', el, values, returnElement);
411
insertAfter : function(el, values, returnElement){
412
return this.doInsert('afterEnd', el, values, returnElement);
416
append : function(el, values, returnElement){
417
return this.doInsert('beforeEnd', el, values, returnElement);
420
doInsert : function(where, el, values, returnEl){
422
var newNode = Ext.DomHelper.insertHtml(where, el, this.applyTemplate(values));
423
return returnEl ? Ext.get(newNode, true) : newNode;
427
overwrite : function(el, values, returnElement){
429
el.innerHTML = this.applyTemplate(values);
430
return returnElement ? Ext.get(el.firstChild, true) : el.firstChild;
434
Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
437
Ext.Template.from = function(el, config){
439
return new Ext.Template(el.value || el.innerHTML, config || '');
442
Ext.apply(Ext.Template.prototype, {
444
applyTemplate : function(values){
446
useF = me.disableFormats !== true,
447
fm = Ext.util.Format,
451
return me.compiled(values);
453
function fn(m, name, format, args){
454
if (format && useF) {
455
if (format.substr(0, 5) == "this.") {
456
return tpl.call(format.substr(5), values[name], values);
459
// quoted values are required for strings in compiled templates,
460
// but for non compiled we need to strip them
461
// quoted reversed for jsmin
462
var re = /^\s*['"](.*)["']\s*$/;
463
args = args.split(',');
464
for(var i = 0, len = args.length; i < len; i++){
465
args[i] = args[i].replace(re, "$1");
467
args = [values[name]].concat(args);
469
args = [values[name]];
471
return fm[format].apply(fm, args);
474
return values[name] !== undefined ? values[name] : "";
477
return me.html.replace(me.re, fn);
481
disableFormats : false,
484
re : /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g,
487
compile : function(){
489
fm = Ext.util.Format,
490
useF = me.disableFormats !== true,
491
sep = Ext.isGecko ? "+" : ",",
494
function fn(m, name, format, args){
496
args = args ? ',' + args : "";
497
if(format.substr(0, 5) != "this."){
498
format = "fm." + format + '(';
500
format = 'this.call("'+ format.substr(5) + '", ';
504
args= ''; format = "(values['" + name + "'] == undefined ? '' : ";
506
return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'";
509
// branched to use + in gecko and [].join() in others
511
body = "this.compiled = function(values){ return '" +
512
me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn) +
515
body = ["this.compiled = function(values){ return ['"];
516
body.push(me.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn));
517
body.push("'].join('');};");
518
body = body.join('');
524
// private function used to call members
525
call : function(fnName, value, allValues){
526
return this[fnName](value, allValues);
529
Ext.Template.prototype.apply = Ext.Template.prototype.applyTemplate;
532
Ext.DomQuery = function(){
537
trimRe = /^\s+|\s+$/g,
538
tplRe = /\{(\d+)\}/g,
539
modeRe = /^(\s?[\/>+~]\s?|\s|$)/,
540
tagTokenRe = /^(#)?([\w-\*]+)/,
541
nthRe = /(\d*)n\+?(\d*)/,
543
// This is for IE MSXML which does not support expandos.
544
// IE runs the same speed using setAttribute, however FF slows way down
545
// and Safari completely fails so they need to continue to use expandos.
546
isIE = window.ActiveXObject ? true : false,
547
isOpera = Ext.isOpera,
550
// this eval is stop the compressor from
551
// renaming the variable to something shorter
552
eval("var batch = 30803;");
554
function child(p, index){
569
while((n = n.nextSibling) && n.nodeType != 1);
574
while((n = n.previousSibling) && n.nodeType != 1);
578
function children(d){
579
var n = d.firstChild, ni = -1,
583
if(n.nodeType == 3 && !nonSpace.test(n.nodeValue)){
593
function byClassName(c, a, v){
597
var r = [], ri = -1, cn;
598
for(var i = 0, ci; ci = c[i]; i++){
599
if((' '+ci.className+' ').indexOf(v) != -1){
606
function attrValue(n, attr){
607
if(!n.tagName && typeof n.length != "undefined"){
616
if(attr == "class" || attr == "className"){
619
return n.getAttribute(attr) || n[attr];
623
function getNodes(ns, mode, tagName){
624
var result = [], ri = -1, cs;
628
tagName = tagName || "*";
629
if(typeof ns.getElementsByTagName != "undefined"){
633
for(var i = 0, ni; ni = ns[i]; i++){
634
cs = ni.getElementsByTagName(tagName);
635
for(var j = 0, ci; ci = cs[j]; j++){
639
}else if(mode == "/" || mode == ">"){
640
var utag = tagName.toUpperCase();
641
for(var i = 0, ni, cn; ni = ns[i]; i++){
642
cn = isOpera ? ni.childNodes : (ni.children || ni.childNodes);
643
for(var j = 0, cj; cj = cn[j]; j++){
644
if(cj.nodeName == utag || cj.nodeName == tagName || tagName == '*'){
649
}else if(mode == "+"){
650
var utag = tagName.toUpperCase();
651
for(var i = 0, n; n = ns[i]; i++){
652
while((n = n.nextSibling) && n.nodeType != 1);
653
if(n && (n.nodeName == utag || n.nodeName == tagName || tagName == '*')){
657
}else if(mode == "~"){
658
var utag = tagName.toUpperCase();
659
for(var i = 0, n; n = ns[i]; i++){
660
while((n = n.nextSibling)){
661
if (n.nodeName == utag || n.nodeName == tagName || tagName == '*'){
670
function concat(a, b){
674
for(var i = 0, l = b.length; i < l; i++){
680
function byTag(cs, tagName){
681
if(cs.tagName || cs == document){
688
tagName = tagName.toLowerCase();
689
for(var i = 0, ci; ci = cs[i]; i++){
690
if(ci.nodeType == 1 && ci.tagName.toLowerCase()==tagName){
697
function byId(cs, attr, id){
698
if(cs.tagName || cs == document){
705
for(var i = 0,ci; ci = cs[i]; i++){
706
if(ci && ci.id == id){
714
function byAttribute(cs, attr, value, op, custom){
718
f = Ext.DomQuery.operators[op];
719
for(var i = 0, ci; ci = cs[i]; i++){
720
if(ci.nodeType != 1){
725
a = Ext.DomQuery.getStyle(ci, attr);
727
else if(attr == "class" || attr == "className"){
729
}else if(attr == "for"){
731
}else if(attr == "href"){
732
a = ci.getAttribute("href", 2);
734
a = ci.getAttribute(attr);
736
if((f && f(a, value)) || (!f && a)){
743
function byPseudo(cs, name, value){
744
return Ext.DomQuery.pseudos[name](cs, value);
747
function nodupIEXml(cs){
750
cs[0].setAttribute("_nodup", d);
752
for(var i = 1, len = cs.length; i < len; i++){
754
if(!c.getAttribute("_nodup") != d){
755
c.setAttribute("_nodup", d);
759
for(var i = 0, len = cs.length; i < len; i++){
760
cs[i].removeAttribute("_nodup");
769
var len = cs.length, c, i, r = cs, cj, ri = -1;
770
if(!len || typeof cs.nodeType != "undefined" || len == 1){
773
if(isIE && typeof cs[0].selectSingleNode != "undefined"){
774
return nodupIEXml(cs);
778
for(i = 1; c = cs[i]; i++){
783
for(var j = 0; j < i; j++){
786
for(j = i+1; cj = cs[j]; j++){
798
function quickDiffIEXml(c1, c2){
801
for(var i = 0, len = c1.length; i < len; i++){
802
c1[i].setAttribute("_qdiff", d);
804
for(var i = 0, len = c2.length; i < len; i++){
805
if(c2[i].getAttribute("_qdiff") != d){
809
for(var i = 0, len = c1.length; i < len; i++){
810
c1[i].removeAttribute("_qdiff");
815
function quickDiff(c1, c2){
816
var len1 = c1.length,
822
if(isIE && c1[0].selectSingleNode){
823
return quickDiffIEXml(c1, c2);
825
for(var i = 0; i < len1; i++){
828
for(var i = 0, len = c2.length; i < len; i++){
829
if(c2[i]._qdiff != d){
836
function quickId(ns, mode, root, id){
838
var d = root.ownerDocument || root;
839
return d.getElementById(id);
841
ns = getNodes(ns, mode, "*");
842
return byId(ns, null, id);
846
getStyle : function(el, name){
847
return Ext.fly(el).getStyle(name);
850
compile : function(path, type){
851
type = type || "select";
853
var fn = ["var f = function(root){\n var mode; ++batch; var n = root || document;\n"],
855
tk = Ext.DomQuery.matchers,
858
// accept leading mode switch
859
lmode = q.match(modeRe);
861
if(lmode && lmode[1]){
862
fn[fn.length] = 'mode="'+lmode[1].replace(trimRe, "")+'";';
863
q = q.replace(lmode[1], "");
865
// strip leading slashes
866
while(path.substr(0, 1)=="/"){
867
path = path.substr(1);
872
var tm = q.match(tagTokenRe);
873
if(type == "select"){
876
fn[fn.length] = 'n = quickId(n, mode, root, "'+tm[2]+'");';
878
fn[fn.length] = 'n = getNodes(n, mode, "'+tm[2]+'");';
880
q = q.replace(tm[0], "");
881
}else if(q.substr(0, 1) != '@'){
882
fn[fn.length] = 'n = getNodes(n, mode, "*");';
887
fn[fn.length] = 'n = byId(n, null, "'+tm[2]+'");';
889
fn[fn.length] = 'n = byTag(n, "'+tm[2]+'");';
891
q = q.replace(tm[0], "");
894
while(!(mm = q.match(modeRe))){
896
for(var j = 0; j < tklen; j++){
898
var m = q.match(t.re);
900
fn[fn.length] = t.select.replace(tplRe, function(x, i){
903
q = q.replace(m[0], "");
908
// prevent infinite loop on bad selector
910
throw 'Error parsing selector, parsing failed at "' + q + '"';
914
fn[fn.length] = 'mode="'+mm[1].replace(trimRe, "")+'";';
915
q = q.replace(mm[1], "");
918
fn[fn.length] = "return nodup(n);\n}";
924
select : function(path, root, type){
925
if(!root || root == document){
928
if(typeof root == "string"){
929
root = document.getElementById(root);
931
var paths = path.split(","),
933
for(var i = 0, len = paths.length; i < len; i++){
934
var p = paths[i].replace(trimRe, "");
936
cache[p] = Ext.DomQuery.compile(p);
938
throw p + " is not a valid selector";
941
var result = cache[p](root);
942
if(result && result != document){
943
results = results.concat(result);
946
if(paths.length > 1){
947
return nodup(results);
953
selectNode : function(path, root){
954
return Ext.DomQuery.select(path, root)[0];
958
selectValue : function(path, root, defaultValue){
959
path = path.replace(trimRe, "");
960
if(!valueCache[path]){
961
valueCache[path] = Ext.DomQuery.compile(path, "select");
963
var n = valueCache[path](root),
966
v = (n && n.firstChild ? n.firstChild.nodeValue : null);
967
return ((v === null||v === undefined||v==='') ? defaultValue : v);
971
selectNumber : function(path, root, defaultValue){
972
var v = Ext.DomQuery.selectValue(path, root, defaultValue || 0);
973
return parseFloat(v);
977
is : function(el, ss){
978
if(typeof el == "string"){
979
el = document.getElementById(el);
981
var isArray = Ext.isArray(el),
982
result = Ext.DomQuery.filter(isArray ? el : [el], ss);
983
return isArray ? (result.length == el.length) : (result.length > 0);
987
filter : function(els, ss, nonMatches){
988
ss = ss.replace(trimRe, "");
989
if(!simpleCache[ss]){
990
simpleCache[ss] = Ext.DomQuery.compile(ss, "simple");
992
var result = simpleCache[ss](els);
993
return nonMatches ? quickDiff(result, els) : result;
999
select: 'n = byClassName(n, null, " {1} ");'
1001
re: /^\:([\w-]+)(?:\(((?:[^\s>\/]*|.*?))\))?/,
1002
select: 'n = byPseudo(n, "{1}", "{2}");'
1004
re: /^(?:([\[\{])(?:@)?([\w-]+)\s?(?:(=|.=)\s?['"]?(.*?)["']?)?[\]\}])/,
1005
select: 'n = byAttribute(n, "{2}", "{4}", "{3}", "{1}");'
1008
select: 'n = byId(n, null, "{1}");'
1011
select: 'return {firstChild:{nodeValue:attrValue(n, "{1}")}};'
1017
"=" : function(a, v){
1020
"!=" : function(a, v){
1023
"^=" : function(a, v){
1024
return a && a.substr(0, v.length) == v;
1026
"$=" : function(a, v){
1027
return a && a.substr(a.length-v.length) == v;
1029
"*=" : function(a, v){
1030
return a && a.indexOf(v) !== -1;
1032
"%=" : function(a, v){
1033
return (a % v) == 0;
1035
"|=" : function(a, v){
1036
return a && (a == v || a.substr(0, v.length+1) == v+'-');
1038
"~=" : function(a, v){
1039
return a && (' '+a+' ').indexOf(' '+v+' ') != -1;
1045
"first-child" : function(c){
1046
var r = [], ri = -1, n;
1047
for(var i = 0, ci; ci = n = c[i]; i++){
1048
while((n = n.previousSibling) && n.nodeType != 1);
1056
"last-child" : function(c){
1057
var r = [], ri = -1, n;
1058
for(var i = 0, ci; ci = n = c[i]; i++){
1059
while((n = n.nextSibling) && n.nodeType != 1);
1067
"nth-child" : function(c, a) {
1068
var r = [], ri = -1,
1069
m = nthRe.exec(a == "even" && "2n" || a == "odd" && "2n+1" || !nthRe2.test(a) && "n+" + a || a),
1070
f = (m[1] || 1) - 0, l = m[2] - 0;
1071
for(var i = 0, n; n = c[i]; i++){
1072
var pn = n.parentNode;
1073
if (batch != pn._batch) {
1075
for(var cn = pn.firstChild; cn; cn = cn.nextSibling){
1076
if(cn.nodeType == 1){
1083
if (l == 0 || n.nodeIndex == l){
1086
} else if ((n.nodeIndex + l) % f == 0){
1094
"only-child" : function(c){
1095
var r = [], ri = -1;;
1096
for(var i = 0, ci; ci = c[i]; i++){
1097
if(!prev(ci) && !next(ci)){
1104
"empty" : function(c){
1105
var r = [], ri = -1;
1106
for(var i = 0, ci; ci = c[i]; i++){
1107
var cns = ci.childNodes, j = 0, cn, empty = true;
1110
if(cn.nodeType == 1 || cn.nodeType == 3){
1122
"contains" : function(c, v){
1123
var r = [], ri = -1;
1124
for(var i = 0, ci; ci = c[i]; i++){
1125
if((ci.textContent||ci.innerText||'').indexOf(v) != -1){
1132
"nodeValue" : function(c, v){
1133
var r = [], ri = -1;
1134
for(var i = 0, ci; ci = c[i]; i++){
1135
if(ci.firstChild && ci.firstChild.nodeValue == v){
1142
"checked" : function(c){
1143
var r = [], ri = -1;
1144
for(var i = 0, ci; ci = c[i]; i++){
1145
if(ci.checked == true){
1152
"not" : function(c, ss){
1153
return Ext.DomQuery.filter(c, ss, true);
1156
"any" : function(c, selectors){
1157
var ss = selectors.split('|'),
1159
for(var i = 0, ci; ci = c[i]; i++){
1160
for(var j = 0; s = ss[j]; j++){
1161
if(Ext.DomQuery.is(ci, s)){
1170
"odd" : function(c){
1171
return this["nth-child"](c, "odd");
1174
"even" : function(c){
1175
return this["nth-child"](c, "even");
1178
"nth" : function(c, a){
1179
return c[a-1] || [];
1182
"first" : function(c){
1186
"last" : function(c){
1187
return c[c.length-1] || [];
1190
"has" : function(c, ss){
1191
var s = Ext.DomQuery.select,
1193
for(var i = 0, ci; ci = c[i]; i++){
1194
if(s(ss, ci).length > 0){
1201
"next" : function(c, ss){
1202
var is = Ext.DomQuery.is,
1204
for(var i = 0, ci; ci = c[i]; i++){
1213
"prev" : function(c, ss){
1214
var is = Ext.DomQuery.is,
1216
for(var i = 0, ci; ci = c[i]; i++){
1229
Ext.query = Ext.DomQuery.select;
1233
var EXTUTIL = Ext.util,
1234
TOARRAY = Ext.toArray,
1236
ISOBJECT = Ext.isObject,
1240
EXTUTIL.Observable = function(){
1242
var me = this, e = me.events;
1244
me.on(me.listeners);
1245
delete me.listeners;
1247
me.events = e || {};
1250
EXTUTIL.Observable.prototype = function(){
1251
var filterOptRe = /^(?:scope|delay|buffer|single)$/, toLower = function(s){
1252
return s.toLowerCase();
1258
fireEvent : function(){
1259
var a = TOARRAY(arguments),
1260
ename = toLower(a[0]),
1263
ce = me.events[ename],
1266
if (me.eventsSuspended === TRUE) {
1267
if (q = me.suspendedEventsQueue) {
1271
else if(ISOBJECT(ce) && ce.bubble){
1272
if(ce.fire.apply(ce, a.slice(1)) === FALSE) {
1275
c = me.getBubbleTarget && me.getBubbleTarget();
1276
if(c && c.enableBubble) {
1277
c.enableBubble(ename);
1278
return c.fireEvent.apply(c, a);
1284
ret = ce.fire.apply(ce, a);
1291
addListener : function(eventName, fn, scope, o){
1297
if (ISOBJECT(eventName)) {
1301
if (!filterOptRe.test(e)) {
1302
me.addListener(e, oe.fn || oe, oe.scope || o.scope, oe.fn ? oe : o);
1306
eventName = toLower(eventName);
1307
ce = me.events[eventName] || TRUE;
1308
if (typeof ce == "boolean") {
1309
me.events[eventName] = ce = new EXTUTIL.Event(me, eventName);
1311
ce.addListener(fn, scope, ISOBJECT(o) ? o : {});
1316
removeListener : function(eventName, fn, scope){
1317
var ce = this.events[toLower(eventName)];
1319
ce.removeListener(fn, scope);
1324
purgeListeners : function(){
1325
var events = this.events,
1331
evt.clearListeners();
1337
addEvents : function(o){
1339
me.events = me.events || {};
1340
if (typeof o == 'string') {
1341
EACH(arguments, function(a) {
1342
me.events[a] = me.events[a] || TRUE;
1345
Ext.applyIf(me.events, o);
1350
hasListener : function(eventName){
1351
var e = this.events[eventName];
1352
return ISOBJECT(e) && e.listeners.length > 0;
1356
suspendEvents : function(queueSuspended){
1357
this.eventsSuspended = TRUE;
1358
if (queueSuspended){
1359
this.suspendedEventsQueue = [];
1364
resumeEvents : function(){
1366
me.eventsSuspended = !delete me.suspendedEventQueue;
1367
EACH(me.suspendedEventsQueue, function(e) {
1368
me.fireEvent.apply(me, e);
1374
var OBSERVABLE = EXTUTIL.Observable.prototype;
1376
OBSERVABLE.on = OBSERVABLE.addListener;
1378
OBSERVABLE.un = OBSERVABLE.removeListener;
1381
EXTUTIL.Observable.releaseCapture = function(o){
1382
o.fireEvent = OBSERVABLE.fireEvent;
1385
function createTargeted(h, o, scope){
1387
if(o.target == arguments[0]){
1388
h.apply(scope, TOARRAY(arguments));
1393
function createBuffered(h, o, scope){
1394
var task = new EXTUTIL.DelayedTask();
1396
task.delay(o.buffer, h, scope, TOARRAY(arguments));
1400
function createSingle(h, e, fn, scope){
1402
e.removeListener(fn, scope);
1403
return h.apply(scope, arguments);
1407
function createDelayed(h, o, scope){
1409
var args = TOARRAY(arguments);
1411
h.apply(scope, args);
1412
}).defer(o.delay || 10);
1416
EXTUTIL.Event = function(obj, name){
1419
this.listeners = [];
1422
EXTUTIL.Event.prototype = {
1423
addListener : function(fn, scope, options){
1426
scope = scope || me.obj;
1427
if(!me.isListening(fn, scope)){
1428
l = me.createListener(fn, scope, options);
1429
if(me.firing){ // if we are currently firing this event, don't disturb the listener loop
1430
me.listeners = me.listeners.slice(0);
1432
me.listeners.push(l);
1436
createListener: function(fn, scope, o){
1437
o = o || {}, scope = scope || this.obj;
1444
h = createTargeted(h, o, scope);
1447
h = createDelayed(h, o, scope);
1450
h = createSingle(h, this, fn, scope);
1453
h = createBuffered(h, o, scope);
1459
findListener : function(fn, scope){
1461
EACH(this.listeners, function(l, i) {
1463
if(l.fn == fn && (s == scope || s == this.obj)){
1472
isListening : function(fn, scope){
1473
return this.findListener(fn, scope) != -1;
1476
removeListener : function(fn, scope){
1480
if((index = me.findListener(fn, scope)) != -1){
1482
me.listeners = me.listeners.slice(0);
1484
me.listeners.splice(index, 1);
1490
clearListeners : function(){
1491
this.listeners = [];
1496
args = TOARRAY(arguments),
1499
EACH(me.listeners, function(l) {
1501
if (l.fireFn.apply(l.scope || me.obj || window, args) === FALSE) {
1502
return ret = me.firing = FALSE;
1511
Ext.apply(Ext.util.Observable.prototype, function(){
1512
// this is considered experimental (along with beforeMethod, afterMethod, removeMethodListener?)
1513
// allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
1515
function getMethodEvent(method){
1516
var e = (this.methodEvents = this.methodEvents ||
1517
{})[method], returnValue, v, cancel, obj = this;
1520
this.methodEvents[method] = e = {};
1521
e.originalFn = this[method];
1522
e.methodName = method;
1526
function makeCall(fn, scope, args){
1527
if (!Ext.isEmpty(v = fn.apply(scope || obj, args))) {
1528
if (Ext.isObject(v)) {
1529
returnValue = !Ext.isEmpty(v.returnValue) ? v.returnValue : v;
1530
cancel = !!v.cancel;
1542
this[method] = function(){
1543
var args = Ext.toArray(arguments);
1544
returnValue = v = undefined;
1547
Ext.each(e.before, function(b){
1548
makeCall(b.fn, b.scope, args);
1554
if (!Ext.isEmpty(v = e.originalFn.apply(obj, args))) {
1557
Ext.each(e.after, function(a){
1558
makeCall(a.fn, a.scope, args);
1570
// these are considered experimental
1571
// allows for easier interceptor and sequences, including cancelling and overwriting the return value of the call
1572
// adds an "interceptor" called before the original method
1573
beforeMethod: function(method, fn, scope){
1574
getMethodEvent.call(this, method).before.push({
1580
// adds a "sequence" called after the original method
1581
afterMethod: function(method, fn, scope){
1582
getMethodEvent.call(this, method).after.push({
1588
removeMethodListener: function(method, fn, scope){
1589
var e = getMethodEvent.call(this, method), found = false;
1590
Ext.each(e.before, function(b){
1591
if (b.fn == fn && b.scope == scope) {
1598
Ext.each(e.after, function(a){
1599
if (a.fn == fn && a.scope == scope) {
1608
relayEvents: function(o, events){
1610
function createHandler(ename){
1612
return me.fireEvent.apply(me, [ename].concat(Ext.toArray(arguments)));
1615
Ext.each(events, function(ename){
1616
me.events[ename] = me.events[ename] || true;
1617
o.on(ename, createHandler(ename), me);
1622
enableBubble: function(events){
1624
events = Ext.isArray(events) ? events : Ext.toArray(arguments);
1625
Ext.each(events, function(ename){
1626
ename = ename.toLowerCase();
1627
var ce = me.events[ename] || true;
1628
if (typeof ce == "boolean") {
1629
ce = new Ext.util.Event(me, ename);
1630
me.events[ename] = ce;
1640
Ext.util.Observable.capture = function(o, fn, scope){
1641
o.fireEvent = o.fireEvent.createInterceptor(fn, scope);
1646
Ext.util.Observable.observeClass = function(c){
1647
Ext.apply(c, new Ext.util.Observable());
1648
c.prototype.fireEvent = function(){
1649
return (c.fireEvent.apply(c, arguments) !== false) &&
1650
(Ext.util.Observable.prototype.fireEvent.apply(this, arguments) !== false);
1654
Ext.EventManager = function(){
1657
docReadyState = false,
1662
IEDEFERED = "ie-deferred-loader",
1663
DOMCONTENTLOADED = "DOMContentLoaded",
1665
propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
1667
/// There is some jquery work around stuff here that isn't needed in Ext Core.
1668
function addListener(el, ename, fn, wrap, scope){
1669
var id = Ext.id(el),
1670
es = elHash[id] = elHash[id] || {};
1672
(es[ename] = es[ename] || []).push([fn, wrap, scope]);
1673
E.on(el, ename, wrap);
1675
// this is a workaround for jQuery and should somehow be removed from Ext Core in the future
1676
// without breaking ExtJS.
1677
if(ename == "mousewheel" && el.addEventListener){ // workaround for jQuery
1678
var args = ["DOMMouseScroll", wrap, false];
1679
el.addEventListener.apply(el, args);
1680
E.on(window, 'unload', function(){
1681
el.removeEventListener.apply(el, args);
1684
if(ename == "mousedown" && el == document){ // fix stopped mousedowns on the document
1685
Ext.EventManager.stoppedMouseDownEvent.addListener(wrap);
1689
function fireDocReady(){
1691
Ext.isReady = docReadyState = true;
1693
clearInterval(docReadyProcId);
1695
if(Ext.isGecko || Ext.isOpera) {
1696
DOC.removeEventListener(DOMCONTENTLOADED, fireDocReady, false);
1699
var defer = DOC.getElementById(IEDEFERED);
1701
defer.onreadystatechange = null;
1702
defer.parentNode.removeChild(defer);
1706
docReadyEvent.fire();
1707
docReadyEvent.clearListeners();
1712
function initDocReady(){
1713
var COMPLETE = "complete";
1715
docReadyEvent = new Ext.util.Event();
1716
if (Ext.isGecko || Ext.isOpera) {
1717
DOC.addEventListener(DOMCONTENTLOADED, fireDocReady, false);
1718
} else if (Ext.isIE){
1719
DOC.write("<s"+'cript id=' + IEDEFERED + ' defer="defer" src="/'+'/:"></s'+"cript>");
1720
DOC.getElementById(IEDEFERED).onreadystatechange = function(){
1721
if(this.readyState == COMPLETE){
1725
} else if (Ext.isWebKit){
1726
docReadyProcId = setInterval(function(){
1727
if(DOC.readyState == COMPLETE) {
1732
// no matter what, make sure it fires on load
1733
E.on(WINDOW, "load", fireDocReady);
1736
function createTargeted(h, o){
1738
var args = Ext.toArray(arguments);
1739
if(o.target == Ext.EventObject.setEvent(args[0]).target){
1740
h.apply(this, args);
1745
function createBuffered(h, o){
1746
var task = new Ext.util.DelayedTask(h);
1748
// create new event object impl so new events don't wipe out properties
1749
task.delay(o.buffer, h, null, [new Ext.EventObjectImpl(e)]);
1753
function createSingle(h, el, ename, fn, scope){
1755
Ext.EventManager.removeListener(el, ename, fn, scope);
1760
function createDelayed(h, o){
1762
// create new event object impl so new events don't wipe out properties
1763
e = new Ext.EventObjectImpl(e);
1764
setTimeout(function(){
1770
function listen(element, ename, opt, fn, scope){
1771
var o = !Ext.isObject(opt) ? {} : opt,
1772
el = Ext.getDom(element);
1775
scope = scope || o.scope;
1778
throw "Error listening for \"" + ename + '\". Element "' + element + '" doesn\'t exist.';
1781
// prevent errors while unload occurring
1782
if(!Ext){// !window[xname]){ ==> can't we do this?
1785
e = Ext.EventObject.setEvent(e);
1788
if(!(t = e.getTarget(o.delegate, el))){
1797
if (o.preventDefault) {
1800
if (o.stopPropagation) {
1801
e.stopPropagation();
1807
fn.call(scope || el, e, t, o);
1810
h = createTargeted(h, o);
1813
h = createDelayed(h, o);
1816
h = createSingle(h, el, ename, fn, scope);
1819
h = createBuffered(h, o);
1822
addListener(el, ename, fn, h, scope);
1828
addListener : function(element, eventName, fn, scope, options){
1829
if(Ext.isObject(eventName)){
1830
var o = eventName, e, val;
1833
if(!propRe.test(e)){
1834
if(Ext.isFunction(val)){
1836
listen(element, e, o, val, o.scope);
1838
// individual options
1839
listen(element, e, val);
1844
listen(element, eventName, options, fn, scope);
1849
removeListener : function(element, eventName, fn, scope){
1850
var el = Ext.getDom(element),
1854
Ext.each((elHash[id] || {})[eventName], function (v,i,a) {
1855
if (Ext.isArray(v) && v[0] == fn && (!scope || v[2] == scope)) {
1856
E.un(el, eventName, wrap = v[1]);
1862
// jQuery workaround that should be removed from Ext Core
1863
if(eventName == "mousewheel" && el.addEventListener && wrap){
1864
el.removeEventListener("DOMMouseScroll", wrap, false);
1867
if(eventName == "mousedown" && el == DOC && wrap){ // fix stopped mousedowns on the document
1868
Ext.EventManager.stoppedMouseDownEvent.removeListener(wrap);
1873
removeAll : function(el){
1874
var id = Ext.id(el = Ext.getDom(el)),
1879
if(es.hasOwnProperty(ename)){
1880
Ext.each(es[ename], function(v) {
1881
E.un(el, ename, v.wrap);
1889
onDocumentReady : function(fn, scope, options){
1890
if(docReadyState){ // if it already fired
1891
docReadyEvent.addListener(fn, scope, options);
1892
docReadyEvent.fire();
1893
docReadyEvent.clearListeners();
1895
if(!docReadyEvent) initDocReady();
1896
options = options || {};
1897
options.delay = options.delay || 1;
1898
docReadyEvent.addListener(fn, scope, options);
1905
pub.on = pub.addListener;
1907
pub.un = pub.removeListener;
1909
pub.stoppedMouseDownEvent = new Ext.util.Event();
1913
Ext.onReady = Ext.EventManager.onDocumentReady;
1916
//Initialize doc classes
1919
var initExtCss = function(){
1920
// find the body element
1921
var bd = document.body || document.getElementsByTagName('body')[0];
1922
if(!bd){ return false; }
1924
Ext.isIE ? "ext-ie " + (Ext.isIE6 ? 'ext-ie6' : (Ext.isIE7 ? 'ext-ie7' : 'ext-ie8'))
1925
: Ext.isGecko ? "ext-gecko " + (Ext.isGecko2 ? 'ext-gecko2' : 'ext-gecko3')
1926
: Ext.isOpera ? "ext-opera"
1927
: Ext.isWebKit ? "ext-webkit" : ""];
1930
cls.push("ext-safari " + (Ext.isSafari2 ? 'ext-safari2' : (Ext.isSafari3 ? 'ext-safari3' : 'ext-safari4')));
1931
}else if(Ext.isChrome){
1932
cls.push("ext-chrome");
1936
cls.push("ext-mac");
1939
cls.push("ext-linux");
1941
if(Ext.isBorderBox){
1942
cls.push('ext-border-box');
1944
if(Ext.isStrict){ // add to the parent to allow for selectors like ".ext-strict .ext-ie"
1945
var p = bd.parentNode;
1947
p.className += ' ext-strict';
1950
bd.className += cls.join(' ');
1955
Ext.onReady(initExtCss);
1961
Ext.EventObject = function(){
1962
var E = Ext.lib.Event,
1963
// safari keypress events for special keys return bad keycodes
1967
63235 : 39, // right
1970
63276 : 33, // page up
1971
63277 : 34, // page down
1972
63272 : 46, // delete
1976
// normalize button clicks
1977
btnMap = Ext.isIE ? {1:0,4:1,2:2} :
1978
(Ext.isWebKit ? {1:0,2:1,3:2} : {0:0,1:1,2:2});
1980
Ext.EventObjectImpl = function(e){
1982
this.setEvent(e.browserEvent || e);
1986
Ext.EventObjectImpl.prototype = {
1988
setEvent : function(e){
1990
if(e == me || (e && e.browserEvent)){ // already wrapped
1993
me.browserEvent = e;
1995
// normalize buttons
1996
me.button = e.button ? btnMap[e.button] : (e.which ? e.which - 1 : -1);
1997
if(e.type == 'click' && me.button == -1){
2001
me.shiftKey = e.shiftKey;
2002
// mac metaKey behaves like ctrlKey
2003
me.ctrlKey = e.ctrlKey || e.metaKey;
2004
me.altKey = e.altKey;
2005
// in getKey these will be normalized for the mac
2006
me.keyCode = e.keyCode;
2007
me.charCode = e.charCode;
2008
// cache the target for the delayed and or buffered events
2009
me.target = E.getTarget(e);
2014
me.shiftKey = false;
2026
stopEvent : function(){
2028
if(me.browserEvent){
2029
if(me.browserEvent.type == 'mousedown'){
2030
Ext.EventManager.stoppedMouseDownEvent.fire(me);
2032
E.stopEvent(me.browserEvent);
2037
preventDefault : function(){
2038
if(this.browserEvent){
2039
E.preventDefault(this.browserEvent);
2044
stopPropagation : function(){
2046
if(me.browserEvent){
2047
if(me.browserEvent.type == 'mousedown'){
2048
Ext.EventManager.stoppedMouseDownEvent.fire(me);
2050
E.stopPropagation(me.browserEvent);
2055
getCharCode : function(){
2056
return this.charCode || this.keyCode;
2060
getKey : function(){
2061
return this.normalizeKey(this.keyCode || this.charCode)
2065
normalizeKey: function(k){
2066
return Ext.isSafari ? (safariKeys[k] || k) : k;
2070
getPageX : function(){
2075
getPageY : function(){
2080
// getTime : function(){
2081
// if(this.browserEvent){
2082
// return E.getTime(this.browserEvent);
2093
getTarget : function(selector, maxDepth, returnEl){
2094
return selector ? Ext.fly(this.target).findParent(selector, maxDepth, returnEl) : (returnEl ? Ext.get(this.target) : this.target);
2098
getRelatedTarget : function(){
2099
return this.browserEvent ? E.getRelatedTarget(this.browserEvent) : null;
2103
getWheelDelta : function(){
2104
var e = this.browserEvent;
2107
delta = e.wheelDelta/120;
2109
delta = -e.detail/3;
2115
within : function(el, related, allowEl){
2117
var t = this[related ? "getRelatedTarget" : "getTarget"]();
2118
return t && ((allowEl ? (t == Ext.getDom(el)) : false) || Ext.fly(el).contains(t));
2124
return new Ext.EventObjectImpl();
2127
Ext.apply(Ext.EventManager, function(){
2134
propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
2138
doResizeEvent: function(){
2139
resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
2143
onWindowResize : function(fn, scope, options){
2145
resizeEvent = new Ext.util.Event();
2146
resizeTask = new Ext.util.DelayedTask(this.doResizeEvent);
2147
E.on(window, "resize", this.fireWindowResize, this);
2149
resizeEvent.addListener(fn, scope, options);
2152
// exposed only to allow manual firing
2153
fireWindowResize : function(){
2155
if((Ext.isIE||Ext.isAir) && resizeTask){
2156
resizeTask.delay(50);
2158
resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
2164
onTextResize : function(fn, scope, options){
2166
textEvent = new Ext.util.Event();
2167
var textEl = new Ext.Element(document.createElement('div'));
2168
textEl.dom.className = 'x-text-resize';
2169
textEl.dom.innerHTML = 'X';
2170
textEl.appendTo(document.body);
2171
textSize = textEl.dom.offsetHeight;
2172
setInterval(function(){
2173
if(textEl.dom.offsetHeight != textSize){
2174
textEvent.fire(textSize, textSize = textEl.dom.offsetHeight);
2176
}, this.textResizeInterval);
2178
textEvent.addListener(fn, scope, options);
2182
removeResizeListener : function(fn, scope){
2184
resizeEvent.removeListener(fn, scope);
2189
fireResize : function(){
2191
resizeEvent.fire(D.getViewWidth(), D.getViewHeight());
2196
textResizeInterval : 50,
2203
Ext.EventManager.on = Ext.EventManager.addListener;
2206
Ext.apply(Ext.EventObjectImpl.prototype, {
2221
CONTROL : 17, // legacy
2234
PAGEUP : 33, // legacy
2237
PAGEDOWN : 34, // legacy
2386
isNavKeyPress : function(){
2388
k = this.normalizeKey(me.keyCode);
2389
return (k >= 33 && k <= 40) || // Page Up/Down, End, Home, Left, Up, Right, Down
2395
isSpecialKey : function(){
2396
var k = this.normalizeKey(this.keyCode);
2397
return (this.type == 'keypress' && this.ctrlKey) ||
2398
this.isNavKeyPress() ||
2399
(k == this.BACKSPACE) || // Backspace
2400
(k >= 16 && k <= 20) || // Shift, Ctrl, Alt, Pause, Caps Lock
2401
(k >= 44 && k <= 45); // Print Screen, Insert
2404
getPoint : function(){
2405
return new Ext.lib.Point(this.xy[0], this.xy[1]);
2409
hasModifier : function(){
2410
return ((this.ctrlKey || this.altKey) || this.shiftKey);
2417
Ext.Element = function(element, forceNew){
2418
var dom = typeof element == "string" ?
2419
DOC.getElementById(element) : element,
2422
if(!dom) return null;
2426
if(!forceNew && id && Ext.Element.cache[id]){ // element object already exists
2427
return Ext.Element.cache[id];
2434
this.id = id || Ext.id(dom);
2437
var D = Ext.lib.Dom,
2445
set : function(o, useSet){
2452
if (attr != "style" && !Ext.isFunction(val)) {
2453
if (attr == "cls" ) {
2455
} else if (o.hasOwnProperty(attr)) {
2456
if (useSet || !!el.setAttribute) el.setAttribute(attr, val);
2457
else el[attr] = val;
2462
Ext.DomHelper.applyStyles(el, o.style);
2484
// HTML frame/object events
2500
// User Interface events
2505
// DOM Mutation events
2518
is : function(simpleSelector){
2519
return Ext.DomQuery.is(this.dom, simpleSelector);
2523
focus : function(defer, dom) {
2525
dom = dom || me.dom;
2528
me.focus.defer(defer, null, [null, dom]);
2545
getValue : function(asNumber){
2546
var val = this.dom.value;
2547
return asNumber ? parseInt(val, 10) : val;
2551
addListener : function(eventName, fn, scope, options){
2552
Ext.EventManager.on(this.dom, eventName, fn, scope || this, options);
2557
removeListener : function(eventName, fn, scope){
2558
Ext.EventManager.removeListener(this.dom, eventName, fn, scope || this);
2563
removeAllListeners : function(){
2564
Ext.EventManager.removeAll(this.dom);
2569
addUnits : function(size){
2570
if(size === "" || size == "auto" || size === undefined){
2572
} else if(!isNaN(size) || !unitPattern.test(size)){
2573
size = size + (this.defaultUnit || 'px');
2579
load : function(url, params, cb){
2580
Ext.Ajax.request(Ext.apply({
2582
url: url.url || url,
2585
indicatorText: url.indicatorText || ''
2586
}, Ext.isObject(url) ? url : {}));
2591
isBorderBox : function(){
2592
return noBoxAdjust[(this.dom.tagName || "").toLowerCase()] || Ext.isBorderBox;
2596
remove : function(){
2599
me.removeAllListeners();
2600
delete El.cache[me.dom.id];
2601
Ext.removeNode(me.dom);
2605
hover : function(overFn, outFn, scope, options){
2607
me.on('mouseenter', overFn, scope || me.dom, options);
2608
me.on('mouseleave', outFn, scope || me.dom, options);
2613
contains : function(el){
2614
return !el ? false : Ext.lib.Dom.isAncestor(this.dom, el.dom ? el.dom : el);
2618
getAttributeNS : function(ns, name){
2619
return this.getAttribute(name, ns);
2623
getAttribute : Ext.isIE ? function(name, ns){
2625
type = typeof d[ns + ":" + name];
2627
if(!Ext.isEmpty(type) && type != 'unknown'){
2628
return d[ns + ":" + name];
2631
} : function(name, ns){
2633
return d.getAttributeNS(ns, name) || d.getAttribute(ns + ":" + name) || d.getAttribute(name) || d[name];
2636
update : function(html) {
2637
this.dom.innerHTML = html;
2641
var ep = El.prototype;
2643
El.addMethods = function(o){
2648
ep.on = ep.addListener;
2651
ep.un = ep.removeListener;
2654
ep.autoBoxAdjust = true;
2657
var unitPattern = /\d+(px|em|%|en|ex|pt|in|cm|mm|pc)$/i,
2664
El.get = function(el){
2668
if(!el){ return null; }
2669
if (typeof el == "string") { // element id
2670
if (!(elm = DOC.getElementById(el))) {
2673
if (ex = El.cache[el]) {
2676
ex = El.cache[el] = new El(elm);
2679
} else if (el.tagName) { // dom element
2683
if(ex = El.cache[id]){
2686
ex = El.cache[id] = new El(el);
2689
} else if (el instanceof El) {
2691
el.dom = DOC.getElementById(el.id) || el.dom; // refresh dom element in case no longer valid,
2692
// catch case where it hasn't been appended
2693
El.cache[el.id] = el; // in case it was created directly with Element(), let's cache it
2696
} else if(el.isComposite) {
2698
} else if(Ext.isArray(el)) {
2699
return El.select(el);
2700
} else if(el == DOC) {
2701
// create a bogus element object representing the document object
2703
var f = function(){};
2704
f.prototype = El.prototype;
2714
// Garbage collection - uncache elements/purge listeners on orphaned elements
2715
// so we don't hold a reference and cause the browser to retain them
2716
function garbageCollect(){
2717
if(!Ext.enableGarbageCollector){
2718
clearInterval(El.collectorThread);
2724
for(eid in El.cache){
2727
// -------------------------------------------------------
2728
// Determining what is garbage:
2729
// -------------------------------------------------------
2731
// dom node is null, definitely garbage
2732
// -------------------------------------------------------
2734
// no parentNode == direct orphan, definitely garbage
2735
// -------------------------------------------------------
2736
// !d.offsetParent && !document.getElementById(eid)
2737
// display none elements have no offsetParent so we will
2738
// also try to look it up by it's id. However, check
2739
// offsetParent first so we don't do unneeded lookups.
2740
// This enables collection of elements that are not orphans
2741
// directly, but somewhere up the line they have an orphan
2743
// -------------------------------------------------------
2744
if(!d || !d.parentNode || (!d.offsetParent && !DOC.getElementById(eid))){
2745
delete El.cache[eid];
2746
if(d && Ext.enableListenerCollection){
2747
Ext.EventManager.removeAll(d);
2753
El.collectorThreadId = setInterval(garbageCollect, 30000);
2755
var flyFn = function(){};
2756
flyFn.prototype = El.prototype;
2759
El.Flyweight = function(dom){
2763
El.Flyweight.prototype = new flyFn();
2764
El.Flyweight.prototype.isFlyweight = true;
2765
El._flyweights = {};
2768
El.fly = function(el, named){
2770
named = named || '_global';
2772
if (el = Ext.getDom(el)) {
2773
(El._flyweights[named] = El._flyweights[named] || new El.Flyweight()).dom = el;
2774
ret = El._flyweights[named];
2785
// speedy lookup for elements never to box adjust
2786
var noBoxAdjust = Ext.isStrict ? {
2789
input:1, select:1, textarea:1
2791
if(Ext.isIE || Ext.isGecko){
2792
noBoxAdjust['button'] = 1;
2796
Ext.EventManager.on(window, 'unload', function(){
2798
delete El._flyweights;
2803
Ext.Element.addMethods({
2805
swallowEvent : function(eventName, preventDefault){
2808
e.stopPropagation();
2813
if(Ext.isArray(eventName)){
2814
Ext.each(eventName, function(e) {
2819
me.on(eventName, fn);
2824
relayEvent : function(eventName, observable){
2825
this.on(eventName, function(e){
2826
observable.fireEvent(eventName, e);
2831
clean : function(forceReclean){
2833
n = me.dom.firstChild,
2836
if(me.isCleaned && forceReclean !== true){
2841
var nx = n.nextSibling;
2842
n.nodeType == 3 && !/\S/.test(n.nodeValue) ? me.dom.removeChild(n) : n.nodeIndex = ++ni;
2845
me.isCleaned = true;
2851
var um = this.getUpdater();
2852
um.update.apply(um, arguments);
2857
getUpdater : function(){
2858
return this.updateManager || (this.updateManager = new Ext.Updater(this));
2862
update : function(html, loadScripts, callback){
2865
if(loadScripts !== true){
2866
this.dom.innerHTML = html;
2867
if(Ext.isFunction(callback)){
2876
html += '<span id="' + id + '"></span>';
2878
Ext.lib.Event.onAvailable(id, function(){
2880
hd = DOC.getElementsByTagName("head")[0],
2881
re = /(?:<script([^>]*)?>)((\n|\r|.)*?)(?:<\/script>)/ig,
2882
srcRe = /\ssrc=([\'\"])(.*?)\1/i,
2883
typeRe = /\stype=([\'\"])(.*?)\1/i,
2891
while(match = re.exec(html)){
2893
srcMatch = attrs ? attrs.match(srcRe) : false;
2894
if(srcMatch && srcMatch[2]){
2895
s = DOC.createElement("script");
2896
s.src = srcMatch[2];
2897
typeMatch = attrs.match(typeRe);
2898
if(typeMatch && typeMatch[2]){
2899
s.type = typeMatch[2];
2902
}else if(match[2] && match[2].length > 0){
2903
if(window.execScript) {
2904
window.execScript(match[2]);
2906
window.eval(match[2]);
2910
el = DOC.getElementById(id);
2911
if(el){Ext.removeNode(el);}
2912
if(Ext.isFunction(callback)){
2916
dom.innerHTML = html.replace(/(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig, "");
2921
createProxy : function(config, renderTo, matchBox){
2922
config = Ext.isObject(config) ? config : {tag : "div", cls: config};
2925
proxy = renderTo ? Ext.DomHelper.append(renderTo, config, true) :
2926
Ext.DomHelper.insertBefore(me.dom, config, true);
2928
if(matchBox && me.setBox && me.getBox){ // check to make sure Element.position.js is loaded
2929
proxy.setBox(me.getBox());
2935
Ext.Element.prototype.getUpdateManager = Ext.Element.prototype.getUpdater;
2938
Ext.Element.uncache = function(el){
2939
for(var i = 0, a = arguments, len = a.length; i < len; i++) {
2941
delete Ext.Element.cache[a[i].id || a[i]];
2946
Ext.Element.addMethods({
2948
getAnchorXY : function(anchor, local, s){
2949
//Passing a different size is useful for pre-calculating anchors,
2950
//especially for anchored animations that change the el size.
2951
anchor = (anchor || "tl").toLowerCase();
2955
vp = me.dom == document.body || me.dom == document,
2956
w = s.width || vp ? Ext.lib.Dom.getViewWidth() : me.getWidth(),
2957
h = s.height || vp ? Ext.lib.Dom.getViewHeight() : me.getHeight(),
2961
scroll = me.getScroll(),
2962
extraX = vp ? scroll.left : !local ? o[0] : 0,
2963
extraY = vp ? scroll.top : !local ? o[1] : 0,
2965
c : [r(w * .5), r(h * .5)],
2977
return [xy[0] + extraX, xy[1] + extraY];
2981
anchorTo : function(el, alignment, offsets, animate, monitorScroll, callback){
2985
this.alignTo(el, alignment, offsets, animate);
2986
Ext.callback(callback, this);
2989
Ext.EventManager.onWindowResize(action, me);
2991
if(!Ext.isEmpty(monitorScroll)){
2992
Ext.EventManager.on(window, 'scroll', action, me,
2993
{buffer: !isNaN(monitorScroll) ? monitorScroll : 50});
2995
action.call(me); // align immediately
3000
getAlignToXY : function(el, p, o){
3004
throw "Element.alignToXY with an element that doesn't exist";
3008
p = (p == "?" ? "tl-bl?" : (!/-/.test(p) && p != "" ? "tl-" + p : p || "tl-bl")).toLowerCase();;
3016
//constrain the aligned el to viewport if necessary
3020
dw = Ext.lib.Dom.getViewWidth() -10, // 10px of margin for ie
3021
dh = Ext.lib.Dom.getViewHeight()-10, // 10px of margin for ie
3029
docElement = doc.documentElement,
3031
scrollX = (docElement.scrollLeft || docBody.scrollLeft || 0)+5,
3032
scrollY = (docElement.scrollTop || docBody.scrollTop || 0)+5,
3033
c = false, //constrain to viewport
3036
m = p.match(/^([a-z]+)-([a-z]+)(\?)?$/)
3039
throw "Element.alignTo with an invalid alignment " + p;
3046
//Subtract the aligned el's internal xy from the target's offset xy
3047
//plus custom offset to get the aligned el's new offset xy
3048
a1 = me.getAnchorXY(p1, true);
3049
a2 = el.getAnchorXY(p2, false);
3051
x = a2[0] - a1[0] + o[0];
3052
y = a2[1] - a1[1] + o[1];
3058
//If we are at a viewport boundary and the aligned el is anchored on a target border that is
3059
//perpendicular to the vp border, allow the aligned el to slide on that border,
3060
//otherwise swap the aligned el to the opposite border of the target.
3062
p1x = p1.charAt(p1.length-1);
3064
p2x = p2.charAt(p2.length-1);
3065
swapY = ((p1y=="t" && p2y=="b") || (p1y=="b" && p2y=="t"));
3066
swapX = ((p1x=="r" && p2x=="l") || (p1x=="l" && p2x=="r"));
3069
if (x + w > dw + scrollX) {
3070
x = swapX ? r.left-w : dw+scrollX-w;
3073
x = swapX ? r.right : scrollX;
3075
if (y + h > dh + scrollY) {
3076
y = swapY ? r.top-h : dh+scrollY-h;
3079
y = swapY ? r.bottom : scrollY;
3086
alignTo : function(element, position, offsets, animate){
3088
return me.setXY(me.getAlignToXY(element, position, offsets),
3089
me.preanim && !!animate ? me.preanim(arguments, 3) : false);
3092
// private ==> used outside of core
3093
adjustForConstraints : function(xy, parent, offsets){
3094
return this.getConstrainToXY(parent || document, false, offsets, xy) || xy;
3097
// private ==> used outside of core
3098
getConstrainToXY : function(el, local, offsets, proposedXY){
3099
var os = {top:0, left:0, bottom:0, right: 0};
3101
return function(el, local, offsets, proposedXY){
3103
offsets = offsets ? Ext.applyIf(offsets, os) : os;
3105
var vw, vh, vx = 0, vy = 0;
3106
if(el.dom == document.body || el.dom == document){
3107
vw =Ext.lib.Dom.getViewWidth();
3108
vh = Ext.lib.Dom.getViewHeight();
3110
vw = el.dom.clientWidth;
3111
vh = el.dom.clientHeight;
3113
var vxy = el.getXY();
3119
var s = el.getScroll();
3121
vx += offsets.left + s.left;
3122
vy += offsets.top + s.top;
3124
vw -= offsets.right;
3125
vh -= offsets.bottom;
3130
var xy = proposedXY || (!local ? this.getXY() : [this.getLeft(true), this.getTop(true)]);
3131
var x = xy[0], y = xy[1];
3132
var w = this.dom.offsetWidth, h = this.dom.offsetHeight;
3134
// only move it if it needs it
3137
// first validate right/bottom
3146
// then make sure top/left isn't negative
3155
return moved ? [x, y] : false;
3161
// el = Ext.get(el);
3162
// offsets = Ext.applyIf(offsets || {}, {top : 0, left : 0, bottom : 0, right : 0});
3166
// s = el.getScroll(),
3167
// vxy = el.getXY(),
3168
// vx = offsets.left + s.left,
3169
// vy = offsets.top + s.top,
3170
// vw = -offsets.right,
3171
// vh = -offsets.bottom,
3174
// xy = proposedXY || (!local ? me.getXY() : [me.getLeft(true), me.getTop(true)]),
3177
// w = me.dom.offsetWidth, h = me.dom.offsetHeight,
3178
// moved = false; // only move it if it needs it
3181
// if(el.dom == doc.body || el.dom == doc){
3182
// vw += Ext.lib.Dom.getViewWidth();
3183
// vh += Ext.lib.Dom.getViewHeight();
3185
// vw += el.dom.clientWidth;
3186
// vh += el.dom.clientHeight;
3193
// // first validate right/bottom
3194
// if(x + w > vx + vw){
3198
// if(y + h > vy + vh){
3202
// // then make sure top/left isn't negative
3211
// return moved ? [x, y] : false;
3215
getCenterXY : function(){
3216
return this.getAlignToXY(document, 'c-c');
3220
center : function(centerIn){
3221
return this.alignTo(centerIn || document, 'c-c');
3226
Ext.Element.addMethods(function(){
3227
var PARENTNODE = 'parentNode',
3228
NEXTSIBLING = 'nextSibling',
3229
PREVIOUSSIBLING = 'previousSibling',
3235
findParent : function(simpleSelector, maxDepth, returnEl){
3240
if(Ext.isGecko && Object.prototype.toString.call(p) == '[object XULElement]') {
3243
maxDepth = maxDepth || 50;
3244
if (isNaN(maxDepth)) {
3245
stopEl = Ext.getDom(maxDepth);
3248
while(p && p.nodeType == 1 && depth < maxDepth && p != b && p != stopEl){
3249
if(DQ.is(p, simpleSelector)){
3250
return returnEl ? GET(p) : p;
3259
findParentNode : function(simpleSelector, maxDepth, returnEl){
3260
var p = Ext.fly(this.dom.parentNode, '_internal');
3261
return p ? p.findParent(simpleSelector, maxDepth, returnEl) : null;
3265
up : function(simpleSelector, maxDepth){
3266
return this.findParentNode(simpleSelector, maxDepth, true);
3270
select : function(selector, unique){
3271
return Ext.Element.select(selector, unique, this.dom);
3275
query : function(selector, unique){
3276
return DQ.select(selector, this.dom);
3280
child : function(selector, returnDom){
3281
var n = DQ.selectNode(selector, this.dom);
3282
return returnDom ? n : GET(n);
3286
down : function(selector, returnDom){
3287
var n = DQ.selectNode(" > " + selector, this.dom);
3288
return returnDom ? n : GET(n);
3292
parent : function(selector, returnDom){
3293
return this.matchNode(PARENTNODE, PARENTNODE, selector, returnDom);
3297
next : function(selector, returnDom){
3298
return this.matchNode(NEXTSIBLING, NEXTSIBLING, selector, returnDom);
3302
prev : function(selector, returnDom){
3303
return this.matchNode(PREVIOUSSIBLING, PREVIOUSSIBLING, selector, returnDom);
3308
first : function(selector, returnDom){
3309
return this.matchNode(NEXTSIBLING, 'firstChild', selector, returnDom);
3313
last : function(selector, returnDom){
3314
return this.matchNode(PREVIOUSSIBLING, 'lastChild', selector, returnDom);
3317
matchNode : function(dir, start, selector, returnDom){
3318
var n = this.dom[start];
3320
if(n.nodeType == 1 && (!selector || DQ.is(n, selector))){
3321
return !returnDom ? GET(n) : n;
3330
Ext.Element.addMethods(
3332
var GETDOM = Ext.getDom,
3335
isEl = function(el){
3336
return (el.nodeType || el.dom || typeof el == 'string');
3341
appendChild: function(el){
3342
return GET(el).appendTo(this);
3346
appendTo: function(el){
3347
GETDOM(el).appendChild(this.dom);
3352
insertBefore: function(el){
3353
(el = GETDOM(el)).parentNode.insertBefore(this.dom, el);
3358
insertAfter: function(el){
3359
(el = GETDOM(el)).parentNode.insertBefore(this.dom, el.nextSibling);
3364
insertFirst: function(el, returnDom){
3366
if(isEl(el)){ // element
3368
this.dom.insertBefore(el, this.dom.firstChild);
3369
return !returnDom ? GET(el) : el;
3371
return this.createChild(el, this.dom.firstChild, returnDom);
3376
replace: function(el){
3378
this.insertBefore(el);
3384
replaceWith: function(el){
3386
Element = Ext.Element;
3389
me.dom.parentNode.insertBefore(el, me.dom);
3391
el = DH.insertBefore(me.dom, el);
3394
delete Element.cache[me.id];
3395
Ext.removeNode(me.dom);
3396
me.id = Ext.id(me.dom = el);
3397
return Element.cache[me.id] = me;
3401
createChild: function(config, insertBefore, returnDom){
3402
config = config || {tag:'div'};
3403
return insertBefore ?
3404
DH.insertBefore(insertBefore, config, returnDom !== true) :
3405
DH[!this.dom.firstChild ? 'overwrite' : 'append'](this.dom, config, returnDom !== true);
3409
wrap: function(config, returnDom){
3410
var newEl = DH.insertBefore(this.dom, config || {tag: "div"}, !returnDom);
3411
newEl.dom ? newEl.dom.appendChild(this.dom) : newEl.appendChild(this.dom);
3416
insertHtml : function(where, html, returnEl){
3417
var el = DH.insertHtml(where, this.dom, html);
3418
return returnEl ? Ext.get(el) : el;
3423
Ext.apply(Ext.Element.prototype, function() {
3424
var GETDOM = Ext.getDom,
3430
insertSibling: function(el, where, returnDom){
3434
if(Ext.isArray(el)){
3435
Ext.each(el, function(e) {
3436
rt = me.insertSibling(e, where, returnDom);
3441
where = (where || 'before').toLowerCase();
3444
if(el.nodeType || el.dom){
3445
rt = me.dom.parentNode.insertBefore(GETDOM(el), where == 'before' ? me.dom : me.dom.nextSibling);
3450
if (where == 'after' && !me.dom.nextSibling) {
3451
rt = DH.append(me.dom.parentNode, el, !returnDom);
3453
rt = DH[where == 'after' ? 'insertAfter' : 'insertBefore'](me.dom, el, !returnDom);
3461
Ext.Element.addMethods(function(){
3462
// local style camelizing for speed
3464
camelRe = /(-[a-z])/gi,
3466
view = document.defaultView,
3467
propFloat = Ext.isIE ? 'styleFloat' : 'cssFloat',
3468
opacityRe = /alpha\(opacity=(.*)\)/i,
3470
PADDING = "padding",
3478
// special markup used throughout Ext when box wrapping elements
3479
borders = {l: BORDER + LEFT + WIDTH, r: BORDER + RIGHT + WIDTH, t: BORDER + TOP + WIDTH, b: BORDER + BOTTOM + WIDTH},
3480
paddings = {l: PADDING + LEFT, r: PADDING + RIGHT, t: PADDING + TOP, b: PADDING + BOTTOM},
3481
margins = {l: MARGIN + LEFT, r: MARGIN + RIGHT, t: MARGIN + TOP, b: MARGIN + BOTTOM};
3485
function camelFn(m, a) {
3486
return a.charAt(1).toUpperCase();
3489
// private (needs to be called => addStyles.call(this, sides, styles))
3490
function addStyles(sides, styles){
3493
Ext.each(sides.match(/\w/g), function(s) {
3494
if (s = parseInt(this.getStyle(styles[s]), 10)) {
3502
function chkCache(prop) {
3503
return propCache[prop] || (propCache[prop] = prop == 'float' ? propFloat : prop.replace(camelRe, camelFn));
3508
// private ==> used by Fx
3509
adjustWidth : function(width) {
3511
if(typeof width == "number" && me.autoBoxAdjust && !me.isBorderBox()){
3512
width -= (me.getBorderWidth("lr") + me.getPadding("lr"));
3513
width = width < 0 ? 0 : width;
3518
// private ==> used by Fx
3519
adjustHeight : function(height) {
3521
if(typeof height == "number" && me.autoBoxAdjust && !me.isBorderBox()){
3522
height -= (me.getBorderWidth("tb") + me.getPadding("tb"));
3523
height = height < 0 ? 0 : height;
3530
addClass : function(className){
3532
Ext.each(className, function(v) {
3533
me.dom.className += (!me.hasClass(v) && v ? " " + v : "");
3539
radioClass : function(className){
3540
Ext.each(this.dom.parentNode.childNodes, function(v) {
3541
if(v.nodeType == 1) {
3542
Ext.fly(v).removeClass(className);
3545
return this.addClass(className);
3549
removeClass : function(className){
3551
if (me.dom.className) {
3552
Ext.each(className, function(v) {
3553
me.dom.className = me.dom.className.replace(
3554
classReCache[v] = classReCache[v] || new RegExp('(?:^|\\s+)' + v + '(?:\\s+|$)', "g"),
3562
toggleClass : function(className){
3563
return this.hasClass(className) ? this.removeClass(className) : this.addClass(className);
3567
hasClass : function(className){
3568
return className && (' '+this.dom.className+' ').indexOf(' '+className+' ') != -1;
3572
replaceClass : function(oldClassName, newClassName){
3573
return this.removeClass(oldClassName).addClass(newClassName);
3576
isStyle : function(style, val) {
3577
return this.getStyle(style) == val;
3581
getStyle : function(){
3582
return view && view.getComputedStyle ?
3587
if(el == document) return null;
3588
prop = chkCache(prop);
3589
return (v = el.style[prop]) ? v :
3590
(cs = view.getComputedStyle(el, "")) ? cs[prop] : null;
3597
if(el == document) return null;
3598
if (prop == 'opacity') {
3599
if (el.style.filter.match) {
3600
if(m = el.style.filter.match(opacityRe)){
3601
var fv = parseFloat(m[1]);
3603
return fv ? fv / 100 : 0;
3609
prop = chkCache(prop);
3610
return el.style[prop] || ((cs = el.currentStyle) ? cs[prop] : null);
3615
getColor : function(attr, defaultValue, prefix){
3617
v = this.getStyle(attr),
3618
color = prefix || "#";
3620
if(!v || v == "transparent" || v == "inherit") {
3621
return defaultValue;
3624
Ext.each(v.slice(4, v.length -1).split(","), function(s) {
3625
h = (s * 1).toString(16);
3626
color += h < 16 ? "0" + h : h;
3629
color += v.replace("#","").replace(/^(\w)(\w)(\w)$/, "$1$1$2$2$3$3");
3631
return color.length > 5 ? color.toLowerCase() : defaultValue;
3635
setStyle : function(prop, value){
3639
if (!Ext.isObject(prop)) {
3644
for (style in prop) {
3645
value = prop[style];
3646
style == 'opacity' ?
3647
this.setOpacity(value) :
3648
this.dom.style[chkCache(style)] = value;
3654
setOpacity : function(opacity, animate){
3657
if(!animate || !me.anim){
3660
s.filter = (s.filter || '').replace(/alpha\([^\)]*\)/gi,"") +
3661
(opacity == 1 ? "" : " alpha(opacity=" + opacity * 100 + ")");
3663
s.opacity = opacity;
3666
me.anim({opacity: {to: opacity}}, me.preanim(arguments, 1), null, .35, 'easeIn');
3672
clearOpacity : function(){
3673
var style = this.dom.style;
3674
if (window.ActiveXObject) {
3675
if(typeof style.filter == 'string' && (/alpha/i).test(style.filter)){
3680
style["-moz-opacity"] = "";
3681
style["-khtml-opacity"] = "";
3687
getHeight : function(contentHeight){
3688
var h = this.dom.offsetHeight || 0;
3689
h = !contentHeight ? h : h - this.getBorderWidth("tb") - this.getPadding("tb");
3690
return h < 0 ? 0 : h;
3694
getWidth : function(contentWidth){
3695
var w = this.dom.offsetWidth || 0;
3696
w = !contentWidth ? w : w - this.getBorderWidth("lr") - this.getPadding("lr");
3697
return w < 0 ? 0 : w;
3701
setWidth : function(width, animate){
3703
width = me.adjustWidth(width);
3704
!animate || !me.anim ?
3705
me.dom.style.width = me.addUnits(width) :
3706
me.anim({width : {to : width}}, me.preanim(arguments, 1));
3711
setHeight : function(height, animate){
3713
height = me.adjustHeight(height);
3714
!animate || !me.anim ?
3715
me.dom.style.height = me.addUnits(height) :
3716
me.anim({height : {to : height}}, me.preanim(arguments, 1));
3721
getBorderWidth : function(side){
3722
return addStyles.call(this, side, borders);
3726
getPadding : function(side){
3727
return addStyles.call(this, side, paddings);
3734
me.isClipped = true;
3736
o: me.getStyle("overflow"),
3737
x: me.getStyle("overflow-x"),
3738
y: me.getStyle("overflow-y")
3740
me.setStyle("overflow", "hidden");
3741
me.setStyle("overflow-x", "hidden");
3742
me.setStyle("overflow-y", "hidden");
3748
unclip : function(){
3751
me.isClipped = false;
3752
var o = me.originalClip;
3753
if(o.o){me.setStyle("overflow", o.o);}
3754
if(o.x){me.setStyle("overflow-x", o.x);}
3755
if(o.y){me.setStyle("overflow-y", o.y);}
3760
addStyles : addStyles,
3767
// special markup used throughout Ext when box wrapping elements
3768
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>';
3770
Ext.Element.addMethods(function(){
3771
var INTERNAL = "_internal";
3774
applyStyles : function(style){
3775
Ext.DomHelper.applyStyles(this.dom, style);
3780
getStyles : function(){
3782
Ext.each(arguments, function(v) {
3783
ret[v] = this.getStyle(v);
3789
getStyleSize : function(){
3795
if(s.width && s.width != 'auto'){
3796
w = parseInt(s.width, 10);
3797
if(me.isBorderBox()){
3798
w -= me.getFrameWidth('lr');
3801
if(s.height && s.height != 'auto'){
3802
h = parseInt(s.height, 10);
3803
if(me.isBorderBox()){
3804
h -= me.getFrameWidth('tb');
3807
return {width: w || me.getWidth(true), height: h || me.getHeight(true)};
3810
// private ==> used by ext full
3811
setOverflow : function(v){
3813
if(v=='auto' && Ext.isMac && Ext.isGecko2){ // work around stupid FF 2.0/Mac scroll bar bug
3814
me.dom.style.overflow = 'hidden';
3815
(function(){me.dom.style.overflow = 'auto';}).defer(1, me);
3817
me.dom.style.overflow = v;
3822
boxWrap : function(cls){
3823
cls = cls || 'x-box';
3824
var el = Ext.get(this.insertHtml("beforeBegin", "<div class='" + cls + "'>" + String.format(Ext.Element.boxMarkup, cls) + "</div>")); //String.format('<div class="{0}">'+Ext.Element.boxMarkup+'</div>', cls)));
3825
Ext.DomQuery.selectNode('.' + cls + '-mc', el.dom).appendChild(this.dom);
3830
setSize : function(width, height, animate){
3832
if(typeof width == "object"){ // in case of object from getSize()
3833
height = width.height;
3834
width = width.width;
3836
width = me.adjustWidth(width);
3837
height = me.adjustHeight(height);
3838
if(!animate || !me.anim){
3839
me.dom.style.width = me.addUnits(width);
3840
me.dom.style.height = me.addUnits(height);
3842
me.anim({width: {to: width}, height: {to: height}}, me.preanim(arguments, 2));
3848
getComputedHeight : function(){
3850
h = Math.max(me.dom.offsetHeight, me.dom.clientHeight);
3852
h = parseInt(me.getStyle('height'), 10) || 0;
3853
if(!me.isBorderBox()){
3854
h += me.getFrameWidth('tb');
3861
getComputedWidth : function(){
3862
var w = Math.max(this.dom.offsetWidth, this.dom.clientWidth);
3864
w = parseInt(this.getStyle('width'), 10) || 0;
3865
if(!this.isBorderBox()){
3866
w += this.getFrameWidth('lr');
3873
getFrameWidth : function(sides, onlyContentBox){
3874
return onlyContentBox && this.isBorderBox() ? 0 : (this.getPadding(sides) + this.getBorderWidth(sides));
3878
addClassOnOver : function(className){
3881
Ext.fly(this, INTERNAL).addClass(className);
3884
Ext.fly(this, INTERNAL).removeClass(className);
3891
addClassOnFocus : function(className){
3892
this.on("focus", function(){
3893
Ext.fly(this, INTERNAL).addClass(className);
3895
this.on("blur", function(){
3896
Ext.fly(this, INTERNAL).removeClass(className);
3902
addClassOnClick : function(className){
3904
this.on("mousedown", function(){
3905
Ext.fly(dom, INTERNAL).addClass(className);
3906
var d = Ext.getDoc(),
3908
Ext.fly(dom, INTERNAL).removeClass(className);
3909
d.removeListener("mouseup", fn);
3911
d.on("mouseup", fn);
3917
getViewSize : function(){
3920
extdom = Ext.lib.Dom,
3921
isDoc = (d == doc || d == doc.body);
3922
return { width : (isDoc ? extdom.getViewWidth() : d.clientWidth),
3923
height : (isDoc ? extdom.getViewHeight() : d.clientHeight) };
3927
getSize : function(contentSize){
3928
return {width: this.getWidth(contentSize), height: this.getHeight(contentSize)};
3932
repaint : function(){
3934
this.addClass("x-repaint");
3935
setTimeout(function(){
3936
Ext.get(dom).removeClass("x-repaint");
3942
unselectable : function(){
3943
this.dom.unselectable = "on";
3944
return this.swallowEvent("selectstart", true).
3945
applyStyles("-moz-user-select:none;-khtml-user-select:none;").
3946
addClass("x-unselectable");
3950
getMargins : function(side){
3953
hash = {t:"top", l:"left", r:"right", b: "bottom"},
3957
for (key in me.margins)
3958
o[hash[key]] = parseInt(me.getStyle(me.margins[key]), 10) || 0;
3961
return me.addStyles.call(me, side, me.margins);
3968
var D = Ext.lib.Dom,
3973
POSITION = "position",
3975
RELATIVE = "relative",
3979
function animTest(args, animate, i) {
3980
return this.preanim && !!animate ? this.preanim(args, i) : false
3983
Ext.Element.addMethods({
3986
return D.getX(this.dom);
3991
return D.getY(this.dom);
3996
return D.getXY(this.dom);
4000
getOffsetsTo : function(el){
4001
var o = this.getXY(),
4002
e = Ext.fly(el, '_internal').getXY();
4003
return [o[0]-e[0],o[1]-e[1]];
4007
setX : function(x, animate){
4008
return this.setXY([x, this.getY()], animTest.call(this, arguments, animate, 1));
4012
setY : function(y, animate){
4013
return this.setXY([this.getX(), y], animTest.call(this, arguments, animate, 1));
4017
setLeft : function(left){
4018
this.setStyle(LEFT, this.addUnits(left));
4023
setTop : function(top){
4024
this.setStyle(TOP, this.addUnits(top));
4029
setRight : function(right){
4030
this.setStyle(RIGHT, this.addUnits(right));
4035
setBottom : function(bottom){
4036
this.setStyle(BOTTOM, this.addUnits(bottom));
4041
setXY : function(pos, animate){
4043
if(!animate || !me.anim){
4044
D.setXY(me.dom, pos);
4046
me.anim({points: {to: pos}}, me.preanim(arguments, 1), 'motion');
4052
setLocation : function(x, y, animate){
4053
return this.setXY([x, y], animTest.call(this, arguments, animate, 2));
4057
moveTo : function(x, y, animate){
4058
return this.setXY([x, y], animTest.call(this, arguments, animate, 2));
4062
getLeft : function(local){
4063
return !local ? this.getX() : parseInt(this.getStyle(LEFT), 10) || 0;
4067
getRight : function(local){
4069
return !local ? me.getX() + me.getWidth() : (me.getLeft(true) + me.getWidth()) || 0;
4073
getTop : function(local) {
4074
return !local ? this.getY() : parseInt(this.getStyle(TOP), 10) || 0;
4078
getBottom : function(local){
4080
return !local ? me.getY() + me.getHeight() : (me.getTop(true) + me.getHeight()) || 0;
4084
position : function(pos, zIndex, x, y){
4087
if(!pos && me.isStyle(POSITION, STATIC)){
4088
me.setStyle(POSITION, RELATIVE);
4090
me.setStyle(POSITION, pos);
4093
me.setStyle(ZINDEX, zIndex);
4095
if(x || y) me.setXY([x || false, y || false]);
4099
clearPositioning : function(value){
4100
value = value || '';
4113
getPositioning : function(){
4114
var l = this.getStyle(LEFT);
4115
var t = this.getStyle(TOP);
4117
"position" : this.getStyle(POSITION),
4119
"right" : l ? "" : this.getStyle(RIGHT),
4121
"bottom" : t ? "" : this.getStyle(BOTTOM),
4122
"z-index" : this.getStyle(ZINDEX)
4127
setPositioning : function(pc){
4129
style = me.dom.style;
4133
if(pc.right == AUTO){
4136
if(pc.bottom == AUTO){
4144
translatePoints : function(x, y){
4145
y = isNaN(x[1]) ? y : x[1];
4146
x = isNaN(x[0]) ? x : x[0];
4148
relative = me.isStyle(POSITION, RELATIVE),
4150
l = parseInt(me.getStyle(LEFT), 10),
4151
t = parseInt(me.getStyle(TOP), 10);
4153
l = !isNaN(l) ? l : (relative ? 0 : me.dom.offsetLeft);
4154
t = !isNaN(t) ? t : (relative ? 0 : me.dom.offsetTop);
4156
return {left: (x - o[0] + l), top: (y - o[1] + t)};
4163
Ext.Element.addMethods({
4165
setBox : function(box, adjust, animate){
4169
if((adjust && !me.autoBoxAdjust) && !me.isBorderBox()){
4170
w -= (me.getBorderWidth("lr") + me.getPadding("lr"));
4171
h -= (me.getBorderWidth("tb") + me.getPadding("tb"));
4173
me.setBounds(box.x, box.y, w, h, me.animTest.call(me, arguments, animate, 2));
4178
getBox : function(contentBox, local) {
4183
getBorderWidth = me.getBorderWidth,
4184
getPadding = me.getPadding,
4192
left = parseInt(me.getStyle("left"), 10) || 0;
4193
top = parseInt(me.getStyle("top"), 10) || 0;
4196
var el = me.dom, w = el.offsetWidth, h = el.offsetHeight, bx;
4198
bx = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: w, height: h};
4200
l = getBorderWidth.call(me, "l") + getPadding.call(me, "l");
4201
r = getBorderWidth.call(me, "r") + getPadding.call(me, "r");
4202
t = getBorderWidth.call(me, "t") + getPadding.call(me, "t");
4203
b = getBorderWidth.call(me, "b") + getPadding.call(me, "b");
4204
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)};
4206
bx.right = bx.x + bx.width;
4207
bx.bottom = bx.y + bx.height;
4212
move : function(direction, distance, animate){
4217
left = [x - distance, y],
4218
right = [x + distance, y],
4219
top = [x, y - distance],
4220
bottom = [x, y + distance],
4234
direction = direction.toLowerCase();
4235
me.moveTo(hash[direction][0], hash[direction][1], me.animTest.call(me, arguments, animate, 2));
4239
setLeftTop : function(left, top){
4241
style = me.dom.style;
4242
style.left = me.addUnits(left);
4243
style.top = me.addUnits(top);
4248
getRegion : function(){
4249
return Ext.lib.Dom.getRegion(this.dom);
4253
setBounds : function(x, y, width, height, animate){
4255
if (!animate || !me.anim) {
4256
me.setSize(width, height);
4257
me.setLocation(x, y);
4259
me.anim({points: {to: [x, y]},
4260
width: {to: me.adjustWidth(width)},
4261
height: {to: me.adjustHeight(height)}},
4262
me.preanim(arguments, 4),
4269
setRegion : function(region, animate) {
4270
return this.setBounds(region.left, region.top, region.right-region.left, region.bottom-region.top, this.animTest.call(this, arguments, animate, 1));
4274
Ext.Element.addMethods({
4276
isScrollable : function(){
4278
return dom.scrollHeight > dom.clientHeight || dom.scrollWidth > dom.clientWidth;
4282
scrollTo : function(side, value){
4283
this.dom["scroll" + (/top/i.test(side) ? "Top" : "Left")] = value;
4288
getScroll : function(){
4292
docElement = doc.documentElement,
4297
if(d == doc || d == body){
4298
if(Ext.isIE && Ext.isStrict){
4299
l = docElement.scrollLeft;
4300
t = docElement.scrollTop;
4302
l = window.pageXOffset;
4303
t = window.pageYOffset;
4305
ret = {left: l || (body ? body.scrollLeft : 0), top: t || (body ? body.scrollTop : 0)};
4307
ret = {left: d.scrollLeft, top: d.scrollTop};
4313
Ext.Element.addMethods({
4315
scrollTo : function(side, value, animate){
4316
var tester = /top/i,
4317
prop = "scroll" + (tester.test(side) ? "Top" : "Left"),
4320
if (!animate || !me.anim) {
4323
me.anim({scroll: {to: tester.test(prop) ? [dom[prop], value] : [value, dom[prop]]}},
4324
me.preanim(arguments, 2), 'scroll');
4330
scrollIntoView : function(container, hscroll){
4331
var c = Ext.getDom(container) || Ext.getBody().dom,
4333
o = this.getOffsetsTo(c),
4334
l = o[0] + c.scrollLeft,
4335
t = o[1] + c.scrollTop,
4336
b = t + el.offsetHeight,
4337
r = l + el.offsetWidth,
4338
ch = c.clientHeight,
4339
ct = parseInt(c.scrollTop, 10),
4340
cl = parseInt(c.scrollLeft, 10),
4342
cr = cl + c.clientWidth;
4344
if (el.offsetHeight > ch || t < ct) {
4349
c.scrollTop = c.scrollTop; // corrects IE, other browsers will ignore
4351
if(hscroll !== false){
4352
if(el.offsetWidth > c.clientWidth || l < cl){
4355
c.scrollLeft = r - c.clientWidth;
4357
c.scrollLeft = c.scrollLeft;
4363
scrollChildIntoView : function(child, hscroll){
4364
Ext.fly(child, '_scrollChildIntoView').scrollIntoView(this, hscroll);
4368
scroll : function(direction, distance, animate){
4369
if(!this.isScrollable()){
4373
l = el.scrollLeft, t = el.scrollTop,
4374
w = el.scrollWidth, h = el.scrollHeight,
4375
cw = el.clientWidth, ch = el.clientHeight,
4376
scrolled = false, v,
4378
l: Math.min(l + distance, w-cw),
4379
r: v = Math.max(l - distance, 0),
4380
t: Math.max(t - distance, 0),
4381
b: Math.min(t + distance, h-ch)
4386
direction = direction.substr(0, 1);
4387
if((v = hash[direction]) > -1){
4389
this.scrollTo(direction == 'l' || direction == 'r' ? 'left' : 'top', v, this.preanim(arguments, 2));
4396
Ext.Element.VISIBILITY = 1;
4398
Ext.Element.DISPLAY = 2;
4400
Ext.Element.addMethods(function(){
4401
var VISIBILITY = "visibility",
4402
DISPLAY = "display",
4405
ELDISPLAY = Ext.Element.DISPLAY;
4409
originalDisplay : "",
4413
setVisibilityMode : function(visMode){
4414
this.visibilityMode = visMode;
4419
animate : function(args, duration, onComplete, easing, animType){
4420
this.anim(args, {duration: duration, callback: onComplete, easing: easing}, animType);
4425
anim : function(args, opt, animType, defaultDur, defaultEase, cb){
4426
animType = animType || 'run';
4429
anim = Ext.lib.Anim[animType](
4432
(opt.duration || defaultDur) || .35,
4433
(opt.easing || defaultEase) || 'easeOut',
4436
if(opt.callback) opt.callback.call(opt.scope || me, me, opt);
4444
// private legacy anim prep
4445
preanim : function(a, i){
4446
return !a[i] ? false : (Ext.isObject(a[i]) ? a[i]: {duration: a[i+1], callback: a[i+2], easing: a[i+3]});
4450
isVisible : function() {
4451
return !this.isStyle(VISIBILITY, HIDDEN) && !this.isStyle(DISPLAY, NONE);
4455
setVisible : function(visible, animate){
4458
isDisplay = (me.visibilityMode == ELDISPLAY);
4460
if (!animate || !me.anim) {
4462
me.setDisplayed(visible);
4465
dom.style.visibility = visible ? "visible" : HIDDEN;
4468
// closure for composites
4471
me.setVisible(true);
4473
me.anim({opacity: { to: (visible?1:0) }},
4474
me.preanim(arguments, 1),
4480
dom.style[isDisplay ? DISPLAY : VISIBILITY] = (isDisplay) ? NONE : HIDDEN;
4481
Ext.fly(dom).setOpacity(1);
4489
toggle : function(animate){
4491
me.setVisible(!me.isVisible(), me.preanim(arguments, 0));
4496
setDisplayed : function(value) {
4497
if(typeof value == "boolean"){
4498
value = value ? this.originalDisplay : NONE;
4500
this.setStyle(DISPLAY, value);
4505
fixDisplay : function(){
4507
if(me.isStyle(DISPLAY, NONE)){
4508
me.setStyle(VISIBILITY, HIDDEN);
4509
me.setStyle(DISPLAY, me.originalDisplay); // first try reverting to default
4510
if(me.isStyle(DISPLAY, NONE)){ // if that fails, default to block
4511
me.setStyle(DISPLAY, "block");
4517
hide : function(animate){
4518
this.setVisible(false, this.preanim(arguments, 0));
4523
show : function(animate){
4524
this.setVisible(true, this.preanim(arguments, 0));
4530
Ext.Element.addMethods(
4532
var VISIBILITY = "visibility",
4533
DISPLAY = "display",
4536
XMASKED = "x-masked",
4537
XMASKEDRELATIVE = "x-masked-relative";
4541
isVisible : function(deep) {
4542
var vis = !this.isStyle(VISIBILITY,HIDDEN) && !this.isStyle(DISPLAY,NONE),
4543
p = this.dom.parentNode;
4544
if(deep !== true || !vis){
4547
while(p && !/body/i.test(p.tagName)){
4548
if(!Ext.fly(p, '_isVisible').isVisible()){
4557
isDisplayed : function() {
4558
return !this.isStyle(DISPLAY, NONE);
4562
enableDisplayMode : function(display){
4563
this.setVisibilityMode(Ext.Element.DISPLAY);
4564
if(!Ext.isEmpty(display)) this.originalDisplay = display;
4569
mask : function(msg, msgCls){
4573
EXTELMASKMSG = "ext-el-mask-msg";
4575
if(me.getStyle("position") == "static"){
4576
me.addClass(XMASKEDRELATIVE);
4579
me._maskMsg.remove();
4585
me._mask = dh.append(dom, {cls : "ext-el-mask"}, true);
4587
me.addClass(XMASKED);
4588
me._mask.setDisplayed(true);
4589
if(typeof msg == 'string'){
4590
me._maskMsg = dh.append(dom, {cls : EXTELMASKMSG, cn:{tag:'div'}}, true);
4591
var mm = me._maskMsg;
4592
mm.dom.className = msgCls ? EXTELMASKMSG + " " + msgCls : EXTELMASKMSG;
4593
mm.dom.firstChild.innerHTML = msg;
4594
mm.setDisplayed(true);
4597
if(Ext.isIE && !(Ext.isIE7 && Ext.isStrict) && me.getStyle('height') == 'auto'){ // ie will not expand full height automatically
4598
me._mask.setSize(undefined, me.getHeight());
4604
unmask : function(){
4607
maskMsg = me._maskMsg;
4616
me.removeClass([XMASKED, XMASKEDRELATIVE]);
4620
isMasked : function(){
4621
return this._mask && this._mask.isVisible();
4625
createShim : function(){
4626
var el = document.createElement('iframe'),
4628
el.frameBorder = '0';
4629
el.className = 'ext-shim';
4630
if(Ext.isIE && Ext.isSecure){
4631
el.src = Ext.SSL_SECURE_URL;
4633
shim = Ext.get(this.dom.parentNode.insertBefore(el, this.dom));
4634
shim.autoBoxAdjust = false;
4640
Ext.Element.addMethods({
4642
initDD : function(group, config, overrides){
4643
var dd = new Ext.dd.DD(Ext.id(this.dom), group, config);
4644
return Ext.apply(dd, overrides);
4648
initDDProxy : function(group, config, overrides){
4649
var dd = new Ext.dd.DDProxy(Ext.id(this.dom), group, config);
4650
return Ext.apply(dd, overrides);
4654
initDDTarget : function(group, config, overrides){
4655
var dd = new Ext.dd.DDTarget(Ext.id(this.dom), group, config);
4656
return Ext.apply(dd, overrides);
4660
Ext.Element.addMethods({
4662
autoHeight : function(animate, duration, onComplete, easing){
4663
var oldHeight = this.getHeight();
4665
this.setHeight(1); // force clipping
4666
setTimeout(function(){
4667
var height = parseInt(this.dom.scrollHeight, 10); // parseInt for Safari
4669
this.setHeight(height);
4671
if(typeof onComplete == "function"){
4675
this.setHeight(oldHeight); // restore original height
4676
this.setHeight(height, animate, duration, function(){
4678
if(typeof onComplete == "function") onComplete();
4679
}.createDelegate(this), easing);
4681
}.createDelegate(this), 0);
4686
Ext.Element.addMethods({
4688
addKeyListener : function(key, fn, scope){
4690
if(typeof key != "object" || Ext.isArray(key)){
4706
return new Ext.KeyMap(this, config);
4710
addKeyMap : function(config){
4711
return new Ext.KeyMap(this, config);
4717
UNDEFINED = undefined,
4731
ABSOLUTE = "absolute",
4732
VISIBLE = "visible",
4734
POSITION = "position",
4735
EASEOUT = "easeOut";
4737
//Notifies Element that fx methods are available
4738
Ext.enableFx = TRUE;
4743
// private - calls the function taking arguments from the argHash based on the key. Returns the return value of the function.
4744
// this is useful for replacing switch statements (for example).
4745
switchStatements : function(key, fn, argHash){
4746
return fn.apply(this, argHash[key]);
4750
slideIn : function(anchor, o){
4766
anchor = anchor || "t";
4768
el.queueFx(o, function(){
4771
// fix display to visibility
4774
// restore values after effect
4775
r = me.getFxRestore();
4776
b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
4777
b.right = b.x + b.width;
4778
b.bottom = b.y + b.height;
4780
// fixed size for slide
4781
me.setWidth(b.width).setHeight(b.height);
4784
wrap = me.fxWrap(r.pos, o, HIDDEN);
4786
st.visibility = VISIBLE;
4787
st.position = ABSOLUTE;
4789
// clear out temp styles after slide and unwrap
4791
el.fxUnwrap(wrap, r.pos, o);
4793
st.height = r.height;
4797
// time to calculate the positions
4798
pt = {to: [b.x, b.y]};
4800
bh = {to: b.height};
4802
function argCalc(wrap, style, ww, wh, sXY, sXYval, s1, s2, w, h, p){
4804
wrap.setWidth(ww).setHeight(wh);
4805
if( wrap[sXY] ) wrap[sXY](sXYval);
4806
style[s1] = style[s2] = "0";
4807
if(w) ret.width = w;
4808
if(h) ret.height = h;
4809
if(p) ret.points = p;
4813
args = me.switchStatements(anchor.toLowerCase(), argCalc, {
4814
t : [wrap, st, b.width, 0, NULL, NULL, LEFT, BOTTOM, NULL, bh, NULL],
4815
l : [wrap, st, 0, b.height, NULL, NULL, RIGHT, TOP, bw, NULL, NULL],
4816
r : [wrap, st, b.width, b.height, SETX, b.right, LEFT, TOP, NULL, NULL, pt],
4817
b : [wrap, st, b.width, b.height, SETY, b.bottom, LEFT, TOP, NULL, bh, pt],
4818
tl : [wrap, st, 0, 0, NULL, NULL, RIGHT, BOTTOM, bw, bh, pt],
4819
bl : [wrap, st, 0, 0, SETY, b.y + b.height, RIGHT, TOP, bw, bh, pt],
4820
br : [wrap, st, 0, 0, SETXY, [b.right, b.bottom], LEFT, TOP, bw, bh, pt],
4821
tr : [wrap, st, 0, 0, SETX, b.x + b.width, LEFT, BOTTOM, bw, bh, pt]
4824
st.visibility = VISIBLE;
4827
arguments.callee.anim = wrap.fxanim(args,
4838
slideOut : function(anchor, o){
4851
anchor = anchor || "t";
4853
el.queueFx(o, function(){
4854
// restore values after effect
4855
r = me.getFxRestore();
4856
b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight};
4857
b.right = b.x + b.width;
4858
b.bottom = b.y + b.height;
4860
// fixed size for slide
4861
me.setWidth(b.width).setHeight(b.height);
4864
wrap = me.fxWrap(r.pos, o, VISIBLE);
4867
st.visibility = VISIBLE;
4868
st.position = ABSOLUTE;
4869
wrap.setWidth(b.width).setHeight(b.height);
4872
o.useDisplay ? el.setDisplayed(FALSE) : el.hide();
4873
el.fxUnwrap(wrap, r.pos, o);
4875
st.height = r.height;
4879
function argCalc(style, s1, s2, p1, v1, p2, v2, p3, v3){
4882
style[s1] = style[s2] = "0";
4884
if(p2) ret[p2] = v2;
4885
if(p3) ret[p3] = v3;
4890
a = me.switchStatements(anchor.toLowerCase(), argCalc, {
4891
t : [st, LEFT, BOTTOM, HEIGHT, zero],
4892
l : [st, RIGHT, TOP, WIDTH, zero],
4893
r : [st, LEFT, TOP, WIDTH, zero, POINTS, {to : [b.right, b.y]}],
4894
b : [st, LEFT, TOP, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
4895
tl : [st, RIGHT, BOTTOM, WIDTH, zero, HEIGHT, zero],
4896
bl : [st, RIGHT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x, b.bottom]}],
4897
br : [st, LEFT, TOP, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.x + b.width, b.bottom]}],
4898
tr : [st, LEFT, BOTTOM, WIDTH, zero, HEIGHT, zero, POINTS, {to : [b.right, b.y]}]
4901
arguments.callee.anim = wrap.fxanim(a,
4919
width = me.getWidth(),
4920
height = me.getHeight();
4922
el.queueFx(o, function(){
4926
// restore values after effect
4927
r = me.getFxRestore();
4930
o.useDisplay ? el.setDisplayed(FALSE) : el.hide();
4932
el.setPositioning(r.pos);
4934
st.height = r.height;
4939
arguments.callee.anim = me.fxanim({
4940
width : {to : me.adjustWidth(width * 2)},
4941
height : {to : me.adjustHeight(height * 2)},
4942
points : {by : [-width * .5, -height * .5]},
4944
fontSize: {to : 200, unit: "%"}
4956
switchOff : function(o){
4962
el.queueFx(o, function(){
4966
// restore values after effect
4967
var r = me.getFxRestore(),
4970
o.useDisplay ? el.setDisplayed(FALSE) : el.hide();
4972
el.setPositioning(r.pos);
4974
st.height = r.height;
4978
me.fxanim({opacity : {to : 0.3}},
4988
points : {by : [0, me.getHeight() * .5]}
5002
highlight : function(color, o){
5007
attr = o.attr || "backgroundColor",
5010
el.queueFx(o, function(){
5015
el.dom.style[attr] = me.dom.style[attr];
5019
a[attr] = {from: color || "ffff9c", to: o.endColor || me.getColor(attr) || "ffffff"};
5020
arguments.callee.anim = me.fxanim(a,
5031
frame : function(color, count, o){
5039
el.queueFx(o, function(){
5040
color = color || "#C3DAF9"
5041
if(color.length == 6){
5042
color = "#" + color;
5047
var xy = me.getXY(),
5049
b = {x: xy[0], y: xy[1], 0: xy[0], 1: xy[1], width: dom.offsetWidth, height: dom.offsetHeight},
5052
proxy = Ext.get(document.body || document.documentElement).createChild({
5055
position : ABSOLUTE,
5056
"z-index": 35000, // yee haw
5057
border : "0px solid " + color
5060
return proxy.queueFx({}, animFn);
5064
arguments.callee.anim = {
5073
var scale = Ext.isBorderBox ? 2 : 1;
5074
active = proxy.anim({
5075
top : {from : b.y, to : b.y - 20},
5076
left : {from : b.x, to : b.x - 20},
5077
borderWidth : {from : 0, to : 10},
5078
opacity : {from : 1, to : 0},
5079
height : {from : b.height, to : b.height + 20 * scale},
5080
width : {from : b.width, to : b.width + 20 * scale}
5082
duration: o.duration || 1,
5083
callback: function() {
5085
--count > 0 ? queue() : el.afterFx(o);
5088
arguments.callee.anim = {
5101
pause : function(seconds){
5102
var el = this.getFxEl(),
5105
el.queueFx({}, function(){
5106
t = setTimeout(function(){
5109
arguments.callee.anim = {
5121
fadeIn : function(o){
5126
el.queueFx(o, function(){
5129
me.dom.style.visibility = VISIBLE;
5130
var to = o.endOpacity || 1;
5131
arguments.callee.anim = me.fxanim({opacity:{to:to}},
5132
o, NULL, .5, EASEOUT, function(){
5134
this.clearOpacity();
5143
fadeOut : function(o){
5147
style = me.dom.style,
5149
to = o.endOpacity || 0;
5151
el.queueFx(o, function(){
5152
arguments.callee.anim = me.fxanim({
5153
opacity : {to : to}},
5160
me.visibilityMode == Ext.Element.DISPLAY || o.useDisplay ?
5161
style.display = "none" :
5162
style.visibility = HIDDEN;
5173
scale : function(w, h, o){
5175
me.shift(Ext.apply({}, o, {
5183
shift : function(o){
5187
var el = me.getFxEl();
5188
el.queueFx(o, function(){
5191
for (var prop in o) {
5192
if (o[prop] != UNDEFINED) {
5193
a[prop] = {to : o[prop]};
5197
a.width ? a.width.to = me.adjustWidth(o.width) : a;
5198
a.height ? a.height.to = me.adjustWidth(o.height) : a;
5200
if (a.x || a.y || a.xy) {
5202
{to : [ a.x ? a.x.to : me.getX(),
5203
a.y ? a.y.to : me.getY()]};
5206
arguments.callee.anim = me.fxanim(a,
5219
ghost : function(anchor, o){
5224
anchor = anchor || "b";
5226
el.queueFx(o, function(){
5227
// restore values after effect
5228
var r = me.getFxRestore(),
5234
el.setDisplayed(FALSE);
5240
el.setPositioning(r.pos);
5246
a = {opacity: {to: 0},
5250
pt.by = me.switchStatements(anchor.toLowerCase(), function(v1,v2){ return [v1, v2];}, {
5261
arguments.callee.anim = me.fxanim(a,
5271
syncFx : function(){
5273
me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
5282
sequenceFx : function(){
5284
me.fxDefaults = Ext.apply(me.fxDefaults || {}, {
5293
nextFx : function(){
5294
var ef = this.fxQueue[0];
5301
hasActiveFx : function(){
5302
return this.fxQueue && this.fxQueue[0];
5306
stopFx : function(finish){
5308
if(me.hasActiveFx()){
5309
var cur = me.fxQueue[0];
5310
if(cur && cur.anim){
5311
if(cur.anim.isAnimated){
5312
me.fxQueue = [cur]; // clear out others
5313
cur.anim.stop(finish !== undefined ? finish : TRUE);
5323
beforeFx : function(o){
5324
if(this.hasActiveFx() && !o.concurrent){
5335
hasFxBlock : function(){
5336
var q = this.fxQueue;
5337
return q && q[0] && q[0].block;
5341
queueFx : function(o, fn){
5346
if(!me.hasFxBlock()){
5347
Ext.applyIf(o, me.fxDefaults);
5349
var run = me.beforeFx(o);
5351
me.fxQueue.push(fn);
5363
fxWrap : function(pos, o, vis){
5367
if(!o.wrap || !(wrap = Ext.get(o.wrap))){
5369
wrapXY = me.getXY();
5371
var div = document.createElement("div");
5372
div.style.visibility = vis;
5373
wrap = Ext.get(me.dom.parentNode.insertBefore(div, me.dom));
5374
wrap.setPositioning(pos);
5375
if(wrap.isStyle(POSITION, "static")){
5376
wrap.position("relative");
5378
me.clearPositioning('auto');
5380
wrap.dom.appendChild(me.dom);
5389
fxUnwrap : function(wrap, pos, o){
5391
me.clearPositioning();
5392
me.setPositioning(pos);
5394
wrap.dom.parentNode.insertBefore(me.dom, wrap.dom);
5400
getFxRestore : function(){
5401
var st = this.dom.style;
5402
return {pos: this.getPositioning(), width: st.width, height : st.height};
5406
afterFx : function(o){
5409
me.setStyle(o.afterStyle);
5412
me.addClass(o.afterCls);
5414
if(o.remove == TRUE){
5417
if(o.callback) o.callback.call(o.scope, me);
5425
getFxEl : function(){ // support for composite element fx
5426
return Ext.get(this.dom);
5430
fxanim : function(args, opt, animType, defaultDur, defaultEase, cb){
5431
animType = animType || 'run';
5433
var anim = Ext.lib.Anim[animType](
5436
(opt.duration || defaultDur) || .35,
5437
(opt.easing || defaultEase) || EASEOUT,
5447
Ext.Fx.resize = Ext.Fx.scale;
5449
//When included, Ext.Fx is automatically applied to Element so that all basic
5450
//effects are available directly via the Element API
5451
Ext.Element.addMethods(Ext.Fx);
5454
Ext.CompositeElementLite = function(els, root){
5456
this.add(els, root);
5457
this.el = new Ext.Element.Flyweight();
5460
Ext.CompositeElementLite.prototype = {
5463
getCount : function(){
5464
return this.elements.length;
5466
add : function(els){
5468
if (Ext.isArray(els)) {
5469
this.elements = this.elements.concat(els);
5471
var yels = this.elements;
5472
Ext.each(els, function(e) {
5479
invoke : function(fn, args){
5480
var els = this.elements,
5482
Ext.each(els, function(e) {
5484
Ext.Element.prototype[fn].apply(el, args);
5489
item : function(index){
5491
if(!me.elements[index]){
5494
me.el.dom = me.elements[index];
5498
// fixes scope with flyweight
5499
addListener : function(eventName, handler, scope, opt){
5500
Ext.each(this.elements, function(e) {
5501
Ext.EventManager.on(e, eventName, handler, scope || e, opt);
5506
each : function(fn, scope){
5510
Ext.each(me.elements, function(e,i) {
5512
return fn.call(scope || el, el, me, i);
5518
indexOf : function(el){
5519
return this.elements.indexOf(Ext.getDom(el));
5523
replaceElement : function(el, replacement, domReplace){
5524
var index = !isNaN(el) ? el : this.indexOf(el),
5527
replacement = Ext.getDom(replacement);
5529
d = this.elements[index];
5530
d.parentNode.insertBefore(replacement, d);
5533
this.elements.splice(index, 1, replacement);
5544
Ext.CompositeElementLite.prototype.on = Ext.CompositeElementLite.prototype.addListener;
5548
ElProto = Ext.Element.prototype,
5549
CelProto = Ext.CompositeElementLite.prototype;
5551
for(var fnName in ElProto){
5552
if(Ext.isFunction(ElProto[fnName])){
5554
CelProto[fnName] = CelProto[fnName] || function(){
5555
return this.invoke(fnName, arguments);
5557
}).call(CelProto, fnName);
5563
Ext.Element.selectorFunction = Ext.DomQuery.select;
5567
Ext.Element.select = function(selector, unique, root){
5569
if(typeof selector == "string"){
5570
els = Ext.Element.selectorFunction(selector, root);
5571
}else if(selector.length !== undefined){
5574
throw "Invalid selector";
5576
return new Ext.CompositeElementLite(els);
5579
Ext.select = Ext.Element.select;
5581
Ext.apply(Ext.CompositeElementLite.prototype, {
5582
addElements : function(els, root){
5583
if(!els) return this;
5584
if(typeof els == "string"){
5585
els = Ext.Element.selectorFunction(els, root);
5587
var yels = this.elements;
5588
Ext.each(els, function(e) {
5589
yels.push(Ext.get(e));
5595
fill : function(els){
5603
return this.item(0);
5608
return this.item(this.getCount()-1);
5612
contains : function(el){
5613
return this.indexOf(el) != -1;
5617
filter : function(selector){
5619
this.each(function(el){
5620
if(el.is(selector)){
5621
els[els.length] = el.dom;
5629
removeElement : function(keys, removeDom){
5631
els = this.elements,
5633
Ext.each(keys, function(val){
5634
if (el = (els[val] || els[val = me.indexOf(val)])) {
5636
el.dom ? el.remove() : Ext.removeNode(el);
5645
Ext.CompositeElement = function(els, root){
5647
this.add(els, root);
5650
Ext.extend(Ext.CompositeElement, Ext.CompositeElementLite, {
5651
invoke : function(fn, args){
5652
Ext.each(this.elements, function(e) {
5653
Ext.Element.prototype[fn].apply(e, args);
5659
add : function(els, root){
5660
if(!els) return this;
5661
if(typeof els == "string"){
5662
els = Ext.Element.selectorFunction(els, root);
5664
var yels = this.elements;
5665
Ext.each(els, function(e) {
5666
yels.push(Ext.get(e));
5672
item : function(index){
5673
return this.elements[index] || null;
5677
indexOf : function(el){
5678
return this.elements.indexOf(Ext.get(el));
5681
filter : function(selector){
5685
Ext.each(me.elements, function(el) {
5686
if(el.is(selector)){
5687
out.push(Ext.get(el));
5695
each : function(fn, scope){
5696
Ext.each(this.elements, function(e,i) {
5697
return fn.call(scope || e, e, this, i)
5704
Ext.Element.select = function(selector, unique, root){
5706
if(typeof selector == "string"){
5707
els = Ext.Element.selectorFunction(selector, root);
5708
}else if(selector.length !== undefined){
5711
throw "Invalid selector";
5714
return (unique === true) ? new Ext.CompositeElement(els) : new Ext.CompositeElementLite(els);
5718
Ext.select = Ext.Element.select;
5720
Ext.handleError = function(e) {
5725
Ext.Error = function(message) {
5726
// Try to read the message from Ext.Error.lang
5727
this.message = (this.lang[message]) ? this.lang[message] : message;
5729
Ext.Error.prototype = new Error();
5730
Ext.apply(Ext.Error.prototype, {
5731
// protected. Extensions place their error-strings here.
5736
getName : function() {
5740
getMessage : function() {
5741
return this.message;
5744
toJson : function() {
5745
return Ext.encode(this);
5751
var BEFOREREQUEST = "beforerequest",
5752
REQUESTCOMPLETE = "requestcomplete",
5753
REQUESTEXCEPTION = "requestexception",
5754
UNDEFINED = undefined,
5761
Ext.data.Connection = function(config){
5762
Ext.apply(this, config);
5771
Ext.data.Connection.superclass.constructor.call(this);
5775
function handleResponse(response){
5776
this.transId = false;
5777
var options = response.argument.options;
5778
response.argument = options ? options.argument : null;
5779
this.fireEvent(REQUESTCOMPLETE, this, response, options);
5780
if(options.success) options.success.call(options.scope, response, options);
5781
if(options.callback) options.callback.call(options.scope, options, true, response);
5785
function handleFailure(response, e){
5786
this.transId = false;
5787
var options = response.argument.options;
5788
response.argument = options ? options.argument : null;
5789
this.fireEvent(REQUESTEXCEPTION, this, response, options, e);
5790
if(options.failure) options.failure.call(options.scope, response, options);
5791
if(options.callback) options.callback.call(options.scope, options, false, response);
5795
function doFormUpload(o, ps, url){
5798
frame = doc.createElement('iframe'),
5799
form = Ext.getDom(o.form),
5803
frame.id = frame.name = id;
5804
frame.className = 'x-hidden';
5805
frame.src = Ext.SSL_SECURE_URL; // for IE
5806
doc.body.appendChild(frame);
5809
doc.frames[id].name = id;
5814
form.enctype = form.encoding = 'multipart/form-data';
5815
form.action = url || "";
5817
// add dynamic params
5818
ps = Ext.urlDecode(ps, false);
5820
if(ps.hasOwnProperty(k)){
5821
hd = doc.createElement('input');
5823
hd.value = ps[hd.name = k];
5824
form.appendChild(hd);
5831
// bogus response object
5832
r = {responseText : '',
5834
argument : o.argument},
5839
doc = frame.contentWindow.document || frame.contentDocument || WINDOW.frames[id].document;
5842
if (/textarea/i.test((firstChild = doc.body.firstChild || {}).tagName)) { // json response wrapped in textarea
5843
r.responseText = firstChild.value;
5845
r.responseText = doc.body.innerHTML;
5848
r.responseXML = doc.XMLDocument || doc;
5854
Ext.EventManager.removeListener(frame, LOAD, cb, me);
5856
me.fireEvent(REQUESTCOMPLETE, me, r, o);
5858
Ext.callback(o.success, o.scope, [r, o]);
5859
Ext.callback(o.callback, o.scope, [o, true, r]);
5861
if(!me.debugUploads){
5862
setTimeout(function(){Ext.removeNode(frame);}, 100);
5866
Ext.EventManager.on(frame, LOAD, cb, this);
5869
Ext.each(hiddens, function(h) {
5874
Ext.extend(Ext.data.Connection, Ext.util.Observable, {
5885
disableCaching: true,
5888
disableCachingParam: '_dc',
5891
request : function(o){
5893
if(me.fireEvent(BEFOREREQUEST, me, o)){
5895
if(!Ext.isEmpty(o.indicatorText)){
5896
me.indicatorText = '<div class="loading-indicator">'+o.indicatorText+"</div>";
5898
if(me.indicatorText) {
5899
Ext.getDom(o.el).innerHTML = me.indicatorText;
5901
o.success = (Ext.isFunction(o.success) ? o.success : function(){}).createInterceptor(function(response) {
5902
Ext.getDom(o.el).innerHTML = response.responseText;
5907
url = o.url || me.url,
5909
cb = {success: handleResponse,
5910
failure: handleFailure,
5912
argument: {options: o},
5913
timeout : o.timeout || me.timeout
5919
if (Ext.isFunction(p)) {
5920
p = p.call(o.scope||WINDOW, o);
5923
p = Ext.urlEncode(me.extraParams, typeof p == 'object' ? Ext.urlEncode(p) : p);
5925
if (Ext.isFunction(url)) {
5926
url = url.call(o.scope || WINDOW, o);
5929
if(form = Ext.getDom(o.form)){
5930
url = url || form.action;
5931
if(o.isUpload || /multipart\/form-data/i.test(form.getAttribute("enctype"))) {
5932
return doFormUpload.call(me, o, p, url);
5934
serForm = Ext.lib.Ajax.serializeForm(form);
5935
p = p ? (p + '&' + serForm) : serForm;
5938
method = o.method || me.method || ((p || o.xmlData || o.jsonData) ? POST : GET);
5940
if(method === GET && (me.disableCaching && o.disableCaching !== false) || o.disableCaching === true){
5941
var dcp = o.disableCachingParam || me.disableCachingParam;
5942
url += (url.indexOf('?') != -1 ? '&' : '?') + dcp + '=' + (new Date().getTime());
5945
o.headers = Ext.apply(o.headers || {}, me.defaultHeaders || {});
5947
if(o.autoAbort === true || me.autoAbort) {
5951
if((method == GET || o.xmlData || o.jsonData) && p){
5952
url += (/\?/.test(url) ? '&' : '?') + p;
5955
return me.transId = Ext.lib.Ajax.request(method, url, cb, p, o);
5957
return o.callback ? o.callback.apply(o.scope, [o,UNDEFINED,UNDEFINED]) : null;
5962
isLoading : function(transId){
5963
return transId ? Ext.lib.Ajax.isCallInProgress(transId) : !! this.transId;
5967
abort : function(transId){
5968
if(transId || this.isLoading()){
5969
Ext.lib.Ajax.abort(transId || this.transId);
5976
Ext.Ajax = new Ext.data.Connection({
5997
serializeForm : function(form){
5998
return Ext.lib.Ajax.serializeForm(form);
6003
Ext.UpdateManager = Ext.Updater = Ext.extend(Ext.util.Observable,
6005
var BEFOREUPDATE = "beforeupdate",
6007
FAILURE = "failure";
6010
function processSuccess(response){
6012
me.transaction = null;
6013
if (response.argument.form && response.argument.reset) {
6014
try { // put in try/catch since some older FF releases had problems with this
6015
response.argument.form.reset();
6018
if (me.loadScripts) {
6019
me.renderer.render(me.el, response, me,
6020
updateComplete.createDelegate(me, [response]));
6022
me.renderer.render(me.el, response, me);
6023
updateComplete.call(me, response);
6028
function updateComplete(response, type, success){
6029
this.fireEvent(type || UPDATE, this.el, response);
6030
if(Ext.isFunction(response.argument.callback)){
6031
response.argument.callback.call(response.argument.scope, this.el, Ext.isEmpty(success) ? true : false, response, response.argument.options);
6036
function processFailure(response){
6037
updateComplete.call(this, response, FAILURE, !!(this.transaction = null));
6041
constructor: function(el, forceNew){
6044
if(!forceNew && el.updateManager){
6045
return el.updateManager;
6050
me.defaultUrl = null;
6061
Ext.apply(me, Ext.Updater.defaults);
6070
me.transaction = null;
6072
me.refreshDelegate = me.refresh.createDelegate(me);
6074
me.updateDelegate = me.update.createDelegate(me);
6076
me.formUpdateDelegate = (me.formUpdate || function(){}).createDelegate(me);
6079
me.renderer = me.renderer || me.getDefaultRenderer();
6081
Ext.Updater.superclass.constructor.call(me);
6085
setRenderer : function(renderer){
6086
this.renderer = renderer;
6090
getRenderer : function(){
6091
return this.renderer;
6095
getDefaultRenderer: function() {
6096
return new Ext.Updater.BasicRenderer();
6100
setDefaultUrl : function(defaultUrl){
6101
this.defaultUrl = defaultUrl;
6110
update : function(url, params, callback, discardUrl){
6115
if(me.fireEvent(BEFOREUPDATE, me.el, url, params) !== false){
6116
if(Ext.isObject(url)){ // must be config object
6119
params = params || cfg.params;
6120
callback = callback || cfg.callback;
6121
discardUrl = discardUrl || cfg.discardUrl;
6122
callerScope = cfg.scope;
6123
if(!Ext.isEmpty(cfg.nocache)){me.disableCaching = cfg.nocache;};
6124
if(!Ext.isEmpty(cfg.text)){me.indicatorText = '<div class="loading-indicator">'+cfg.text+"</div>";};
6125
if(!Ext.isEmpty(cfg.scripts)){me.loadScripts = cfg.scripts;};
6126
if(!Ext.isEmpty(cfg.timeout)){me.timeout = cfg.timeout;};
6131
me.defaultUrl = url;
6133
if(Ext.isFunction(url)){
6137
var o = Ext.apply({}, {
6139
params: (Ext.isFunction(params) && callerScope) ? params.createDelegate(callerScope) : params,
6140
success: processSuccess,
6141
failure: processFailure,
6143
callback: undefined,
6144
timeout: (me.timeout*1000),
6145
disableCaching: me.disableCaching,
6150
"callback": callback,
6151
"scope": callerScope || window,
6156
me.transaction = Ext.Ajax.request(o);
6161
formUpdate : function(form, url, reset, callback){
6163
if(me.fireEvent(BEFOREUPDATE, me.el, form, url) !== false){
6164
if(Ext.isFunction(url)){
6167
form = Ext.getDom(form)
6168
me.transaction = Ext.Ajax.request({
6171
success: processSuccess,
6172
failure: processFailure,
6174
timeout: (me.timeout*1000),
6178
"callback": callback,
6182
me.showLoading.defer(1, me);
6187
startAutoRefresh : function(interval, url, params, callback, refreshNow){
6190
me.update(url || me.defaultUrl, params, callback, true);
6192
if(me.autoRefreshProcId){
6193
clearInterval(me.autoRefreshProcId);
6195
me.autoRefreshProcId = setInterval(me.update.createDelegate(me, [url || me.defaultUrl, params, callback, true]), interval * 1000);
6199
stopAutoRefresh : function(){
6200
if(this.autoRefreshProcId){
6201
clearInterval(this.autoRefreshProcId);
6202
delete this.autoRefreshProcId;
6207
isAutoRefreshing : function(){
6208
return !!this.autoRefreshProcId;
6212
showLoading : function(){
6213
if(this.showLoadIndicator){
6214
this.el.dom.innerHTML = this.indicatorText;
6220
if(this.transaction){
6221
Ext.Ajax.abort(this.transaction);
6226
isUpdating : function(){
6227
return this.transaction ? Ext.Ajax.isLoading(this.transaction) : false;
6231
refresh : function(callback){
6232
if(this.defaultUrl){
6233
this.update(this.defaultUrl, null, callback, true);
6240
Ext.Updater.defaults = {
6244
disableCaching : false,
6246
showLoadIndicator : true,
6248
indicatorText : '<div class="loading-indicator">Loading...</div>',
6250
loadScripts : false,
6252
sslBlankUrl : (Ext.SSL_SECURE_URL || "javascript:false")
6257
Ext.Updater.updateElement = function(el, url, params, options){
6258
var um = Ext.get(el).getUpdater();
6259
Ext.apply(um, options);
6260
um.update(url, params, options ? options.callback : null);
6264
Ext.Updater.BasicRenderer = function(){};
6266
Ext.Updater.BasicRenderer.prototype = {
6268
render : function(el, response, updateManager, callback){
6269
el.update(response.responseText, updateManager.loadScripts, callback);
6278
// create private copy of Ext's String.format() method
6279
// - to remove unnecessary dependency
6280
// - to resolve namespace conflict with M$-Ajax's implementation
6281
function xf(format) {
6282
var args = Array.prototype.slice.call(arguments, 1);
6283
return format.replace(/\{(\d+)\}/g, function(m, i) {
6290
Date.formatCodeToRegex = function(character, currentGroup) {
6291
// Note: currentGroup - position in regex result array (see notes for Date.parseCodes below)
6292
var p = Date.parseCodes[character];
6295
p = typeof p == 'function'? p() : p;
6296
Date.parseCodes[character] = p; // reassign function result to prevent repeated execution
6299
return p? Ext.applyIf({
6300
c: p.c? xf(p.c, currentGroup || "{0}") : p.c
6304
s:Ext.escapeRe(character) // treat unrecognised characters as literals
6308
// private shorthand for Date.formatCodeToRegex since we'll be using it fairly often
6309
var $f = Date.formatCodeToRegex;
6314
"M$": function(input, strict) {
6315
// note: the timezone offset is ignored since the M$ Ajax server sends
6316
// a UTC milliseconds-since-Unix-epoch value
6317
var re = new RegExp('\\/Date\\((\\d+)(?:[+-]\\d{4})?\\)\\/');
6318
var r = (input || '').match(re);
6319
return r? new Date(r[1] * 1) : null;
6327
// UTC milliseconds since Unix epoch (M$-AJAX serialized date format (MRSF))
6328
return '\\/Date(' + this.getTime() + ')\\/';
6331
daysInMonth : [31,28,31,30,31,30,31,31,30,31,30,31],
6402
getShortMonthName : function(month) {
6403
return Date.monthNames[month].substring(0, 3);
6407
getShortDayName : function(day) {
6408
return Date.dayNames[day].substring(0, 3);
6412
getMonthNumber : function(name) {
6413
// handle camel casing for english month names (since the keys for the Date.monthNumbers hash are case sensitive)
6414
return Date.monthNumbers[name.substring(0, 1).toUpperCase() + name.substring(1, 3).toLowerCase()];
6419
d: "String.leftPad(this.getDate(), 2, '0')",
6420
D: "Date.getShortDayName(this.getDay())", // get localised short day name
6421
j: "this.getDate()",
6422
l: "Date.dayNames[this.getDay()]",
6423
N: "(this.getDay() ? this.getDay() : 7)",
6424
S: "this.getSuffix()",
6426
z: "this.getDayOfYear()",
6427
W: "String.leftPad(this.getWeekOfYear(), 2, '0')",
6428
F: "Date.monthNames[this.getMonth()]",
6429
m: "String.leftPad(this.getMonth() + 1, 2, '0')",
6430
M: "Date.getShortMonthName(this.getMonth())", // get localised short month name
6431
n: "(this.getMonth() + 1)",
6432
t: "this.getDaysInMonth()",
6433
L: "(this.isLeapYear() ? 1 : 0)",
6434
o: "(this.getFullYear() + (this.getWeekOfYear() == 1 && this.getMonth() > 0 ? +1 : (this.getWeekOfYear() >= 52 && this.getMonth() < 11 ? -1 : 0)))",
6435
Y: "this.getFullYear()",
6436
y: "('' + this.getFullYear()).substring(2, 4)",
6437
a: "(this.getHours() < 12 ? 'am' : 'pm')",
6438
A: "(this.getHours() < 12 ? 'AM' : 'PM')",
6439
g: "((this.getHours() % 12) ? this.getHours() % 12 : 12)",
6440
G: "this.getHours()",
6441
h: "String.leftPad((this.getHours() % 12) ? this.getHours() % 12 : 12, 2, '0')",
6442
H: "String.leftPad(this.getHours(), 2, '0')",
6443
i: "String.leftPad(this.getMinutes(), 2, '0')",
6444
s: "String.leftPad(this.getSeconds(), 2, '0')",
6445
u: "String.leftPad(this.getMilliseconds(), 3, '0')",
6446
O: "this.getGMTOffset()",
6447
P: "this.getGMTOffset(true)",
6448
T: "this.getTimezone()",
6449
Z: "(this.getTimezoneOffset() * -60)",
6451
c: function() { // ISO-8601 -- GMT format
6452
for (var c = "Y-m-dTH:i:sP", code = [], i = 0, l = c.length; i < l; ++i) {
6453
var e = c.charAt(i);
6454
code.push(e == "T" ? "'T'" : Date.getFormatCode(e)); // treat T as a character literal
6456
return code.join(" + ");
6460
U: "Math.round(this.getTime() / 1000)"
6464
isValid : function(y, m, d, h, i, s, ms) {
6471
var dt = new Date(y, m - 1, d, h, i, s, ms);
6473
return y == dt.getFullYear() &&
6474
m == dt.getMonth() + 1 &&
6475
d == dt.getDate() &&
6476
h == dt.getHours() &&
6477
i == dt.getMinutes() &&
6478
s == dt.getSeconds() &&
6479
ms == dt.getMilliseconds();
6483
parseDate : function(input, format, strict) {
6484
var p = Date.parseFunctions;
6485
if (p[format] == null) {
6486
Date.createParser(format);
6488
return p[format](input, strict);
6492
getFormatCode : function(character) {
6493
var f = Date.formatCodes[character];
6496
f = typeof f == 'function'? f() : f;
6497
Date.formatCodes[character] = f; // reassign function result to prevent repeated execution
6500
// note: unknown characters are treated as literals
6501
return f || ("'" + String.escape(character) + "'");
6505
createFormat : function(format) {
6510
for (var i = 0; i < format.length; ++i) {
6511
ch = format.charAt(i);
6512
if (!special && ch == "\\") {
6514
} else if (special) {
6516
code.push("'" + String.escape(ch) + "'");
6518
code.push(Date.getFormatCode(ch))
6521
Date.formatFunctions[format] = new Function("return " + code.join('+'));
6525
createParser : function() {
6527
"var dt, y, m, d, h, i, s, ms, o, z, zz, u, v,",
6528
"def = Date.defaults,",
6529
"results = String(input).match(Date.parseRegexes[{0}]);", // either null, or an array of matched strings
6534
"if(u != null){", // i.e. unix time is defined
6535
"v = new Date(u * 1000);", // give top priority to UNIX time
6537
// create Date object representing midnight of the current day;
6538
// this will provide us with our date defaults
6539
// (note: clearTime() handles Daylight Saving Time automatically)
6540
"dt = (new Date()).clearTime();",
6542
// date calculations (note: these calculations create a dependency on Ext.num())
6543
"y = y >= 0? y : Ext.num(def.y, dt.getFullYear());",
6544
"m = m >= 0? m : Ext.num(def.m - 1, dt.getMonth());",
6545
"d = d || Ext.num(def.d, dt.getDate());",
6547
// time calculations (note: these calculations create a dependency on Ext.num())
6548
"h = h || Ext.num(def.h, dt.getHours());",
6549
"i = i || Ext.num(def.i, dt.getMinutes());",
6550
"s = s || Ext.num(def.s, dt.getSeconds());",
6551
"ms = ms || Ext.num(def.ms, dt.getMilliseconds());",
6553
"if(z >= 0 && y >= 0){",
6554
// both the year and zero-based day of year are defined and >= 0.
6555
// these 2 values alone provide sufficient info to create a full date object
6557
// create Date object representing January 1st for the given year
6558
"v = new Date(y, 0, 1, h, i, s, ms);",
6560
// then add day of year, checking for Date "rollover" if necessary
6561
"v = !strict? v : (strict === true && (z <= 364 || (v.isLeapYear() && z <= 365))? v.add(Date.DAY, z) : null);",
6562
"}else if(strict === true && !Date.isValid(y, m + 1, d, h, i, s, ms)){", // check for Date "rollover"
6563
"v = null;", // invalid date, so return null
6565
// plain old Date object
6566
"v = new Date(y, m, d, h, i, s, ms);",
6572
// favour UTC offset over GMT offset
6574
// reset to UTC, then add offset
6575
"v = v.add(Date.SECOND, -v.getTimezoneOffset() * 60 - zz);",
6577
// reset to GMT, then add offset
6578
"v = v.add(Date.MINUTE, -v.getTimezoneOffset() + (sn == '+'? -1 : 1) * (hr * 60 + mn));",
6585
return function(format) {
6586
var regexNum = Date.parseRegexes.length,
6593
for (var i = 0; i < format.length; ++i) {
6594
ch = format.charAt(i);
6595
if (!special && ch == "\\") {
6597
} else if (special) {
6599
regex.push(String.escape(ch));
6601
var obj = $f(ch, currentGroup);
6602
currentGroup += obj.g;
6604
if (obj.g && obj.c) {
6610
Date.parseRegexes[regexNum] = new RegExp("^" + regex.join('') + "$", "i");
6611
Date.parseFunctions[format] = new Function("input", "strict", xf(code, regexNum, calc.join('')));
6620
c:"d = parseInt(results[{0}], 10);\n",
6621
s:"(\\d{2})" // day of month with leading zeroes (01 - 31)
6625
c:"d = parseInt(results[{0}], 10);\n",
6626
s:"(\\d{1,2})" // day of month without leading zeroes (1 - 31)
6629
for (var a = [], i = 0; i < 7; a.push(Date.getShortDayName(i)), ++i); // get localised short day names
6633
s:"(?:" + a.join("|") +")"
6640
s:"(?:" + Date.dayNames.join("|") + ")"
6646
s:"[1-7]" // ISO-8601 day number (1 (monday) - 7 (sunday))
6656
s:"[0-6]" // javascript day number (0 (sunday) - 6 (saturday))
6660
c:"z = parseInt(results[{0}], 10);\n",
6661
s:"(\\d{1,3})" // day of the year (0 - 364 (365 in leap years))
6666
s:"(?:\\d{2})" // ISO-8601 week number (with leading zero)
6671
c:"m = parseInt(Date.getMonthNumber(results[{0}]), 10);\n", // get localised month number
6672
s:"(" + Date.monthNames.join("|") + ")"
6676
for (var a = [], i = 0; i < 12; a.push(Date.getShortMonthName(i)), ++i); // get localised short month names
6677
return Ext.applyIf({
6678
s:"(" + a.join("|") + ")"
6683
c:"m = parseInt(results[{0}], 10) - 1;\n",
6684
s:"(\\d{2})" // month number with leading zeros (01 - 12)
6688
c:"m = parseInt(results[{0}], 10) - 1;\n",
6689
s:"(\\d{1,2})" // month number without leading zeros (1 - 12)
6694
s:"(?:\\d{2})" // no. of days in the month (28 - 31)
6706
c:"y = parseInt(results[{0}], 10);\n",
6707
s:"(\\d{4})" // 4-digit year
6711
c:"var ty = parseInt(results[{0}], 10);\n"
6712
+ "y = ty > Date.y2kYear ? 1900 + ty : 2000 + ty;\n", // 2-digit year
6717
c:"if (results[{0}] == 'am') {\n"
6718
+ "if (h == 12) { h = 0; }\n"
6719
+ "} else { if (h < 12) { h += 12; }}",
6724
c:"if (results[{0}] == 'AM') {\n"
6725
+ "if (h == 12) { h = 0; }\n"
6726
+ "} else { if (h < 12) { h += 12; }}",
6734
c:"h = parseInt(results[{0}], 10);\n",
6735
s:"(\\d{1,2})" // 24-hr format of an hour without leading zeroes (0 - 23)
6742
c:"h = parseInt(results[{0}], 10);\n",
6743
s:"(\\d{2})" // 24-hr format of an hour with leading zeroes (00 - 23)
6747
c:"i = parseInt(results[{0}], 10);\n",
6748
s:"(\\d{2})" // minutes with leading zeros (00 - 59)
6752
c:"s = parseInt(results[{0}], 10);\n",
6753
s:"(\\d{2})" // seconds with leading zeros (00 - 59)
6757
c:"ms = results[{0}]; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n",
6758
s:"(\\d+)" // decimal fraction of a second (minimum = 1 digit, maximum = unlimited)
6763
"o = results[{0}];",
6764
"var sn = o.substring(0,1),", // get + / - sign
6765
"hr = o.substring(1,3)*1 + Math.floor(o.substring(3,5) / 60),", // get hours (performs minutes-to-hour conversion also, just in case)
6766
"mn = o.substring(3,5) % 60;", // get minutes
6767
"o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" // -12hrs <= GMT offset <= 14hrs
6769
s: "([+\-]\\d{4})" // GMT offset in hrs and mins
6774
"o = results[{0}];",
6775
"var sn = o.substring(0,1),", // get + / - sign
6776
"hr = o.substring(1,3)*1 + Math.floor(o.substring(4,6) / 60),", // get hours (performs minutes-to-hour conversion also, just in case)
6777
"mn = o.substring(4,6) % 60;", // get minutes
6778
"o = ((-12 <= (hr*60 + mn)/60) && ((hr*60 + mn)/60 <= 14))? (sn + String.leftPad(hr, 2, '0') + String.leftPad(mn, 2, '0')) : null;\n" // -12hrs <= GMT offset <= 14hrs
6780
s: "([+\-]\\d{2}:\\d{2})" // GMT offset in hrs and mins (with colon separator)
6785
s:"[A-Z]{1,4}" // timezone abbrev. may be between 1 - 4 chars
6789
c:"zz = results[{0}] * 1;\n" // -43200 <= UTC offset <= 50400
6790
+ "zz = (-43200 <= zz && zz <= 50400)? zz : null;\n",
6791
s:"([+\-]?\\d{1,5})" // leading '+' sign is optional for UTC offset
6797
$f("m", 2), // month
6800
$f("i", 5), // minute
6801
$f("s", 6), // second
6802
{c:"ms = results[7] || '0'; ms = parseInt(ms, 10)/Math.pow(10, ms.length - 3);\n"}, // decimal fraction of a second (minimum = 1 digit, maximum = unlimited)
6803
{c:[ // allow either "Z" (i.e. UTC) or "-0530" or "+08:00" (i.e. UTC offset) timezone delimiters. assumes local timezone if no timezone is specified
6804
"if(results[8]) {", // timezone specified
6805
"if(results[8] == 'Z'){",
6807
"}else if (results[8].indexOf(':') > -1){",
6808
$f("P", 8).c, // timezone offset with colon separator
6810
$f("O", 8).c, // timezone offset without colon separator
6816
for (var i = 0, l = arr.length; i < l; ++i) {
6817
calc.push(arr[i].c);
6824
arr[0].s, // year (required)
6825
"(?:", "-", arr[1].s, // month (optional)
6826
"(?:", "-", arr[2].s, // day (optional)
6828
"(?:T| )?", // time delimiter -- either a "T" or a single blank space
6829
arr[3].s, ":", arr[4].s, // hour AND minute, delimited by a single colon (optional). MUST be preceded by either a "T" or a single blank space
6830
"(?::", arr[5].s, ")?", // seconds (optional)
6831
"(?:(?:\\.|,)(\\d+))?", // decimal fraction of a second (e.g. ",12345" or ".98765") (optional)
6832
"(Z|(?:[-+]\\d{2}(?::)?\\d{2}))?", // "Z" (UTC) or "-0530" (UTC offset without colon delimiter) or "+08:00" (UTC offset with colon delimiter) (optional)
6841
c:"u = parseInt(results[{0}], 10);\n",
6842
s:"(-?\\d+)" // leading minus sign indicates seconds before UNIX epoch
6849
Ext.apply(Date.prototype, {
6851
dateFormat : function(format) {
6852
if (Date.formatFunctions[format] == null) {
6853
Date.createFormat(format);
6855
return Date.formatFunctions[format].call(this);
6859
getTimezone : function() {
6860
// the following list shows the differences between date strings from different browsers on a WinXP SP2 machine from an Asian locale:
6862
// Opera : "Thu, 25 Oct 2007 22:53:45 GMT+0800" -- shortest (weirdest) date string of the lot
6863
// Safari : "Thu Oct 25 2007 22:55:35 GMT+0800 (Malay Peninsula Standard Time)" -- value in parentheses always gives the correct timezone (same as FF)
6864
// FF : "Thu Oct 25 2007 22:55:35 GMT+0800 (Malay Peninsula Standard Time)" -- value in parentheses always gives the correct timezone
6865
// IE : "Thu Oct 25 22:54:35 UTC+0800 2007" -- (Asian system setting) look for 3-4 letter timezone abbrev
6866
// IE : "Thu Oct 25 17:06:37 PDT 2007" -- (American system setting) look for 3-4 letter timezone abbrev
6868
// this crazy regex attempts to guess the correct timezone abbreviation despite these differences.
6869
// step 1: (?:\((.*)\) -- find timezone in parentheses
6870
// step 2: ([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?) -- if nothing was found in step 1, find timezone from timezone offset portion of date string
6871
// step 3: remove all non uppercase characters found in step 1 and 2
6872
return this.toString().replace(/^.* (?:\((.*)\)|([A-Z]{1,4})(?:[\-+][0-9]{4})?(?: -?\d+)?)$/, "$1$2").replace(/[^A-Z]/g, "");
6876
getGMTOffset : function(colon) {
6877
return (this.getTimezoneOffset() > 0 ? "-" : "+")
6878
+ String.leftPad(Math.floor(Math.abs(this.getTimezoneOffset()) / 60), 2, "0")
6879
+ (colon ? ":" : "")
6880
+ String.leftPad(Math.abs(this.getTimezoneOffset() % 60), 2, "0");
6884
getDayOfYear : function() {
6886
Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
6887
for (var i = 0; i < this.getMonth(); ++i) {
6888
num += Date.daysInMonth[i];
6890
return num + this.getDate() - 1;
6894
getWeekOfYear : function() {
6895
// adapted from http://www.merlyn.demon.co.uk/weekcalc.htm
6896
var ms1d = 864e5, // milliseconds in a day
6897
ms7d = 7 * ms1d; // milliseconds in a week
6899
return function() { // return a closure so constants get calculated only once
6900
var DC3 = Date.UTC(this.getFullYear(), this.getMonth(), this.getDate() + 3) / ms1d, // an Absolute Day Number
6901
AWN = Math.floor(DC3 / 7), // an Absolute Week Number
6902
Wyr = new Date(AWN * ms7d).getUTCFullYear();
6904
return AWN - Math.floor(Date.UTC(Wyr, 0, 7) / ms7d) + 1;
6909
isLeapYear : function() {
6910
var year = this.getFullYear();
6911
return !!((year & 3) == 0 && (year % 100 || (year % 400 == 0 && year)));
6915
getFirstDayOfMonth : function() {
6916
var day = (this.getDay() - (this.getDate() - 1)) % 7;
6917
return (day < 0) ? (day + 7) : day;
6921
getLastDayOfMonth : function() {
6922
var day = (this.getDay() + (Date.daysInMonth[this.getMonth()] - this.getDate())) % 7;
6923
return (day < 0) ? (day + 7) : day;
6928
getFirstDateOfMonth : function() {
6929
return new Date(this.getFullYear(), this.getMonth(), 1);
6933
getLastDateOfMonth : function() {
6934
return new Date(this.getFullYear(), this.getMonth(), this.getDaysInMonth());
6938
getDaysInMonth : function() {
6939
Date.daysInMonth[1] = this.isLeapYear() ? 29 : 28;
6940
return Date.daysInMonth[this.getMonth()];
6944
getSuffix : function() {
6945
switch (this.getDate()) {
6962
clone : function() {
6963
return new Date(this.getTime());
6967
isDST : function() {
6968
// adapted from http://extjs.com/forum/showthread.php?p=247172#post247172
6969
// courtesy of @geoffrey.mcgill
6970
return new Date(this.getFullYear(), 0, 1).getTimezoneOffset() != this.getTimezoneOffset();
6974
clearTime : function(clone) {
6976
return this.clone().clearTime();
6979
// get current date before clearing time
6980
var d = this.getDate();
6986
this.setMilliseconds(0);
6988
if (this.getDate() != d) { // account for DST (i.e. day of month changed when setting hour = 0)
6989
// note: DST adjustments are assumed to occur in multiples of 1 hour (this is almost always the case)
6990
// refer to http://www.timeanddate.com/time/aboutdst.html for the (rare) exceptions to this rule
6992
// increment hour until cloned date == current date
6993
for (var hr = 1, c = this.add(Date.HOUR, hr); c.getDate() != d; hr++, c = this.add(Date.HOUR, hr));
6996
this.setHours(c.getHours());
7003
add : function(interval, value) {
7004
var d = this.clone();
7005
if (!interval || value === 0) return d;
7007
switch(interval.toLowerCase()) {
7009
d.setMilliseconds(this.getMilliseconds() + value);
7012
d.setSeconds(this.getSeconds() + value);
7015
d.setMinutes(this.getMinutes() + value);
7018
d.setHours(this.getHours() + value);
7021
d.setDate(this.getDate() + value);
7024
var day = this.getDate();
7026
day = Math.min(day, this.getFirstDateOfMonth().add('mo', value).getLastDateOfMonth().getDate());
7029
d.setMonth(this.getMonth() + value);
7032
d.setFullYear(this.getFullYear() + value);
7039
between : function(start, end) {
7040
var t = this.getTime();
7041
return start.getTime() <= t && t <= end.getTime();
7047
Date.prototype.format = Date.prototype.dateFormat;
7051
if (Ext.isSafari && (navigator.userAgent.match(/WebKit\/(\d+)/)[1] || NaN) < 420) {
7052
Ext.apply(Date.prototype, {
7053
_xMonth : Date.prototype.setMonth,
7054
_xDate : Date.prototype.setDate,
7056
// Bug in Safari 1.3, 2.0 (WebKit build < 420)
7057
// Date.setMonth does not work consistently if iMonth is not 0-11
7058
setMonth : function(num) {
7060
var n = Math.ceil(-num),
7061
back_year = Math.ceil(n / 12),
7062
month = (n % 12) ? 12 - n % 12 : 0;
7064
this.setFullYear(this.getFullYear() - back_year);
7066
return this._xMonth(month);
7068
return this._xMonth(num);
7072
// Bug in setDate() method (resolved in WebKit build 419.3, so to be safe we target Webkit builds < 420)
7073
// The parameter for Date.setDate() is converted to a signed byte integer in Safari
7074
// http://brianary.blogspot.com/2006/03/safari-date-bug.html
7075
setDate : function(d) {
7076
// use setTime() to workaround setDate() bug
7077
// subtract current day of month in milliseconds, then add desired day of month in milliseconds
7078
return this.setTime(this.getTime() - (this.getDate() - d) * 864e5);
7087
Ext.util.DelayedTask = function(fn, scope, args){
7093
fn.apply(scope, args || []);
7097
me.delay = function(delay, newFn, newScope, newArgs){
7100
scope = newScope || scope;
7101
args = newArgs || args;
7102
id = setInterval(call, delay);
7106
me.cancel = function(){
7114
Ext.util.MixedCollection = function(allowFunctions, keyFn){
7130
this.allowFunctions = allowFunctions === true;
7132
this.getKey = keyFn;
7134
Ext.util.MixedCollection.superclass.constructor.call(this);
7137
Ext.extend(Ext.util.MixedCollection, Ext.util.Observable, {
7138
allowFunctions : false,
7141
add: function(key, o){
7142
if(arguments.length == 1){
7144
key = this.getKey(o);
7146
if(typeof key != 'undefined' && key !== null){
7147
var old = this.map[key];
7148
if(typeof old != 'undefined'){
7149
return this.replace(key, o);
7155
this.keys.push(key);
7156
this.fireEvent('add', this.length-1, o, key);
7161
getKey : function(o){
7166
replace : function(key, o){
7167
if(arguments.length == 1){
7169
key = this.getKey(o);
7171
var old = this.map[key];
7172
if(typeof key == "undefined" || key === null || typeof old == "undefined"){
7173
return this.add(key, o);
7175
var index = this.indexOfKey(key);
7176
this.items[index] = o;
7178
this.fireEvent("replace", key, old, o);
7183
addAll : function(objs){
7184
if(arguments.length > 1 || Ext.isArray(objs)){
7185
var args = arguments.length > 1 ? arguments : objs;
7186
for(var i = 0, len = args.length; i < len; i++){
7190
for(var key in objs){
7191
if(this.allowFunctions || typeof objs[key] != "function"){
7192
this.add(key, objs[key]);
7199
each : function(fn, scope){
7200
var items = [].concat(this.items); // each safe for removal
7201
for(var i = 0, len = items.length; i < len; i++){
7202
if(fn.call(scope || items[i], items[i], i, len) === false){
7209
eachKey : function(fn, scope){
7210
for(var i = 0, len = this.keys.length; i < len; i++){
7211
fn.call(scope || window, this.keys[i], this.items[i], i, len);
7216
find : function(fn, scope){
7217
for(var i = 0, len = this.items.length; i < len; i++){
7218
if(fn.call(scope || window, this.items[i], this.keys[i])){
7219
return this.items[i];
7226
insert : function(index, key, o){
7227
if(arguments.length == 2){
7229
key = this.getKey(o);
7231
if(this.containsKey(key)){
7232
this.suspendEvents();
7233
this.removeKey(key);
7234
this.resumeEvents();
7236
if(index >= this.length){
7237
return this.add(key, o);
7240
this.items.splice(index, 0, o);
7241
if(typeof key != "undefined" && key != null){
7244
this.keys.splice(index, 0, key);
7245
this.fireEvent("add", index, o, key);
7250
remove : function(o){
7251
return this.removeAt(this.indexOf(o));
7255
removeAt : function(index){
7256
if(index < this.length && index >= 0){
7258
var o = this.items[index];
7259
this.items.splice(index, 1);
7260
var key = this.keys[index];
7261
if(typeof key != "undefined"){
7262
delete this.map[key];
7264
this.keys.splice(index, 1);
7265
this.fireEvent("remove", o, key);
7272
removeKey : function(key){
7273
return this.removeAt(this.indexOfKey(key));
7277
getCount : function(){
7282
indexOf : function(o){
7283
return this.items.indexOf(o);
7287
indexOfKey : function(key){
7288
return this.keys.indexOf(key);
7292
item : function(key){
7293
var item = typeof this.map[key] != "undefined" ? this.map[key] : (typeof key == 'number') ? this.items[key] : null;
7294
return !Ext.isFunction(item) || this.allowFunctions ? item : null; // for prototype!
7298
itemAt : function(index){
7299
return this.items[index];
7303
key : function(key){
7304
return this.map[key];
7308
contains : function(o){
7309
return this.indexOf(o) != -1;
7313
containsKey : function(key){
7314
return typeof this.map[key] != "undefined";
7323
this.fireEvent("clear");
7328
return this.items[0];
7333
return this.items[this.length-1];
7337
_sort : function(property, dir, fn){
7338
var dsc = String(dir).toUpperCase() == "DESC" ? -1 : 1;
7339
fn = fn || function(a, b){
7342
var c = [], k = this.keys, items = this.items;
7343
for(var i = 0, len = items.length; i < len; i++){
7344
c[c.length] = {key: k[i], value: items[i], index: i};
7346
c.sort(function(a, b){
7347
var v = fn(a[property], b[property]) * dsc;
7349
v = (a.index < b.index ? -1 : 1);
7353
for(var i = 0, len = c.length; i < len; i++){
7354
items[i] = c[i].value;
7357
this.fireEvent("sort", this);
7361
sort : function(dir, fn){
7362
this._sort("value", dir, fn);
7366
keySort : function(dir, fn){
7367
this._sort("key", dir, fn || function(a, b){
7368
var v1 = String(a).toUpperCase(), v2 = String(b).toUpperCase();
7369
return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
7374
getRange : function(start, end){
7375
var items = this.items;
7376
if(items.length < 1){
7380
end = Math.min(typeof end == "undefined" ? this.length-1 : end, this.length-1);
7383
for(var i = start; i <= end; i++) {
7384
r[r.length] = items[i];
7387
for(var i = start; i >= end; i--) {
7388
r[r.length] = items[i];
7395
filter : function(property, value, anyMatch, caseSensitive){
7396
if(Ext.isEmpty(value, false)){
7397
return this.clone();
7399
value = this.createValueMatcher(value, anyMatch, caseSensitive);
7400
return this.filterBy(function(o){
7401
return o && value.test(o[property]);
7406
filterBy : function(fn, scope){
7407
var r = new Ext.util.MixedCollection();
7408
r.getKey = this.getKey;
7409
var k = this.keys, it = this.items;
7410
for(var i = 0, len = it.length; i < len; i++){
7411
if(fn.call(scope||this, it[i], k[i])){
7419
findIndex : function(property, value, start, anyMatch, caseSensitive){
7420
if(Ext.isEmpty(value, false)){
7423
value = this.createValueMatcher(value, anyMatch, caseSensitive);
7424
return this.findIndexBy(function(o){
7425
return o && value.test(o[property]);
7430
findIndexBy : function(fn, scope, start){
7431
var k = this.keys, it = this.items;
7432
for(var i = (start||0), len = it.length; i < len; i++){
7433
if(fn.call(scope||this, it[i], k[i])){
7441
createValueMatcher : function(value, anyMatch, caseSensitive){
7442
if(!value.exec){ // not a regex
7443
value = String(value);
7444
value = new RegExp((anyMatch === true ? '' : '^') + Ext.escapeRe(value), caseSensitive ? '' : 'i');
7451
var r = new Ext.util.MixedCollection();
7452
var k = this.keys, it = this.items;
7453
for(var i = 0, len = it.length; i < len; i++){
7456
r.getKey = this.getKey;
7461
Ext.util.MixedCollection.prototype.get = Ext.util.MixedCollection.prototype.item;
7463
Ext.ComponentMgr = function(){
7464
var all = new Ext.util.MixedCollection();
7470
register : function(c){
7475
unregister : function(c){
7485
onAvailable : function(id, fn, scope){
7486
all.on("add", function(index, o){
7488
fn.call(scope || o, o);
7489
all.un("add", fn, scope);
7498
registerType : function(xtype, cls){
7504
create : function(config, defaultType){
7505
return config.render ? config : new types[config.xtype || defaultType](config);
7509
registerPlugin : function(ptype, cls){
7510
ptypes[ptype] = cls;
7515
createPlugin : function(config, defaultType){
7516
return new ptypes[config.ptype || defaultType](config);
7522
Ext.reg = Ext.ComponentMgr.registerType; // this will be called a lot internally, shorthand to keep the bytes down
7524
Ext.preg = Ext.ComponentMgr.registerPlugin;
7525
Ext.create = Ext.ComponentMgr.create;
7528
Ext.util.JSON = new (function(){
7529
var useHasOwn = !!{}.hasOwnProperty,
7530
isNative = Ext.USE_NATIVE_JSON && JSON && JSON.toString() == '[object JSON]';
7532
// crashes Safari in some instances
7533
//var validRE = /^("(\\.|[^"\\\n\r])*?"|[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t])+?$/;
7535
var pad = function(n) {
7536
return n < 10 ? "0" + n : n;
7549
var encodeString = function(s){
7550
if (/["\\\x00-\x1f]/.test(s)) {
7551
return '"' + s.replace(/([\x00-\x1f\\"])/g, function(a, b) {
7558
Math.floor(c / 16).toString(16) +
7559
(c % 16).toString(16);
7562
return '"' + s + '"';
7565
var encodeArray = function(o){
7566
var a = ["["], b, i, l = o.length, v;
7567
for (i = 0; i < l; i += 1) {
7578
a.push(v === null ? "null" : Ext.util.JSON.encode(v));
7586
this.encodeDate = function(o){
7587
return '"' + o.getFullYear() + "-" +
7588
pad(o.getMonth() + 1) + "-" +
7589
pad(o.getDate()) + "T" +
7590
pad(o.getHours()) + ":" +
7591
pad(o.getMinutes()) + ":" +
7592
pad(o.getSeconds()) + '"';
7596
this.encode = isNative ? JSON.stringify : function(o){
7597
if(typeof o == "undefined" || o === null){
7599
}else if(Ext.isArray(o)){
7600
return encodeArray(o);
7601
}else if(Object.prototype.toString.apply(o) === '[object Date]'){
7602
return Ext.util.JSON.encodeDate(o);
7603
}else if(typeof o == "string"){
7604
return encodeString(o);
7605
}else if(typeof o == "number"){
7606
return isFinite(o) ? String(o) : "null";
7607
}else if(typeof o == "boolean"){
7610
var a = ["{"], b, i, v;
7612
if(!useHasOwn || o.hasOwnProperty(i)) {
7623
a.push(this.encode(i), ":",
7624
v === null ? "null" : this.encode(v));
7635
this.decode = isNative ? JSON.parse : function(json){
7636
return eval("(" + json + ')');
7640
Ext.encode = Ext.util.JSON.encode;
7642
Ext.decode = Ext.util.JSON.decode;
7645
Ext.util.Format = function(){
7646
var trimRe = /^\s+|\s+$/g;
7649
ellipsis : function(value, len, word){
7650
if(value && value.length > len){
7652
var vs = value.substr(0, len - 2);
7653
var index = Math.max(vs.lastIndexOf(' '), vs.lastIndexOf('.'), vs.lastIndexOf('!'), vs.lastIndexOf('?'));
7654
if(index == -1 || index < (len - 15)){
7655
return value.substr(0, len - 3) + "...";
7657
return vs.substr(0, index) + "...";
7660
return value.substr(0, len - 3) + "...";
7667
undef : function(value){
7668
return value !== undefined ? value : "";
7672
defaultValue : function(value, defaultValue){
7673
return value !== undefined && value !== '' ? value : defaultValue;
7677
htmlEncode : function(value){
7678
return !value ? value : String(value).replace(/&/g, "&").replace(/>/g, ">").replace(/</g, "<").replace(/"/g, """);
7682
htmlDecode : function(value){
7683
return !value ? value : String(value).replace(/>/g, ">").replace(/</g, "<").replace(/"/g, '"').replace(/&/g, "&");
7687
trim : function(value){
7688
return String(value).replace(trimRe, "");
7692
substr : function(value, start, length){
7693
return String(value).substr(start, length);
7697
lowercase : function(value){
7698
return String(value).toLowerCase();
7702
uppercase : function(value){
7703
return String(value).toUpperCase();
7707
capitalize : function(value){
7708
return !value ? value : value.charAt(0).toUpperCase() + value.substr(1).toLowerCase();
7712
call : function(value, fn){
7713
if(arguments.length > 2){
7714
var args = Array.prototype.slice.call(arguments, 2);
7715
args.unshift(value);
7716
return eval(fn).apply(window, args);
7718
return eval(fn).call(window, value);
7723
usMoney : function(v){
7724
v = (Math.round((v-0)*100))/100;
7725
v = (v == Math.floor(v)) ? v + ".00" : ((v*10 == Math.floor(v*10)) ? v + "0" : v);
7727
var ps = v.split('.');
7729
var sub = ps[1] ? '.'+ ps[1] : '.00';
7730
var r = /(\d+)(\d{3})/;
7731
while (r.test(whole)) {
7732
whole = whole.replace(r, '$1' + ',' + '$2');
7735
if(v.charAt(0) == '-'){
7736
return '-$' + v.substr(1);
7742
date : function(v, format){
7747
v = new Date(Date.parse(v));
7749
return v.dateFormat(format || "m/d/Y");
7753
dateRenderer : function(format){
7755
return Ext.util.Format.date(v, format);
7760
stripTagsRE : /<\/?[^>]+>/gi,
7763
stripTags : function(v){
7764
return !v ? v : String(v).replace(this.stripTagsRE, "");
7767
stripScriptsRe : /(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)/ig,
7770
stripScripts : function(v){
7771
return !v ? v : String(v).replace(this.stripScriptsRe, "");
7775
fileSize : function(size){
7777
return size + " bytes";
7778
} else if(size < 1048576) {
7779
return (Math.round(((size*10) / 1024))/10) + " KB";
7781
return (Math.round(((size*10) / 1048576))/10) + " MB";
7787
return function(v, a){
7789
fns[a] = new Function('v', 'return v ' + a + ';');
7796
round : function(value, precision) {
7797
var result = Number(value);
7798
if (typeof precision == 'number') {
7799
precision = Math.pow(10, precision);
7800
result = Math.round(value * precision) / precision;
7806
number: function(v, format) {
7810
v = Ext.num(v, NaN);
7820
if(format.substr(format.length - 2) == '/i'){
7821
format = format.substr(0, format.length - 2);
7827
var hasComma = format.indexOf(comma) != -1,
7828
psplit = (i18n ? format.replace(/[^\d\,]/g, '') : format.replace(/[^\d\.]/g, '')).split(dec);
7830
if(1 < psplit.length){
7831
v = v.toFixed(psplit[1].length);
7832
}else if(2 < psplit.length){
7833
throw ('NumberFormatException: invalid format, formats should have no more than 1 period: ' + format);
7838
var fnum = v.toString();
7840
psplit = fnum.split('.');
7842
var cnum = psplit[0], parr = [], j = cnum.length, m = Math.floor(j / 3), n = cnum.length % 3 || 3;
7844
for(var i = 0; i < j; i += n){
7848
parr[parr.length] = cnum.substr(i, n);
7851
fnum = parr.join(comma);
7853
fnum += dec + psplit[1];
7857
return (neg ? '-' : '') + format.replace(/[\d,?\.?]+/, fnum);
7861
numberRenderer : function(format){
7863
return Ext.util.Format.number(v, format);
7868
plural : function(v, s, p){
7869
return v +' ' + (v == 1 ? s : (p ? p : s+'s'));
7873
nl2br : function(v){
7874
return v === undefined || v === null ? '' : v.replace(/\n/g, '<br/>');
7879
Ext.XTemplate = function(){
7880
Ext.XTemplate.superclass.constructor.apply(this, arguments);
7884
re = /<tpl\b[^>]*>((?:(?=([^<]+))\2|<(?!tpl\b[^>]*>))*?)<\/tpl>/,
7885
nameRe = /^<tpl\b[^>]*?for="(.*?)"/,
7886
ifRe = /^<tpl\b[^>]*?if="(.*?)"/,
7887
execRe = /^<tpl\b[^>]*?exec="(.*?)"/,
7896
WITHVALUES = 'with(values){ ';
7898
s = ['<tpl>', s, '</tpl>'].join('');
7900
while(m = s.match(re)){
7901
var m2 = m[0].match(nameRe),
7902
m3 = m[0].match(ifRe),
7903
m4 = m[0].match(execRe),
7907
name = m2 && m2[1] ? m2[1] : '';
7910
exp = m3 && m3[1] ? m3[1] : null;
7912
fn = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES + RETURN +(Ext.util.Format.htmlDecode(exp))+'; }');
7916
exp = m4 && m4[1] ? m4[1] : null;
7918
exec = new Function(VALUES, PARENT, XINDEX, XCOUNT, WITHVALUES +(Ext.util.Format.htmlDecode(exp))+'; }');
7923
case '.': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + VALUES + '; }'); break;
7924
case '..': name = new Function(VALUES, PARENT, WITHVALUES + RETURN + PARENT + '; }'); break;
7925
default: name = new Function(VALUES, PARENT, WITHVALUES + RETURN + name + '; }');
7935
s = s.replace(m[0], '{xtpl'+ id + '}');
7938
Ext.each(tpls, function(t) {
7941
me.master = tpls[tpls.length-1];
7944
Ext.extend(Ext.XTemplate, Ext.Template, {
7946
re : /\{([\w-\.\#]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?(\s?[\+\-\*\\]\s?[\d\.\+\-\*\\\(\)]+)?\}/g,
7948
codeRe : /\{\[((?:\\\]|.|\n)*?)\]\}/g,
7951
applySubTemplate : function(id, values, parent, xindex, xcount){
7957
if ((t.test && !t.test.call(me, values, parent, xindex, xcount)) ||
7958
(t.exec && t.exec.call(me, values, parent, xindex, xcount))) {
7961
vs = t.target ? t.target.call(me, values, parent) : values;
7963
parent = t.target ? values : parent;
7964
if(t.target && Ext.isArray(vs)){
7965
Ext.each(vs, function(v, i) {
7966
buf[buf.length] = t.compiled.call(me, v, parent, i+1, len);
7968
return buf.join('');
7970
return t.compiled.call(me, vs, parent, xindex, xcount);
7974
compileTpl : function(tpl){
7975
var fm = Ext.util.Format,
7976
useF = this.disableFormats !== true,
7977
sep = Ext.isGecko ? "+" : ",",
7980
function fn(m, name, format, args, math){
7981
if(name.substr(0, 4) == 'xtpl'){
7982
return "'"+ sep +'this.applySubTemplate('+name.substr(4)+', values, parent, xindex, xcount)'+sep+"'";
7987
}else if(name === '#'){
7989
}else if(name.indexOf('.') != -1){
7992
v = "values['" + name + "']";
7995
v = '(' + v + math + ')';
7997
if (format && useF) {
7998
args = args ? ',' + args : "";
7999
if(format.substr(0, 5) != "this."){
8000
format = "fm." + format + '(';
8002
format = 'this.call("'+ format.substr(5) + '", ';
8006
args= ''; format = "("+v+" === undefined ? '' : ";
8008
return "'"+ sep + format + v + args + ")"+sep+"'";
8011
function codeFn(m, code){
8012
return "'"+ sep +'('+code+')'+sep+"'";
8015
// branched to use + in gecko and [].join() in others
8017
body = "tpl.compiled = function(values, parent, xindex, xcount){ return '" +
8018
tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn) +
8021
body = ["tpl.compiled = function(values, parent, xindex, xcount){ return ['"];
8022
body.push(tpl.body.replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.re, fn).replace(this.codeRe, codeFn));
8023
body.push("'].join('');};");
8024
body = body.join('');
8031
applyTemplate : function(values){
8032
return this.master.compiled.call(this, values, {}, 1, 1);
8036
compile : function(){return this;}
8044
Ext.XTemplate.prototype.apply = Ext.XTemplate.prototype.applyTemplate;
8047
Ext.XTemplate.from = function(el){
8048
el = Ext.getDom(el);
8049
return new Ext.XTemplate(el.value || el.innerHTML);
8052
Ext.util.CSS = function(){
8056
var camelRe = /(-[a-z])/gi;
8057
var camelFn = function(m, a){ return a.charAt(1).toUpperCase(); };
8061
createStyleSheet : function(cssText, id){
8063
var head = doc.getElementsByTagName("head")[0];
8064
var rules = doc.createElement("style");
8065
rules.setAttribute("type", "text/css");
8067
rules.setAttribute("id", id);
8070
head.appendChild(rules);
8071
ss = rules.styleSheet;
8072
ss.cssText = cssText;
8075
rules.appendChild(doc.createTextNode(cssText));
8077
rules.cssText = cssText;
8079
head.appendChild(rules);
8080
ss = rules.styleSheet ? rules.styleSheet : (rules.sheet || doc.styleSheets[doc.styleSheets.length-1]);
8082
this.cacheStyleSheet(ss);
8087
removeStyleSheet : function(id){
8088
var existing = doc.getElementById(id);
8090
existing.parentNode.removeChild(existing);
8095
swapStyleSheet : function(id, url){
8096
this.removeStyleSheet(id);
8097
var ss = doc.createElement("link");
8098
ss.setAttribute("rel", "stylesheet");
8099
ss.setAttribute("type", "text/css");
8100
ss.setAttribute("id", id);
8101
ss.setAttribute("href", url);
8102
doc.getElementsByTagName("head")[0].appendChild(ss);
8106
refreshCache : function(){
8107
return this.getRules(true);
8111
cacheStyleSheet : function(ss){
8115
try{// try catch for cross domain access issue
8116
var ssRules = ss.cssRules || ss.rules;
8117
for(var j = ssRules.length-1; j >= 0; --j){
8118
rules[ssRules[j].selectorText] = ssRules[j];
8124
getRules : function(refreshCache){
8125
if(rules == null || refreshCache){
8127
var ds = doc.styleSheets;
8128
for(var i =0, len = ds.length; i < len; i++){
8130
this.cacheStyleSheet(ds[i]);
8138
getRule : function(selector, refreshCache){
8139
var rs = this.getRules(refreshCache);
8140
if(!Ext.isArray(selector)){
8141
return rs[selector];
8143
for(var i = 0; i < selector.length; i++){
8144
if(rs[selector[i]]){
8145
return rs[selector[i]];
8153
updateRule : function(selector, property, value){
8154
if(!Ext.isArray(selector)){
8155
var rule = this.getRule(selector);
8157
rule.style[property.replace(camelRe, camelFn)] = value;
8161
for(var i = 0; i < selector.length; i++){
8162
if(this.updateRule(selector[i], property, value)){
8172
Ext.util.ClickRepeater = function(el, config)
8174
this.el = Ext.get(el);
8175
this.el.unselectable();
8177
Ext.apply(this, config);
8188
this.el.on("mousedown", this.handleMouseDown, this);
8189
if(this.preventDefault || this.stopDefault){
8190
this.el.on("click", function(e){
8191
if(this.preventDefault){
8194
if(this.stopDefault){
8200
// allow inline handler
8202
this.on("click", this.handler, this.scope || this);
8205
Ext.util.ClickRepeater.superclass.constructor.call(this);
8208
Ext.extend(Ext.util.ClickRepeater, Ext.util.Observable, {
8211
preventDefault : true,
8212
stopDefault : false,
8216
destroy : function() {
8217
Ext.destroy(this.el);
8218
this.purgeListeners();
8222
handleMouseDown : function(){
8223
clearTimeout(this.timer);
8225
if(this.pressClass){
8226
this.el.addClass(this.pressClass);
8228
this.mousedownTime = new Date();
8230
Ext.getDoc().on("mouseup", this.handleMouseUp, this);
8231
this.el.on("mouseout", this.handleMouseOut, this);
8233
this.fireEvent("mousedown", this);
8234
this.fireEvent("click", this);
8236
// Do not honor delay or interval if acceleration wanted.
8237
if (this.accelerate) {
8240
this.timer = this.click.defer(this.delay || this.interval, this);
8245
this.fireEvent("click", this);
8246
this.timer = this.click.defer(this.accelerate ?
8247
this.easeOutExpo(this.mousedownTime.getElapsed(),
8251
this.interval, this);
8254
easeOutExpo : function (t, b, c, d) {
8255
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
8259
handleMouseOut : function(){
8260
clearTimeout(this.timer);
8261
if(this.pressClass){
8262
this.el.removeClass(this.pressClass);
8264
this.el.on("mouseover", this.handleMouseReturn, this);
8268
handleMouseReturn : function(){
8269
this.el.un("mouseover", this.handleMouseReturn, this);
8270
if(this.pressClass){
8271
this.el.addClass(this.pressClass);
8277
handleMouseUp : function(){
8278
clearTimeout(this.timer);
8279
this.el.un("mouseover", this.handleMouseReturn, this);
8280
this.el.un("mouseout", this.handleMouseOut, this);
8281
Ext.getDoc().un("mouseup", this.handleMouseUp, this);
8282
this.el.removeClass(this.pressClass);
8283
this.fireEvent("mouseup", this);
8287
Ext.KeyNav = function(el, config){
8288
this.el = Ext.get(el);
8289
Ext.apply(this, config);
8291
this.disabled = true;
8296
Ext.KeyNav.prototype = {
8300
defaultEventAction: "stopEvent",
8302
forceKeyDown : false,
8305
prepareEvent : function(e){
8307
var h = this.keyToHandler[k];
8308
if(Ext.isSafari2 && h && k >= 37 && k <= 40){
8314
relay : function(e){
8316
var h = this.keyToHandler[k];
8318
if(this.doRelay(e, this[h], h) !== true){
8319
e[this.defaultEventAction]();
8325
doRelay : function(e, h, hname){
8326
return h.call(this.scope || this, e);
8329
// possible handlers
8343
// quick lookup hash
8362
// ie won't do special keys on keypress, no one else will repeat keys with keydown
8363
// the EventObject will normalize Safari automatically
8364
if(this.isKeyDown()){
8365
this.el.on("keydown", this.relay, this);
8367
this.el.on("keydown", this.prepareEvent, this);
8368
this.el.on("keypress", this.relay, this);
8370
this.disabled = false;
8375
disable: function(){
8377
if(this.isKeyDown()){
8378
this.el.un("keydown", this.relay, this);
8380
this.el.un("keydown", this.prepareEvent, this);
8381
this.el.un("keypress", this.relay, this);
8383
this.disabled = true;
8388
setDisabled : function(disabled){
8389
this[disabled ? "disable" : "enable"]();
8393
isKeyDown: function(){
8394
return this.forceKeyDown || Ext.isIE || Ext.isSafari3 || Ext.isChrome || Ext.isAir;
8399
Ext.KeyMap = function(el, config, eventName){
8400
this.el = Ext.get(el);
8401
this.eventName = eventName || "keydown";
8404
this.addBinding(config);
8409
Ext.KeyMap.prototype = {
8414
addBinding : function(config){
8415
if(Ext.isArray(config)){
8416
for(var i = 0, len = config.length; i < len; i++){
8417
this.addBinding(config[i]);
8421
var keyCode = config.key,
8422
fn = config.fn || config.handler,
8423
scope = config.scope;
8425
if (config.stopEvent) {
8426
this.stopEvent = config.stopEvent;
8429
if(typeof keyCode == "string"){
8431
var keyString = keyCode.toUpperCase();
8432
for(var j = 0, len = keyString.length; j < len; j++){
8433
ks.push(keyString.charCodeAt(j));
8437
var keyArray = Ext.isArray(keyCode);
8439
var handler = function(e){
8440
if(this.checkModifiers(config, e)){
8443
for(var i = 0, len = keyCode.length; i < len; i++){
8444
if(keyCode[i] == k){
8448
fn.call(scope || window, k, e);
8457
fn.call(scope || window, k, e);
8462
this.bindings.push(handler);
8466
checkModifiers: function(config, e){
8467
var val, key, keys = ['shift', 'ctrl', 'alt'];
8468
for (var i = 0, len = keys.length; i < len; ++i){
8469
key = keys[i], val = config[key];
8470
if(!(val === undefined || (val === e[key + 'Key']))){
8478
on : function(key, fn, scope){
8479
var keyCode, shift, ctrl, alt;
8480
if(typeof key == "object" && !Ext.isArray(key)){
8499
handleKeyDown : function(e){
8500
if(this.enabled){ //just in case
8501
var b = this.bindings;
8502
for(var i = 0, len = b.length; i < len; i++){
8509
isEnabled : function(){
8510
return this.enabled;
8516
this.el.on(this.eventName, this.handleKeyDown, this);
8517
this.enabled = true;
8522
disable: function(){
8524
this.el.removeListener(this.eventName, this.handleKeyDown, this);
8525
this.enabled = false;
8530
setDisabled : function(disabled){
8531
this[disabled ? "disable" : "enable"]();
8535
Ext.util.TextMetrics = function(){
8539
measure : function(el, text, fixedWidth){
8541
shared = Ext.util.TextMetrics.Instance(el, fixedWidth);
8544
shared.setFixedWidth(fixedWidth || 'auto');
8545
return shared.getSize(text);
8549
createInstance : function(el, fixedWidth){
8550
return Ext.util.TextMetrics.Instance(el, fixedWidth);
8555
Ext.util.TextMetrics.Instance = function(bindTo, fixedWidth){
8556
var ml = new Ext.Element(document.createElement('div'));
8557
document.body.appendChild(ml.dom);
8558
ml.position('absolute');
8559
ml.setLeftTop(-1000, -1000);
8563
ml.setWidth(fixedWidth);
8568
getSize : function(text){
8570
var s = ml.getSize();
8576
bind : function(el){
8578
Ext.fly(el).getStyles('font-size','font-style', 'font-weight', 'font-family','line-height', 'text-transform', 'letter-spacing')
8583
setFixedWidth : function(width){
8588
getWidth : function(text){
8589
ml.dom.style.width = 'auto';
8590
return this.getSize(text).width;
8594
getHeight : function(text){
8595
return this.getSize(text).height;
8599
instance.bind(bindTo);
8604
Ext.Element.addMethods({
8606
getTextWidth : function(text, min, max){
8607
return (Ext.util.TextMetrics.measure(this.dom, Ext.value(text, this.dom.innerHTML, true)).width).constrain(min || 0, max || 1000000);
8615
var Event=Ext.EventManager;
8616
var Dom=Ext.lib.Dom;
8619
Ext.dd.DragDrop = function(id, sGroup, config) {
8621
this.init(id, sGroup, config);
8625
Ext.dd.DragDrop.prototype = {
8642
invalidHandleTypes: null,
8645
invalidHandleIds: null,
8648
invalidHandleClasses: null,
8663
lock: function() { this.locked = true; },
8669
unlock: function() { this.locked = false; },
8702
maintainOffset: false,
8711
primaryButtonOnly: true,
8717
hasOuterHandles: false,
8720
b4StartDrag: function(x, y) { },
8723
startDrag: function(x, y) { },
8726
b4Drag: function(e) { },
8729
onDrag: function(e) { },
8732
onDragEnter: function(e, id) { },
8735
b4DragOver: function(e) { },
8738
onDragOver: function(e, id) { },
8741
b4DragOut: function(e) { },
8744
onDragOut: function(e, id) { },
8747
b4DragDrop: function(e) { },
8750
onDragDrop: function(e, id) { },
8753
onInvalidDrop: function(e) { },
8756
b4EndDrag: function(e) { },
8759
endDrag: function(e) { },
8762
b4MouseDown: function(e) { },
8765
onMouseDown: function(e) { },
8768
onMouseUp: function(e) { },
8771
onAvailable: function () {
8775
defaultPadding : {left:0, right:0, top:0, bottom:0},
8778
constrainTo : function(constrainTo, pad, inContent){
8779
if(typeof pad == "number"){
8780
pad = {left: pad, right:pad, top:pad, bottom:pad};
8782
pad = pad || this.defaultPadding;
8783
var b = Ext.get(this.getEl()).getBox();
8784
var ce = Ext.get(constrainTo);
8785
var s = ce.getScroll();
8787
if(cd == document.body){
8788
c = { x: s.left, y: s.top, width: Ext.lib.Dom.getViewWidth(), height: Ext.lib.Dom.getViewHeight()};
8790
var xy = ce.getXY();
8791
c = {x : xy[0]+s.left, y: xy[1]+s.top, width: cd.clientWidth, height: cd.clientHeight};
8795
var topSpace = b.y - c.y;
8796
var leftSpace = b.x - c.x;
8798
this.resetConstraints();
8799
this.setXConstraint(leftSpace - (pad.left||0), // left
8800
c.width - leftSpace - b.width - (pad.right||0), //right
8803
this.setYConstraint(topSpace - (pad.top||0), //top
8804
c.height - topSpace - b.height - (pad.bottom||0), //bottom
8811
if (!this._domRef) {
8812
this._domRef = Ext.getDom(this.id);
8815
return this._domRef;
8819
getDragEl: function() {
8820
return Ext.getDom(this.dragElId);
8824
init: function(id, sGroup, config) {
8825
this.initTarget(id, sGroup, config);
8826
Event.on(this.id, "mousedown", this.handleMouseDown, this);
8827
// Event.on(this.id, "selectstart", Event.preventDefault);
8831
initTarget: function(id, sGroup, config) {
8833
// configuration attributes
8834
this.config = config || {};
8836
// create a local reference to the drag and drop manager
8837
this.DDM = Ext.dd.DDM;
8838
// initialize the groups array
8841
// assume that we have an element reference instead of an id if the
8842
// parameter is not a string
8843
if (typeof id !== "string") {
8850
// add to an interaction group
8851
this.addToGroup((sGroup) ? sGroup : "default");
8853
// We don't want to register this as the handle with the manager
8854
// so we just set the id rather than calling the setter.
8855
this.handleElId = id;
8857
// the linked element is the element that gets dragged by default
8858
this.setDragElId(id);
8860
// by default, clicked anchors will not start drag operations.
8861
this.invalidHandleTypes = { A: "A" };
8862
this.invalidHandleIds = {};
8863
this.invalidHandleClasses = [];
8867
this.handleOnAvailable();
8871
applyConfig: function() {
8873
// configurable properties:
8874
// padding, isTarget, maintainOffset, primaryButtonOnly
8875
this.padding = this.config.padding || [0, 0, 0, 0];
8876
this.isTarget = (this.config.isTarget !== false);
8877
this.maintainOffset = (this.config.maintainOffset);
8878
this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);
8883
handleOnAvailable: function() {
8884
this.available = true;
8885
this.resetConstraints();
8890
setPadding: function(iTop, iRight, iBot, iLeft) {
8891
// this.padding = [iLeft, iRight, iTop, iBot];
8892
if (!iRight && 0 !== iRight) {
8893
this.padding = [iTop, iTop, iTop, iTop];
8894
} else if (!iBot && 0 !== iBot) {
8895
this.padding = [iTop, iRight, iTop, iRight];
8897
this.padding = [iTop, iRight, iBot, iLeft];
8902
setInitPosition: function(diffX, diffY) {
8903
var el = this.getEl();
8905
if (!this.DDM.verifyEl(el)) {
8909
var dx = diffX || 0;
8910
var dy = diffY || 0;
8912
var p = Dom.getXY( el );
8914
this.initPageX = p[0] - dx;
8915
this.initPageY = p[1] - dy;
8917
this.lastPageX = p[0];
8918
this.lastPageY = p[1];
8921
this.setStartPosition(p);
8925
setStartPosition: function(pos) {
8926
var p = pos || Dom.getXY( this.getEl() );
8927
this.deltaSetXY = null;
8929
this.startPageX = p[0];
8930
this.startPageY = p[1];
8934
addToGroup: function(sGroup) {
8935
this.groups[sGroup] = true;
8936
this.DDM.regDragDrop(this, sGroup);
8940
removeFromGroup: function(sGroup) {
8941
if (this.groups[sGroup]) {
8942
delete this.groups[sGroup];
8945
this.DDM.removeDDFromGroup(this, sGroup);
8949
setDragElId: function(id) {
8954
setHandleElId: function(id) {
8955
if (typeof id !== "string") {
8958
this.handleElId = id;
8959
this.DDM.regHandle(this.id, id);
8963
setOuterHandleElId: function(id) {
8964
if (typeof id !== "string") {
8967
Event.on(id, "mousedown",
8968
this.handleMouseDown, this);
8969
this.setHandleElId(id);
8971
this.hasOuterHandles = true;
8976
Event.un(this.id, "mousedown",
8977
this.handleMouseDown);
8978
this._domRef = null;
8979
this.DDM._remove(this);
8982
destroy : function(){
8987
isLocked: function() {
8988
return (this.DDM.isLocked() || this.locked);
8992
handleMouseDown: function(e, oDD){
8993
if (this.primaryButtonOnly && e.button != 0) {
8997
if (this.isLocked()) {
9001
this.DDM.refreshCache(this.groups);
9003
var pt = new Ext.lib.Point(Ext.lib.Event.getPageX(e), Ext.lib.Event.getPageY(e));
9004
if (!this.hasOuterHandles && !this.DDM.isOverTarget(pt, this) ) {
9006
if (this.clickValidator(e)) {
9008
// set the initial element position
9009
this.setStartPosition();
9012
this.b4MouseDown(e);
9013
this.onMouseDown(e);
9015
this.DDM.handleMouseDown(e, this);
9017
this.DDM.stopEvent(e);
9025
clickValidator: function(e) {
9026
var target = e.getTarget();
9027
return ( this.isValidHandleChild(target) &&
9028
(this.id == this.handleElId ||
9029
this.DDM.handleWasClicked(target, this.id)) );
9033
addInvalidHandleType: function(tagName) {
9034
var type = tagName.toUpperCase();
9035
this.invalidHandleTypes[type] = type;
9039
addInvalidHandleId: function(id) {
9040
if (typeof id !== "string") {
9043
this.invalidHandleIds[id] = id;
9047
addInvalidHandleClass: function(cssClass) {
9048
this.invalidHandleClasses.push(cssClass);
9052
removeInvalidHandleType: function(tagName) {
9053
var type = tagName.toUpperCase();
9054
// this.invalidHandleTypes[type] = null;
9055
delete this.invalidHandleTypes[type];
9059
removeInvalidHandleId: function(id) {
9060
if (typeof id !== "string") {
9063
delete this.invalidHandleIds[id];
9067
removeInvalidHandleClass: function(cssClass) {
9068
for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
9069
if (this.invalidHandleClasses[i] == cssClass) {
9070
delete this.invalidHandleClasses[i];
9076
isValidHandleChild: function(node) {
9079
// var n = (node.nodeName == "#text") ? node.parentNode : node;
9082
nodeName = node.nodeName.toUpperCase();
9084
nodeName = node.nodeName;
9086
valid = valid && !this.invalidHandleTypes[nodeName];
9087
valid = valid && !this.invalidHandleIds[node.id];
9089
for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
9090
valid = !Ext.fly(node).hasClass(this.invalidHandleClasses[i]);
9099
setXTicks: function(iStartX, iTickSize) {
9101
this.xTickSize = iTickSize;
9105
for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
9107
this.xTicks[this.xTicks.length] = i;
9112
for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
9114
this.xTicks[this.xTicks.length] = i;
9119
this.xTicks.sort(this.DDM.numericSort) ;
9123
setYTicks: function(iStartY, iTickSize) {
9125
this.yTickSize = iTickSize;
9129
for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
9131
this.yTicks[this.yTicks.length] = i;
9136
for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
9138
this.yTicks[this.yTicks.length] = i;
9143
this.yTicks.sort(this.DDM.numericSort) ;
9147
setXConstraint: function(iLeft, iRight, iTickSize) {
9148
this.leftConstraint = iLeft;
9149
this.rightConstraint = iRight;
9151
this.minX = this.initPageX - iLeft;
9152
this.maxX = this.initPageX + iRight;
9153
if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }
9155
this.constrainX = true;
9159
clearConstraints: function() {
9160
this.constrainX = false;
9161
this.constrainY = false;
9166
clearTicks: function() {
9174
setYConstraint: function(iUp, iDown, iTickSize) {
9175
this.topConstraint = iUp;
9176
this.bottomConstraint = iDown;
9178
this.minY = this.initPageY - iUp;
9179
this.maxY = this.initPageY + iDown;
9180
if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }
9182
this.constrainY = true;
9187
resetConstraints: function() {
9190
// Maintain offsets if necessary
9191
if (this.initPageX || this.initPageX === 0) {
9192
// figure out how much this thing has moved
9193
var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
9194
var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;
9196
this.setInitPosition(dx, dy);
9198
// This is the first time we have detected the element's position
9200
this.setInitPosition();
9203
if (this.constrainX) {
9204
this.setXConstraint( this.leftConstraint,
9205
this.rightConstraint,
9209
if (this.constrainY) {
9210
this.setYConstraint( this.topConstraint,
9211
this.bottomConstraint,
9217
getTick: function(val, tickArray) {
9220
// If tick interval is not defined, it is effectively 1 pixel,
9221
// so we return the value passed to us.
9223
} else if (tickArray[0] >= val) {
9224
// The value is lower than the first tick, so we return the first
9226
return tickArray[0];
9228
for (var i=0, len=tickArray.length; i<len; ++i) {
9230
if (tickArray[next] && tickArray[next] >= val) {
9231
var diff1 = val - tickArray[i];
9232
var diff2 = tickArray[next] - val;
9233
return (diff2 > diff1) ? tickArray[i] : tickArray[next];
9237
// The value is larger than the last tick, so we return the last
9239
return tickArray[tickArray.length - 1];
9244
toString: function() {
9245
return ("DragDrop " + this.id);
9253
// Only load the library once. Rewriting the manager class would orphan
9254
// existing drag and drop instances.
9255
if (!Ext.dd.DragDropMgr) {
9258
Ext.dd.DragDropMgr = function() {
9260
var Event = Ext.EventManager;
9283
preventDefault: true,
9286
stopPropagation: true,
9296
this.initialized = true;
9309
_execOnAll: function(sMethod, args) {
9310
for (var i in this.ids) {
9311
for (var j in this.ids[i]) {
9312
var oDD = this.ids[i][j];
9313
if (! this.isTypeOfDD(oDD)) {
9316
oDD[sMethod].apply(oDD, args);
9322
_onLoad: function() {
9327
Event.on(document, "mouseup", this.handleMouseUp, this, true);
9328
Event.on(document, "mousemove", this.handleMouseMove, this, true);
9329
Event.on(window, "unload", this._onUnload, this, true);
9330
Event.on(window, "resize", this._onResize, this, true);
9331
// Event.on(window, "mouseout", this._test);
9336
_onResize: function(e) {
9337
this._execOnAll("resetConstraints", []);
9341
lock: function() { this.locked = true; },
9344
unlock: function() { this.locked = false; },
9347
isLocked: function() { return this.locked; },
9356
clickPixelThresh: 3,
9359
clickTimeThresh: 350,
9362
dragThreshMet: false,
9374
regDragDrop: function(oDD, sGroup) {
9375
if (!this.initialized) { this.init(); }
9377
if (!this.ids[sGroup]) {
9378
this.ids[sGroup] = {};
9380
this.ids[sGroup][oDD.id] = oDD;
9384
removeDDFromGroup: function(oDD, sGroup) {
9385
if (!this.ids[sGroup]) {
9386
this.ids[sGroup] = {};
9389
var obj = this.ids[sGroup];
9390
if (obj && obj[oDD.id]) {
9396
_remove: function(oDD) {
9397
for (var g in oDD.groups) {
9398
if (g && this.ids[g] && this.ids[g][oDD.id]) {
9399
delete this.ids[g][oDD.id];
9402
delete this.handleIds[oDD.id];
9406
regHandle: function(sDDId, sHandleId) {
9407
if (!this.handleIds[sDDId]) {
9408
this.handleIds[sDDId] = {};
9410
this.handleIds[sDDId][sHandleId] = sHandleId;
9414
isDragDrop: function(id) {
9415
return ( this.getDDById(id) ) ? true : false;
9419
getRelated: function(p_oDD, bTargetsOnly) {
9421
for (var i in p_oDD.groups) {
9422
for (var j in this.ids[i]) {
9423
var dd = this.ids[i][j];
9424
if (! this.isTypeOfDD(dd)) {
9427
if (!bTargetsOnly || dd.isTarget) {
9428
oDDs[oDDs.length] = dd;
9437
isLegalTarget: function (oDD, oTargetDD) {
9438
var targets = this.getRelated(oDD, true);
9439
for (var i=0, len=targets.length;i<len;++i) {
9440
if (targets[i].id == oTargetDD.id) {
9449
isTypeOfDD: function (oDD) {
9450
return (oDD && oDD.__ygDragDrop);
9454
isHandle: function(sDDId, sHandleId) {
9455
return ( this.handleIds[sDDId] &&
9456
this.handleIds[sDDId][sHandleId] );
9460
getDDById: function(id) {
9461
for (var i in this.ids) {
9462
if (this.ids[i][id]) {
9463
return this.ids[i][id];
9470
handleMouseDown: function(e, oDD) {
9472
Ext.QuickTips.disable();
9474
if(this.dragCurrent){
9475
// the original browser mouseup wasn't handled (e.g. outside FF browser window)
9476
// so clean up first to avoid breaking the next drag
9477
this.handleMouseUp(e);
9480
this.currentTarget = e.getTarget();
9481
this.dragCurrent = oDD;
9483
var el = oDD.getEl();
9485
// track start position
9486
this.startX = e.getPageX();
9487
this.startY = e.getPageY();
9489
this.deltaX = this.startX - el.offsetLeft;
9490
this.deltaY = this.startY - el.offsetTop;
9492
this.dragThreshMet = false;
9494
this.clickTimeout = setTimeout(
9496
var DDM = Ext.dd.DDM;
9497
DDM.startDrag(DDM.startX, DDM.startY);
9499
this.clickTimeThresh );
9503
startDrag: function(x, y) {
9504
clearTimeout(this.clickTimeout);
9505
if (this.dragCurrent) {
9506
this.dragCurrent.b4StartDrag(x, y);
9507
this.dragCurrent.startDrag(x, y);
9509
this.dragThreshMet = true;
9513
handleMouseUp: function(e) {
9516
Ext.QuickTips.enable();
9518
if (! this.dragCurrent) {
9522
clearTimeout(this.clickTimeout);
9524
if (this.dragThreshMet) {
9525
this.fireEvents(e, true);
9535
stopEvent: function(e){
9536
if(this.stopPropagation) {
9537
e.stopPropagation();
9540
if (this.preventDefault) {
9546
stopDrag: function(e) {
9547
// Fire the drag end event for the item that was dragged
9548
if (this.dragCurrent) {
9549
if (this.dragThreshMet) {
9550
this.dragCurrent.b4EndDrag(e);
9551
this.dragCurrent.endDrag(e);
9554
this.dragCurrent.onMouseUp(e);
9557
this.dragCurrent = null;
9558
this.dragOvers = {};
9562
handleMouseMove: function(e) {
9563
if (! this.dragCurrent) {
9566
// var button = e.which || e.button;
9568
// check for IE mouseup outside of page boundary
9569
if (Ext.isIE && (e.button !== 0 && e.button !== 1 && e.button !== 2)) {
9571
return this.handleMouseUp(e);
9574
if (!this.dragThreshMet) {
9575
var diffX = Math.abs(this.startX - e.getPageX());
9576
var diffY = Math.abs(this.startY - e.getPageY());
9577
if (diffX > this.clickPixelThresh ||
9578
diffY > this.clickPixelThresh) {
9579
this.startDrag(this.startX, this.startY);
9583
if (this.dragThreshMet) {
9584
this.dragCurrent.b4Drag(e);
9585
this.dragCurrent.onDrag(e);
9586
if(!this.dragCurrent.moveOnly){
9587
this.fireEvents(e, false);
9597
fireEvents: function(e, isDrop) {
9598
var dc = this.dragCurrent;
9600
// If the user did the mouse up outside of the window, we could
9601
// get here even though we have ended the drag.
9602
if (!dc || dc.isLocked()) {
9606
var pt = e.getPoint();
9608
// cache the previous dragOver array
9616
// Check to see if the object(s) we were hovering over is no longer
9617
// being hovered over so we can fire the onDragOut event
9618
for (var i in this.dragOvers) {
9620
var ddo = this.dragOvers[i];
9622
if (! this.isTypeOfDD(ddo)) {
9626
if (! this.isOverTarget(pt, ddo, this.mode)) {
9627
outEvts.push( ddo );
9631
delete this.dragOvers[i];
9634
for (var sGroup in dc.groups) {
9636
if ("string" != typeof sGroup) {
9640
for (i in this.ids[sGroup]) {
9641
var oDD = this.ids[sGroup][i];
9642
if (! this.isTypeOfDD(oDD)) {
9646
if (oDD.isTarget && !oDD.isLocked() && ((oDD != dc) || (dc.ignoreSelf === false))) {
9647
if (this.isOverTarget(pt, oDD, this.mode)) {
9648
// look for drop interactions
9650
dropEvts.push( oDD );
9651
// look for drag enter and drag over interactions
9654
// initial drag over: dragEnter fires
9655
if (!oldOvers[oDD.id]) {
9656
enterEvts.push( oDD );
9657
// subsequent drag overs: dragOver fires
9659
overEvts.push( oDD );
9662
this.dragOvers[oDD.id] = oDD;
9670
if (outEvts.length) {
9671
dc.b4DragOut(e, outEvts);
9672
dc.onDragOut(e, outEvts);
9675
if (enterEvts.length) {
9676
dc.onDragEnter(e, enterEvts);
9679
if (overEvts.length) {
9680
dc.b4DragOver(e, overEvts);
9681
dc.onDragOver(e, overEvts);
9684
if (dropEvts.length) {
9685
dc.b4DragDrop(e, dropEvts);
9686
dc.onDragDrop(e, dropEvts);
9690
// fire dragout events
9692
for (i=0, len=outEvts.length; i<len; ++i) {
9693
dc.b4DragOut(e, outEvts[i].id);
9694
dc.onDragOut(e, outEvts[i].id);
9697
// fire enter events
9698
for (i=0,len=enterEvts.length; i<len; ++i) {
9699
// dc.b4DragEnter(e, oDD.id);
9700
dc.onDragEnter(e, enterEvts[i].id);
9704
for (i=0,len=overEvts.length; i<len; ++i) {
9705
dc.b4DragOver(e, overEvts[i].id);
9706
dc.onDragOver(e, overEvts[i].id);
9710
for (i=0, len=dropEvts.length; i<len; ++i) {
9711
dc.b4DragDrop(e, dropEvts[i].id);
9712
dc.onDragDrop(e, dropEvts[i].id);
9717
// notify about a drop that did not find a target
9718
if (isDrop && !dropEvts.length) {
9719
dc.onInvalidDrop(e);
9725
getBestMatch: function(dds) {
9727
// Return null if the input is not what we expect
9728
//if (!dds || !dds.length || dds.length == 0) {
9730
// If there is only one item, it wins
9731
//} else if (dds.length == 1) {
9733
var len = dds.length;
9738
// Loop through the targeted items
9739
for (var i=0; i<len; ++i) {
9741
// If the cursor is over the object, it wins. If the
9742
// cursor is over multiple matches, the first one we come
9744
if (dd.cursorIsOver) {
9747
// Otherwise the object with the most overlap wins
9750
winner.overlap.getArea() < dd.overlap.getArea()) {
9761
refreshCache: function(groups) {
9762
for (var sGroup in groups) {
9763
if ("string" != typeof sGroup) {
9766
for (var i in this.ids[sGroup]) {
9767
var oDD = this.ids[sGroup][i];
9769
if (this.isTypeOfDD(oDD)) {
9770
// if (this.isTypeOfDD(oDD) && oDD.isTarget) {
9771
var loc = this.getLocation(oDD);
9773
this.locationCache[oDD.id] = loc;
9775
delete this.locationCache[oDD.id];
9776
// this will unregister the drag and drop object if
9777
// the element is not in a usable state
9786
verifyEl: function(el) {
9791
parent = el.offsetParent;
9794
parent = el.offsetParent;
9805
getLocation: function(oDD) {
9806
if (! this.isTypeOfDD(oDD)) {
9810
var el = oDD.getEl(), pos, x1, x2, y1, y2, t, r, b, l;
9813
pos= Ext.lib.Dom.getXY(el);
9821
x2 = x1 + el.offsetWidth;
9823
y2 = y1 + el.offsetHeight;
9825
t = y1 - oDD.padding[0];
9826
r = x2 + oDD.padding[1];
9827
b = y2 + oDD.padding[2];
9828
l = x1 - oDD.padding[3];
9830
return new Ext.lib.Region( t, r, b, l );
9834
isOverTarget: function(pt, oTarget, intersect) {
9835
// use cache if available
9836
var loc = this.locationCache[oTarget.id];
9837
if (!loc || !this.useCache) {
9838
loc = this.getLocation(oTarget);
9839
this.locationCache[oTarget.id] = loc;
9847
oTarget.cursorIsOver = loc.contains( pt );
9849
// DragDrop is using this as a sanity check for the initial mousedown
9850
// in this case we are done. In POINT mode, if the drag obj has no
9851
// contraints, we are also done. Otherwise we need to evaluate the
9852
// location of the target as related to the actual location of the
9854
var dc = this.dragCurrent;
9855
if (!dc || !dc.getTargetCoord ||
9856
(!intersect && !dc.constrainX && !dc.constrainY)) {
9857
return oTarget.cursorIsOver;
9860
oTarget.overlap = null;
9862
// Get the current location of the drag element, this is the
9863
// location of the mouse event less the delta that represents
9864
// where the original mousedown happened on the element. We
9865
// need to consider constraints and ticks as well.
9866
var pos = dc.getTargetCoord(pt.x, pt.y);
9868
var el = dc.getDragEl();
9869
var curRegion = new Ext.lib.Region( pos.y,
9870
pos.x + el.offsetWidth,
9871
pos.y + el.offsetHeight,
9874
var overlap = curRegion.intersect(loc);
9877
oTarget.overlap = overlap;
9878
return (intersect) ? true : oTarget.cursorIsOver;
9885
_onUnload: function(e, me) {
9886
Ext.dd.DragDropMgr.unregAll();
9890
unregAll: function() {
9892
if (this.dragCurrent) {
9894
this.dragCurrent = null;
9897
this._execOnAll("unreg", []);
9899
for (var i in this.elementCache) {
9900
delete this.elementCache[i];
9903
this.elementCache = {};
9911
getElWrapper: function(id) {
9912
var oWrapper = this.elementCache[id];
9913
if (!oWrapper || !oWrapper.el) {
9914
oWrapper = this.elementCache[id] =
9915
new this.ElementWrapper(Ext.getDom(id));
9921
getElement: function(id) {
9922
return Ext.getDom(id);
9926
getCss: function(id) {
9927
var el = Ext.getDom(id);
9928
return (el) ? el.style : null;
9932
ElementWrapper: function(el) {
9934
this.el = el || null;
9936
this.id = this.el && el.id;
9938
this.css = this.el && el.style;
9942
getPosX: function(el) {
9943
return Ext.lib.Dom.getX(el);
9947
getPosY: function(el) {
9948
return Ext.lib.Dom.getY(el);
9952
swapNode: function(n1, n2) {
9956
var p = n2.parentNode;
9957
var s = n2.nextSibling;
9960
p.insertBefore(n1, n2);
9961
} else if (n2 == n1.nextSibling) {
9962
p.insertBefore(n2, n1);
9964
n1.parentNode.replaceChild(n2, n1);
9965
p.insertBefore(n1, s);
9971
getScroll: function () {
9972
var t, l, dde=document.documentElement, db=document.body;
9973
if (dde && (dde.scrollTop || dde.scrollLeft)) {
9982
return { top: t, left: l };
9986
getStyle: function(el, styleProp) {
9987
return Ext.fly(el).getStyle(styleProp);
9991
getScrollTop: function () { return this.getScroll().top; },
9994
getScrollLeft: function () { return this.getScroll().left; },
9997
moveToEl: function (moveEl, targetEl) {
9998
var aCoord = Ext.lib.Dom.getXY(targetEl);
9999
Ext.lib.Dom.setXY(moveEl, aCoord);
10003
numericSort: function(a, b) { return (a - b); },
10009
_addListeners: function() {
10010
var DDM = Ext.dd.DDM;
10011
if ( Ext.lib.Event && document ) {
10014
if (DDM._timeoutCount > 2000) {
10016
setTimeout(DDM._addListeners, 10);
10017
if (document && document.body) {
10018
DDM._timeoutCount += 1;
10025
handleWasClicked: function(node, id) {
10026
if (this.isHandle(id, node.id)) {
10029
// check to see if this is a text node child of the one we want
10030
var p = node.parentNode;
10033
if (this.isHandle(id, p.id)) {
10048
// shorter alias, save a few bytes
10049
Ext.dd.DDM = Ext.dd.DragDropMgr;
10050
Ext.dd.DDM._addListeners();
10055
Ext.dd.DD = function(id, sGroup, config) {
10057
this.init(id, sGroup, config);
10061
Ext.extend(Ext.dd.DD, Ext.dd.DragDrop, {
10067
autoOffset: function(iPageX, iPageY) {
10068
var x = iPageX - this.startPageX;
10069
var y = iPageY - this.startPageY;
10070
this.setDelta(x, y);
10074
setDelta: function(iDeltaX, iDeltaY) {
10075
this.deltaX = iDeltaX;
10076
this.deltaY = iDeltaY;
10080
setDragElPos: function(iPageX, iPageY) {
10081
// the first time we do this, we are going to check to make sure
10082
// the element has css positioning
10084
var el = this.getDragEl();
10085
this.alignElWithMouse(el, iPageX, iPageY);
10089
alignElWithMouse: function(el, iPageX, iPageY) {
10090
var oCoord = this.getTargetCoord(iPageX, iPageY);
10091
var fly = el.dom ? el : Ext.fly(el, '_dd');
10092
if (!this.deltaSetXY) {
10093
var aCoord = [oCoord.x, oCoord.y];
10095
var newLeft = fly.getLeft(true);
10096
var newTop = fly.getTop(true);
10097
this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
10099
fly.setLeftTop(oCoord.x + this.deltaSetXY[0], oCoord.y + this.deltaSetXY[1]);
10102
this.cachePosition(oCoord.x, oCoord.y);
10103
this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
10108
cachePosition: function(iPageX, iPageY) {
10110
this.lastPageX = iPageX;
10111
this.lastPageY = iPageY;
10113
var aCoord = Ext.lib.Dom.getXY(this.getEl());
10114
this.lastPageX = aCoord[0];
10115
this.lastPageY = aCoord[1];
10120
autoScroll: function(x, y, h, w) {
10123
// The client height
10124
var clientH = Ext.lib.Dom.getViewHeight();
10126
// The client width
10127
var clientW = Ext.lib.Dom.getViewWidth();
10129
// The amt scrolled down
10130
var st = this.DDM.getScrollTop();
10132
// The amt scrolled right
10133
var sl = this.DDM.getScrollLeft();
10135
// Location of the bottom of the element
10138
// Location of the right of the element
10141
// The distance from the cursor to the bottom of the visible area,
10142
// adjusted so that we don't scroll if the cursor is beyond the
10143
// element drag constraints
10144
var toBot = (clientH + st - y - this.deltaY);
10146
// The distance from the cursor to the right of the visible area
10147
var toRight = (clientW + sl - x - this.deltaX);
10150
// How close to the edge the cursor must be before we scroll
10151
// var thresh = (document.all) ? 100 : 40;
10154
// How many pixels to scroll per autoscroll op. This helps to reduce
10155
// clunky scrolling. IE is more sensitive about this ... it needs this
10156
// value to be higher.
10157
var scrAmt = (document.all) ? 80 : 30;
10159
// Scroll down if we are near the bottom of the visible page and the
10160
// obj extends below the crease
10161
if ( bot > clientH && toBot < thresh ) {
10162
window.scrollTo(sl, st + scrAmt);
10165
// Scroll up if the window is scrolled down and the top of the object
10166
// goes above the top border
10167
if ( y < st && st > 0 && y - st < thresh ) {
10168
window.scrollTo(sl, st - scrAmt);
10171
// Scroll right if the obj is beyond the right border and the cursor is
10172
// near the border.
10173
if ( right > clientW && toRight < thresh ) {
10174
window.scrollTo(sl + scrAmt, st);
10177
// Scroll left if the window has been scrolled to the right and the obj
10178
// extends past the left border
10179
if ( x < sl && sl > 0 && x - sl < thresh ) {
10180
window.scrollTo(sl - scrAmt, st);
10186
getTargetCoord: function(iPageX, iPageY) {
10189
var x = iPageX - this.deltaX;
10190
var y = iPageY - this.deltaY;
10192
if (this.constrainX) {
10193
if (x < this.minX) { x = this.minX; }
10194
if (x > this.maxX) { x = this.maxX; }
10197
if (this.constrainY) {
10198
if (y < this.minY) { y = this.minY; }
10199
if (y > this.maxY) { y = this.maxY; }
10202
x = this.getTick(x, this.xTicks);
10203
y = this.getTick(y, this.yTicks);
10210
applyConfig: function() {
10211
Ext.dd.DD.superclass.applyConfig.call(this);
10212
this.scroll = (this.config.scroll !== false);
10216
b4MouseDown: function(e) {
10217
// this.resetConstraints();
10218
this.autoOffset(e.getPageX(),
10223
b4Drag: function(e) {
10224
this.setDragElPos(e.getPageX(),
10228
toString: function() {
10229
return ("DD " + this.id);
10232
//////////////////////////////////////////////////////////////////////////
10233
// Debugging ygDragDrop events that can be overridden
10234
//////////////////////////////////////////////////////////////////////////
10239
Ext.dd.DDProxy = function(id, sGroup, config) {
10241
this.init(id, sGroup, config);
10247
Ext.dd.DDProxy.dragElId = "ygddfdiv";
10249
Ext.extend(Ext.dd.DDProxy, Ext.dd.DD, {
10255
centerFrame: false,
10258
createFrame: function() {
10260
var body = document.body;
10262
if (!body || !body.firstChild) {
10263
setTimeout( function() { self.createFrame(); }, 50 );
10267
var div = this.getDragEl();
10270
div = document.createElement("div");
10271
div.id = this.dragElId;
10274
s.position = "absolute";
10275
s.visibility = "hidden";
10277
s.border = "2px solid #aaa";
10280
// appendChild can blow up IE if invoked prior to the window load event
10281
// while rendering a table. It is possible there are other scenarios
10282
// that would cause this to happen as well.
10283
body.insertBefore(div, body.firstChild);
10288
initFrame: function() {
10289
this.createFrame();
10292
applyConfig: function() {
10293
Ext.dd.DDProxy.superclass.applyConfig.call(this);
10295
this.resizeFrame = (this.config.resizeFrame !== false);
10296
this.centerFrame = (this.config.centerFrame);
10297
this.setDragElId(this.config.dragElId || Ext.dd.DDProxy.dragElId);
10301
showFrame: function(iPageX, iPageY) {
10302
var el = this.getEl();
10303
var dragEl = this.getDragEl();
10304
var s = dragEl.style;
10306
this._resizeProxy();
10308
if (this.centerFrame) {
10309
this.setDelta( Math.round(parseInt(s.width, 10)/2),
10310
Math.round(parseInt(s.height, 10)/2) );
10313
this.setDragElPos(iPageX, iPageY);
10315
Ext.fly(dragEl).show();
10319
_resizeProxy: function() {
10320
if (this.resizeFrame) {
10321
var el = this.getEl();
10322
Ext.fly(this.getDragEl()).setSize(el.offsetWidth, el.offsetHeight);
10326
// overrides Ext.dd.DragDrop
10327
b4MouseDown: function(e) {
10328
var x = e.getPageX();
10329
var y = e.getPageY();
10330
this.autoOffset(x, y);
10331
this.setDragElPos(x, y);
10334
// overrides Ext.dd.DragDrop
10335
b4StartDrag: function(x, y) {
10336
// show the drag frame
10337
this.showFrame(x, y);
10340
// overrides Ext.dd.DragDrop
10341
b4EndDrag: function(e) {
10342
Ext.fly(this.getDragEl()).hide();
10345
// overrides Ext.dd.DragDrop
10346
// By default we try to move the element to the last location of the frame.
10347
// This is so that the default behavior mirrors that of Ext.dd.DD.
10348
endDrag: function(e) {
10350
var lel = this.getEl();
10351
var del = this.getDragEl();
10353
// Show the drag frame briefly so we can get its position
10354
del.style.visibility = "";
10357
// Hide the linked element before the move to get around a Safari
10359
lel.style.visibility = "hidden";
10360
Ext.dd.DDM.moveToEl(lel, del);
10361
del.style.visibility = "hidden";
10362
lel.style.visibility = "";
10367
beforeMove : function(){
10371
afterDrag : function(){
10375
toString: function() {
10376
return ("DDProxy " + this.id);
10381
Ext.dd.DDTarget = function(id, sGroup, config) {
10383
this.initTarget(id, sGroup, config);
10387
// Ext.dd.DDTarget.prototype = new Ext.dd.DragDrop();
10388
Ext.extend(Ext.dd.DDTarget, Ext.dd.DragDrop, {
10389
toString: function() {
10390
return ("DDTarget " + this.id);
10395
Ext.dd.DragTracker = function(config){
10396
Ext.apply(this, config);
10412
this.dragRegion = new Ext.lib.Region(0,0,0,0);
10415
this.initEl(this.el);
10419
Ext.extend(Ext.dd.DragTracker, Ext.util.Observable, {
10427
initEl: function(el){
10428
this.el = Ext.get(el);
10429
el.on('mousedown', this.onMouseDown, this,
10430
this.delegate ? {delegate: this.delegate} : undefined);
10433
destroy : function(){
10434
this.el.un('mousedown', this.onMouseDown, this);
10437
onMouseDown: function(e, target){
10438
if(this.fireEvent('mousedown', this, e) !== false && this.onBeforeStart(e) !== false){
10439
this.startXY = this.lastXY = e.getXY();
10440
this.dragTarget = this.delegate ? target : this.el.dom;
10441
if(this.preventDefault !== false){
10442
e.preventDefault();
10444
var doc = Ext.getDoc();
10445
doc.on('mouseup', this.onMouseUp, this);
10446
doc.on('mousemove', this.onMouseMove, this);
10447
doc.on('selectstart', this.stopSelect, this);
10448
if(this.autoStart){
10449
this.timer = this.triggerStart.defer(this.autoStart === true ? 1000 : this.autoStart, this);
10454
onMouseMove: function(e, target){
10455
// HACK: IE hack to see if button was released outside of window. */
10456
if(this.active && Ext.isIE && !e.browserEvent.button){
10457
e.preventDefault();
10462
e.preventDefault();
10463
var xy = e.getXY(), s = this.startXY;
10466
if(Math.abs(s[0]-xy[0]) > this.tolerance || Math.abs(s[1]-xy[1]) > this.tolerance){
10467
this.triggerStart();
10472
this.fireEvent('mousemove', this, e);
10474
this.fireEvent('drag', this, e);
10477
onMouseUp: function(e){
10478
var doc = Ext.getDoc();
10479
doc.un('mousemove', this.onMouseMove, this);
10480
doc.un('mouseup', this.onMouseUp, this);
10481
doc.un('selectstart', this.stopSelect, this);
10482
e.preventDefault();
10484
var wasActive = this.active;
10485
this.active = false;
10486
delete this.elRegion;
10487
this.fireEvent('mouseup', this, e);
10490
this.fireEvent('dragend', this, e);
10494
triggerStart: function(isTimer){
10496
this.active = true;
10497
this.onStart(this.startXY);
10498
this.fireEvent('dragstart', this, this.startXY);
10501
clearStart : function(){
10503
clearTimeout(this.timer);
10508
stopSelect : function(e){
10513
onBeforeStart : function(e){
10517
onStart : function(xy){
10521
onDrag : function(e){
10525
onEnd : function(e){
10529
getDragTarget : function(){
10530
return this.dragTarget;
10533
getDragCt : function(){
10537
getXY : function(constrain){
10539
this.constrainModes[constrain].call(this, this.lastXY) : this.lastXY;
10542
getOffset : function(constrain){
10543
var xy = this.getXY(constrain);
10544
var s = this.startXY;
10545
return [s[0]-xy[0], s[1]-xy[1]];
10549
'point' : function(xy){
10551
if(!this.elRegion){
10552
this.elRegion = this.getDragCt().getRegion();
10555
var dr = this.dragRegion;
10562
dr.constrainTo(this.elRegion);
10564
return [dr.left, dr.top];
10569
Ext.dd.ScrollManager = function(){
10570
var ddm = Ext.dd.DragDropMgr;
10575
var onStop = function(e){
10580
var triggerRefresh = function(){
10581
if(ddm.dragCurrent){
10582
ddm.refreshCache(ddm.dragCurrent.groups);
10586
var doScroll = function(){
10587
if(ddm.dragCurrent){
10588
var dds = Ext.dd.ScrollManager;
10589
var inc = proc.el.ddScrollConfig ?
10590
proc.el.ddScrollConfig.increment : dds.increment;
10592
if(proc.el.scroll(proc.dir, inc)){
10596
proc.el.scroll(proc.dir, inc, true, dds.animDuration, triggerRefresh);
10601
var clearProc = function(){
10603
clearInterval(proc.id);
10610
var startProc = function(el, dir){
10614
var freq = (el.ddScrollConfig && el.ddScrollConfig.frequency) ?
10615
el.ddScrollConfig.frequency : Ext.dd.ScrollManager.frequency;
10616
proc.id = setInterval(doScroll, freq);
10619
var onFire = function(e, isDrop){
10620
if(isDrop || !ddm.dragCurrent){ return; }
10621
var dds = Ext.dd.ScrollManager;
10622
if(!dragEl || dragEl != ddm.dragCurrent){
10623
dragEl = ddm.dragCurrent;
10624
// refresh regions on drag start
10625
dds.refreshCache();
10628
var xy = Ext.lib.Event.getXY(e);
10629
var pt = new Ext.lib.Point(xy[0], xy[1]);
10630
for(var id in els){
10631
var el = els[id], r = el._region;
10632
var c = el.ddScrollConfig ? el.ddScrollConfig : dds;
10633
if(r && r.contains(pt) && el.isScrollable()){
10634
if(r.bottom - pt.y <= c.vthresh){
10636
startProc(el, "down");
10639
}else if(r.right - pt.x <= c.hthresh){
10641
startProc(el, "left");
10644
}else if(pt.y - r.top <= c.vthresh){
10646
startProc(el, "up");
10649
}else if(pt.x - r.left <= c.hthresh){
10651
startProc(el, "right");
10660
ddm.fireEvents = ddm.fireEvents.createSequence(onFire, ddm);
10661
ddm.stopDrag = ddm.stopDrag.createSequence(onStop, ddm);
10665
register : function(el){
10666
if(Ext.isArray(el)){
10667
for(var i = 0, len = el.length; i < len; i++) {
10668
this.register(el[i]);
10677
unregister : function(el){
10678
if(Ext.isArray(el)){
10679
for(var i = 0, len = el.length; i < len; i++) {
10680
this.unregister(el[i]);
10706
refreshCache : function(){
10707
for(var id in els){
10708
if(typeof els[id] == 'object'){ // for people extending the object prototype
10709
els[id]._region = els[id].getRegion();
10716
Ext.dd.Registry = function(){
10719
var autoIdSeed = 0;
10721
var getId = function(el, autogen){
10722
if(typeof el == "string"){
10726
if(!id && autogen !== false){
10727
id = "extdd-" + (++autoIdSeed);
10735
register : function(el, data){
10737
if(typeof el == "string"){
10738
el = document.getElementById(el);
10741
elements[getId(el)] = data;
10742
if(data.isHandle !== false){
10743
handles[data.ddel.id] = data;
10746
var hs = data.handles;
10747
for(var i = 0, len = hs.length; i < len; i++){
10748
handles[getId(hs[i])] = data;
10754
unregister : function(el){
10755
var id = getId(el, false);
10756
var data = elements[id];
10758
delete elements[id];
10760
var hs = data.handles;
10761
for(var i = 0, len = hs.length; i < len; i++){
10762
delete handles[getId(hs[i], false)];
10769
getHandle : function(id){
10770
if(typeof id != "string"){ // must be element?
10773
return handles[id];
10777
getHandleFromEvent : function(e){
10778
var t = Ext.lib.Event.getTarget(e);
10779
return t ? handles[t.id] : null;
10783
getTarget : function(id){
10784
if(typeof id != "string"){ // must be element?
10787
return elements[id];
10791
getTargetFromEvent : function(e){
10792
var t = Ext.lib.Event.getTarget(e);
10793
return t ? elements[t.id] || handles[t.id] : null;
10798
Ext.dd.StatusProxy = function(config){
10799
Ext.apply(this, config);
10800
this.id = this.id || Ext.id();
10801
this.el = new Ext.Layer({
10803
id: this.id, tag: "div", cls: "x-dd-drag-proxy "+this.dropNotAllowed, children: [
10804
{tag: "div", cls: "x-dd-drop-icon"},
10805
{tag: "div", cls: "x-dd-drag-ghost"}
10808
shadow: !config || config.shadow !== false
10810
this.ghost = Ext.get(this.el.dom.childNodes[1]);
10811
this.dropStatus = this.dropNotAllowed;
10814
Ext.dd.StatusProxy.prototype = {
10816
dropAllowed : "x-dd-drop-ok",
10818
dropNotAllowed : "x-dd-drop-nodrop",
10821
setStatus : function(cssClass){
10822
cssClass = cssClass || this.dropNotAllowed;
10823
if(this.dropStatus != cssClass){
10824
this.el.replaceClass(this.dropStatus, cssClass);
10825
this.dropStatus = cssClass;
10830
reset : function(clearGhost){
10831
this.el.dom.className = "x-dd-drag-proxy " + this.dropNotAllowed;
10832
this.dropStatus = this.dropNotAllowed;
10834
this.ghost.update("");
10839
update : function(html){
10840
if(typeof html == "string"){
10841
this.ghost.update(html);
10843
this.ghost.update("");
10844
html.style.margin = "0";
10845
this.ghost.dom.appendChild(html);
10847
var el = this.ghost.dom.firstChild;
10849
Ext.fly(el).setStyle('float', 'none');
10854
getEl : function(){
10859
getGhost : function(){
10864
hide : function(clear){
10873
if(this.anim && this.anim.isAnimated && this.anim.isAnimated()){
10889
repair : function(xy, callback, scope){
10890
this.callback = callback;
10891
this.scope = scope;
10892
if(xy && this.animRepair !== false){
10893
this.el.addClass("x-dd-drag-repair");
10894
this.el.hideUnders(true);
10895
this.anim = this.el.shift({
10896
duration: this.repairDuration || .5,
10900
callback: this.afterRepair,
10904
this.afterRepair();
10909
afterRepair : function(){
10911
if(typeof this.callback == "function"){
10912
this.callback.call(this.scope || this);
10914
this.callback = null;
10919
Ext.dd.DragSource = function(el, config){
10920
this.el = Ext.get(el);
10921
if(!this.dragData){
10922
this.dragData = {};
10925
Ext.apply(this, config);
10928
this.proxy = new Ext.dd.StatusProxy();
10930
Ext.dd.DragSource.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
10931
{dragElId : this.proxy.id, resizeFrame: false, isTarget: false, scroll: this.scroll === true});
10933
this.dragging = false;
10936
Ext.extend(Ext.dd.DragSource, Ext.dd.DDProxy, {
10939
dropAllowed : "x-dd-drop-ok",
10941
dropNotAllowed : "x-dd-drop-nodrop",
10944
getDragData : function(e){
10945
return this.dragData;
10949
onDragEnter : function(e, id){
10950
var target = Ext.dd.DragDropMgr.getDDById(id);
10951
this.cachedTarget = target;
10952
if(this.beforeDragEnter(target, e, id) !== false){
10953
if(target.isNotifyTarget){
10954
var status = target.notifyEnter(this, e, this.dragData);
10955
this.proxy.setStatus(status);
10957
this.proxy.setStatus(this.dropAllowed);
10960
if(this.afterDragEnter){
10962
this.afterDragEnter(target, e, id);
10968
beforeDragEnter : function(target, e, id){
10973
alignElWithMouse: function() {
10974
Ext.dd.DragSource.superclass.alignElWithMouse.apply(this, arguments);
10979
onDragOver : function(e, id){
10980
var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
10981
if(this.beforeDragOver(target, e, id) !== false){
10982
if(target.isNotifyTarget){
10983
var status = target.notifyOver(this, e, this.dragData);
10984
this.proxy.setStatus(status);
10987
if(this.afterDragOver){
10989
this.afterDragOver(target, e, id);
10995
beforeDragOver : function(target, e, id){
11000
onDragOut : function(e, id){
11001
var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
11002
if(this.beforeDragOut(target, e, id) !== false){
11003
if(target.isNotifyTarget){
11004
target.notifyOut(this, e, this.dragData);
11006
this.proxy.reset();
11007
if(this.afterDragOut){
11009
this.afterDragOut(target, e, id);
11012
this.cachedTarget = null;
11016
beforeDragOut : function(target, e, id){
11021
onDragDrop : function(e, id){
11022
var target = this.cachedTarget || Ext.dd.DragDropMgr.getDDById(id);
11023
if(this.beforeDragDrop(target, e, id) !== false){
11024
if(target.isNotifyTarget){
11025
if(target.notifyDrop(this, e, this.dragData)){ // valid drop?
11026
this.onValidDrop(target, e, id);
11028
this.onInvalidDrop(target, e, id);
11031
this.onValidDrop(target, e, id);
11034
if(this.afterDragDrop){
11036
this.afterDragDrop(target, e, id);
11039
delete this.cachedTarget;
11043
beforeDragDrop : function(target, e, id){
11048
onValidDrop : function(target, e, id){
11050
if(this.afterValidDrop){
11052
this.afterValidDrop(target, e, id);
11057
getRepairXY : function(e, data){
11058
return this.el.getXY();
11062
onInvalidDrop : function(target, e, id){
11063
this.beforeInvalidDrop(target, e, id);
11064
if(this.cachedTarget){
11065
if(this.cachedTarget.isNotifyTarget){
11066
this.cachedTarget.notifyOut(this, e, this.dragData);
11068
this.cacheTarget = null;
11070
this.proxy.repair(this.getRepairXY(e, this.dragData), this.afterRepair, this);
11072
if(this.afterInvalidDrop){
11074
this.afterInvalidDrop(e, id);
11079
afterRepair : function(){
11081
this.el.highlight(this.hlColor || "c3daf9");
11083
this.dragging = false;
11087
beforeInvalidDrop : function(target, e, id){
11092
handleMouseDown : function(e){
11093
if(this.dragging) {
11096
var data = this.getDragData(e);
11097
if(data && this.onBeforeDrag(data, e) !== false){
11098
this.dragData = data;
11100
Ext.dd.DragSource.superclass.handleMouseDown.apply(this, arguments);
11105
onBeforeDrag : function(data, e){
11110
onStartDrag : Ext.emptyFn,
11112
// private override
11113
startDrag : function(x, y){
11114
this.proxy.reset();
11115
this.dragging = true;
11116
this.proxy.update("");
11117
this.onInitDrag(x, y);
11122
onInitDrag : function(x, y){
11123
var clone = this.el.dom.cloneNode(true);
11124
clone.id = Ext.id(); // prevent duplicate ids
11125
this.proxy.update(clone);
11126
this.onStartDrag(x, y);
11131
getProxy : function(){
11136
hideProxy : function(){
11138
this.proxy.reset(true);
11139
this.dragging = false;
11143
triggerCacheRefresh : function(){
11144
Ext.dd.DDM.refreshCache(this.groups);
11147
// private - override to prevent hiding
11148
b4EndDrag: function(e) {
11151
// private - override to prevent moving
11152
endDrag : function(e){
11153
this.onEndDrag(this.dragData, e);
11157
onEndDrag : function(data, e){
11160
// private - pin to cursor
11161
autoOffset : function(x, y) {
11162
this.setDelta(-12, -20);
11166
Ext.dd.DropTarget = function(el, config){
11167
this.el = Ext.get(el);
11169
Ext.apply(this, config);
11171
if(this.containerScroll){
11172
Ext.dd.ScrollManager.register(this.el);
11175
Ext.dd.DropTarget.superclass.constructor.call(this, this.el.dom, this.ddGroup || this.group,
11180
Ext.extend(Ext.dd.DropTarget, Ext.dd.DDTarget, {
11184
dropAllowed : "x-dd-drop-ok",
11186
dropNotAllowed : "x-dd-drop-nodrop",
11192
isNotifyTarget : true,
11195
notifyEnter : function(dd, e, data){
11196
if(this.overClass){
11197
this.el.addClass(this.overClass);
11199
return this.dropAllowed;
11203
notifyOver : function(dd, e, data){
11204
return this.dropAllowed;
11208
notifyOut : function(dd, e, data){
11209
if(this.overClass){
11210
this.el.removeClass(this.overClass);
11215
notifyDrop : function(dd, e, data){
11220
Ext.dd.DragZone = function(el, config){
11221
Ext.dd.DragZone.superclass.constructor.call(this, el, config);
11222
if(this.containerScroll){
11223
Ext.dd.ScrollManager.register(this.el);
11227
Ext.extend(Ext.dd.DragZone, Ext.dd.DragSource, {
11233
getDragData : function(e){
11234
return Ext.dd.Registry.getHandleFromEvent(e);
11238
onInitDrag : function(x, y){
11239
this.proxy.update(this.dragData.ddel.cloneNode(true));
11240
this.onStartDrag(x, y);
11245
afterRepair : function(){
11247
Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
11249
this.dragging = false;
11253
getRepairXY : function(e){
11254
return Ext.Element.fly(this.dragData.ddel).getXY();
11258
Ext.dd.DropZone = function(el, config){
11259
Ext.dd.DropZone.superclass.constructor.call(this, el, config);
11262
Ext.extend(Ext.dd.DropZone, Ext.dd.DropTarget, {
11264
getTargetFromEvent : function(e){
11265
return Ext.dd.Registry.getTargetFromEvent(e);
11269
onNodeEnter : function(n, dd, e, data){
11274
onNodeOver : function(n, dd, e, data){
11275
return this.dropAllowed;
11279
onNodeOut : function(n, dd, e, data){
11284
onNodeDrop : function(n, dd, e, data){
11289
onContainerOver : function(dd, e, data){
11290
return this.dropNotAllowed;
11294
onContainerDrop : function(dd, e, data){
11299
notifyEnter : function(dd, e, data){
11300
return this.dropNotAllowed;
11304
notifyOver : function(dd, e, data){
11305
var n = this.getTargetFromEvent(e);
11306
if(!n){ // not over valid drop target
11307
if(this.lastOverNode){
11308
this.onNodeOut(this.lastOverNode, dd, e, data);
11309
this.lastOverNode = null;
11311
return this.onContainerOver(dd, e, data);
11313
if(this.lastOverNode != n){
11314
if(this.lastOverNode){
11315
this.onNodeOut(this.lastOverNode, dd, e, data);
11317
this.onNodeEnter(n, dd, e, data);
11318
this.lastOverNode = n;
11320
return this.onNodeOver(n, dd, e, data);
11324
notifyOut : function(dd, e, data){
11325
if(this.lastOverNode){
11326
this.onNodeOut(this.lastOverNode, dd, e, data);
11327
this.lastOverNode = null;
11332
notifyDrop : function(dd, e, data){
11333
if(this.lastOverNode){
11334
this.onNodeOut(this.lastOverNode, dd, e, data);
11335
this.lastOverNode = null;
11337
var n = this.getTargetFromEvent(e);
11339
this.onNodeDrop(n, dd, e, data) :
11340
this.onContainerDrop(dd, e, data);
11344
triggerCacheRefresh : function(){
11345
Ext.dd.DDM.refreshCache(this.groups);
11349
Ext.data.Api = (function() {
11351
// private validActions. validActions is essentially an inverted hash of Ext.data.Api.actions, where value becomes the key.
11352
// Some methods in this singleton (eg: getActions, getVerb) will loop through actions with the code <code>for (var verb in this.actions)</code>
11353
// For efficiency, some methods will first check this hash for a match. Those methods which do acces validActions will cache their result here.
11354
// We cannot pre-define this hash since the developer may over-ride the actions at runtime.
11355
var validActions = {};
11363
destroy : 'destroy'
11375
isAction : function(action) {
11376
return (Ext.data.Api.actions[action]) ? true : false;
11380
getVerb : function(name) {
11381
if (validActions[name]) {
11382
return validActions[name]; // <-- found in cache. return immediately.
11384
for (var verb in this.actions) {
11385
if (this.actions[verb] === name) {
11386
validActions[name] = verb;
11390
return (validActions[name] !== undefined) ? validActions[name] : null;
11394
isValid : function(api){
11396
var crud = this.actions; // <-- cache a copy of the actions.
11397
for (var action in api) {
11398
if (!(action in crud)) {
11399
invalid.push(action);
11402
return (!invalid.length) ? true : invalid;
11406
hasUniqueUrl : function(proxy, verb) {
11407
var url = (proxy.api[verb]) ? proxy.api[verb].url : null;
11409
for (var action in proxy.api) {
11410
if ((unique = (action === verb) ? true : (proxy.api[action].url != url) ? true : false) === false) {
11418
prepare : function(proxy) {
11420
proxy.api = {}; // <-- No api? create a blank one.
11422
for (var verb in this.actions) {
11423
var action = this.actions[verb];
11424
proxy.api[action] = proxy.api[action] || proxy.url || proxy.directFn;
11425
if (typeof(proxy.api[action]) == 'string') {
11426
proxy.api[action] = {
11427
url: proxy.api[action]
11434
restify : function(proxy) {
11435
proxy.restful = true;
11436
for (var verb in this.restActions) {
11437
proxy.api[this.actions[verb]].method = this.restActions[verb];
11445
Ext.data.Api.Error = Ext.extend(Ext.Error, {
11446
constructor : function(message, arg) {
11448
Ext.Error.call(this, message);
11450
name: 'Ext.data.Api'
11452
Ext.apply(Ext.data.Api.Error.prototype, {
11454
'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.',
11455
'invalid': 'received an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions defined in Ext.data.Api.actions',
11456
'invalid-url': 'Invalid url. Please review your proxy configuration.',
11457
'execute': 'Attempted to execute an unknown action. Valid API actions are defined in Ext.data.Api.actions"'
11463
Ext.data.SortTypes = {
11465
none : function(s){
11470
stripTagsRE : /<\/?[^>]+>/gi,
11473
asText : function(s){
11474
return String(s).replace(this.stripTagsRE, "");
11478
asUCText : function(s){
11479
return String(s).toUpperCase().replace(this.stripTagsRE, "");
11483
asUCString : function(s) {
11484
return String(s).toUpperCase();
11488
asDate : function(s) {
11493
return s.getTime();
11495
return Date.parse(String(s));
11499
asFloat : function(s) {
11500
var val = parseFloat(String(s).replace(/,/g, ""));
11501
if(isNaN(val)) val = 0;
11506
asInt : function(s) {
11507
var val = parseInt(String(s).replace(/,/g, ""));
11508
if(isNaN(val)) val = 0;
11513
Ext.data.Record = function(data, id){
11514
// if no id, call the auto id method
11515
this.id = (id || id === 0) ? id : Ext.data.Record.id(this);
11516
this.data = data || {};
11520
Ext.data.Record.create = function(o){
11521
var f = Ext.extend(Ext.data.Record, {});
11522
var p = f.prototype;
11523
p.fields = new Ext.util.MixedCollection(false, function(field){
11526
for(var i = 0, len = o.length; i < len; i++){
11527
p.fields.add(new Ext.data.Field(o[i]));
11529
f.getField = function(name){
11530
return p.fields.get(name);
11535
Ext.data.Record.PREFIX = 'ext-record';
11536
Ext.data.Record.AUTO_ID = 1;
11537
Ext.data.Record.EDIT = 'edit';
11538
Ext.data.Record.REJECT = 'reject';
11539
Ext.data.Record.COMMIT = 'commit';
11543
Ext.data.Record.id = function(rec) {
11544
rec.phantom = true;
11545
return [Ext.data.Record.PREFIX, '-', Ext.data.Record.AUTO_ID++].join('');
11548
Ext.data.Record.prototype = {
11562
join : function(store){
11564
this.store = store;
11568
set : function(name, value){
11569
if(String(this.data[name]) == String(value)){
11573
if(!this.modified){
11574
this.modified = {};
11576
if(typeof this.modified[name] == 'undefined'){
11577
this.modified[name] = this.data[name];
11579
this.data[name] = value;
11586
afterEdit: function(){
11588
this.store.afterEdit(this);
11593
afterReject: function(){
11595
this.store.afterReject(this);
11600
afterCommit: function(){
11602
this.store.afterCommit(this);
11607
get : function(name){
11608
return this.data[name];
11612
beginEdit : function(){
11613
this.editing = true;
11614
this.modified = this.modified || {};
11618
cancelEdit : function(){
11619
this.editing = false;
11620
delete this.modified;
11624
endEdit : function(){
11625
this.editing = false;
11632
reject : function(silent){
11633
var m = this.modified;
11635
if(typeof m[n] != "function"){
11636
this.data[n] = m[n];
11639
this.dirty = false;
11640
delete this.modified;
11641
this.editing = false;
11642
if(silent !== true){
11643
this.afterReject();
11648
commit : function(silent){
11649
this.dirty = false;
11650
delete this.modified;
11651
this.editing = false;
11652
if(silent !== true){
11653
this.afterCommit();
11658
getChanges : function(){
11659
var m = this.modified, cs = {};
11661
if(m.hasOwnProperty(n)){
11662
cs[n] = this.data[n];
11669
hasError : function(){
11670
return this.error != null;
11674
clearError : function(){
11679
copy : function(newId) {
11680
return new this.constructor(Ext.apply({}, this.data), newId || this.id);
11684
isModified : function(fieldName){
11685
return !!(this.modified && this.modified.hasOwnProperty(fieldName));
11689
isValid : function() {
11690
return this.fields.find(function(f) {
11691
return (f.allowBlank == false && Ext.isEmpty(this.data[f.name])) ? true : false;
11692
},this) ? false : true;
11696
markDirty : function(){
11698
if(!this.modified){
11699
this.modified = {};
11701
this.fields.each(function(f) {
11702
this.modified[f.name] = this.data[f.name];
11707
Ext.StoreMgr = Ext.apply(new Ext.util.MixedCollection(), {
11711
register : function(){
11712
for(var i = 0, s; s = arguments[i]; i++){
11718
unregister : function(){
11719
for(var i = 0, s; s = arguments[i]; i++){
11720
this.remove(this.lookup(s));
11725
lookup : function(id){
11726
if(Ext.isArray(id)){
11727
var fields = ['field1'], expand = !Ext.isArray(id[0]);
11729
for(var i = 2, len = id[0].length; i <= len; ++i){
11730
fields.push('field' + i);
11733
return new Ext.data.ArrayStore({
11736
expandData: expand,
11742
return Ext.isObject(id) ? (id.events ? id : Ext.create(id, 'store')) : this.get(id);
11745
// getKey implementation for MixedCollection
11746
getKey : function(o){
11751
Ext.data.Store = function(config){
11752
this.data = new Ext.util.MixedCollection(false);
11753
this.data.getKey = function(o){
11757
this.baseParams = {};
11759
// temporary removed-records cache
11763
this.paramNames = {
11770
if(config && config.data){
11771
this.inlineData = config.data;
11772
delete config.data;
11775
Ext.apply(this, config);
11777
if(this.url && !this.proxy){
11778
this.proxy = new Ext.data.HttpProxy({url: this.url});
11780
// If Store is RESTful, so too is the DataProxy
11781
if (this.restful === true) {
11782
// When operating RESTfully, a unique transaction is generated for each record.
11783
this.batch = false;
11784
Ext.data.Api.restify(this.proxy);
11787
if(this.reader){ // reader passed
11788
if(!this.recordType){
11789
this.recordType = this.reader.recordType;
11791
if(this.reader.onMetaChange){
11792
this.reader.onMetaChange = this.onMetaChange.createDelegate(this);
11794
if (this.writer) { // writer passed
11795
this.writer.meta = this.reader.meta;
11796
this.pruneModifiedRecords = true;
11802
if(this.recordType){
11804
this.fields = this.recordType.prototype.fields;
11806
this.modified = [];
11836
this.relayEvents(this.proxy, ["loadexception", "exception"]);
11838
// With a writer set for the Store, we want to listen to add/remove events to remotely create/destroy records.
11840
this.on('add', this.createRecords.createDelegate(this));
11841
this.on('remove', this.destroyRecord.createDelegate(this));
11842
this.on('update', this.updateRecord.createDelegate(this));
11845
this.sortToggle = {};
11846
if(this.sortField){
11847
this.setDefaultSort(this.sortField, this.sortDir);
11848
}else if(this.sortInfo){
11849
this.setDefaultSort(this.sortInfo.field, this.sortInfo.direction);
11852
Ext.data.Store.superclass.constructor.call(this);
11855
this.storeId = this.id;
11859
Ext.StoreMgr.register(this);
11861
if(this.inlineData){
11862
this.loadData(this.inlineData);
11863
delete this.inlineData;
11864
}else if(this.autoLoad){
11865
this.load.defer(10, this, [
11866
typeof this.autoLoad == 'object' ?
11867
this.autoLoad : undefined]);
11870
Ext.extend(Ext.data.Store, Ext.util.Observable, {
11878
writer : undefined,
11882
remoteSort : false,
11885
autoDestroy : false,
11888
pruneModifiedRecords : false,
11891
lastOptions : null,
11903
destroy : function(){
11905
Ext.StoreMgr.unregister(this);
11908
Ext.destroy(this.proxy);
11909
this.reader = this.writer = null;
11910
this.purgeListeners();
11914
add : function(records){
11915
records = [].concat(records);
11916
if(records.length < 1){
11919
for(var i = 0, len = records.length; i < len; i++){
11920
records[i].join(this);
11922
var index = this.data.length;
11923
this.data.addAll(records);
11925
this.snapshot.addAll(records);
11927
this.fireEvent("add", this, records, index);
11931
addSorted : function(record){
11932
var index = this.findInsertIndex(record);
11933
this.insert(index, record);
11937
remove : function(record){
11938
var index = this.data.indexOf(record);
11940
this.data.removeAt(index);
11941
if(this.pruneModifiedRecords){
11942
this.modified.remove(record);
11945
this.snapshot.remove(record);
11947
this.fireEvent("remove", this, record, index);
11952
removeAt : function(index){
11953
this.remove(this.getAt(index));
11957
removeAll : function(){
11960
this.snapshot.clear();
11962
if(this.pruneModifiedRecords){
11963
this.modified = [];
11965
this.fireEvent("clear", this);
11969
insert : function(index, records){
11970
records = [].concat(records);
11971
for(var i = 0, len = records.length; i < len; i++){
11972
this.data.insert(index, records[i]);
11973
records[i].join(this);
11975
this.fireEvent("add", this, records, index);
11979
indexOf : function(record){
11980
return this.data.indexOf(record);
11984
indexOfId : function(id){
11985
return this.data.indexOfKey(id);
11989
getById : function(id){
11990
return this.data.key(id);
11994
getAt : function(index){
11995
return this.data.itemAt(index);
11999
getRange : function(start, end){
12000
return this.data.getRange(start, end);
12004
storeOptions : function(o){
12005
o = Ext.apply({}, o);
12008
this.lastOptions = o;
12012
load : function(options) {
12013
options = options || {};
12014
this.storeOptions(options);
12015
if(this.sortInfo && this.remoteSort){
12016
var pn = this.paramNames;
12017
options.params = options.params || {};
12018
options.params[pn["sort"]] = this.sortInfo.field;
12019
options.params[pn["dir"]] = this.sortInfo.direction;
12022
return this.execute("read", null, options); // <-- null represents rs. No rs for load actions.
12024
this.handleException(e);
12030
updateRecord : function(store, record, action) {
12031
if (action == Ext.data.Record.EDIT && this.autoSave === true && (!record.phantom || (record.phantom && record.isValid))) {
12037
createRecords : function(store, rs, index) {
12038
for (var i = 0, len = rs.length; i < len; i++) {
12039
if (rs[i].phantom && rs[i].isValid()) {
12040
rs[i].markDirty(); // <-- Mark new records dirty
12041
this.modified.push(rs[i]); // <-- add to modified
12044
if (this.autoSave === true) {
12050
destroyRecord : function(store, record, index) {
12051
if (this.modified.indexOf(record) != -1) { // <-- handled already if @cfg pruneModifiedRecords == true
12052
this.modified.remove(record);
12054
if (!record.phantom) {
12055
this.removed.push(record);
12057
// since the record has already been removed from the store but the server request has not yet been executed,
12058
// must keep track of the last known index this record existed. If a server error occurs, the record can be
12059
// put back into the store. @see Store#createCallback where the record is returned when response status === false
12060
record.lastIndex = index;
12062
if (this.autoSave === true) {
12069
execute : function(action, rs, options) {
12070
// blow up if action not Ext.data.CREATE, READ, UPDATE, DESTROY
12071
if (!Ext.data.Api.isAction(action)) {
12072
throw new Ext.data.Api.Error('execute', action);
12074
// make sure options has a params key
12075
options = Ext.applyIf(options||{}, {
12079
// have to separate before-events since load has a different signature than create,destroy and save events since load does not
12080
// include the rs (record resultset) parameter. Capture return values from the beforeaction into doRequest flag.
12081
var doRequest = true;
12083
if (action === "read") {
12084
doRequest = this.fireEvent('beforeload', this, options);
12087
// if Writer is configured as listful, force single-recoord rs to be [{}} instead of {}
12088
if (this.writer.listful === true && this.restful !== true) {
12089
rs = (Ext.isArray(rs)) ? rs : [rs];
12091
// if rs has just a single record, shift it off so that Writer writes data as "{}" rather than "[{}]"
12092
else if (Ext.isArray(rs) && rs.length == 1) {
12095
// Write the action to options.params
12096
if ((doRequest = this.fireEvent('beforewrite', this, action, rs, options)) !== false) {
12097
this.writer.write(action, options.params, rs);
12100
if (doRequest !== false) {
12101
// Send request to proxy.
12102
var params = Ext.apply(options.params || {}, this.baseParams);
12103
if (this.writer && this.proxy.url && !this.proxy.restful && !Ext.data.Api.hasUniqueUrl(this.proxy, action)) {
12104
params.xaction = action;
12106
// Note: Up until this point we've been dealing with "action" as a key from Ext.data.Api.actions. We'll flip it now
12107
// and send the value into DataProxy#request, since it's the value which maps to the DataProxy#api
12108
this.proxy.request(Ext.data.Api.actions[action], rs, params, this.reader, this.createCallback(action, rs), this, options);
12114
save : function() {
12115
if (!this.writer) {
12116
throw new Ext.data.Store.Error('writer-undefined');
12119
// DESTROY: First check for removed records. Records in this.removed are guaranteed non-phantoms. @see Store#remove
12120
if (this.removed.length) {
12121
this.doTransaction("destroy", this.removed);
12124
// Check for modified records. Bail-out if empty...
12125
var rs = this.getModifiedRecords();
12130
// CREATE: Next check for phantoms within rs. splice-off and execute create.
12132
for (var i = rs.length-1; i >= 0; i--) {
12133
if (rs[i].phantom === true) {
12134
var rec = rs.splice(i, 1).shift();
12135
if (rec.isValid()) {
12136
phantoms.push(rec);
12138
} else if (!rs[i].isValid()) { // <-- while we're here, splice-off any !isValid real records
12142
// If we have valid phantoms, create them...
12143
if (phantoms.length) {
12144
this.doTransaction('create', phantoms);
12147
// UPDATE: And finally, if we're still here after splicing-off phantoms and !isValid real records, update the rest...
12149
this.doTransaction('update', rs);
12154
// private. Simply wraps call to Store#execute in try/catch. Defers to Store#handleException on error. Loops if batch: false
12155
doTransaction : function(action, rs) {
12156
if (this.batch === false) {
12157
for (var i = 0, len = rs.length; i < len; i++) {
12158
transaction.call(this, rs[i]);
12161
transaction.call(this, rs);
12163
function transaction(records) {
12165
this.execute(action, records);
12167
this.handleException(e);
12172
// @private callback-handler for remote CRUD actions
12173
// Do not override -- override loadRecords, onCreateRecords, onDestroyRecords and onUpdateRecords instead.
12174
createCallback : function(action, rs) {
12175
var actions = Ext.data.Api.actions;
12176
return (action == "read") ? this.loadRecords : function(data, response, success) {
12177
// If success === false here, exception will have been called in DataProxy
12178
if (success === true) {
12179
this.fireEvent('write', this, action, data, response, rs);
12181
this.clearModified(rs); // <-- If not cleared, they'll keep getting posted with the same data which caused the server error.
12183
// calls: onCreateRecords | onUpdateRecords | onDestroyRecords
12184
this['on' + Ext.util.Format.capitalize(action) + 'Records'](success, rs, data);
12188
// Clears records from modified array after an exception event.
12189
// NOTE: records are left marked dirty. Do we want to commit them even though they were not updated/realized?
12190
clearModified : function(rs) {
12191
if (Ext.isArray(rs)) {
12192
for (var n=rs.length-1;n>=0;n--) {
12193
this.modified.splice(this.modified.indexOf(rs[n]), 1);
12196
this.modified.splice(this.modified.indexOf(rs), 1);
12200
// remap record ids in MixedCollection after records have been realized. @see Store#onCreateRecords, @see DataReader#realize
12201
reMap : function(record) {
12202
if (Ext.isArray(record)) {
12203
for (var i = 0, len = record.length; i < len; i++) {
12204
this.reMap(record[i]);
12207
delete this.data.map[record._phid];
12208
this.data.map[record.id] = record;
12209
var index = this.data.keys.indexOf(record._phid);
12210
this.data.keys.splice(index, 1, record.id);
12211
delete record._phid;
12215
// @protected onCreateRecord proxy callback for create action
12216
onCreateRecords : function(success, rs, data) {
12217
if (success === true) {
12219
this.reader.realize(rs, data);
12223
this.handleException(e);
12224
if (Ext.isArray(rs)) {
12225
// Recurse to run back into the try {}. DataReader#realize splices-off the rs until empty.
12226
this.onCreateRecords(success, rs, data);
12232
// @protected, onUpdateRecords proxy callback for update action
12233
onUpdateRecords : function(success, rs, data) {
12234
if (success === true) {
12236
this.reader.update(rs, data);
12238
this.handleException(e);
12239
if (Ext.isArray(rs)) {
12240
// Recurse to run back into the try {}. DataReader#update splices-off the rs until empty.
12241
this.onUpdateRecords(success, rs, data);
12247
// @protected onDestroyRecords proxy callback for destroy action
12248
onDestroyRecords : function(success, rs, data) {
12249
// splice each rec out of this.removed
12250
rs = (rs instanceof Ext.data.Record) ? [rs] : rs;
12251
for (var i=0,len=rs.length;i<len;i++) {
12252
this.removed.splice(this.removed.indexOf(rs[i]), 1);
12254
if (success === false) {
12255
// put records back into store if remote destroy fails.
12256
// @TODO: Might want to let developer decide.
12257
for (i=rs.length-1;i>=0;i--) {
12258
this.insert(rs[i].lastIndex, rs[i]); // <-- lastIndex set in Store#destroyRecord
12263
// protected handleException. Possibly temporary until Ext framework has an exception-handler.
12264
handleException : function(e) {
12265
// @see core/Error.js
12266
Ext.handleError(e);
12270
reload : function(options){
12271
this.load(Ext.applyIf(options||{}, this.lastOptions));
12275
// Called as a callback by the Reader during a load operation.
12276
loadRecords : function(o, options, success){
12277
if(!o || success === false){
12278
if(success !== false){
12279
this.fireEvent("load", this, [], options);
12281
if(options.callback){
12282
options.callback.call(options.scope || this, [], options, false, o);
12286
var r = o.records, t = o.totalRecords || r.length;
12287
if(!options || options.add !== true){
12288
if(this.pruneModifiedRecords){
12289
this.modified = [];
12291
for(var i = 0, len = r.length; i < len; i++){
12295
this.data = this.snapshot;
12296
delete this.snapshot;
12299
this.data.addAll(r);
12300
this.totalLength = t;
12302
this.fireEvent("datachanged", this);
12304
this.totalLength = Math.max(t, this.data.length+r.length);
12307
this.fireEvent("load", this, r, options);
12308
if(options.callback){
12309
options.callback.call(options.scope || this, r, options, true);
12314
loadData : function(o, append){
12315
var r = this.reader.readRecords(o);
12316
this.loadRecords(r, {add: append}, true);
12320
getCount : function(){
12321
return this.data.length || 0;
12325
getTotalCount : function(){
12326
return this.totalLength || 0;
12330
getSortState : function(){
12331
return this.sortInfo;
12335
applySort : function(){
12336
if(this.sortInfo && !this.remoteSort){
12337
var s = this.sortInfo, f = s.field;
12338
this.sortData(f, s.direction);
12343
sortData : function(f, direction){
12344
direction = direction || 'ASC';
12345
var st = this.fields.get(f).sortType;
12346
var fn = function(r1, r2){
12347
var v1 = st(r1.data[f]), v2 = st(r2.data[f]);
12348
return v1 > v2 ? 1 : (v1 < v2 ? -1 : 0);
12350
this.data.sort(direction, fn);
12351
if(this.snapshot && this.snapshot != this.data){
12352
this.snapshot.sort(direction, fn);
12357
setDefaultSort : function(field, dir){
12358
dir = dir ? dir.toUpperCase() : "ASC";
12359
this.sortInfo = {field: field, direction: dir};
12360
this.sortToggle[field] = dir;
12364
sort : function(fieldName, dir){
12365
var f = this.fields.get(fieldName);
12370
if(this.sortInfo && this.sortInfo.field == f.name){ // toggle sort dir
12371
dir = (this.sortToggle[f.name] || "ASC").toggle("ASC", "DESC");
12376
var st = (this.sortToggle) ? this.sortToggle[f.name] : null;
12377
var si = (this.sortInfo) ? this.sortInfo : null;
12379
this.sortToggle[f.name] = dir;
12380
this.sortInfo = {field: f.name, direction: dir};
12381
if(!this.remoteSort){
12383
this.fireEvent("datachanged", this);
12385
if (!this.load(this.lastOptions)) {
12387
this.sortToggle[f.name] = st;
12390
this.sortInfo = si;
12397
each : function(fn, scope){
12398
this.data.each(fn, scope);
12402
getModifiedRecords : function(){
12403
return this.modified;
12407
createFilterFn : function(property, value, anyMatch, caseSensitive){
12408
if(Ext.isEmpty(value, false)){
12411
value = this.data.createValueMatcher(value, anyMatch, caseSensitive);
12412
return function(r){
12413
return value.test(r.data[property]);
12418
sum : function(property, start, end){
12419
var rs = this.data.items, v = 0;
12420
start = start || 0;
12421
end = (end || end === 0) ? end : rs.length-1;
12423
for(var i = start; i <= end; i++){
12424
v += (rs[i].data[property] || 0);
12430
filter : function(property, value, anyMatch, caseSensitive){
12431
var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
12432
return fn ? this.filterBy(fn) : this.clearFilter();
12436
filterBy : function(fn, scope){
12437
this.snapshot = this.snapshot || this.data;
12438
this.data = this.queryBy(fn, scope||this);
12439
this.fireEvent("datachanged", this);
12443
query : function(property, value, anyMatch, caseSensitive){
12444
var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
12445
return fn ? this.queryBy(fn) : this.data.clone();
12449
queryBy : function(fn, scope){
12450
var data = this.snapshot || this.data;
12451
return data.filterBy(fn, scope||this);
12455
find : function(property, value, start, anyMatch, caseSensitive){
12456
var fn = this.createFilterFn(property, value, anyMatch, caseSensitive);
12457
return fn ? this.data.findIndexBy(fn, null, start) : -1;
12461
findBy : function(fn, scope, start){
12462
return this.data.findIndexBy(fn, scope, start);
12466
collect : function(dataIndex, allowNull, bypassFilter){
12467
var d = (bypassFilter === true && this.snapshot) ?
12468
this.snapshot.items : this.data.items;
12469
var v, sv, r = [], l = {};
12470
for(var i = 0, len = d.length; i < len; i++){
12471
v = d[i].data[dataIndex];
12473
if((allowNull || !Ext.isEmpty(v)) && !l[sv]){
12482
clearFilter : function(suppressEvent){
12483
if(this.isFiltered()){
12484
this.data = this.snapshot;
12485
delete this.snapshot;
12486
if(suppressEvent !== true){
12487
this.fireEvent("datachanged", this);
12493
isFiltered : function(){
12494
return this.snapshot && this.snapshot != this.data;
12498
afterEdit : function(record){
12499
if(this.modified.indexOf(record) == -1){
12500
this.modified.push(record);
12502
this.fireEvent("update", this, record, Ext.data.Record.EDIT);
12506
afterReject : function(record){
12507
this.modified.remove(record);
12508
this.fireEvent("update", this, record, Ext.data.Record.REJECT);
12512
afterCommit : function(record){
12513
this.modified.remove(record);
12514
this.fireEvent("update", this, record, Ext.data.Record.COMMIT);
12518
commitChanges : function(){
12519
var m = this.modified.slice(0);
12520
this.modified = [];
12521
for(var i = 0, len = m.length; i < len; i++){
12527
rejectChanges : function(){
12528
var m = this.modified.slice(0);
12529
this.modified = [];
12530
for(var i = 0, len = m.length; i < len; i++){
12536
onMetaChange : function(meta, rtype, o){
12537
this.recordType = rtype;
12538
this.fields = rtype.prototype.fields;
12539
delete this.snapshot;
12541
this.sortInfo = meta.sortInfo;
12542
}else if(this.sortInfo && !this.fields.get(this.sortInfo.field)){
12543
delete this.sortInfo;
12545
this.modified = [];
12546
this.fireEvent('metachange', this, this.reader.meta);
12550
findInsertIndex : function(record){
12551
this.suspendEvents();
12552
var data = this.data.clone();
12553
this.data.add(record);
12555
var index = this.data.indexOf(record);
12557
this.resumeEvents();
12562
setBaseParam : function (name, value){
12563
this.baseParams = this.baseParams || {};
12564
this.baseParams[name] = value;
12568
Ext.reg('store', Ext.data.Store);
12571
Ext.data.Store.Error = Ext.extend(Ext.Error, {
12572
name: 'Ext.data.Store'
12574
Ext.apply(Ext.data.Store.Error.prototype, {
12576
"writer-undefined" : "Attempted to execute a write-action without a DataWriter installed."
12582
Ext.data.DirectStore = function(c){
12583
// each transaction upon a singe record will generatie a distinct Direct transaction since Direct queues them into one Ajax request.
12584
c.batchTransactions = false;
12586
Ext.data.DirectStore.superclass.constructor.call(this, Ext.apply(c, {
12587
proxy: (typeof(c.proxy) == 'undefined') ? new Ext.data.DirectProxy(Ext.copyTo({}, c, 'paramOrder,paramsAsHash,directFn,api')) : c.proxy,
12588
reader: (typeof(c.reader) == 'undefined' && typeof(c.fields) == 'object') ? new Ext.data.JsonReader(Ext.copyTo({}, c, 'totalProperty,root,idProperty'), c.fields) : c.reader
12591
Ext.extend(Ext.data.DirectStore, Ext.data.Store, {});
12592
Ext.reg('directstore', Ext.data.DirectStore);
12595
Ext.data.JsonStore = Ext.extend(Ext.data.Store, {
12597
constructor: function(config){
12598
Ext.data.JsonStore.superclass.constructor.call(this, Ext.apply(config, {
12599
reader: new Ext.data.JsonReader(config)
12603
Ext.reg('jsonstore', Ext.data.JsonStore);
12605
Ext.data.XmlStore = Ext.extend(Ext.data.Store, {
12607
constructor: function(config){
12608
Ext.data.XmlStore.superclass.constructor.call(this, Ext.apply(config, {
12609
reader: new Ext.data.XmlReader(config)
12613
Ext.reg('xmlstore', Ext.data.XmlStore);
12615
Ext.data.ArrayStore = Ext.extend(Ext.data.Store, {
12617
constructor: function(config){
12618
Ext.data.ArrayStore.superclass.constructor.call(this, Ext.apply(config, {
12619
reader: new Ext.data.ArrayReader(config)
12623
loadData : function(data, append){
12624
if(this.expandData === true){
12626
for(var i = 0, len = data.length; i < len; i++){
12627
r[r.length] = [data[i]];
12631
Ext.data.ArrayStore.superclass.loadData.call(this, data, append);
12634
Ext.reg('arraystore', Ext.data.ArrayStore);
12636
// backwards compat
12637
Ext.data.SimpleStore = Ext.data.ArrayStore;
12638
Ext.reg('simplestore', Ext.data.SimpleStore);
12640
Ext.data.Field = function(config){
12641
if(typeof config == "string"){
12642
config = {name: config};
12644
Ext.apply(this, config);
12647
this.type = "auto";
12650
var st = Ext.data.SortTypes;
12651
// named sortTypes are supported, here we look them up
12652
if(typeof this.sortType == "string"){
12653
this.sortType = st[this.sortType];
12656
// set default sortType for strings and dates
12657
if(!this.sortType){
12660
this.sortType = st.asUCString;
12663
this.sortType = st.asDate;
12666
this.sortType = st.none;
12671
var stripRe = /[\$,%]/g;
12673
// prebuilt conversion function for this field, instead of
12674
// switching every time we're reading a value
12676
var cv, dateFormat = this.dateFormat;
12681
cv = function(v){ return v; };
12684
cv = function(v){ return (v === undefined || v === null) ? '' : String(v); };
12688
return v !== undefined && v !== null && v !== '' ?
12689
parseInt(String(v).replace(stripRe, ""), 10) : '';
12694
return v !== undefined && v !== null && v !== '' ?
12695
parseFloat(String(v).replace(stripRe, ""), 10) : '';
12700
cv = function(v){ return v === true || v === "true" || v == 1; };
12711
if(dateFormat == "timestamp"){
12712
return new Date(v*1000);
12714
if(dateFormat == "time"){
12715
return new Date(parseInt(v, 10));
12717
return Date.parseDate(v, dateFormat);
12719
var parsed = Date.parse(v);
12720
return parsed ? new Date(parsed) : null;
12729
Ext.data.Field.prototype = {
12747
Ext.data.DataReader = function(meta, recordType){
12751
this.recordType = Ext.isArray(recordType) ?
12752
Ext.data.Record.create(recordType) : recordType;
12755
Ext.data.DataReader.prototype = {
12758
realize: function(rs, data){
12759
if (Ext.isArray(rs)) {
12760
for (var i = rs.length - 1; i >= 0; i--) {
12762
if (Ext.isArray(data)) {
12763
this.realize(rs.splice(i,1).shift(), data.splice(i,1).shift());
12766
// weird...rs is an array but data isn't?? recurse but just send in the whole invalid data object.
12767
// the else clause below will detect !this.isData and throw exception.
12768
this.realize(rs.splice(i,1).shift(), data);
12773
// If rs is NOT an array but data IS, see if data contains just 1 record. If so extract it and carry on.
12774
if (Ext.isArray(data) && data.length == 1) {
12775
data = data.shift();
12777
if (!this.isData(data)) {
12778
// TODO: Let exception-handler choose to commit or not rather than blindly rs.commit() here.
12780
throw new Ext.data.DataReader.Error('realize', rs);
12782
var values = this.extractValues(data, rs.fields.items, rs.fields.items.length);
12783
rs.phantom = false; // <-- That's what it's all about
12784
rs._phid = rs.id; // <-- copy phantom-id -> _phid, so we can remap in Store#onCreateRecords
12785
rs.id = data[this.meta.idProperty];
12792
update : function(rs, data) {
12793
if (Ext.isArray(rs)) {
12794
for (var i=rs.length-1; i >= 0; i--) {
12795
if (Ext.isArray(data)) {
12796
this.update(rs.splice(i,1).shift(), data.splice(i,1).shift());
12799
// weird...rs is an array but data isn't?? recurse but just send in the whole data object.
12800
// the else clause below will detect !this.isData and throw exception.
12801
this.update(rs.splice(i,1).shift(), data);
12806
// If rs is NOT an array but data IS, see if data contains just 1 record. If so extract it and carry on.
12807
if (Ext.isArray(data) && data.length == 1) {
12808
data = data.shift();
12810
if (!this.isData(data)) {
12811
// TODO: create custom Exception class to return record in thrown exception. Allow exception-handler the choice
12812
// to commit or not rather than blindly rs.commit() here.
12814
throw new Ext.data.DataReader.Error('update', rs);
12816
rs.data = this.extractValues(Ext.apply(rs.data, data), rs.fields.items, rs.fields.items.length);
12822
isData : function(data) {
12823
return (data && typeof(data) == 'object' && !Ext.isEmpty(data[this.meta.idProperty])) ? true : false
12828
Ext.data.DataReader.Error = Ext.extend(Ext.Error, {
12829
constructor : function(message, arg) {
12831
Ext.Error.call(this, message);
12833
name: 'Ext.data.DataReader'
12835
Ext.apply(Ext.data.DataReader.Error.prototype, {
12837
'update': "#update received invalid data from server. Please see docs for DataReader#update and review your DataReader configuration.",
12838
'realize': "#realize was called with invalid remote-data. Please see the docs for DataReader#realize and review your DataReader configuration.",
12839
'invalid-response': "#readResponse received an invalid response from the server."
12846
Ext.data.DataWriter = function(config){
12848
Ext.apply(this, config);
12851
Ext.data.DataWriter.prototype = {
12854
writeAllFields : false,
12856
listful : false, // <-- listful is actually not used internally here in DataWriter. @see Ext.data.Store#execute.
12859
write : function(action, params, rs) {
12860
this.render(action, rs, params, this[action](rs));
12864
render : Ext.emptyFn,
12867
update : function(rs) {
12869
if (Ext.isArray(rs)) {
12872
for (var n=0,len=rs.length;n<len;n++) {
12873
ids.push(rs[n].id);
12874
data.push(this.updateRecord(rs[n]));
12876
params[this.meta.idProperty] = ids;
12877
params[this.meta.root] = data;
12879
else if (rs instanceof Ext.data.Record) {
12880
params[this.meta.idProperty] = rs.id;
12881
params[this.meta.root] = this.updateRecord(rs);
12887
updateRecord : Ext.emptyFn,
12890
create : function(rs) {
12892
if (Ext.isArray(rs)) {
12894
for (var n=0,len=rs.length;n<len;n++) {
12895
data.push(this.createRecord(rs[n]));
12897
params[this.meta.root] = data;
12899
else if (rs instanceof Ext.data.Record) {
12900
params[this.meta.root] = this.createRecord(rs);
12906
createRecord : Ext.emptyFn,
12909
destroy : function(rs) {
12911
if (Ext.isArray(rs)) {
12914
for (var i=0,len=rs.length;i<len;i++) {
12915
data.push(this.destroyRecord(rs[i]));
12917
params[this.meta.root] = data;
12918
} else if (rs instanceof Ext.data.Record) {
12919
params[this.meta.root] = this.destroyRecord(rs);
12925
destroyRecord : Ext.emptyFn,
12928
toHash : function(rec) {
12929
var map = rec.fields.map;
12931
var raw = (this.writeAllFields === false && rec.phantom === false) ? rec.getChanges() : rec.data;
12932
for (var k in raw) {
12933
data[(map[k].mapping) ? map[k].mapping : map[k].name] = raw[k];
12935
data[this.meta.idProperty] = rec.id;
12940
Ext.data.JsonWriter = Ext.extend(Ext.data.DataWriter, {
12945
render : function(action, rs, params, data) {
12946
Ext.apply(params, data);
12947
if (this.returnJson) {
12948
if (Ext.isArray(rs) && data[this.meta.idProperty]) {
12949
params[this.meta.idProperty] = Ext.encode(params[this.meta.idProperty]);
12951
params[this.meta.root] = Ext.encode(params[this.meta.root]);
12955
createRecord : function(rec) {
12956
return this.toHash(rec);
12959
updateRecord : function(rec) {
12960
return this.toHash(rec);
12964
destroyRecord : function(rec) {
12969
Ext.data.DataProxy = function(conn){
12970
// make sure we have a config object here to support ux proxies.
12971
// All proxies should now send config into superclass constructor.
12974
// This line caused a bug when people use custom Connection object having its own request method.
12975
// http://extjs.com/forum/showthread.php?t=67194. Have to set DataProxy config
12976
//Ext.applyIf(this, conn);
12978
this.api = conn.api;
12979
this.url = conn.url;
12980
this.restful = conn.restful;
12981
this.listeners = conn.listeners;
12984
this.prettyUrls = conn.prettyUrls;
12987
// Prepare the proxy api. Ensures all API-actions are defined with the Object-form.
12989
Ext.data.Api.prepare(this);
12991
if (e instanceof Ext.data.Api.Error) {
13010
Ext.data.DataProxy.superclass.constructor.call(this);
13013
Ext.extend(Ext.data.DataProxy, Ext.util.Observable, {
13018
setApi : function() {
13019
if (arguments.length == 1) {
13020
var valid = Ext.data.Api.isValid(arguments[0]);
13021
if (valid === true) {
13022
this.api = arguments[0];
13025
throw new Ext.data.Api.Error('invalid', valid);
13028
else if (arguments.length == 2) {
13029
if (!Ext.data.Api.isAction(arguments[0])) {
13030
throw new Ext.data.Api.Error('invalid', arguments[0]);
13032
this.api[arguments[0]] = arguments[1];
13034
Ext.data.Api.prepare(this);
13038
isApiAction : function(action) {
13039
return (this.api[action]) ? true : false;
13043
request : function(action, rs, params, reader, callback, scope, options) {
13044
if (!this.api[action]) {
13045
throw new Ext.data.DataProxy.Error('action-undefined', action);
13047
params = params || {};
13048
if ((action === Ext.data.Api.actions.read) ? this.fireEvent("beforeload", this, params) : this.fireEvent("beforewrite", this, action, rs, params) !== false) {
13049
this.doRequest.apply(this, arguments);
13052
callback.call(scope || this, null, options, false);
13058
load : function(params, reader, callback, scope, arg) {
13059
this.doRequest(Ext.data.Api.actions.read, null, params, reader, callback, scope, arg);
13063
doRequest : function(action, rs, params, reader, callback, scope, options) {
13064
// default implementation of doRequest for backwards compatibility with 2.0 proxies.
13065
// If we're executing here, the action is probably "load".
13066
// Call with the pre-3.0 method signature.
13067
// WARNING: Potentially infinitely recursive: See load above which calls this.doRequest
13068
this.load(params, reader, callback, scope, options);
13072
buildUrl : function(action, record) {
13073
record = record || null;
13074
var url = (this.api[action]) ? this.api[action]['url'] : this.url;
13076
throw new Ext.data.Api.Error('invalid-url', action);
13078
// prettyUrls is deprectated in favor of restful-config
13079
if ((this.prettyUrls === true || this.restful === true) && record instanceof Ext.data.Record && !record.phantom) {
13080
url += '/' + record.id;
13086
destroy: function(){
13087
this.purgeListeners();
13092
Ext.data.DataProxy.Error = Ext.extend(Ext.Error, {
13093
constructor : function(message, arg) {
13095
Ext.Error.call(this, message);
13097
name: 'Ext.data.DataProxy'
13099
Ext.apply(Ext.data.DataProxy.Error.prototype, {
13101
'action-undefined': "DataProxy attempted to execute an API-action but found an undefined url / function. Please review your Proxy url/api-configuration.",
13102
'api-invalid': 'Recieved an invalid API-configuration. Please ensure your proxy API-configuration contains only the actions from Ext.data.Api.actions.'
13107
Ext.data.MemoryProxy = function(data){
13108
// Must define a dummy api with "read" action to satisfy DataProxy#doRequest and Ext.data.Api#prepare *before* calling super
13110
api[Ext.data.Api.actions.read] = true;
13111
Ext.data.MemoryProxy.superclass.constructor.call(this, {
13117
Ext.extend(Ext.data.MemoryProxy, Ext.data.DataProxy, {
13121
doRequest : function(action, rs, params, reader, callback, scope, arg) {
13122
// No implementation for CRUD in MemoryProxy. Assumes all actions are 'load'
13123
params = params || {};
13126
result = reader.readRecords(this.data);
13128
// @deprecated loadexception
13129
this.fireEvent("loadexception", this, null, arg, e);
13131
this.fireEvent('exception', this, 'response', action, arg, null, e);
13132
callback.call(scope, null, arg, false);
13135
callback.call(scope, result, arg, true);
13139
Ext.data.HttpProxy = function(conn){
13140
Ext.data.HttpProxy.superclass.constructor.call(this, conn);
13145
// nullify the connection url. The url param has been copied to "this" above. The connection
13146
// url will be set during each execution of doRequest when buildUrl is called. This makes it easier for users to override the
13147
// connection url during beforeaction events (ie: beforeload, beforesave, etc). The connection url will be nullified
13148
// after each request as well. Url is always re-defined during doRequest.
13149
this.conn.url = null;
13151
this.useAjax = !conn || !conn.events;
13153
//private. A hash containing active requests, keyed on action [Ext.data.Api.actions.create|read|update|destroy]
13154
var actions = Ext.data.Api.actions
13155
this.activeRequest = {};
13156
for (var verb in actions) {
13157
this.activeRequest[actions[verb]] = undefined;
13161
Ext.extend(Ext.data.HttpProxy, Ext.data.DataProxy, {
13165
getConnection : function() {
13166
return this.useAjax ? Ext.Ajax : this.conn;
13170
setUrl : function(url, makePermanent) {
13171
this.conn.url = url;
13172
if (makePermanent === true) {
13174
Ext.data.Api.prepare(this);
13179
doRequest : function(action, rs, params, reader, cb, scope, arg) {
13181
params : params || {},
13182
method: (this.api[action]) ? this.api[action]['method'] : undefined,
13189
callback : this.createCallback(action, rs),
13192
// Set the connection url. If this.conn.url is not null here,
13193
// the user may have overridden the url during a beforeaction event-handler.
13194
// this.conn.url is nullified after each request.
13195
if (this.conn.url === null) {
13196
this.conn.url = this.buildUrl(action, rs);
13198
else if (this.restful === true && rs instanceof Ext.data.Record && !rs.phantom) {
13199
this.conn.url += '/' + rs.id;
13203
Ext.applyIf(o, this.conn);
13205
// If a currently running request is found for this action, abort it.
13206
if (this.activeRequest[action]) {
13207
// Disabled aborting activeRequest while implementing REST. activeRequest[action] will have to become an array
13208
//Ext.Ajax.abort(this.activeRequest[action]);
13210
this.activeRequest[action] = Ext.Ajax.request(o);
13212
this.conn.request(o);
13214
// request is sent, nullify the connection url in preparation for the next request
13215
this.conn.url = null;
13219
createCallback : function(action, rs) {
13220
return function(o, success, response) {
13221
this.activeRequest[action] = undefined;
13223
if (action === Ext.data.Api.actions.read) {
13224
// @deprecated: fire loadexception for backwards compat.
13225
this.fireEvent("loadexception", this, o, response);
13227
this.fireEvent('exception', this, 'response', action, o, response);
13228
o.request.callback.call(o.request.scope, null, o.request.arg, false);
13231
if (action === Ext.data.Api.actions.read) {
13232
this.onRead(action, o, response);
13234
this.onWrite(action, o, response, rs);
13240
onRead : function(action, o, response) {
13243
result = o.reader.read(response);
13245
// @deprecated: fire old loadexception for backwards-compat.
13246
this.fireEvent("loadexception", this, o, response, e);
13247
this.fireEvent('exception', this, 'response', action, o, response, e);
13248
o.request.callback.call(o.request.scope, null, o.request.arg, false);
13251
if (result.success === false) {
13252
// @deprecated: fire old loadexception for backwards-compat.
13253
this.fireEvent('loadexception', this, o, response);
13255
// Get DataReader read-back a response-object to pass along to exception event
13256
var res = o.reader.readResponse(action, response);
13257
this.fireEvent('exception', this, 'remote', action, o, res, null);
13260
this.fireEvent("load", this, o, o.request.arg);
13262
o.request.callback.call(o.request.scope, result, o.request.arg, result.success);
13265
onWrite : function(action, o, response, rs) {
13266
var reader = o.reader;
13269
res = reader.readResponse(action, response);
13271
this.fireEvent('exception', this, 'response', action, o, response, e);
13272
o.request.callback.call(o.request.scope, null, o.request.arg, false);
13275
if (res[reader.meta.successProperty] === false) {
13276
this.fireEvent('exception', this, 'remote', action, o, res, rs);
13278
this.fireEvent("write", this, action, res[reader.meta.root], res, rs, o.request.arg);
13280
o.request.callback.call(o.request.scope, res[reader.meta.root], res, res[reader.meta.successProperty]);
13284
destroy: function(){
13287
}else if(this.activeRequest){
13288
var actions = Ext.data.Api.actions;
13289
for (var verb in actions) {
13290
if(this.activeRequest[actions[verb]]){
13291
Ext.Ajax.abort(this.activeRequest[actions[verb]]);
13295
Ext.data.HttpProxy.superclass.destroy.call(this);
13299
Ext.data.ScriptTagProxy = function(config){
13300
Ext.apply(this, config);
13302
Ext.data.ScriptTagProxy.superclass.constructor.call(this, config);
13304
this.head = document.getElementsByTagName("head")[0];
13309
Ext.data.ScriptTagProxy.TRANS_ID = 1000;
13311
Ext.extend(Ext.data.ScriptTagProxy, Ext.data.DataProxy, {
13316
callbackParam : "callback",
13321
doRequest : function(action, rs, params, reader, callback, scope, arg) {
13322
var p = Ext.urlEncode(Ext.apply(params, this.extraParams));
13324
var url = this.buildUrl(action, rs);
13326
throw new Ext.data.Api.Error('invalid-url', url);
13328
url += (url.indexOf("?") != -1 ? "&" : "?") + p;
13331
url += "&_dc=" + (new Date().getTime());
13333
var transId = ++Ext.data.ScriptTagProxy.TRANS_ID;
13337
cb : "stcCallback"+transId,
13338
scriptId : "stcScript"+transId,
13342
callback : callback,
13346
window[trans.cb] = this.createCallback(action, rs, trans);
13347
url += String.format("&{0}={1}", this.callbackParam, trans.cb);
13348
if(this.autoAbort !== false){
13352
trans.timeoutId = this.handleFailure.defer(this.timeout, this, [trans]);
13354
var script = document.createElement("script");
13355
script.setAttribute("src", url);
13356
script.setAttribute("type", "text/javascript");
13357
script.setAttribute("id", trans.scriptId);
13358
this.head.appendChild(script);
13360
this.trans = trans;
13363
// @private createCallback
13364
createCallback : function(action, rs, trans) {
13366
return function(res) {
13367
self.trans = false;
13368
self.destroyTrans(trans, true);
13369
if (action === Ext.data.Api.actions.read) {
13370
self.onRead.call(self, action, trans, res);
13372
self.onWrite.call(self, action, trans, res, rs);
13377
onRead : function(action, trans, res) {
13380
result = trans.reader.readRecords(res);
13382
// @deprecated: fire loadexception
13383
this.fireEvent("loadexception", this, trans, res, e);
13385
this.fireEvent('exception', this, 'response', action, trans, res, e);
13386
trans.callback.call(trans.scope||window, null, trans.arg, false);
13389
if (result.success === false) {
13390
// @deprecated: fire old loadexception for backwards-compat.
13391
this.fireEvent('loadexception', this, trans, res);
13393
this.fireEvent('exception', this, 'remote', action, trans, res, null);
13395
this.fireEvent("load", this, res, trans.arg);
13397
trans.callback.call(trans.scope||window, result, trans.arg, result.success);
13400
onWrite : function(action, trans, res, rs) {
13401
var reader = trans.reader;
13403
// though we already have a response object here in STP, run through readResponse to catch any meta-data exceptions.
13404
reader.readResponse(action, res);
13406
this.fireEvent('exception', this, 'response', action, trans, res, e);
13407
trans.callback.call(trans.scope||window, null, res, false);
13410
if(!res[reader.meta.successProperty] === true){
13411
this.fireEvent('exception', this, 'remote', action, trans, res, rs);
13412
trans.callback.call(trans.scope||window, null, res, false);
13415
this.fireEvent("write", this, action, res[reader.meta.root], res, rs, trans.arg );
13416
trans.callback.call(trans.scope||window, res[reader.meta.root], res, true);
13420
isLoading : function(){
13421
return this.trans ? true : false;
13425
abort : function(){
13426
if(this.isLoading()){
13427
this.destroyTrans(this.trans);
13432
destroyTrans : function(trans, isLoaded){
13433
this.head.removeChild(document.getElementById(trans.scriptId));
13434
clearTimeout(trans.timeoutId);
13436
window[trans.cb] = undefined;
13438
delete window[trans.cb];
13441
// if hasn't been loaded, wait for load to remove it to prevent script error
13442
window[trans.cb] = function(){
13443
window[trans.cb] = undefined;
13445
delete window[trans.cb];
13452
handleFailure : function(trans){
13453
this.trans = false;
13454
this.destroyTrans(trans, false);
13455
if (trans.action === Ext.data.Api.actions.read) {
13456
// @deprecated firing loadexception
13457
this.fireEvent("loadexception", this, null, trans.arg);
13460
this.fireEvent('exception', this, 'response', trans.action, {
13464
trans.callback.call(trans.scope||window, null, trans.arg, false);
13468
destroy: function(){
13470
Ext.data.ScriptTagProxy.superclass.destroy.call(this);
13474
Ext.data.DirectProxy = function(config){
13475
Ext.apply(this, config);
13476
if(typeof this.paramOrder == 'string'){
13477
this.paramOrder = this.paramOrder.split(/[\s,|]/);
13479
Ext.data.DirectProxy.superclass.constructor.call(this, config);
13482
Ext.extend(Ext.data.DirectProxy, Ext.data.DataProxy, {
13484
paramOrder: undefined,
13487
paramsAsHash: true,
13490
directFn : undefined,
13493
doRequest : function(action, rs, params, reader, callback, scope, options) {
13495
var directFn = this.api[action] || this.directFn;
13498
case Ext.data.Api.actions.create:
13499
args.push(params[reader.meta.root]); // <-- create(Hash)
13501
case Ext.data.Api.actions.read:
13502
if(this.paramOrder){
13503
for(var i = 0, len = this.paramOrder.length; i < len; i++){
13504
args.push(params[this.paramOrder[i]]);
13506
}else if(this.paramsAsHash){
13510
case Ext.data.Api.actions.update:
13511
args.push(params[reader.meta.idProperty]); // <-- save(Integer/Integer[], Hash/Hash[])
13512
args.push(params[reader.meta.root]);
13514
case Ext.data.Api.actions.destroy:
13515
args.push(params[reader.meta.root]); // <-- destroy(Int/Int[])
13520
params : params || {},
13521
callback : callback,
13527
args.push(this.createCallback(action, rs, trans), this);
13528
directFn.apply(window, args);
13532
createCallback : function(action, rs, trans) {
13533
return function(result, res) {
13535
// @deprecated fire loadexception
13536
if (action === Ext.data.Api.actions.read) {
13537
this.fireEvent("loadexception", this, trans, res, null);
13539
this.fireEvent('exception', this, 'remote', action, trans, res, null);
13540
trans.callback.call(trans.scope, null, trans.arg, false);
13543
if (action === Ext.data.Api.actions.read) {
13544
this.onRead(action, trans, result, res);
13546
this.onWrite(action, trans, result, res, rs);
13551
onRead : function(action, trans, result, res) {
13554
records = trans.reader.readRecords(result);
13557
// @deprecated: Fire old loadexception for backwards-compat.
13558
this.fireEvent("loadexception", this, trans, res, ex);
13560
this.fireEvent('exception', this, 'response', action, trans, res, ex);
13561
trans.callback.call(trans.scope, null, trans.arg, false);
13564
this.fireEvent("load", this, res, trans.arg);
13565
trans.callback.call(trans.scope, records, trans.arg, true);
13568
onWrite : function(action, trans, result, res, rs) {
13569
this.fireEvent("write", this, action, result, res, rs, trans.arg);
13570
trans.callback.call(trans.scope, result, res, true);
13576
Ext.data.JsonReader = function(meta, recordType){
13579
// default idProperty, successProperty & totalProperty -> "id", "success", "total"
13580
Ext.applyIf(meta, {
13582
successProperty: 'success',
13583
totalProperty: 'total'
13586
Ext.data.JsonReader.superclass.constructor.call(this, meta, recordType || meta.fields);
13588
Ext.extend(Ext.data.JsonReader, Ext.data.DataReader, {
13591
read : function(response){
13592
var json = response.responseText;
13593
var o = Ext.decode(json);
13595
throw {message: "JsonReader.read: Json object not found"};
13597
return this.readRecords(o);
13600
// private function a store will implement
13601
onMetaChange : function(meta, recordType, o){
13606
simpleAccess: function(obj, subsc) {
13611
getJsonAccessor: function(){
13613
return function(expr) {
13615
return(re.test(expr))
13616
? new Function("obj", "return obj." + expr)
13621
return Ext.emptyFn;
13626
readRecords : function(o){
13631
this.meta = o.metaData;
13632
this.recordType = Ext.data.Record.create(o.metaData.fields);
13633
this.onMetaChange(this.meta, this.recordType, o);
13635
var s = this.meta, Record = this.recordType,
13636
f = Record.prototype.fields, fi = f.items, fl = f.length;
13638
// Generate extraction functions for the totalProperty, the root, the id, and for each field
13640
this.ef = this.buildExtractors();
13642
var root = this.getRoot(o), c = root.length, totalRecords = c, success = true;
13643
if(s.totalProperty){
13644
var v = parseInt(this.getTotal(o), 10);
13649
if(s.successProperty){
13650
var v = this.getSuccess(o);
13651
if(v === false || v === 'false'){
13657
for(var i = 0; i < c; i++){
13659
var record = new Record(this.extractValues(n, fi, fl), this.getId(n));
13661
records[i] = record;
13666
totalRecords : totalRecords
13671
buildExtractors : function() {
13672
var s = this.meta, Record = this.recordType,
13673
f = Record.prototype.fields, fi = f.items, fl = f.length;
13675
if(s.totalProperty) {
13676
this.getTotal = this.getJsonAccessor(s.totalProperty);
13678
if(s.successProperty) {
13679
this.getSuccess = this.getJsonAccessor(s.successProperty);
13681
this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p){return p;};
13682
if (s.id || s.idProperty) {
13683
var g = this.getJsonAccessor(s.id || s.idProperty);
13684
this.getId = function(rec) {
13686
return (r === undefined || r === "") ? null : r;
13689
this.getId = function(){return null;};
13692
for(var i = 0; i < fl; i++){
13694
var map = (f.mapping !== undefined && f.mapping !== null) ? f.mapping : f.name;
13695
ef.push(this.getJsonAccessor(map));
13700
// private extractValues
13701
extractValues: function(data, items, len) {
13702
var f, values = {};
13703
for(var j = 0; j < len; j++){
13705
var v = this.ef[j](data);
13706
values[f.name] = f.convert((v !== undefined) ? v : f.defaultValue, data);
13712
readResponse : function(action, response) {
13713
var o = (typeof(response.responseText) != undefined) ? Ext.decode(response.responseText) : response;
13715
throw new Ext.data.JsonReader.Error('response');
13717
if (Ext.isEmpty(o[this.meta.successProperty])) {
13718
throw new Ext.data.JsonReader.Error('successProperty-response', this.meta.successProperty);
13720
// TODO, separate empty and undefined exceptions.
13721
if ((action === Ext.data.Api.actions.create || action === Ext.data.Api.actions.update)) {
13722
if (Ext.isEmpty(o[this.meta.root])) {
13723
throw new Ext.data.JsonReader.Error('root-emtpy', this.meta.root);
13725
else if (typeof(o[this.meta.root]) === undefined) {
13726
throw new Ext.data.JsonReader.Error('root-undefined-response', this.meta.root);
13729
// makde sure extaction functions are defined.
13731
this.ef = this.buildExtractors();
13738
Ext.data.JsonReader.Error = Ext.extend(Ext.Error, {
13739
constructor : function(message, arg) {
13741
Ext.Error.call(this, message);
13743
name : 'Ext.data.JsonReader'
13745
Ext.apply(Ext.data.JsonReader.Error.prototype, {
13747
'response': "An error occurred while json-decoding your server response",
13748
'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.',
13749
'root-undefined-response': 'Could not locate your "root" property in your server response. Please review your JsonReader config to ensure the config-property "root" matches the property your server-response. See the JsonReader docs.',
13750
'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.',
13751
'idProperty-undefined' : 'Your JsonReader was configured without an "idProperty" Please review your JsonReader configuration and ensure the "idProperty" is set (eg: "id"). See the JsonReader docs.',
13752
'root-emtpy': '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.'
13757
Ext.data.XmlReader = function(meta, recordType){
13759
Ext.data.XmlReader.superclass.constructor.call(this, meta, recordType || meta.fields);
13761
Ext.extend(Ext.data.XmlReader, Ext.data.DataReader, {
13763
read : function(response){
13764
var doc = response.responseXML;
13766
throw {message: "XmlReader.read: XML Document not available"};
13768
return this.readRecords(doc);
13772
readRecords : function(doc){
13774
this.xmlData = doc;
13775
var root = doc.documentElement || doc;
13776
var q = Ext.DomQuery;
13777
var recordType = this.recordType, fields = recordType.prototype.fields;
13778
var sid = this.meta.idPath || this.meta.id;
13779
var totalRecords = 0, success = true;
13780
if(this.meta.totalRecords){
13781
totalRecords = q.selectNumber(this.meta.totalRecords, root, 0);
13784
if(this.meta.success){
13785
var sv = q.selectValue(this.meta.success, root, true);
13786
success = sv !== false && sv !== 'false';
13789
var ns = q.select(this.meta.record, root);
13790
for(var i = 0, len = ns.length; i < len; i++) {
13793
var id = sid ? q.selectValue(sid, n) : undefined;
13794
for(var j = 0, jlen = fields.length; j < jlen; j++){
13795
var f = fields.items[j];
13796
var v = q.selectValue(Ext.value(f.mapping, f.name, true), n, f.defaultValue);
13797
v = f.convert(v, n);
13798
values[f.name] = v;
13800
var record = new recordType(values, id);
13802
records[records.length] = record;
13808
totalRecords : totalRecords || records.length
13812
// TODO: implement readResponse for XmlReader
13813
readResponse : Ext.emptyFn
13816
Ext.data.ArrayReader = Ext.extend(Ext.data.JsonReader, {
13821
readRecords : function(o){
13822
this.arrayData = o;
13824
var sid = s ? Ext.num(s.idIndex, s.id) : null;
13825
var recordType = this.recordType, fields = recordType.prototype.fields;
13828
if(!this.getRoot) {
13829
this.getRoot = s.root ? this.getJsonAccessor(s.root) : function(p) {return p;};
13830
if(s.totalProperty) {
13831
this.getTotal = this.getJsonAccessor(s.totalProperty);
13835
var root = this.getRoot(o);
13837
for(var i = 0; i < root.length; i++) {
13840
var id = ((sid || sid === 0) && n[sid] !== undefined && n[sid] !== "" ? n[sid] : null);
13841
for(var j = 0, jlen = fields.length; j < jlen; j++) {
13842
var f = fields.items[j];
13843
var k = f.mapping !== undefined && f.mapping !== null ? f.mapping : j;
13844
var v = n[k] !== undefined ? n[k] : f.defaultValue;
13845
v = f.convert(v, n);
13846
values[f.name] = v;
13848
var record = new recordType(values, id);
13850
records[records.length] = record;
13853
var totalRecords = records.length;
13855
if(s.totalProperty) {
13856
var v = parseInt(this.getTotal(o), 10);
13864
totalRecords : totalRecords
13869
Ext.Direct = Ext.extend(Ext.util.Observable, {
13877
SERVER: 'exception'
13881
constructor: function(){
13888
this.transactions = {};
13889
this.providers = {};
13893
addProvider : function(provider){
13896
for(var i = 0, len = a.length; i < len; i++){
13897
this.addProvider(a[i]);
13902
// if provider has not already been instantiated
13903
if(!provider.events){
13904
provider = new Ext.Direct.PROVIDERS[provider.type](provider);
13906
provider.id = provider.id || Ext.id();
13907
this.providers[provider.id] = provider;
13909
provider.on('data', this.onProviderData, this);
13910
provider.on('exception', this.onProviderException, this);
13913
if(!provider.isConnected()){
13914
provider.connect();
13921
getProvider : function(id){
13922
return this.providers[id];
13925
removeProvider : function(id){
13926
var provider = id.id ? id : providers[id.id];
13927
provider.un('data', this.onProviderData, this);
13928
provider.un('exception', this.onProviderException, this);
13929
delete this.providers[provider.id];
13933
addTransaction: function(t){
13934
this.transactions[t.tid] = t;
13938
removeTransaction: function(t){
13939
delete this.transactions[t.tid || t];
13943
getTransaction: function(tid){
13944
return this.transactions[tid.tid || tid];
13947
onProviderData : function(provider, e){
13948
if(Ext.isArray(e)){
13949
for(var i = 0, len = e.length; i < len; i++){
13950
this.onProviderData(provider, e[i]);
13954
if(e.name && e.name != 'event' && e.name != 'exception'){
13955
this.fireEvent(e.name, e);
13956
}else if(e.type == 'exception'){
13957
this.fireEvent('exception', e);
13959
this.fireEvent('event', e, provider);
13962
createEvent : function(response, extraProps){
13963
return new Ext.Direct.eventTypes[response.type](Ext.apply(response, extraProps));
13966
// overwrite impl. with static instance
13967
Ext.Direct = new Ext.Direct();
13969
Ext.Direct.TID = 1;
13970
Ext.Direct.PROVIDERS = {};
13971
Ext.Direct.Transaction = function(config){
13972
Ext.apply(this, config);
13973
this.tid = ++Ext.Direct.TID;
13974
this.retryCount = 0;
13976
Ext.Direct.Transaction.prototype = {
13978
this.provider.queueTransaction(this);
13986
getProvider: function(){
13987
return this.provider;
13990
Ext.Direct.Event = function(config){
13991
Ext.apply(this, config);
13993
Ext.Direct.Event.prototype = {
13995
getData: function(){
14000
Ext.Direct.RemotingEvent = Ext.extend(Ext.Direct.Event, {
14002
getTransaction: function(){
14003
return this.transaction || Ext.Direct.getTransaction(this.tid);
14007
Ext.Direct.ExceptionEvent = Ext.extend(Ext.Direct.RemotingEvent, {
14012
Ext.Direct.eventTypes = {
14013
'rpc': Ext.Direct.RemotingEvent,
14014
'event': Ext.Direct.Event,
14015
'exception': Ext.Direct.ExceptionEvent
14020
Ext.direct.Provider = Ext.extend(Ext.util.Observable, {
14029
constructor : function(config){
14030
Ext.apply(this, config);
14041
Ext.direct.Provider.superclass.constructor.call(this, config);
14045
isConnected: function(){
14050
connect: Ext.emptyFn,
14053
disconnect: Ext.emptyFn
14057
Ext.direct.JsonProvider = Ext.extend(Ext.direct.Provider, {
14058
parseResponse: function(xhr){
14059
if(!Ext.isEmpty(xhr.responseText)){
14060
if(typeof xhr.responseText == 'object'){
14061
return xhr.responseText;
14063
return Ext.decode(xhr.responseText);
14068
getEvents: function(xhr){
14071
data = this.parseResponse(xhr);
14073
var event = new Ext.Direct.ExceptionEvent({
14076
code: Ext.Direct.exceptions.PARSE,
14077
message: 'Error parsing json response: \n\n ' + data
14082
if(Ext.isArray(data)){
14083
for(var i = 0, len = data.length; i < len; i++){
14084
events.push(Ext.Direct.createEvent(data[i]));
14087
events.push(Ext.Direct.createEvent(data));
14093
Ext.direct.PollingProvider = Ext.extend(Ext.direct.JsonProvider, {
14095
// override default priority
14106
constructor : function(config){
14107
Ext.direct.PollingProvider.superclass.constructor.call(this, config);
14117
isConnected: function(){
14118
return !!this.pollTask;
14122
connect: function(){
14123
if(this.url && !this.pollTask){
14124
this.pollTask = Ext.TaskMgr.start({
14126
if(this.fireEvent('beforepoll', this) !== false){
14127
if(typeof this.url == 'function'){
14128
this.url(this.baseParams);
14132
callback: this.onData,
14134
params: this.baseParams
14139
interval: this.interval,
14142
this.fireEvent('connect', this);
14143
}else if(!this.url){
14144
throw 'Error initializing PollingProvider, no url configured.';
14149
disconnect: function(){
14151
Ext.TaskMgr.stop(this.pollTask);
14152
delete this.pollTask;
14153
this.fireEvent('disconnect', this);
14158
onData: function(opt, success, xhr){
14160
var events = this.getEvents(xhr);
14161
for(var i = 0, len = events.length; i < len; i++){
14163
this.fireEvent('data', this, e);
14166
var e = new Ext.Direct.ExceptionEvent({
14168
code: Ext.Direct.exceptions.TRANSPORT,
14169
message: 'Unable to connect to the server.',
14172
this.fireEvent('data', this, e);
14177
Ext.Direct.PROVIDERS['polling'] = Ext.direct.PollingProvider;
14179
Ext.direct.RemotingProvider = Ext.extend(Ext.direct.JsonProvider, {
14194
constructor : function(config){
14195
Ext.direct.RemotingProvider.superclass.constructor.call(this, config);
14202
this.namespace = (typeof this.namespace === 'string') ? Ext.ns(this.namespace) : this.namespace || window;
14203
this.transactions = {};
14204
this.callBuffer = [];
14208
initAPI : function(){
14209
var o = this.actions;
14211
var cls = this.namespace[c] || (this.namespace[c] = {});
14213
for(var i = 0, len = ms.length; i < len; i++){
14215
cls[m.name] = this.createMethod(c, m);
14221
isConnected: function(){
14222
return !!this.connected;
14225
connect: function(){
14228
this.connected = true;
14229
this.fireEvent('connect', this);
14230
}else if(!this.url){
14231
throw 'Error initializing RemotingProvider, no url configured.';
14235
disconnect: function(){
14236
if(this.connected){
14237
this.connected = false;
14238
this.fireEvent('disconnect', this);
14242
onData: function(opt, success, xhr){
14244
var events = this.getEvents(xhr);
14245
for(var i = 0, len = events.length; i < len; i++){
14247
var t = e.getTransaction();
14248
this.fireEvent('data', this, e);
14250
this.doCallback(t, e, true);
14251
Ext.Direct.removeTransaction(t);
14255
var ts = [].concat(opt.ts);
14256
for(var i = 0, len = ts.length; i < len; i++){
14257
var t = this.getTransaction(ts[i]);
14258
if(t && t.retryCount < this.maxRetries){
14261
var e = new Ext.Direct.ExceptionEvent({
14264
code: Ext.Direct.exceptions.TRANSPORT,
14265
message: 'Unable to connect to the server.',
14268
this.fireEvent('data', this, e);
14270
this.doCallback(t, e, false);
14271
Ext.Direct.removeTransaction(t);
14278
getCallData: function(t){
14288
doSend : function(data){
14291
callback: this.onData,
14295
// send only needed data
14297
if(Ext.isArray(data)){
14299
for(var i = 0, len = data.length; i < len; i++){
14300
callData.push(this.getCallData(data[i]));
14303
callData = this.getCallData(data);
14306
if(this.enableUrlEncode){
14308
params[typeof this.enableUrlEncode == 'string' ? this.enableUrlEncode : 'data'] = Ext.encode(callData);
14311
o.jsonData = callData;
14313
Ext.Ajax.request(o);
14316
combineAndSend : function(){
14317
var len = this.callBuffer.length;
14319
this.doSend(len == 1 ? this.callBuffer[0] : this.callBuffer);
14320
this.callBuffer = [];
14324
queueTransaction: function(t){
14325
this.callBuffer.push(t);
14326
if(this.enableBuffer){
14327
if(!this.callTask){
14328
this.callTask = new Ext.util.DelayedTask(this.combineAndSend, this);
14330
this.callTask.delay(typeof this.enableBuffer == 'number' ? this.enableBuffer : 10);
14332
this.combineAndSend();
14336
doCall : function(c, m, args){
14337
var data = null, hs = args[m.len], scope = args[m.len+1];
14340
data = args.slice(0, m.len);
14343
var t = new Ext.Direct.Transaction({
14349
cb: scope && typeof hs == 'function' ? hs.createDelegate(scope) : hs
14352
if(this.fireEvent('beforecall', this, t) !== false){
14353
Ext.Direct.addTransaction(t);
14354
this.queueTransaction(t);
14355
this.fireEvent('call', this, t);
14359
doForm : function(c, m, form, callback, scope){
14360
var t = new Ext.Direct.Transaction({
14364
args:[form, callback, scope],
14365
cb: scope && typeof callback == 'function' ? callback.createDelegate(scope) : callback
14368
if(this.fireEvent('beforecall', this, t) !== false){
14369
Ext.Direct.addTransaction(t);
14371
form = Ext.getDom(form);
14372
var isUpload = String(form.getAttribute("enctype")).toLowerCase() == 'multipart/form-data';
14379
extUpload: String(isUpload)
14381
// change made from typeof callback check to callback.params
14382
// to support addl param passing in DirectSubmit EAC 6/2
14383
if(callback && typeof callback.params == 'object'){
14384
Ext.apply(params, callback.params);
14389
callback: this.onData,
14392
isUpload: isUpload,
14398
createMethod : function(c, m){
14400
if(!m.formHandler){
14402
this.doCall(c, m, Array.prototype.slice.call(arguments, 0));
14403
}.createDelegate(this);
14405
f = function(form, callback, scope){
14406
this.doForm(c, m, form, callback, scope);
14407
}.createDelegate(this);
14416
getTransaction: function(opt){
14417
return opt && opt.tid ? Ext.Direct.getTransaction(opt.tid) : null;
14420
doCallback: function(t, e){
14421
var fn = e.status ? 'success' : 'failure';
14424
var result = e.result || e.data;
14425
if(typeof hs == 'function'){
14428
Ext.callback(hs[fn], hs.scope, [result, e]);
14429
Ext.callback(hs.callback, hs.scope, [result, e]);
14434
Ext.Direct.PROVIDERS['remoting'] = Ext.direct.RemotingProvider;
14436
Ext.data.Tree = function(root){
14437
this.nodeHash = {};
14441
this.setRootNode(root);
14462
Ext.data.Tree.superclass.constructor.call(this);
14465
Ext.extend(Ext.data.Tree, Ext.util.Observable, {
14467
pathSeparator: "/",
14470
proxyNodeEvent : function(){
14471
return this.fireEvent.apply(this, arguments);
14475
getRootNode : function(){
14480
setRootNode : function(node){
14482
node.ownerTree = this;
14483
node.isRoot = true;
14484
this.registerNode(node);
14489
getNodeById : function(id){
14490
return this.nodeHash[id];
14494
registerNode : function(node){
14495
this.nodeHash[node.id] = node;
14499
unregisterNode : function(node){
14500
delete this.nodeHash[node.id];
14503
toString : function(){
14504
return "[Tree"+(this.id?" "+this.id:"")+"]";
14509
Ext.data.Node = function(attributes){
14511
this.attributes = attributes || {};
14512
this.leaf = this.attributes.leaf;
14514
this.id = this.attributes.id;
14516
this.id = Ext.id(null, "xnode-");
14517
this.attributes.id = this.id;
14520
this.childNodes = [];
14521
if(!this.childNodes.indexOf){ // indexOf is a must
14522
this.childNodes.indexOf = function(o){
14523
for(var i = 0, len = this.length; i < len; i++){
14524
if(this[i] == o) return i;
14530
this.parentNode = null;
14532
this.firstChild = null;
14534
this.lastChild = null;
14536
this.previousSibling = null;
14538
this.nextSibling = null;
14550
"beforeappend" : true,
14552
"beforeremove" : true,
14554
"beforemove" : true,
14556
"beforeinsert" : true
14558
this.listeners = this.attributes.listeners;
14559
Ext.data.Node.superclass.constructor.call(this);
14562
Ext.extend(Ext.data.Node, Ext.util.Observable, {
14564
fireEvent : function(evtName){
14565
// first do standard event for this node
14566
if(Ext.data.Node.superclass.fireEvent.apply(this, arguments) === false){
14569
// then bubble it up to the tree if the event wasn't cancelled
14570
var ot = this.getOwnerTree();
14572
if(ot.proxyNodeEvent.apply(ot, arguments) === false){
14580
isLeaf : function(){
14581
return this.leaf === true;
14585
setFirstChild : function(node){
14586
this.firstChild = node;
14590
setLastChild : function(node){
14591
this.lastChild = node;
14596
isLast : function(){
14597
return (!this.parentNode ? true : this.parentNode.lastChild == this);
14601
isFirst : function(){
14602
return (!this.parentNode ? true : this.parentNode.firstChild == this);
14606
hasChildNodes : function(){
14607
return !this.isLeaf() && this.childNodes.length > 0;
14611
isExpandable : function(){
14612
return this.attributes.expandable || this.hasChildNodes();
14616
appendChild : function(node){
14618
if(Ext.isArray(node)){
14620
}else if(arguments.length > 1){
14623
// if passed an array or multiple args do them one by one
14625
for(var i = 0, len = multi.length; i < len; i++) {
14626
this.appendChild(multi[i]);
14629
if(this.fireEvent("beforeappend", this.ownerTree, this, node) === false){
14632
var index = this.childNodes.length;
14633
var oldParent = node.parentNode;
14634
// it's a move, make sure we move it cleanly
14636
if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index) === false){
14639
oldParent.removeChild(node);
14641
index = this.childNodes.length;
14643
this.setFirstChild(node);
14645
this.childNodes.push(node);
14646
node.parentNode = this;
14647
var ps = this.childNodes[index-1];
14649
node.previousSibling = ps;
14650
ps.nextSibling = node;
14652
node.previousSibling = null;
14654
node.nextSibling = null;
14655
this.setLastChild(node);
14656
node.setOwnerTree(this.getOwnerTree());
14657
this.fireEvent("append", this.ownerTree, this, node, index);
14659
node.fireEvent("move", this.ownerTree, node, oldParent, this, index);
14666
removeChild : function(node){
14667
var index = this.childNodes.indexOf(node);
14671
if(this.fireEvent("beforeremove", this.ownerTree, this, node) === false){
14675
// remove it from childNodes collection
14676
this.childNodes.splice(index, 1);
14679
if(node.previousSibling){
14680
node.previousSibling.nextSibling = node.nextSibling;
14682
if(node.nextSibling){
14683
node.nextSibling.previousSibling = node.previousSibling;
14686
// update child refs
14687
if(this.firstChild == node){
14688
this.setFirstChild(node.nextSibling);
14690
if(this.lastChild == node){
14691
this.setLastChild(node.previousSibling);
14694
node.setOwnerTree(null);
14695
// clear any references from the node
14696
node.parentNode = null;
14697
node.previousSibling = null;
14698
node.nextSibling = null;
14699
this.fireEvent("remove", this.ownerTree, this, node);
14704
insertBefore : function(node, refNode){
14705
if(!refNode){ // like standard Dom, refNode can be null for append
14706
return this.appendChild(node);
14709
if(node == refNode){
14713
if(this.fireEvent("beforeinsert", this.ownerTree, this, node, refNode) === false){
14716
var index = this.childNodes.indexOf(refNode);
14717
var oldParent = node.parentNode;
14718
var refIndex = index;
14720
// when moving internally, indexes will change after remove
14721
if(oldParent == this && this.childNodes.indexOf(node) < index){
14725
// it's a move, make sure we move it cleanly
14727
if(node.fireEvent("beforemove", node.getOwnerTree(), node, oldParent, this, index, refNode) === false){
14730
oldParent.removeChild(node);
14733
this.setFirstChild(node);
14735
this.childNodes.splice(refIndex, 0, node);
14736
node.parentNode = this;
14737
var ps = this.childNodes[refIndex-1];
14739
node.previousSibling = ps;
14740
ps.nextSibling = node;
14742
node.previousSibling = null;
14744
node.nextSibling = refNode;
14745
refNode.previousSibling = node;
14746
node.setOwnerTree(this.getOwnerTree());
14747
this.fireEvent("insert", this.ownerTree, this, node, refNode);
14749
node.fireEvent("move", this.ownerTree, node, oldParent, this, refIndex, refNode);
14755
remove : function(){
14756
this.parentNode.removeChild(this);
14761
item : function(index){
14762
return this.childNodes[index];
14766
replaceChild : function(newChild, oldChild){
14767
var s = oldChild ? oldChild.nextSibling : null;
14768
this.removeChild(oldChild);
14769
this.insertBefore(newChild, s);
14774
indexOf : function(child){
14775
return this.childNodes.indexOf(child);
14779
getOwnerTree : function(){
14780
// if it doesn't have one, look for one
14781
if(!this.ownerTree){
14785
this.ownerTree = p.ownerTree;
14791
return this.ownerTree;
14795
getDepth : function(){
14798
while(p.parentNode){
14806
setOwnerTree : function(tree){
14807
// if it is a move, we need to update everyone
14808
if(tree != this.ownerTree){
14809
if(this.ownerTree){
14810
this.ownerTree.unregisterNode(this);
14812
this.ownerTree = tree;
14813
var cs = this.childNodes;
14814
for(var i = 0, len = cs.length; i < len; i++) {
14815
cs[i].setOwnerTree(tree);
14818
tree.registerNode(this);
14824
setId: function(id){
14825
if(id !== this.id){
14826
var t = this.ownerTree;
14828
t.unregisterNode(this);
14832
t.registerNode(this);
14834
this.onIdChange(id);
14839
onIdChange: Ext.emptyFn,
14842
getPath : function(attr){
14843
attr = attr || "id";
14844
var p = this.parentNode;
14845
var b = [this.attributes[attr]];
14847
b.unshift(p.attributes[attr]);
14850
var sep = this.getOwnerTree().pathSeparator;
14851
return sep + b.join(sep);
14855
bubble : function(fn, scope, args){
14858
if(fn.apply(scope || p, args || [p]) === false){
14866
cascade : function(fn, scope, args){
14867
if(fn.apply(scope || this, args || [this]) !== false){
14868
var cs = this.childNodes;
14869
for(var i = 0, len = cs.length; i < len; i++) {
14870
cs[i].cascade(fn, scope, args);
14876
eachChild : function(fn, scope, args){
14877
var cs = this.childNodes;
14878
for(var i = 0, len = cs.length; i < len; i++) {
14879
if(fn.apply(scope || this, args || [cs[i]]) === false){
14886
findChild : function(attribute, value){
14887
var cs = this.childNodes;
14888
for(var i = 0, len = cs.length; i < len; i++) {
14889
if(cs[i].attributes[attribute] == value){
14897
findChildBy : function(fn, scope){
14898
var cs = this.childNodes;
14899
for(var i = 0, len = cs.length; i < len; i++) {
14900
if(fn.call(scope||cs[i], cs[i]) === true){
14908
sort : function(fn, scope){
14909
var cs = this.childNodes;
14910
var len = cs.length;
14912
var sortFn = scope ? function(){fn.apply(scope, arguments);} : fn;
14914
for(var i = 0; i < len; i++){
14916
n.previousSibling = cs[i-1];
14917
n.nextSibling = cs[i+1];
14919
this.setFirstChild(n);
14922
this.setLastChild(n);
14929
contains : function(node){
14930
return node.isAncestor(this);
14934
isAncestor : function(node){
14935
var p = this.parentNode;
14945
toString : function(){
14946
return "[Node"+(this.id?" "+this.id:"")+"]";
14950
Ext.data.GroupingStore = Ext.extend(Ext.data.Store, {
14953
constructor: function(config){
14954
Ext.data.GroupingStore.superclass.constructor.call(this, config);
14955
this.applyGroupField();
14960
remoteGroup : false,
14967
clearGrouping : function(){
14968
this.groupField = false;
14969
if(this.remoteGroup){
14970
if(this.baseParams){
14971
delete this.baseParams.groupBy;
14973
var lo = this.lastOptions;
14974
if(lo && lo.params){
14975
delete lo.params.groupBy;
14980
this.fireEvent('datachanged', this);
14985
groupBy : function(field, forceRegroup, direction){
14986
direction = direction ? (String(direction).toUpperCase() == 'DESC' ? 'DESC' : 'ASC') : this.groupDir;
14987
if(this.groupField == field && this.groupDir == direction && !forceRegroup){
14988
return; // already grouped by this field
14990
this.groupField = field;
14991
this.groupDir = direction;
14992
this.applyGroupField();
14993
if(this.groupOnSort){
14994
this.sort(field, direction);
14997
if(this.remoteGroup){
15000
var si = this.sortInfo || {};
15001
if(si.field != field || si.direction != direction){
15004
this.sortData(field, direction);
15006
this.fireEvent('datachanged', this);
15011
applyGroupField: function(){
15012
if(this.remoteGroup){
15013
if(!this.baseParams){
15014
this.baseParams = {};
15016
this.baseParams.groupBy = this.groupField;
15017
this.baseParams.groupDir = this.groupDir;
15022
applySort : function(){
15023
Ext.data.GroupingStore.superclass.applySort.call(this);
15024
if(!this.groupOnSort && !this.remoteGroup){
15025
var gs = this.getGroupState();
15026
if(gs && (gs != this.sortInfo.field || this.groupDir != this.sortInfo.direction)){
15027
this.sortData(this.groupField, this.groupDir);
15033
applyGrouping : function(alwaysFireChange){
15034
if(this.groupField !== false){
15035
this.groupBy(this.groupField, true, this.groupDir);
15038
if(alwaysFireChange === true){
15039
this.fireEvent('datachanged', this);
15046
getGroupState : function(){
15047
return this.groupOnSort && this.groupField !== false ?
15048
(this.sortInfo ? this.sortInfo.field : undefined) : this.groupField;
15051
Ext.reg('groupingstore', Ext.data.GroupingStore);
15053
Ext.Component = function(config){
15054
config = config || {};
15055
if(config.initialConfig){
15056
if(config.isAction){ // actions
15057
this.baseAction = config;
15059
config = config.initialConfig; // component cloning / action set up
15060
}else if(config.tagName || config.dom || typeof config == "string"){ // element object
15061
config = {applyTo: config, id: config.id || config};
15065
this.initialConfig = config;
15067
Ext.apply(this, config);
15092
'beforestaterestore',
15101
Ext.ComponentMgr.register(this);
15102
Ext.Component.superclass.constructor.call(this);
15104
if(this.baseAction){
15105
this.baseAction.addComponent(this);
15108
this.initComponent();
15111
if(Ext.isArray(this.plugins)){
15112
for(var i = 0, len = this.plugins.length; i < len; i++){
15113
this.plugins[i] = this.initPlugin(this.plugins[i]);
15116
this.plugins = this.initPlugin(this.plugins);
15120
if(this.stateful !== false){
15121
this.initState(config);
15125
this.applyToMarkup(this.applyTo);
15126
delete this.applyTo;
15127
}else if(this.renderTo){
15128
this.render(this.renderTo);
15129
delete this.renderTo;
15134
Ext.Component.AUTO_ID = 1000;
15136
Ext.extend(Ext.Component, Ext.util.Observable, {
15137
// Configs below are used for all Components when rendered by FormLayout.
15145
// Configs below are used for all Components when rendered by AnchorLayout.
15169
disabledClass : "x-item-disabled",
15171
allowDomMove : true,
15175
hideMode: 'display',
15188
ctype : "Ext.Component",
15194
getActionEl : function(){
15195
return this[this.actionMode];
15198
initPlugin : function(p){
15199
if(p.ptype && typeof p.init != 'function'){
15200
p = Ext.ComponentMgr.createPlugin(p);
15201
}else if(typeof p == 'string'){
15202
p = Ext.ComponentMgr.createPlugin({
15211
initComponent : Ext.emptyFn,
15214
render : function(container, position){
15215
if(!this.rendered && this.fireEvent("beforerender", this) !== false){
15216
if(!container && this.el){
15217
this.el = Ext.get(this.el);
15218
container = this.el.dom.parentNode;
15219
this.allowDomMove = false;
15221
this.container = Ext.get(container);
15223
this.container.addClass(this.ctCls);
15225
this.rendered = true;
15226
if(position !== undefined){
15227
if(typeof position == 'number'){
15228
position = this.container.dom.childNodes[position];
15230
position = Ext.getDom(position);
15233
this.onRender(this.container, position || null);
15235
this.el.removeClass(['x-hidden','x-hide-' + this.hideMode]);
15238
this.el.addClass(this.cls);
15242
this.el.applyStyles(this.style);
15246
this.el.addClassOnOver(this.overCls);
15248
this.fireEvent("render", this);
15249
this.afterRender(this.container);
15257
if(this.stateful !== false){
15258
this.initStateEvents();
15261
this.fireEvent("afterrender", this);
15266
initRef : function(){
15269
var levels = this.ref.split('/');
15270
var last = levels.length, i = 0;
15278
t[levels[--i]] = this;
15283
initState : function(config){
15284
if(Ext.state.Manager){
15285
var id = this.getStateId();
15287
var state = Ext.state.Manager.get(id);
15289
if(this.fireEvent('beforestaterestore', this, state) !== false){
15290
this.applyState(state);
15291
this.fireEvent('staterestore', this, state);
15299
getStateId : function(){
15300
return this.stateId || ((this.id.indexOf('ext-comp-') == 0 || this.id.indexOf('ext-gen') == 0) ? null : this.id);
15304
initStateEvents : function(){
15305
if(this.stateEvents){
15306
for(var i = 0, e; e = this.stateEvents[i]; i++){
15307
this.on(e, this.saveState, this, {delay:100});
15313
applyState : function(state, config){
15315
Ext.apply(this, state);
15320
getState : function(){
15325
saveState : function(){
15326
if(Ext.state.Manager && this.stateful !== false){
15327
var id = this.getStateId();
15329
var state = this.getState();
15330
if(this.fireEvent('beforestatesave', this, state) !== false){
15331
Ext.state.Manager.set(id, state);
15332
this.fireEvent('statesave', this, state);
15339
applyToMarkup : function(el){
15340
this.allowDomMove = false;
15341
this.el = Ext.get(el);
15342
this.render(this.el.dom.parentNode);
15346
addClass : function(cls){
15348
this.el.addClass(cls);
15350
this.cls = this.cls ? this.cls + ' ' + cls : cls;
15356
removeClass : function(cls){
15358
this.el.removeClass(cls);
15359
}else if(this.cls){
15360
this.cls = this.cls.split(' ').remove(cls).join(' ');
15366
// default function is not really useful
15367
onRender : function(ct, position){
15368
if(!this.el && this.autoEl){
15369
if(typeof this.autoEl == 'string'){
15370
this.el = document.createElement(this.autoEl);
15372
var div = document.createElement('div');
15373
Ext.DomHelper.overwrite(div, this.autoEl);
15374
this.el = div.firstChild;
15377
this.el.id = this.getId();
15381
this.el = Ext.get(this.el);
15382
if(this.allowDomMove !== false){
15383
ct.dom.insertBefore(this.el.dom, position);
15389
getAutoCreate : function(){
15390
var cfg = Ext.isObject(this.autoCreate) ?
15391
this.autoCreate : Ext.apply({}, this.defaultAutoCreate);
15392
if(this.id && !cfg.id){
15399
afterRender : Ext.emptyFn,
15402
destroy : function(){
15403
if(this.fireEvent("beforedestroy", this) !== false){
15404
this.beforeDestroy();
15406
this.el.removeAllListeners();
15408
if(this.actionMode == "container" || this.removeMode == "container"){
15409
this.container.remove();
15413
Ext.ComponentMgr.unregister(this);
15414
this.fireEvent("destroy", this);
15415
this.purgeListeners();
15420
beforeDestroy : Ext.emptyFn,
15423
onDestroy : Ext.emptyFn,
15426
getEl : function(){
15431
getId : function(){
15432
return this.id || (this.id = "ext-comp-" + (++Ext.Component.AUTO_ID));
15436
getItemId : function(){
15437
return this.itemId || this.getId();
15441
focus : function(selectText, delay){
15443
this.focus.defer(typeof delay == 'number' ? delay : 10, this, [selectText, false]);
15448
if(selectText === true){
15449
this.el.dom.select();
15464
disable : function(){
15468
this.disabled = true;
15469
this.fireEvent("disable", this);
15474
onDisable : function(){
15475
this.getActionEl().addClass(this.disabledClass);
15476
this.el.dom.disabled = true;
15480
enable : function(){
15484
this.disabled = false;
15485
this.fireEvent("enable", this);
15490
onEnable : function(){
15491
this.getActionEl().removeClass(this.disabledClass);
15492
this.el.dom.disabled = false;
15496
setDisabled : function(disabled){
15497
return this[disabled ? "disable" : "enable"]();
15502
if(this.fireEvent("beforeshow", this) !== false){
15503
this.hidden = false;
15504
if(this.autoRender){
15505
this.render(typeof this.autoRender == 'boolean' ? Ext.getBody() : this.autoRender);
15510
this.fireEvent("show", this);
15516
onShow : function(){
15517
this.getVisibiltyEl().removeClass('x-hide-' + this.hideMode);
15522
if(this.fireEvent("beforehide", this) !== false){
15523
this.hidden = true;
15527
this.fireEvent("hide", this);
15533
onHide : function(){
15534
this.getVisibiltyEl().addClass('x-hide-' + this.hideMode);
15538
getVisibiltyEl: function(){
15539
return this.hideParent ? this.container : this.getActionEl();
15543
setVisible: function(visible){
15544
return this[visible ? "show" : "hide"]();
15548
isVisible : function(){
15549
return this.rendered && this.getVisibiltyEl().isVisible();
15553
cloneConfig : function(overrides){
15554
overrides = overrides || {};
15555
var id = overrides.id || Ext.id();
15556
var cfg = Ext.applyIf(overrides, this.initialConfig);
15557
cfg.id = id; // prevent dup id
15558
return new this.constructor(cfg);
15562
getXType : function(){
15563
return this.constructor.xtype;
15567
isXType : function(xtype, shallow){
15568
//assume a string by default
15569
if (typeof xtype == 'function'){
15570
xtype = xtype.xtype; //handle being passed the class, eg. Ext.Component
15571
}else if (typeof xtype == 'object'){
15572
xtype = xtype.constructor.xtype; //handle being passed an instance
15575
return !shallow ? ('/' + this.getXTypes() + '/').indexOf('/' + xtype + '/') != -1 : this.constructor.xtype == xtype;
15579
getXTypes : function(){
15580
var tc = this.constructor;
15582
var c = [], sc = this;
15583
while(sc && sc.constructor.xtype){
15584
c.unshift(sc.constructor.xtype);
15585
sc = sc.constructor.superclass;
15588
tc.xtypes = c.join('/');
15594
findParentBy: function(fn) {
15595
for (var p = this.ownerCt; (p != null) && !fn(p, this); p = p.ownerCt);
15600
findParentByType: function(xtype) {
15601
return typeof xtype == 'function' ?
15602
this.findParentBy(function(p){
15603
return p.constructor === xtype;
15605
this.findParentBy(function(p){
15606
return p.constructor.xtype === xtype;
15610
getDomPositionEl : function(){
15611
return this.getPositionEl ? this.getPositionEl() : this.getEl();
15615
purgeListeners: function(){
15616
Ext.Component.superclass.purgeListeners.call(this);
15618
this.on('beforedestroy', this.clearMons, this, {single: true});
15623
clearMons: function(){
15624
Ext.each(this.mons, function(m){
15625
m.item.un(m.ename, m.fn, m.scope);
15630
// internal function for auto removal of assigned event handlers on destruction
15631
mon : function(item, ename, fn, scope, opt){
15634
this.on('beforedestroy', this.clearMons, this, {single: true});
15637
if(Ext.isObject(ename)){
15638
var propRe = /^(?:scope|delay|buffer|single|stopEvent|preventDefault|stopPropagation|normalized|args|delegate)$/;
15642
if(propRe.test(e)){
15645
if(Ext.isFunction(o[e])){
15648
item: item, ename: e, fn: o[e], scope: o.scope
15650
item.on(e, o[e], o.scope, o);
15652
// individual options
15654
item: item, ename: e, fn: o[e], scope: o.scope
15664
item: item, ename: ename, fn: fn, scope: scope
15666
item.on(ename, fn, scope, opt);
15669
// protected, opposite of mon
15670
mun: function(item, ename, fn, scope){
15672
for(var i = 0, len = this.mons.length; i < len; ++i){
15673
mon = this.mons[i];
15674
if(item === mon.item && ename == mon.ename && fn === mon.fn && scope === mon.scope){
15675
this.mons.splice(i, 1);
15676
item.un(ename, fn, scope);
15685
nextSibling : function(){
15687
var index = this.ownerCt.items.indexOf(this);
15688
if(index != -1 && index+1 < this.ownerCt.items.getCount()){
15689
return this.ownerCt.items.itemAt(index+1);
15696
previousSibling : function(){
15698
var index = this.ownerCt.items.indexOf(this);
15700
return this.ownerCt.items.itemAt(index-1);
15707
getBubbleTarget : function(){
15708
return this.ownerCt;
15712
Ext.reg('component', Ext.Component);
15715
Ext.Action = function(config){
15716
this.initialConfig = config;
15717
this.itemId = config.itemId = (config.itemId || config.id || Ext.id());
15721
Ext.Action.prototype = {
15734
setText : function(text){
15735
this.initialConfig.text = text;
15736
this.callEach('setText', [text]);
15740
getText : function(){
15741
return this.initialConfig.text;
15745
setIconClass : function(cls){
15746
this.initialConfig.iconCls = cls;
15747
this.callEach('setIconClass', [cls]);
15751
getIconClass : function(){
15752
return this.initialConfig.iconCls;
15756
setDisabled : function(v){
15757
this.initialConfig.disabled = v;
15758
this.callEach('setDisabled', [v]);
15762
enable : function(){
15763
this.setDisabled(false);
15767
disable : function(){
15768
this.setDisabled(true);
15772
isDisabled : function(){
15773
return this.initialConfig.disabled;
15777
setHidden : function(v){
15778
this.initialConfig.hidden = v;
15779
this.callEach('setVisible', [!v]);
15784
this.setHidden(false);
15789
this.setHidden(true);
15793
isHidden : function(){
15794
return this.initialConfig.hidden;
15798
setHandler : function(fn, scope){
15799
this.initialConfig.handler = fn;
15800
this.initialConfig.scope = scope;
15801
this.callEach('setHandler', [fn, scope]);
15805
each : function(fn, scope){
15806
Ext.each(this.items, fn, scope);
15810
callEach : function(fnName, args){
15811
var cs = this.items;
15812
for(var i = 0, len = cs.length; i < len; i++){
15813
cs[i][fnName].apply(cs[i], args);
15818
addComponent : function(comp){
15819
this.items.push(comp);
15820
comp.on('destroy', this.removeComponent, this);
15824
removeComponent : function(comp){
15825
this.items.remove(comp);
15829
execute : function(){
15830
this.initialConfig.handler.apply(this.initialConfig.scope || window, arguments);
15835
Ext.Layer = function(config, existingEl){
15836
config = config || {};
15837
var dh = Ext.DomHelper;
15838
var cp = config.parentEl, pel = cp ? Ext.getDom(cp) : document.body;
15840
this.dom = Ext.getDom(existingEl);
15843
var o = config.dh || {tag: "div", cls: "x-layer"};
15844
this.dom = dh.append(pel, o);
15847
this.addClass(config.cls);
15849
this.constrain = config.constrain !== false;
15850
this.visibilityMode = Ext.Element.VISIBILITY;
15852
this.id = this.dom.id = config.id;
15854
this.id = Ext.id(this.dom);
15856
this.zindex = config.zindex || this.getZIndex();
15857
this.position("absolute", this.zindex);
15859
this.shadowOffset = config.shadowOffset || 4;
15860
this.shadow = new Ext.Shadow({
15861
offset : this.shadowOffset,
15862
mode : config.shadow
15865
this.shadowOffset = 0;
15867
this.useShim = config.shim !== false && Ext.useShims;
15868
this.useDisplay = config.useDisplay;
15872
var supr = Ext.Element.prototype;
15874
// shims are shared among layer to keep from having 100 iframes
15877
Ext.extend(Ext.Layer, Ext.Element, {
15879
getZIndex : function(){
15880
return this.zindex || parseInt((this.getShim() || this).getStyle("z-index"), 10) || 11000;
15883
getShim : function(){
15890
var shim = shims.shift();
15892
shim = this.createShim();
15893
shim.enableDisplayMode('block');
15894
shim.dom.style.display = 'none';
15895
shim.dom.style.visibility = 'visible';
15897
var pn = this.dom.parentNode;
15898
if(shim.dom.parentNode != pn){
15899
pn.insertBefore(shim.dom, this.dom);
15901
shim.setStyle('z-index', this.getZIndex()-2);
15906
hideShim : function(){
15908
this.shim.setDisplayed(false);
15909
shims.push(this.shim);
15914
disableShadow : function(){
15916
this.shadowDisabled = true;
15917
this.shadow.hide();
15918
this.lastShadowOffset = this.shadowOffset;
15919
this.shadowOffset = 0;
15923
enableShadow : function(show){
15925
this.shadowDisabled = false;
15926
this.shadowOffset = this.lastShadowOffset;
15927
delete this.lastShadowOffset;
15935
// this code can execute repeatedly in milliseconds (i.e. during a drag) so
15936
// code size was sacrificed for effeciency (e.g. no getBox/setBox, no XY calls)
15937
sync : function(doShow){
15938
var sw = this.shadow;
15939
if(!this.updating && this.isVisible() && (sw || this.useShim)){
15940
var sh = this.getShim();
15942
var w = this.getWidth(),
15943
h = this.getHeight();
15945
var l = this.getLeft(true),
15946
t = this.getTop(true);
15948
if(sw && !this.shadowDisabled){
15949
if(doShow && !sw.isVisible()){
15952
sw.realign(l, t, w, h);
15958
// fit the shim behind the shadow, so it is shimmed too
15959
var a = sw.adjusts, s = sh.dom.style;
15960
s.left = (Math.min(l, l+a.l))+"px";
15961
s.top = (Math.min(t, t+a.t))+"px";
15962
s.width = (w+a.w)+"px";
15963
s.height = (h+a.h)+"px";
15970
sh.setLeftTop(l, t);
15977
destroy : function(){
15980
this.shadow.hide();
15982
this.removeAllListeners();
15983
Ext.removeNode(this.dom);
15984
Ext.Element.uncache(this.id);
15987
remove : function(){
15992
beginUpdate : function(){
15993
this.updating = true;
15997
endUpdate : function(){
15998
this.updating = false;
16003
hideUnders : function(negOffset){
16005
this.shadow.hide();
16011
constrainXY : function(){
16012
if(this.constrain){
16013
var vw = Ext.lib.Dom.getViewWidth(),
16014
vh = Ext.lib.Dom.getViewHeight();
16015
var s = Ext.getDoc().getScroll();
16017
var xy = this.getXY();
16018
var x = xy[0], y = xy[1];
16019
var so = this.shadowOffset;
16020
var w = this.dom.offsetWidth+so, h = this.dom.offsetHeight+so;
16021
// only move it if it needs it
16023
// first validate right/bottom
16024
if((x + w) > vw+s.left){
16028
if((y + h) > vh+s.top){
16032
// then make sure top/left isn't negative
16043
var ay = this.avoidY;
16044
if(y <= ay && (y+h) >= ay){
16050
supr.setXY.call(this, xy);
16057
isVisible : function(){
16058
return this.visible;
16062
showAction : function(){
16063
this.visible = true; // track visibility to prevent getStyle calls
16064
if(this.useDisplay === true){
16065
this.setDisplayed("");
16066
}else if(this.lastXY){
16067
supr.setXY.call(this, this.lastXY);
16068
}else if(this.lastLT){
16069
supr.setLeftTop.call(this, this.lastLT[0], this.lastLT[1]);
16074
hideAction : function(){
16075
this.visible = false;
16076
if(this.useDisplay === true){
16077
this.setDisplayed(false);
16079
this.setLeftTop(-10000,-10000);
16083
// overridden Element method
16084
setVisible : function(v, a, d, c, e){
16089
var cb = function(){
16094
}.createDelegate(this);
16095
supr.setVisible.call(this, true, true, d, cb, e);
16098
this.hideUnders(true);
16107
}.createDelegate(this);
16109
supr.setVisible.call(this, v, a, d, cb, e);
16119
storeXY : function(xy){
16120
delete this.lastLT;
16124
storeLeftTop : function(left, top){
16125
delete this.lastXY;
16126
this.lastLT = [left, top];
16130
beforeFx : function(){
16131
this.beforeAction();
16132
return Ext.Layer.superclass.beforeFx.apply(this, arguments);
16136
afterFx : function(){
16137
Ext.Layer.superclass.afterFx.apply(this, arguments);
16138
this.sync(this.isVisible());
16142
beforeAction : function(){
16143
if(!this.updating && this.shadow){
16144
this.shadow.hide();
16148
// overridden Element method
16149
setLeft : function(left){
16150
this.storeLeftTop(left, this.getTop(true));
16151
supr.setLeft.apply(this, arguments);
16156
setTop : function(top){
16157
this.storeLeftTop(this.getLeft(true), top);
16158
supr.setTop.apply(this, arguments);
16163
setLeftTop : function(left, top){
16164
this.storeLeftTop(left, top);
16165
supr.setLeftTop.apply(this, arguments);
16170
setXY : function(xy, a, d, c, e){
16172
this.beforeAction();
16174
var cb = this.createCB(c);
16175
supr.setXY.call(this, xy, a, d, cb, e);
16183
createCB : function(c){
16194
// overridden Element method
16195
setX : function(x, a, d, c, e){
16196
this.setXY([x, this.getY()], a, d, c, e);
16200
// overridden Element method
16201
setY : function(y, a, d, c, e){
16202
this.setXY([this.getX(), y], a, d, c, e);
16206
// overridden Element method
16207
setSize : function(w, h, a, d, c, e){
16208
this.beforeAction();
16209
var cb = this.createCB(c);
16210
supr.setSize.call(this, w, h, a, d, cb, e);
16217
// overridden Element method
16218
setWidth : function(w, a, d, c, e){
16219
this.beforeAction();
16220
var cb = this.createCB(c);
16221
supr.setWidth.call(this, w, a, d, cb, e);
16228
// overridden Element method
16229
setHeight : function(h, a, d, c, e){
16230
this.beforeAction();
16231
var cb = this.createCB(c);
16232
supr.setHeight.call(this, h, a, d, cb, e);
16239
// overridden Element method
16240
setBounds : function(x, y, w, h, a, d, c, e){
16241
this.beforeAction();
16242
var cb = this.createCB(c);
16244
this.storeXY([x, y]);
16245
supr.setXY.call(this, [x, y]);
16246
supr.setSize.call(this, w, h, a, d, cb, e);
16249
supr.setBounds.call(this, x, y, w, h, a, d, cb, e);
16255
setZIndex : function(zindex){
16256
this.zindex = zindex;
16257
this.setStyle("z-index", zindex + 2);
16259
this.shadow.setZIndex(zindex + 1);
16262
this.shim.setStyle("z-index", zindex);
16269
Ext.Shadow = function(config){
16270
Ext.apply(this, config);
16271
if(typeof this.mode != "string"){
16272
this.mode = this.defaultMode;
16274
var o = this.offset, a = {h: 0};
16275
var rad = Math.floor(this.offset/2);
16276
switch(this.mode.toLowerCase()){ // all this hideous nonsense calculates the various offsets for shadows
16282
a.l -= this.offset + rad;
16283
a.t -= this.offset + rad;
16294
a.l -= (this.offset - rad);
16295
a.t -= this.offset + rad;
16297
a.w -= (this.offset - rad)*2;
16308
a.l -= (this.offset - rad);
16309
a.t -= (this.offset - rad);
16311
a.w -= (this.offset + rad + 1);
16312
a.h -= (this.offset + rad);
16321
Ext.Shadow.prototype = {
16327
defaultMode: "drop",
16330
show : function(target){
16331
target = Ext.get(target);
16333
this.el = Ext.Shadow.Pool.pull();
16334
if(this.el.dom.nextSibling != target.dom){
16335
this.el.insertBefore(target);
16338
this.el.setStyle("z-index", this.zIndex || parseInt(target.getStyle("z-index"), 10)-1);
16340
this.el.dom.style.filter="progid:DXImageTransform.Microsoft.alpha(opacity=50) progid:DXImageTransform.Microsoft.Blur(pixelradius="+(this.offset)+")";
16343
target.getLeft(true),
16344
target.getTop(true),
16348
this.el.dom.style.display = "block";
16352
isVisible : function(){
16353
return this.el ? true : false;
16357
realign : function(l, t, w, h){
16361
var a = this.adjusts, d = this.el.dom, s = d.style;
16363
s.left = (l+a.l)+"px";
16364
s.top = (t+a.t)+"px";
16365
var sw = (w+a.w), sh = (h+a.h), sws = sw +"px", shs = sh + "px";
16366
if(s.width != sws || s.height != shs){
16370
var cn = d.childNodes;
16371
var sww = Math.max(0, (sw-12))+"px";
16372
cn[0].childNodes[1].style.width = sww;
16373
cn[1].childNodes[1].style.width = sww;
16374
cn[2].childNodes[1].style.width = sww;
16375
cn[1].style.height = Math.max(0, (sh-12))+"px";
16383
this.el.dom.style.display = "none";
16384
Ext.Shadow.Pool.push(this.el);
16390
setZIndex : function(z){
16393
this.el.setStyle("z-index", z);
16398
// Private utility class that manages the internal Shadow cache
16399
Ext.Shadow.Pool = function(){
16401
var markup = Ext.isIE ?
16402
'<div class="x-ie-shadow"></div>' :
16403
'<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>';
16406
var sh = p.shift();
16408
sh = Ext.get(Ext.DomHelper.insertHtml("beforeBegin", document.body.firstChild, markup));
16409
sh.autoBoxAdjust = false;
16414
push : function(sh){
16420
Ext.BoxComponent = Ext.extend(Ext.Component, {
16422
// Configs below are used for all Components when rendered by BorderLayout.
16437
initComponent : function(){
16438
Ext.BoxComponent.superclass.initComponent.call(this);
16447
// private, set in afterRender to signify that the component has been rendered
16449
// private, used to defer height settings to subclasses
16450
deferHeight: false,
16453
setSize : function(w, h){
16454
// support for standard size objects
16455
if(typeof w == 'object'){
16460
if(!this.boxReady){
16466
// prevent recalcs when not needed
16467
if(this.cacheSizes !== false && this.lastSize && this.lastSize.width == w && this.lastSize.height == h){
16470
this.lastSize = {width: w, height: h};
16471
var adj = this.adjustSize(w, h);
16472
var aw = adj.width, ah = adj.height;
16473
if(aw !== undefined || ah !== undefined){ // this code is nasty but performs better with floaters
16474
var rz = this.getResizeEl();
16475
if(!this.deferHeight && aw !== undefined && ah !== undefined){
16476
rz.setSize(aw, ah);
16477
}else if(!this.deferHeight && ah !== undefined){
16479
}else if(aw !== undefined){
16482
this.onResize(aw, ah, w, h);
16483
this.fireEvent('resize', this, aw, ah, w, h);
16489
setWidth : function(width){
16490
return this.setSize(width);
16494
setHeight : function(height){
16495
return this.setSize(undefined, height);
16499
getSize : function(){
16500
return this.getResizeEl().getSize();
16504
getWidth : function(){
16505
return this.getResizeEl().getWidth();
16509
getHeight : function(){
16510
return this.getResizeEl().getHeight();
16514
getOuterSize : function(){
16515
var el = this.getResizeEl();
16516
return {width: el.getWidth() + el.getMargins('lr'),
16517
height: el.getHeight() + el.getMargins('tb')};
16521
getPosition : function(local){
16522
var el = this.getPositionEl();
16523
if(local === true){
16524
return [el.getLeft(true), el.getTop(true)];
16526
return this.xy || el.getXY();
16530
getBox : function(local){
16531
var pos = this.getPosition(local);
16532
var s = this.getSize();
16539
updateBox : function(box){
16540
this.setSize(box.width, box.height);
16541
this.setPagePosition(box.x, box.y);
16546
getResizeEl : function(){
16547
return this.resizeEl || this.el;
16551
getPositionEl : function(){
16552
return this.positionEl || this.el;
16556
setPosition : function(x, y){
16557
if(x && typeof x[1] == 'number'){
16563
if(!this.boxReady){
16566
var adj = this.adjustPosition(x, y);
16567
var ax = adj.x, ay = adj.y;
16569
var el = this.getPositionEl();
16570
if(ax !== undefined || ay !== undefined){
16571
if(ax !== undefined && ay !== undefined){
16572
el.setLeftTop(ax, ay);
16573
}else if(ax !== undefined){
16575
}else if(ay !== undefined){
16578
this.onPosition(ax, ay);
16579
this.fireEvent('move', this, ax, ay);
16585
setPagePosition : function(x, y){
16586
if(x && typeof x[1] == 'number'){
16592
if(!this.boxReady){
16595
if(x === undefined || y === undefined){ // cannot translate undefined points
16598
var p = this.getPositionEl().translatePoints(x, y);
16599
this.setPosition(p.left, p.top);
16604
onRender : function(ct, position){
16605
Ext.BoxComponent.superclass.onRender.call(this, ct, position);
16607
this.resizeEl = Ext.get(this.resizeEl);
16609
if(this.positionEl){
16610
this.positionEl = Ext.get(this.positionEl);
16615
afterRender : function(){
16616
Ext.BoxComponent.superclass.afterRender.call(this);
16617
this.boxReady = true;
16618
this.setSize(this.width, this.height);
16619
if(this.x || this.y){
16620
this.setPosition(this.x, this.y);
16621
}else if(this.pageX || this.pageY){
16622
this.setPagePosition(this.pageX, this.pageY);
16627
syncSize : function(){
16628
delete this.lastSize;
16629
this.setSize(this.autoWidth ? undefined : this.getResizeEl().getWidth(), this.autoHeight ? undefined : this.getResizeEl().getHeight());
16634
onResize : function(adjWidth, adjHeight, rawWidth, rawHeight){
16639
onPosition : function(x, y){
16644
adjustSize : function(w, h){
16645
if(this.autoWidth){
16648
if(this.autoHeight){
16651
return {width : w, height: h};
16655
adjustPosition : function(x, y){
16656
return {x : x, y: y};
16659
Ext.reg('box', Ext.BoxComponent);
16663
Ext.Spacer = Ext.extend(Ext.BoxComponent, {
16666
Ext.reg('spacer', Ext.Spacer);
16668
Ext.SplitBar = function(dragElement, resizingElement, orientation, placement, existingProxy){
16671
this.el = Ext.get(dragElement, true);
16672
this.el.dom.unselectable = "on";
16674
this.resizingEl = Ext.get(resizingElement, true);
16677
this.orientation = orientation || Ext.SplitBar.HORIZONTAL;
16684
this.maxSize = 2000;
16687
this.animate = false;
16690
this.useShim = false;
16695
if(!existingProxy){
16697
this.proxy = Ext.SplitBar.createProxy(this.orientation);
16699
this.proxy = Ext.get(existingProxy).dom;
16702
this.dd = new Ext.dd.DDProxy(this.el.dom.id, "XSplitBars", {dragElId : this.proxy.id});
16705
this.dd.b4StartDrag = this.onStartProxyDrag.createDelegate(this);
16708
this.dd.endDrag = this.onEndProxyDrag.createDelegate(this);
16711
this.dragSpecs = {};
16714
this.adapter = new Ext.SplitBar.BasicLayoutAdapter();
16715
this.adapter.init(this);
16717
if(this.orientation == Ext.SplitBar.HORIZONTAL){
16719
this.placement = placement || (this.el.getX() > this.resizingEl.getX() ? Ext.SplitBar.LEFT : Ext.SplitBar.RIGHT);
16720
this.el.addClass("x-splitbar-h");
16723
this.placement = placement || (this.el.getY() > this.resizingEl.getY() ? Ext.SplitBar.TOP : Ext.SplitBar.BOTTOM);
16724
this.el.addClass("x-splitbar-v");
16738
Ext.SplitBar.superclass.constructor.call(this);
16741
Ext.extend(Ext.SplitBar, Ext.util.Observable, {
16742
onStartProxyDrag : function(x, y){
16743
this.fireEvent("beforeresize", this);
16744
this.overlay = Ext.DomHelper.append(document.body, {cls: "x-drag-overlay", html: " "}, true);
16745
this.overlay.unselectable();
16746
this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
16747
this.overlay.show();
16748
Ext.get(this.proxy).setDisplayed("block");
16749
var size = this.adapter.getElementSize(this);
16750
this.activeMinSize = this.getMinimumSize();
16751
this.activeMaxSize = this.getMaximumSize();
16752
var c1 = size - this.activeMinSize;
16753
var c2 = Math.max(this.activeMaxSize - size, 0);
16754
if(this.orientation == Ext.SplitBar.HORIZONTAL){
16755
this.dd.resetConstraints();
16756
this.dd.setXConstraint(
16757
this.placement == Ext.SplitBar.LEFT ? c1 : c2,
16758
this.placement == Ext.SplitBar.LEFT ? c2 : c1,
16761
this.dd.setYConstraint(0, 0);
16763
this.dd.resetConstraints();
16764
this.dd.setXConstraint(0, 0);
16765
this.dd.setYConstraint(
16766
this.placement == Ext.SplitBar.TOP ? c1 : c2,
16767
this.placement == Ext.SplitBar.TOP ? c2 : c1,
16771
this.dragSpecs.startSize = size;
16772
this.dragSpecs.startPoint = [x, y];
16773
Ext.dd.DDProxy.prototype.b4StartDrag.call(this.dd, x, y);
16777
onEndProxyDrag : function(e){
16778
Ext.get(this.proxy).setDisplayed(false);
16779
var endPoint = Ext.lib.Event.getXY(e);
16781
Ext.destroy(this.overlay);
16782
delete this.overlay;
16785
if(this.orientation == Ext.SplitBar.HORIZONTAL){
16786
newSize = this.dragSpecs.startSize +
16787
(this.placement == Ext.SplitBar.LEFT ?
16788
endPoint[0] - this.dragSpecs.startPoint[0] :
16789
this.dragSpecs.startPoint[0] - endPoint[0]
16792
newSize = this.dragSpecs.startSize +
16793
(this.placement == Ext.SplitBar.TOP ?
16794
endPoint[1] - this.dragSpecs.startPoint[1] :
16795
this.dragSpecs.startPoint[1] - endPoint[1]
16798
newSize = Math.min(Math.max(newSize, this.activeMinSize), this.activeMaxSize);
16799
if(newSize != this.dragSpecs.startSize){
16800
if(this.fireEvent('beforeapply', this, newSize) !== false){
16801
this.adapter.setElementSize(this, newSize);
16802
this.fireEvent("moved", this, newSize);
16803
this.fireEvent("resize", this, newSize);
16809
getAdapter : function(){
16810
return this.adapter;
16814
setAdapter : function(adapter){
16815
this.adapter = adapter;
16816
this.adapter.init(this);
16820
getMinimumSize : function(){
16821
return this.minSize;
16825
setMinimumSize : function(minSize){
16826
this.minSize = minSize;
16830
getMaximumSize : function(){
16831
return this.maxSize;
16835
setMaximumSize : function(maxSize){
16836
this.maxSize = maxSize;
16840
setCurrentSize : function(size){
16841
var oldAnimate = this.animate;
16842
this.animate = false;
16843
this.adapter.setElementSize(this, size);
16844
this.animate = oldAnimate;
16848
destroy : function(removeEl){
16849
Ext.destroy(this.shim, Ext.get(this.proxy));
16854
this.purgeListeners();
16859
Ext.SplitBar.createProxy = function(dir){
16860
var proxy = new Ext.Element(document.createElement("div"));
16861
proxy.unselectable();
16862
var cls = 'x-splitbar-proxy';
16863
proxy.addClass(cls + ' ' + (dir == Ext.SplitBar.HORIZONTAL ? cls +'-h' : cls + '-v'));
16864
document.body.appendChild(proxy.dom);
16869
Ext.SplitBar.BasicLayoutAdapter = function(){
16872
Ext.SplitBar.BasicLayoutAdapter.prototype = {
16873
// do nothing for now
16874
init : function(s){
16878
getElementSize : function(s){
16879
if(s.orientation == Ext.SplitBar.HORIZONTAL){
16880
return s.resizingEl.getWidth();
16882
return s.resizingEl.getHeight();
16887
setElementSize : function(s, newSize, onComplete){
16888
if(s.orientation == Ext.SplitBar.HORIZONTAL){
16890
s.resizingEl.setWidth(newSize);
16892
onComplete(s, newSize);
16895
s.resizingEl.setWidth(newSize, true, .1, onComplete, 'easeOut');
16900
s.resizingEl.setHeight(newSize);
16902
onComplete(s, newSize);
16905
s.resizingEl.setHeight(newSize, true, .1, onComplete, 'easeOut');
16912
Ext.SplitBar.AbsoluteLayoutAdapter = function(container){
16913
this.basic = new Ext.SplitBar.BasicLayoutAdapter();
16914
this.container = Ext.get(container);
16917
Ext.SplitBar.AbsoluteLayoutAdapter.prototype = {
16918
init : function(s){
16919
this.basic.init(s);
16922
getElementSize : function(s){
16923
return this.basic.getElementSize(s);
16926
setElementSize : function(s, newSize, onComplete){
16927
this.basic.setElementSize(s, newSize, this.moveSplitter.createDelegate(this, [s]));
16930
moveSplitter : function(s){
16931
var yes = Ext.SplitBar;
16932
switch(s.placement){
16934
s.el.setX(s.resizingEl.getRight());
16937
s.el.setStyle("right", (this.container.getWidth() - s.resizingEl.getLeft()) + "px");
16940
s.el.setY(s.resizingEl.getBottom());
16943
s.el.setY(s.resizingEl.getTop() - s.el.getHeight());
16950
Ext.SplitBar.VERTICAL = 1;
16953
Ext.SplitBar.HORIZONTAL = 2;
16956
Ext.SplitBar.LEFT = 1;
16959
Ext.SplitBar.RIGHT = 2;
16962
Ext.SplitBar.TOP = 3;
16965
Ext.SplitBar.BOTTOM = 4;
16968
Ext.Container = Ext.extend(Ext.BoxComponent, {
16981
defaultType: 'panel',
16984
initComponent : function(){
16985
Ext.Container.superclass.initComponent.call(this);
17000
this.enableBubble('add', 'remove');
17003
var items = this.items;
17006
if(Ext.isArray(items) && items.length > 0){
17007
this.add.apply(this, items);
17015
initItems : function(){
17017
this.items = new Ext.util.MixedCollection(false, this.getComponentId);
17018
this.getLayout(); // initialize the layout
17023
setLayout : function(layout){
17024
if(this.layout && this.layout != layout){
17025
this.layout.setContainer(null);
17028
this.layout = layout;
17029
layout.setContainer(this);
17033
render : function(){
17034
Ext.Container.superclass.render.apply(this, arguments);
17036
if(typeof this.layout == 'object' && !this.layout.layout){
17037
this.layoutConfig = this.layout;
17038
this.layout = this.layoutConfig.type;
17040
if(typeof this.layout == 'string'){
17041
this.layout = new Ext.Container.LAYOUTS[this.layout.toLowerCase()](this.layoutConfig);
17043
this.setLayout(this.layout);
17045
if(this.activeItem !== undefined){
17046
var item = this.activeItem;
17047
delete this.activeItem;
17048
this.layout.setActiveItem(item);
17052
// force a layout if no ownerCt is set
17053
this.doLayout(false, true);
17055
if(this.monitorResize === true){
17056
Ext.EventManager.onWindowResize(this.doLayout, this, [false]);
17061
getLayoutTarget : function(){
17065
// private - used as the key lookup function for the items collection
17066
getComponentId : function(comp){
17067
return comp.getItemId();
17071
add : function(comp){
17073
var a = arguments, len = a.length;
17075
for(var i = 0; i < len; i++){
17080
var c = this.lookupComponent(this.applyDefaults(comp));
17081
var pos = this.items.length;
17082
if(this.fireEvent('beforeadd', this, c, pos) !== false && this.onBeforeAdd(c) !== false){
17085
this.fireEvent('add', this, c, pos);
17091
insert : function(index, comp){
17093
var a = arguments, len = a.length;
17095
for(var i = len-1; i >= 1; --i) {
17096
this.insert(index, a[i]);
17100
var c = this.lookupComponent(this.applyDefaults(comp));
17102
if(c.ownerCt == this && this.items.indexOf(c) < index){
17106
if(this.fireEvent('beforeadd', this, c, index) !== false && this.onBeforeAdd(c) !== false){
17107
this.items.insert(index, c);
17109
this.fireEvent('add', this, c, index);
17115
applyDefaults : function(c){
17117
if(typeof c == 'string'){
17118
c = Ext.ComponentMgr.get(c);
17119
Ext.apply(c, this.defaults);
17120
}else if(!c.events){
17121
Ext.applyIf(c, this.defaults);
17123
Ext.apply(c, this.defaults);
17130
onBeforeAdd : function(item){
17132
item.ownerCt.remove(item, false);
17134
if(this.hideBorders === true){
17135
item.border = (item.border === true);
17140
remove : function(comp, autoDestroy){
17142
var c = this.getComponent(comp);
17143
if(c && this.fireEvent('beforeremove', this, c) !== false){
17144
this.items.remove(c);
17146
if(autoDestroy === true || (autoDestroy !== false && this.autoDestroy)){
17149
if(this.layout && this.layout.activeItem == c){
17150
delete this.layout.activeItem;
17152
this.fireEvent('remove', this, c);
17158
removeAll: function(autoDestroy){
17160
var item, rem = [], items = [];
17161
this.items.each(function(i){
17164
for (var i = 0, len = rem.length; i < len; ++i){
17166
this.remove(item, autoDestroy);
17167
if(item.ownerCt !== this){
17175
getComponent : function(comp){
17176
if(typeof comp == 'object'){
17179
return this.items.get(comp);
17183
lookupComponent : function(comp){
17184
if(typeof comp == 'string'){
17185
return Ext.ComponentMgr.get(comp);
17186
}else if(!comp.events){
17187
return this.createComponent(comp);
17193
createComponent : function(config){
17194
return Ext.create(config, this.defaultType);
17198
doLayout: function(shallow, force){
17199
var rendered = this.rendered;
17200
if(!this.isVisible() || this.collapsed){
17202
this.deferLayout = this.deferLayout || !shallow;
17205
delete this.deferLayout;
17208
shallow = shallow && !this.deferLayout;
17209
delete this.deferLayout;
17210
if(rendered && this.layout){
17211
this.layout.layout();
17213
if(shallow !== true && this.items){
17214
var cs = this.items.items;
17215
for(var i = 0, len = cs.length; i < len; i++){
17223
this.onLayout(shallow, force);
17228
onLayout: Ext.emptyFn,
17230
onShow: function(){
17231
Ext.Container.superclass.onShow.call(this);
17232
if(this.deferLayout !== undefined){
17233
this.doLayout(true);
17238
getLayout : function(){
17240
var layout = new Ext.layout.ContainerLayout(this.layoutConfig);
17241
this.setLayout(layout);
17243
return this.layout;
17247
beforeDestroy : function(){
17249
Ext.destroy.apply(Ext, this.items.items);
17251
if(this.monitorResize){
17252
Ext.EventManager.removeResizeListener(this.doLayout, this);
17254
Ext.destroy(this.layout);
17255
Ext.Container.superclass.beforeDestroy.call(this);
17259
bubble : function(fn, scope, args){
17262
if(fn.apply(scope || p, args || [p]) === false){
17271
cascade : function(fn, scope, args){
17272
if(fn.apply(scope || this, args || [this]) !== false){
17274
var cs = this.items.items;
17275
for(var i = 0, len = cs.length; i < len; i++){
17277
cs[i].cascade(fn, scope, args);
17279
fn.apply(scope || cs[i], args || [cs[i]]);
17288
findById : function(id){
17290
this.cascade(function(c){
17291
if(ct != c && c.id === id){
17300
findByType : function(xtype, shallow){
17301
return this.findBy(function(c){
17302
return c.isXType(xtype, shallow);
17307
find : function(prop, value){
17308
return this.findBy(function(c){
17309
return c[prop] === value;
17314
findBy : function(fn, scope){
17315
var m = [], ct = this;
17316
this.cascade(function(c){
17317
if(ct != c && fn.call(scope || c, c, ct) === true){
17325
get : function(key){
17326
return this.items.get(key);
17330
Ext.Container.LAYOUTS = {};
17331
Ext.reg('container', Ext.Container);
17333
Ext.layout.ContainerLayout = function(config){
17334
Ext.apply(this, config);
17337
Ext.layout.ContainerLayout.prototype = {
17344
monitorResize:false,
17349
layout : function(){
17350
var target = this.container.getLayoutTarget();
17351
this.onLayout(this.container, target);
17352
this.container.fireEvent('afterlayout', this.container, this);
17356
onLayout : function(ct, target){
17357
this.renderAll(ct, target);
17361
isValidParent : function(c, target){
17362
return target && c.getDomPositionEl().dom.parentNode == (target.dom || target);
17366
renderAll : function(ct, target){
17367
var items = ct.items.items;
17368
for(var i = 0, len = items.length; i < len; i++) {
17370
if(c && (!c.rendered || !this.isValidParent(c, target))){
17371
this.renderItem(c, i, target);
17377
renderItem : function(c, position, target){
17378
if(c && !c.rendered){
17379
c.render(target, position);
17380
this.configureItem(c, position);
17381
}else if(c && !this.isValidParent(c, target)){
17382
if(typeof position == 'number'){
17383
position = target.dom.childNodes[position];
17385
target.dom.insertBefore(c.getDomPositionEl().dom, position || null);
17386
c.container = target;
17387
this.configureItem(c, position);
17392
configureItem: function(c, position){
17394
var t = c.getPositionEl ? c.getPositionEl() : c;
17395
t.addClass(this.extraCls);
17397
if (this.renderHidden && c != this.activeItem) {
17400
if(position !== undefined && c.doLayout){
17401
c.doLayout(false, true);
17406
onResize: function(){
17407
if(this.container.collapsed){
17410
var b = this.container.bufferResize;
17412
if(!this.resizeTask){
17413
this.resizeTask = new Ext.util.DelayedTask(this.layout, this);
17414
this.resizeBuffer = typeof b == 'number' ? b : 100;
17416
this.resizeTask.delay(this.resizeBuffer);
17423
setContainer : function(ct){
17424
if(this.monitorResize && ct != this.container){
17425
if(this.container){
17426
this.container.un('resize', this.onResize, this);
17431
resize: this.onResize,
17432
bodyresize: this.onResize
17436
this.container = ct;
17440
parseMargins : function(v){
17441
if(typeof v == 'number'){
17444
var ms = v.split(' ');
17445
var len = ms.length;
17459
top:parseInt(ms[0], 10) || 0,
17460
right:parseInt(ms[1], 10) || 0,
17461
bottom:parseInt(ms[2], 10) || 0,
17462
left:parseInt(ms[3], 10) || 0
17467
fieldTpl: (function() {
17468
var t = new Ext.Template(
17469
'<div class="x-form-item {itemCls}" tabIndex="-1">',
17470
'<label for="{id}" style="{labelStyle}" class="x-form-item-label">{label}{labelSeparator}</label>',
17471
'<div class="x-form-element" id="x-form-el-{id}" style="{elementStyle}">',
17472
'</div><div class="{clearCls}"></div>',
17475
t.disableFormats = true;
17476
return t.compile();
17480
destroy : Ext.emptyFn
17482
Ext.Container.LAYOUTS['auto'] = Ext.layout.ContainerLayout;
17484
Ext.layout.FitLayout = Ext.extend(Ext.layout.ContainerLayout, {
17486
monitorResize:true,
17489
onLayout : function(ct, target){
17490
Ext.layout.FitLayout.superclass.onLayout.call(this, ct, target);
17491
if(!this.container.collapsed){
17492
var sz = (Ext.isIE6 && Ext.isStrict && target.dom == document.body) ? target.getViewSize() : target.getStyleSize();
17493
this.setItemSize(this.activeItem || ct.items.itemAt(0), sz);
17498
setItemSize : function(item, size){
17499
if(item && size.height > 0){ // display none?
17500
item.setSize(size);
17504
Ext.Container.LAYOUTS['fit'] = Ext.layout.FitLayout;
17506
Ext.layout.CardLayout = Ext.extend(Ext.layout.FitLayout, {
17508
deferredRender : false,
17511
layoutOnCardChange : false,
17515
renderHidden : true,
17518
setActiveItem : function(item){
17519
item = this.container.getComponent(item);
17520
if(this.activeItem != item){
17521
if(this.activeItem){
17522
this.activeItem.hide();
17524
this.activeItem = item;
17526
this.container.doLayout();
17527
if(this.layoutOnCardChange && item.doLayout){
17534
renderAll : function(ct, target){
17535
if(this.deferredRender){
17536
this.renderItem(this.activeItem, undefined, target);
17538
Ext.layout.CardLayout.superclass.renderAll.call(this, ct, target);
17542
Ext.Container.LAYOUTS['card'] = Ext.layout.CardLayout;
17544
Ext.layout.AnchorLayout = Ext.extend(Ext.layout.ContainerLayout, {
17548
monitorResize:true,
17551
getAnchorViewSize : function(ct, target){
17552
return target.dom == document.body ?
17553
target.getViewSize() : target.getStyleSize();
17557
onLayout : function(ct, target){
17558
Ext.layout.AnchorLayout.superclass.onLayout.call(this, ct, target);
17560
var size = this.getAnchorViewSize(ct, target);
17562
var w = size.width, h = size.height;
17564
if(w < 20 && h < 20){
17568
// find the container anchoring size
17571
if(typeof ct.anchorSize == 'number'){
17572
aw = ct.anchorSize;
17574
aw = ct.anchorSize.width;
17575
ah = ct.anchorSize.height;
17578
aw = ct.initialConfig.width;
17579
ah = ct.initialConfig.height;
17582
var cs = ct.items.items, len = cs.length, i, c, a, cw, ch;
17583
for(i = 0; i < len; i++){
17587
if(!a){ // cache all anchor values
17588
var vs = c.anchor.split(' ');
17589
c.anchorSpec = a = {
17590
right: this.parseAnchor(vs[0], c.initialConfig.width, aw),
17591
bottom: this.parseAnchor(vs[1], c.initialConfig.height, ah)
17594
cw = a.right ? this.adjustWidthAnchor(a.right(w), c) : undefined;
17595
ch = a.bottom ? this.adjustHeightAnchor(a.bottom(h), c) : undefined;
17598
c.setSize(cw || undefined, ch || undefined);
17605
parseAnchor : function(a, start, cstart){
17606
if(a && a != 'none'){
17608
if(/^(r|right|b|bottom)$/i.test(a)){ // standard anchor
17609
var diff = cstart - start;
17610
return function(v){
17616
}else if(a.indexOf('%') != -1){
17617
var ratio = parseFloat(a.replace('%', ''))*.01; // percentage
17618
return function(v){
17621
return Math.floor(v*ratio);
17625
a = parseInt(a, 10);
17626
if(!isNaN(a)){ // simple offset adjustment
17627
return function(v){
17640
adjustWidthAnchor : function(value, comp){
17645
adjustHeightAnchor : function(value, comp){
17651
Ext.Container.LAYOUTS['anchor'] = Ext.layout.AnchorLayout;
17653
Ext.layout.ColumnLayout = Ext.extend(Ext.layout.ContainerLayout, {
17655
monitorResize:true,
17657
extraCls: 'x-column',
17662
isValidParent : function(c, target){
17663
return (c.getPositionEl ? c.getPositionEl() : c.getEl()).dom.parentNode == this.innerCt.dom;
17667
onLayout : function(ct, target){
17668
var cs = ct.items.items, len = cs.length, c, i;
17671
target.addClass('x-column-layout-ct');
17673
// the innerCt prevents wrapping and shuffling while
17674
// the container is resizing
17675
this.innerCt = target.createChild({cls:'x-column-inner'});
17676
this.innerCt.createChild({cls:'x-clear'});
17678
this.renderAll(ct, this.innerCt);
17680
var size = Ext.isIE && target.dom != Ext.getBody().dom ? target.getStyleSize() : target.getViewSize();
17682
if(size.width < 1 && size.height < 1){ // display none?
17686
var w = size.width - target.getPadding('lr') - this.scrollOffset,
17687
h = size.height - target.getPadding('tb'),
17690
this.innerCt.setWidth(w);
17692
// some columns can be percentages while others are fixed
17693
// so we need to make 2 passes
17695
for(i = 0; i < len; i++){
17697
if(!c.columnWidth){
17698
pw -= (c.getSize().width + c.getEl().getMargins('lr'));
17702
pw = pw < 0 ? 0 : pw;
17704
for(i = 0; i < len; i++){
17707
c.setSize(Math.floor(c.columnWidth*pw) - c.getEl().getMargins('lr'));
17715
Ext.Container.LAYOUTS['column'] = Ext.layout.ColumnLayout;
17717
Ext.layout.BorderLayout = Ext.extend(Ext.layout.ContainerLayout, {
17719
monitorResize:true,
17724
onLayout : function(ct, target){
17726
if(!this.rendered){
17727
target.addClass('x-border-layout-ct');
17728
var items = ct.items.items;
17730
for(var i = 0, len = items.length; i < len; i++) {
17732
var pos = c.region;
17736
c.collapsed = false;
17738
c.cls = c.cls ? c.cls +' x-border-panel' : 'x-border-panel';
17739
c.render(target, i);
17741
this[pos] = pos != 'center' && c.split ?
17742
new Ext.layout.BorderLayout.SplitRegion(this, c.initialConfig, pos) :
17743
new Ext.layout.BorderLayout.Region(this, c.initialConfig, pos);
17744
this[pos].render(target, c);
17746
this.rendered = true;
17749
var size = target.getViewSize();
17750
if(size.width < 20 || size.height < 20){ // display none?
17752
this.restoreCollapsed = collapsed;
17755
}else if(this.restoreCollapsed){
17756
collapsed = this.restoreCollapsed;
17757
delete this.restoreCollapsed;
17760
var w = size.width, h = size.height;
17761
var centerW = w, centerH = h, centerY = 0, centerX = 0;
17763
var n = this.north, s = this.south, west = this.west, e = this.east, c = this.center;
17764
if(!c && Ext.layout.BorderLayout.WARN !== false){
17765
throw 'No center region defined in BorderLayout ' + ct.id;
17768
if(n && n.isVisible()){
17769
var b = n.getSize();
17770
var m = n.getMargins();
17771
b.width = w - (m.left+m.right);
17774
centerY = b.height + b.y + m.bottom;
17775
centerH -= centerY;
17778
if(s && s.isVisible()){
17779
var b = s.getSize();
17780
var m = s.getMargins();
17781
b.width = w - (m.left+m.right);
17783
var totalHeight = (b.height + m.top + m.bottom);
17784
b.y = h - totalHeight + m.top;
17785
centerH -= totalHeight;
17788
if(west && west.isVisible()){
17789
var b = west.getSize();
17790
var m = west.getMargins();
17791
b.height = centerH - (m.top+m.bottom);
17793
b.y = centerY + m.top;
17794
var totalWidth = (b.width + m.left + m.right);
17795
centerX += totalWidth;
17796
centerW -= totalWidth;
17797
west.applyLayout(b);
17799
if(e && e.isVisible()){
17800
var b = e.getSize();
17801
var m = e.getMargins();
17802
b.height = centerH - (m.top+m.bottom);
17803
var totalWidth = (b.width + m.left + m.right);
17804
b.x = w - totalWidth + m.left;
17805
b.y = centerY + m.top;
17806
centerW -= totalWidth;
17810
var m = c.getMargins();
17812
x: centerX + m.left,
17813
y: centerY + m.top,
17814
width: centerW - (m.left+m.right),
17815
height: centerH - (m.top+m.bottom)
17817
c.applyLayout(centerBox);
17820
for(var i = 0, len = collapsed.length; i < len; i++){
17821
collapsed[i].collapse(false);
17824
if(Ext.isIE && Ext.isStrict){ // workaround IE strict repainting issue
17829
destroy: function() {
17830
var r = ['north', 'south', 'east', 'west'];
17831
for (var i = 0; i < r.length; i++) {
17832
var region = this[r[i]];
17834
if(region.destroy){
17836
}else if (region.split){
17837
region.split.destroy(true);
17841
Ext.layout.BorderLayout.superclass.destroy.call(this);
17848
Ext.layout.BorderLayout.Region = function(layout, config, pos){
17849
Ext.apply(this, config);
17850
this.layout = layout;
17851
this.position = pos;
17853
if(typeof this.margins == 'string'){
17854
this.margins = this.layout.parseMargins(this.margins);
17856
this.margins = Ext.applyIf(this.margins || {}, this.defaultMargins);
17857
if(this.collapsible){
17858
if(typeof this.cmargins == 'string'){
17859
this.cmargins = this.layout.parseMargins(this.cmargins);
17861
if(this.collapseMode == 'mini' && !this.cmargins){
17862
this.cmargins = {left:0,top:0,right:0,bottom:0};
17864
this.cmargins = Ext.applyIf(this.cmargins || {},
17865
pos == 'north' || pos == 'south' ? this.defaultNSCMargins : this.defaultEWCMargins);
17870
Ext.layout.BorderLayout.Region.prototype = {
17877
collapsible : false,
17888
defaultMargins : {left:0,top:0,right:0,bottom:0},
17890
defaultNSCMargins : {left:5,top:5,right:5,bottom:5},
17892
defaultEWCMargins : {left:5,top:0,right:5,bottom:0},
17893
floatingZIndex: 100,
17896
isCollapsed : false,
17903
render : function(ct, p){
17905
p.el.enableDisplayMode();
17906
this.targetEl = ct;
17909
var gs = p.getState, ps = this.position;
17910
p.getState = function(){
17911
return Ext.apply(gs.call(p) || {}, this.state);
17912
}.createDelegate(this);
17914
if(ps != 'center'){
17915
p.allowQueuedExpand = false;
17917
beforecollapse: this.beforeCollapse,
17918
collapse: this.onCollapse,
17919
beforeexpand: this.beforeExpand,
17920
expand: this.onExpand,
17925
if(this.collapsible || this.floatable){
17926
p.collapseEl = 'el';
17927
p.slideAnchor = this.getSlideAnchor();
17929
if(p.tools && p.tools.toggle){
17930
p.tools.toggle.addClass('x-tool-collapse-'+ps);
17931
p.tools.toggle.addClassOnOver('x-tool-collapse-'+ps+'-over');
17937
getCollapsedEl : function(){
17938
if(!this.collapsedEl){
17939
if(!this.toolTemplate){
17940
var tt = new Ext.Template(
17941
'<div class="x-tool x-tool-{id}"> </div>'
17943
tt.disableFormats = true;
17945
Ext.layout.BorderLayout.Region.prototype.toolTemplate = tt;
17947
this.collapsedEl = this.targetEl.createChild({
17948
cls: "x-layout-collapsed x-layout-collapsed-"+this.position,
17949
id: this.panel.id + '-xcollapsed'
17951
this.collapsedEl.enableDisplayMode('block');
17953
if(this.collapseMode == 'mini'){
17954
this.collapsedEl.addClass('x-layout-cmini-'+this.position);
17955
this.miniCollapsedEl = this.collapsedEl.createChild({
17956
cls: "x-layout-mini x-layout-mini-"+this.position, html: " "
17958
this.miniCollapsedEl.addClassOnOver('x-layout-mini-over');
17959
this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
17960
this.collapsedEl.on('click', this.onExpandClick, this, {stopEvent:true});
17962
if(this.collapsible !== false && !this.hideCollapseTool) {
17963
var t = this.toolTemplate.append(
17964
this.collapsedEl.dom,
17965
{id:'expand-'+this.position}, true);
17966
t.addClassOnOver('x-tool-expand-'+this.position+'-over');
17967
t.on('click', this.onExpandClick, this, {stopEvent:true});
17969
if(this.floatable !== false || this.titleCollapse){
17970
this.collapsedEl.addClassOnOver("x-layout-collapsed-over");
17971
this.collapsedEl.on("click", this[this.floatable ? 'collapseClick' : 'onExpandClick'], this);
17975
return this.collapsedEl;
17979
onExpandClick : function(e){
17981
this.afterSlideIn();
17982
this.panel.expand(false);
17984
this.panel.expand();
17989
onCollapseClick : function(e){
17990
this.panel.collapse();
17994
beforeCollapse : function(p, animate){
17995
this.lastAnim = animate;
17997
this.splitEl.hide();
17999
this.getCollapsedEl().show();
18000
this.panel.el.setStyle('z-index', 100);
18001
this.isCollapsed = true;
18002
this.layout.layout();
18006
onCollapse : function(animate){
18007
this.panel.el.setStyle('z-index', 1);
18008
if(this.lastAnim === false || this.panel.animCollapse === false){
18009
this.getCollapsedEl().dom.style.visibility = 'visible';
18011
this.getCollapsedEl().slideIn(this.panel.slideAnchor, {duration:.2});
18013
this.state.collapsed = true;
18014
this.panel.saveState();
18018
beforeExpand : function(animate){
18019
var c = this.getCollapsedEl();
18021
if(this.position == 'east' || this.position == 'west'){
18022
this.panel.setSize(undefined, c.getHeight());
18024
this.panel.setSize(c.getWidth(), undefined);
18027
c.dom.style.visibility = 'hidden';
18028
this.panel.el.setStyle('z-index', this.floatingZIndex);
18032
onExpand : function(){
18033
this.isCollapsed = false;
18035
this.splitEl.show();
18037
this.layout.layout();
18038
this.panel.el.setStyle('z-index', 1);
18039
this.state.collapsed = false;
18040
this.panel.saveState();
18044
collapseClick : function(e){
18046
e.stopPropagation();
18049
e.stopPropagation();
18055
onHide : function(){
18056
if(this.isCollapsed){
18057
this.getCollapsedEl().hide();
18058
}else if(this.splitEl){
18059
this.splitEl.hide();
18064
onShow : function(){
18065
if(this.isCollapsed){
18066
this.getCollapsedEl().show();
18067
}else if(this.splitEl){
18068
this.splitEl.show();
18073
isVisible : function(){
18074
return !this.panel.hidden;
18078
getMargins : function(){
18079
return this.isCollapsed && this.cmargins ? this.cmargins : this.margins;
18083
getSize : function(){
18084
return this.isCollapsed ? this.getCollapsedEl().getSize() : this.panel.getSize();
18088
setPanel : function(panel){
18089
this.panel = panel;
18093
getMinWidth: function(){
18094
return this.minWidth;
18098
getMinHeight: function(){
18099
return this.minHeight;
18103
applyLayoutCollapsed : function(box){
18104
var ce = this.getCollapsedEl();
18105
ce.setLeftTop(box.x, box.y);
18106
ce.setSize(box.width, box.height);
18110
applyLayout : function(box){
18111
if(this.isCollapsed){
18112
this.applyLayoutCollapsed(box);
18114
this.panel.setPosition(box.x, box.y);
18115
this.panel.setSize(box.width, box.height);
18120
beforeSlide: function(){
18121
this.panel.beforeEffect();
18125
afterSlide : function(){
18126
this.panel.afterEffect();
18130
initAutoHide : function(){
18131
if(this.autoHide !== false){
18132
if(!this.autoHideHd){
18133
var st = new Ext.util.DelayedTask(this.slideIn, this);
18134
this.autoHideHd = {
18135
"mouseout": function(e){
18136
if(!e.within(this.el, true)){
18140
"mouseover" : function(e){
18146
this.el.on(this.autoHideHd);
18151
clearAutoHide : function(){
18152
if(this.autoHide !== false){
18153
this.el.un("mouseout", this.autoHideHd.mouseout);
18154
this.el.un("mouseover", this.autoHideHd.mouseover);
18159
clearMonitor : function(){
18160
Ext.getDoc().un("click", this.slideInIf, this);
18163
// these names are backwards but not changed for compat
18165
slideOut : function(){
18166
if(this.isSlid || this.el.hasActiveFx()){
18169
this.isSlid = true;
18170
var ts = this.panel.tools;
18171
if(ts && ts.toggle){
18175
if(this.position == 'east' || this.position == 'west'){
18176
this.panel.setSize(undefined, this.collapsedEl.getHeight());
18178
this.panel.setSize(this.collapsedEl.getWidth(), undefined);
18180
this.restoreLT = [this.el.dom.style.left, this.el.dom.style.top];
18181
this.el.alignTo(this.collapsedEl, this.getCollapseAnchor());
18182
this.el.setStyle("z-index", this.floatingZIndex+2);
18183
this.panel.el.replaceClass('x-panel-collapsed', 'x-panel-floating');
18184
if(this.animFloat !== false){
18185
this.beforeSlide();
18186
this.el.slideIn(this.getSlideAnchor(), {
18187
callback: function(){
18189
this.initAutoHide();
18190
Ext.getDoc().on("click", this.slideInIf, this);
18196
this.initAutoHide();
18197
Ext.getDoc().on("click", this.slideInIf, this);
18202
afterSlideIn : function(){
18203
this.clearAutoHide();
18204
this.isSlid = false;
18205
this.clearMonitor();
18206
this.el.setStyle("z-index", "");
18207
this.panel.el.replaceClass('x-panel-floating', 'x-panel-collapsed');
18208
this.el.dom.style.left = this.restoreLT[0];
18209
this.el.dom.style.top = this.restoreLT[1];
18211
var ts = this.panel.tools;
18212
if(ts && ts.toggle){
18218
slideIn : function(cb){
18219
if(!this.isSlid || this.el.hasActiveFx()){
18223
this.isSlid = false;
18224
if(this.animFloat !== false){
18225
this.beforeSlide();
18226
this.el.slideOut(this.getSlideAnchor(), {
18227
callback: function(){
18230
this.afterSlideIn();
18238
this.afterSlideIn();
18243
slideInIf : function(e){
18244
if(!e.within(this.el)){
18274
getAnchor : function(){
18275
return this.anchors[this.position];
18279
getCollapseAnchor : function(){
18280
return this.canchors[this.position];
18284
getSlideAnchor : function(){
18285
return this.sanchors[this.position];
18289
getAlignAdj : function(){
18290
var cm = this.cmargins;
18291
switch(this.position){
18308
getExpandAdj : function(){
18309
var c = this.collapsedEl, cm = this.cmargins;
18310
switch(this.position){
18312
return [-(cm.right+c.getWidth()+cm.left), 0];
18315
return [cm.right+c.getWidth()+cm.left, 0];
18318
return [0, -(cm.top+cm.bottom+c.getHeight())];
18321
return [0, cm.top+cm.bottom+c.getHeight()];
18328
Ext.layout.BorderLayout.SplitRegion = function(layout, config, pos){
18329
Ext.layout.BorderLayout.SplitRegion.superclass.constructor.call(this, layout, config, pos);
18331
this.applyLayout = this.applyFns[pos];
18334
Ext.extend(Ext.layout.BorderLayout.SplitRegion, Ext.layout.BorderLayout.Region, {
18337
splitTip : "Drag to resize.",
18339
collapsibleSplitTip : "Drag to resize. Double click to hide.",
18341
useSplitTips : false,
18346
orientation: Ext.SplitBar.VERTICAL,
18347
placement: Ext.SplitBar.TOP,
18348
maxFn : 'getVMaxSize',
18349
minProp: 'minHeight',
18350
maxProp: 'maxHeight'
18353
orientation: Ext.SplitBar.VERTICAL,
18354
placement: Ext.SplitBar.BOTTOM,
18355
maxFn : 'getVMaxSize',
18356
minProp: 'minHeight',
18357
maxProp: 'maxHeight'
18360
orientation: Ext.SplitBar.HORIZONTAL,
18361
placement: Ext.SplitBar.RIGHT,
18362
maxFn : 'getHMaxSize',
18363
minProp: 'minWidth',
18364
maxProp: 'maxWidth'
18367
orientation: Ext.SplitBar.HORIZONTAL,
18368
placement: Ext.SplitBar.LEFT,
18369
maxFn : 'getHMaxSize',
18370
minProp: 'minWidth',
18371
maxProp: 'maxWidth'
18377
west : function(box){
18378
if(this.isCollapsed){
18379
return this.applyLayoutCollapsed(box);
18381
var sd = this.splitEl.dom, s = sd.style;
18382
this.panel.setPosition(box.x, box.y);
18383
var sw = sd.offsetWidth;
18384
s.left = (box.x+box.width-sw)+'px';
18385
s.top = (box.y)+'px';
18386
s.height = Math.max(0, box.height)+'px';
18387
this.panel.setSize(box.width-sw, box.height);
18389
east : function(box){
18390
if(this.isCollapsed){
18391
return this.applyLayoutCollapsed(box);
18393
var sd = this.splitEl.dom, s = sd.style;
18394
var sw = sd.offsetWidth;
18395
this.panel.setPosition(box.x+sw, box.y);
18396
s.left = (box.x)+'px';
18397
s.top = (box.y)+'px';
18398
s.height = Math.max(0, box.height)+'px';
18399
this.panel.setSize(box.width-sw, box.height);
18401
north : function(box){
18402
if(this.isCollapsed){
18403
return this.applyLayoutCollapsed(box);
18405
var sd = this.splitEl.dom, s = sd.style;
18406
var sh = sd.offsetHeight;
18407
this.panel.setPosition(box.x, box.y);
18408
s.left = (box.x)+'px';
18409
s.top = (box.y+box.height-sh)+'px';
18410
s.width = Math.max(0, box.width)+'px';
18411
this.panel.setSize(box.width, box.height-sh);
18413
south : function(box){
18414
if(this.isCollapsed){
18415
return this.applyLayoutCollapsed(box);
18417
var sd = this.splitEl.dom, s = sd.style;
18418
var sh = sd.offsetHeight;
18419
this.panel.setPosition(box.x, box.y+sh);
18420
s.left = (box.x)+'px';
18421
s.top = (box.y)+'px';
18422
s.width = Math.max(0, box.width)+'px';
18423
this.panel.setSize(box.width, box.height-sh);
18428
render : function(ct, p){
18429
Ext.layout.BorderLayout.SplitRegion.superclass.render.call(this, ct, p);
18431
var ps = this.position;
18433
this.splitEl = ct.createChild({
18434
cls: "x-layout-split x-layout-split-"+ps, html: " ",
18435
id: this.panel.id + '-xsplit'
18438
if(this.collapseMode == 'mini'){
18439
this.miniSplitEl = this.splitEl.createChild({
18440
cls: "x-layout-mini x-layout-mini-"+ps, html: " "
18442
this.miniSplitEl.addClassOnOver('x-layout-mini-over');
18443
this.miniSplitEl.on('click', this.onCollapseClick, this, {stopEvent:true});
18446
var s = this.splitSettings[ps];
18448
this.split = new Ext.SplitBar(this.splitEl.dom, p.el, s.orientation);
18449
this.split.tickSize = this.tickSize;
18450
this.split.placement = s.placement;
18451
this.split.getMaximumSize = this[s.maxFn].createDelegate(this);
18452
this.split.minSize = this.minSize || this[s.minProp];
18453
this.split.on("beforeapply", this.onSplitMove, this);
18454
this.split.useShim = this.useShim === true;
18455
this.maxSize = this.maxSize || this[s.maxProp];
18458
this.splitEl.hide();
18461
if(this.useSplitTips){
18462
this.splitEl.dom.title = this.collapsible ? this.collapsibleSplitTip : this.splitTip;
18464
if(this.collapsible){
18465
this.splitEl.on("dblclick", this.onCollapseClick, this);
18469
//docs inherit from superclass
18470
getSize : function(){
18471
if(this.isCollapsed){
18472
return this.collapsedEl.getSize();
18474
var s = this.panel.getSize();
18475
if(this.position == 'north' || this.position == 'south'){
18476
s.height += this.splitEl.dom.offsetHeight;
18478
s.width += this.splitEl.dom.offsetWidth;
18484
getHMaxSize : function(){
18485
var cmax = this.maxSize || 10000;
18486
var center = this.layout.center;
18487
return Math.min(cmax, (this.el.getWidth()+center.el.getWidth())-center.getMinWidth());
18491
getVMaxSize : function(){
18492
var cmax = this.maxSize || 10000;
18493
var center = this.layout.center;
18494
return Math.min(cmax, (this.el.getHeight()+center.el.getHeight())-center.getMinHeight());
18498
onSplitMove : function(split, newSize){
18499
var s = this.panel.getSize();
18500
this.lastSplitSize = newSize;
18501
if(this.position == 'north' || this.position == 'south'){
18502
this.panel.setSize(s.width, newSize);
18503
this.state.height = newSize;
18505
this.panel.setSize(newSize, s.height);
18506
this.state.width = newSize;
18508
this.layout.layout();
18509
this.panel.saveState();
18514
getSplitBar : function(){
18519
destroy : function() {
18528
Ext.Container.LAYOUTS['border'] = Ext.layout.BorderLayout;
18530
Ext.layout.FormLayout = Ext.extend(Ext.layout.AnchorLayout, {
18533
labelSeparator : ':',
18538
setContainer : function(ct){
18539
Ext.layout.FormLayout.superclass.setContainer.call(this, ct);
18541
ct.addClass('x-form-label-'+ct.labelAlign);
18545
this.labelStyle = "display:none";
18546
this.elementStyle = "padding-left:0;";
18547
this.labelAdjust = 0;
18549
this.labelSeparator = ct.labelSeparator || this.labelSeparator;
18550
ct.labelWidth = ct.labelWidth || 100;
18551
if(typeof ct.labelWidth == 'number'){
18552
var pad = (typeof ct.labelPad == 'number' ? ct.labelPad : 5);
18553
this.labelAdjust = ct.labelWidth+pad;
18554
this.labelStyle = "width:"+ct.labelWidth+"px;";
18555
this.elementStyle = "padding-left:"+(ct.labelWidth+pad)+'px';
18557
if(ct.labelAlign == 'top'){
18558
this.labelStyle = "width:auto;";
18559
this.labelAdjust = 0;
18560
this.elementStyle = "padding-left:0;";
18566
getLabelStyle: function(s){
18567
var ls = '', items = [this.labelStyle, s];
18568
for (var i = 0, len = items.length; i < len; ++i){
18571
if (ls.substr(-1, 1) != ';'){
18582
renderItem : function(c, position, target){
18583
if(c && !c.rendered && (c.isFormField || c.fieldLabel) && c.inputType != 'hidden'){
18584
var args = this.getTemplateArgs(c);
18585
if(typeof position == 'number'){
18586
position = target.dom.childNodes[position] || null;
18589
this.fieldTpl.insertBefore(position, args);
18591
this.fieldTpl.append(target, args);
18593
c.render('x-form-el-'+c.id);
18595
Ext.layout.FormLayout.superclass.renderItem.apply(this, arguments);
18600
getTemplateArgs: function(field) {
18601
var noLabelSep = !field.fieldLabel || field.hideLabel;
18604
label: field.fieldLabel,
18605
labelStyle: field.labelStyle||this.labelStyle||'',
18606
elementStyle: this.elementStyle||'',
18607
labelSeparator: noLabelSep ? '' : (typeof field.labelSeparator == 'undefined' ? this.labelSeparator : field.labelSeparator),
18608
itemCls: (field.itemCls||this.container.itemCls||'') + (field.hideLabel ? ' x-hide-label' : ''),
18609
clearCls: field.clearCls || 'x-form-clear-left'
18614
adjustWidthAnchor : function(value, comp){
18615
return value - (comp.isFormField || comp.fieldLabel ? (comp.hideLabel ? 0 : this.labelAdjust) : 0);
18619
isValidParent : function(c, target){
18626
Ext.Container.LAYOUTS['form'] = Ext.layout.FormLayout;
18628
Ext.layout.AccordionLayout = Ext.extend(Ext.layout.FitLayout, {
18634
titleCollapse : true,
18636
hideCollapseTool : false,
18638
collapseFirst : false,
18644
activeOnTop : false,
18646
renderItem : function(c){
18647
if(this.animate === false){
18648
c.animCollapse = false;
18650
c.collapsible = true;
18651
if(this.autoWidth){
18652
c.autoWidth = true;
18654
if(this.titleCollapse){
18655
c.titleCollapse = true;
18657
if(this.hideCollapseTool){
18658
c.hideCollapseTool = true;
18660
if(this.collapseFirst !== undefined){
18661
c.collapseFirst = this.collapseFirst;
18663
if(!this.activeItem && !c.collapsed){
18664
this.activeItem = c;
18665
}else if(this.activeItem && this.activeItem != c){
18666
c.collapsed = true;
18668
Ext.layout.AccordionLayout.superclass.renderItem.apply(this, arguments);
18669
c.header.addClass('x-accordion-hd');
18670
c.on('beforeexpand', this.beforeExpand, this);
18674
beforeExpand : function(p, anim){
18675
var ai = this.activeItem;
18678
delete this.activeItem;
18679
if (!ai.collapsed){
18680
ai.collapse({callback:function(){
18681
p.expand(anim || true);
18686
ai.collapse(this.animate);
18689
this.activeItem = p;
18690
if(this.activeOnTop){
18691
p.el.dom.parentNode.insertBefore(p.el.dom, p.el.dom.parentNode.firstChild);
18697
setItemSize : function(item, size){
18698
if(this.fill && item){
18699
var items = this.container.items.items;
18701
for(var i = 0, len = items.length; i < len; i++){
18704
hh += (p.getSize().height - p.bwrap.getHeight());
18708
item.setSize(size);
18713
setActiveItem : function(item){
18714
item = this.container.getComponent(item);
18715
if(this.activeItem != item){
18716
if(item.rendered && item.collapsed){
18719
this.activeItem = c;
18725
Ext.Container.LAYOUTS['accordion'] = Ext.layout.AccordionLayout;
18728
Ext.layout.Accordion = Ext.layout.AccordionLayout;
18730
Ext.layout.TableLayout = Ext.extend(Ext.layout.ContainerLayout, {
18734
monitorResize:false,
18740
setContainer : function(ct){
18741
Ext.layout.TableLayout.superclass.setContainer.call(this, ct);
18743
this.currentRow = 0;
18744
this.currentColumn = 0;
18749
onLayout : function(ct, target){
18750
var cs = ct.items.items, len = cs.length, c, i;
18753
target.addClass('x-table-layout-ct');
18755
this.table = target.createChild(
18756
Ext.apply({tag:'table', cls:'x-table-layout', cellspacing: 0, cn: {tag: 'tbody'}}, this.tableAttrs), null, true);
18758
this.renderAll(ct, target);
18762
getRow : function(index){
18763
var row = this.table.tBodies[0].childNodes[index];
18765
row = document.createElement('tr');
18766
this.table.tBodies[0].appendChild(row);
18772
getNextCell : function(c){
18773
var cell = this.getNextNonSpan(this.currentColumn, this.currentRow);
18774
var curCol = this.currentColumn = cell[0], curRow = this.currentRow = cell[1];
18775
for(var rowIndex = curRow; rowIndex < curRow + (c.rowspan || 1); rowIndex++){
18776
if(!this.cells[rowIndex]){
18777
this.cells[rowIndex] = [];
18779
for(var colIndex = curCol; colIndex < curCol + (c.colspan || 1); colIndex++){
18780
this.cells[rowIndex][colIndex] = true;
18783
var td = document.createElement('td');
18787
var cls = 'x-table-layout-cell';
18789
cls += ' ' + c.cellCls;
18791
td.className = cls;
18793
td.colSpan = c.colspan;
18796
td.rowSpan = c.rowspan;
18798
this.getRow(curRow).appendChild(td);
18803
getNextNonSpan: function(colIndex, rowIndex){
18804
var cols = this.columns;
18805
while((cols && colIndex >= cols) || (this.cells[rowIndex] && this.cells[rowIndex][colIndex])) {
18806
if(cols && colIndex >= cols){
18813
return [colIndex, rowIndex];
18817
renderItem : function(c, position, target){
18818
if(c && !c.rendered){
18819
c.render(this.getNextCell(c));
18821
var t = c.getPositionEl ? c.getPositionEl() : c;
18822
t.addClass(this.extraCls);
18828
isValidParent : function(c, target){
18835
Ext.Container.LAYOUTS['table'] = Ext.layout.TableLayout;
18837
Ext.layout.AbsoluteLayout = Ext.extend(Ext.layout.AnchorLayout, {
18839
extraCls: 'x-abs-layout-item',
18841
onLayout : function(ct, target){
18843
this.paddingLeft = target.getPadding('l');
18844
this.paddingTop = target.getPadding('t');
18846
Ext.layout.AbsoluteLayout.superclass.onLayout.call(this, ct, target);
18850
adjustWidthAnchor : function(value, comp){
18851
return value ? value - comp.getPosition(true)[0] + this.paddingLeft : value;
18855
adjustHeightAnchor : function(value, comp){
18856
return value ? value - comp.getPosition(true)[1] + this.paddingTop : value;
18860
Ext.Container.LAYOUTS['absolute'] = Ext.layout.AbsoluteLayout;
18863
Ext.Viewport = Ext.extend(Ext.Container, {
18876
initComponent : function() {
18877
Ext.Viewport.superclass.initComponent.call(this);
18878
document.getElementsByTagName('html')[0].className += ' x-viewport';
18879
this.el = Ext.getBody();
18880
this.el.setHeight = Ext.emptyFn;
18881
this.el.setWidth = Ext.emptyFn;
18882
this.el.setSize = Ext.emptyFn;
18883
this.el.dom.scroll = 'no';
18884
this.allowDomMove = false;
18885
this.autoWidth = true;
18886
this.autoHeight = true;
18887
Ext.EventManager.onWindowResize(this.fireResize, this);
18888
this.renderTo = this.el;
18891
fireResize : function(w, h){
18892
this.fireEvent('resize', this, w, h, w, h);
18895
Ext.reg('viewport', Ext.Viewport);
18897
Ext.layout.BoxLayout = Ext.extend(Ext.layout.ContainerLayout, {
18899
monitorResize:true,
18901
extraCls: 'x-box-item',
18902
ctCls: 'x-box-layout-ct',
18903
innerCls: 'x-box-inner',
18906
defaultMargins : {left:0,top:0,right:0,bottom:0},
18912
isValidParent : function(c, target){
18913
return c.getEl().dom.parentNode == this.innerCt.dom;
18917
onLayout : function(ct, target){
18918
var cs = ct.items.items, len = cs.length, c, i, last = len-1, cm;
18921
target.addClass(this.ctCls);
18923
// the innerCt prevents wrapping and shuffling while
18924
// the container is resizing
18925
this.innerCt = target.createChild({cls:this.innerCls});
18926
this.padding = this.parseMargins(this.padding);
18928
this.renderAll(ct, this.innerCt);
18932
renderItem : function(c){
18933
if(typeof c.margins == 'string'){
18934
c.margins = this.parseMargins(c.margins);
18935
}else if(!c.margins){
18936
c.margins = this.defaultMargins;
18938
Ext.layout.BoxLayout.superclass.renderItem.apply(this, arguments);
18941
getTargetSize : function(target){
18942
return (Ext.isIE6 && Ext.isStrict && target.dom == document.body) ? target.getStyleSize() : target.getViewSize();
18943
//return Ext.isIE && target.dom != Ext.getBody().dom ? target.getStyleSize() : target.getViewSize();
18950
Ext.layout.VBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
18952
align: 'left', // left, center, stretch, strechmax
18958
onLayout : function(ct, target){
18959
Ext.layout.VBoxLayout.superclass.onLayout.call(this, ct, target);
18961
var cs = ct.items.items, len = cs.length, c, i, last = len-1, cm,
18962
size = this.getTargetSize(target),
18963
w = size.width - target.getPadding('lr') - this.scrollOffset,
18964
h = size.height - target.getPadding('tb'),
18965
l = this.padding.left, t = this.padding.top;
18967
if ((Ext.isIE && !Ext.isStrict) && (w < 1 || h < 1)) {
18969
} else if (w < 1 && h < 1) {
18972
var totalFlex = totalHeight = 0;
18973
for(i = 0; i < len; i++){
18976
totalFlex += c.flex || 0;
18977
totalHeight += c.getHeight() + cm.top + cm.bottom;
18979
var ch, extraHeight = h - totalHeight - this.padding.top - this.padding.bottom, allocated = 0;
18980
if(this.pack == 'center'){
18981
t += extraHeight ? extraHeight/2 : 0;
18982
}else if(this.pack == 'end'){
18985
for(i = 0; i < len; i++){
18988
ch = c.getHeight();
18990
c.setPosition(l + cm.left, t);
18991
if(this.pack == 'start' && c.flex){
18992
var ratio = c.flex/totalFlex, add = Math.floor(extraHeight*ratio);
18994
add += (i == last) ? (extraHeight-allocated) : 0;
18998
t += ch + cm.bottom;
19000
var stretchWidth = w - (this.padding.left + this.padding.right),
19002
for(i = 0; i < len; i++){
19005
maxWidth = Math.max(maxWidth, c.getWidth() + cm.left + cm.right);
19007
var innerCtWidth = maxWidth + this.padding.left + this.padding.right;
19008
switch(this.align){
19010
this.innerCt.setSize(w, h);
19014
this.innerCt.setSize(innerCtWidth, h);
19017
this.innerCt.setSize(w = Math.max(w, innerCtWidth), h);
19020
var availableWidth = w - this.padding.left - this.padding.right;
19021
for(i = 0; i < len; i++){
19023
if(this.align == 'center'){
19024
var diff = availableWidth - (c.getWidth() + cm.left + cm.right);
19026
c.setPosition(l + cm.left + (diff/2), c.y);
19028
}else if(this.align == 'stretch'){
19029
c.setWidth((stretchWidth - (cm.left + cm.right)).constrain(
19030
c.minWidth || 0, c.maxWidth || 1000000));
19031
}else if(this.align == 'stretchmax'){
19032
c.setWidth((maxWidth - (cm.left + cm.right)).constrain(
19033
c.minWidth || 0, c.maxWidth || 1000000));
19040
Ext.Container.LAYOUTS['vbox'] = Ext.layout.VBoxLayout;
19043
Ext.layout.HBoxLayout = Ext.extend(Ext.layout.BoxLayout, {
19045
align: 'top', // top, middle, stretch, strechmax
19051
onLayout : function(ct, target){
19052
Ext.layout.HBoxLayout.superclass.onLayout.call(this, ct, target);
19053
var cs = ct.items.items, len = cs.length, c, i, last = len-1, cm,
19054
size = this.getTargetSize(target),
19055
w = size.width - target.getPadding('lr') - this.scrollOffset,
19056
h = size.height - target.getPadding('tb'),
19057
l = this.padding.left, t = this.padding.top;
19059
if ((Ext.isIE && !Ext.isStrict) && (w < 1 || h < 1)) {
19061
} else if (w < 1 && h < 1) {
19064
var totalFlex = totalWidth = 0;
19065
for(i = 0; i < len; i++){
19068
totalFlex += c.flex || 0;
19069
totalWidth += c.getWidth() + cm.left + cm.right;
19071
var cw, extraWidth = w - totalWidth - this.padding.left - this.padding.right, allocated = 0;
19072
if(this.pack == 'center'){
19073
l += extraWidth ? extraWidth/2 : 0;
19074
}else if(this.pack == 'end'){
19077
for(i = 0; i < len; i++){
19082
c.setPosition(l, t + cm.top);
19083
if(this.pack == 'start' && c.flex){
19084
var ratio = c.flex/totalFlex, add = Math.floor(extraWidth*ratio);
19086
add += (i == last) ? (extraWidth-allocated) : 0;
19090
l += cw + cm.right;
19092
var stretchHeight = h - (this.padding.top + this.padding.bottom),
19094
for(i = 0; i < len; i++){
19097
maxHeight = Math.max(maxHeight, c.getHeight() + cm.top + cm.bottom);
19099
var innerCtHeight = maxHeight + this.padding.top + this.padding.bottom;
19100
switch(this.align){
19102
this.innerCt.setSize(w, h);
19106
this.innerCt.setSize(w, innerCtHeight);
19109
this.innerCt.setSize(w, h = Math.max(h, innerCtHeight));
19112
var availableHeight = h - this.padding.top - this.padding.bottom;
19113
for(i = 0; i < len; i++){
19115
if(this.align == 'middle'){
19116
var diff = availableHeight - (c.getHeight() + cm.top + cm.bottom);
19118
c.setPosition(c.x, t + cm.top + (diff/2));
19120
}else if(this.align == 'stretch'){
19121
c.setHeight((stretchHeight - (cm.top + cm.bottom)).constrain(
19122
c.minHeight || 0, c.maxHeight || 1000000));
19123
}else if(this.align == 'stretchmax'){
19124
c.setHeight((maxHeight - (cm.top + cm.bottom)).constrain(
19125
c.minHeight || 0, c.maxHeight || 1000000));
19133
Ext.Container.LAYOUTS['hbox'] = Ext.layout.HBoxLayout;
19136
Ext.Panel = Ext.extend(Ext.Container, {
19183
baseCls : 'x-panel',
19185
collapsedCls : 'x-panel-collapsed',
19187
maskDisabled: true,
19189
animCollapse: Ext.enableFx,
19191
headerAsText: true,
19193
buttonAlign: 'right',
19197
collapseFirst: true,
19204
preventBodyReset: false,
19206
// protected - these could be used to customize the behavior of the window,
19207
// but changing them would not be useful without further mofifications and
19208
// could lead to unexpected or undesirable results.
19209
toolTarget : 'header',
19210
collapseEl : 'bwrap',
19214
// private, notify box this class will handle heights
19221
collapseDefaults: {
19226
initComponent : function(){
19227
Ext.Panel.superclass.initComponent.call(this);
19255
this.baseCls = 'x-plain';
19260
this.elements += ',tbar';
19261
if(Ext.isObject(this.tbar)){
19262
this.topToolbar = this.tbar;
19267
this.elements += ',bbar';
19268
if(Ext.isObject(this.bbar)){
19269
this.bottomToolbar = this.bbar;
19274
if(this.header === true){
19275
this.elements += ',header';
19276
delete this.header;
19277
}else if(this.title && this.header !== false){
19278
this.elements += ',header';
19281
if(this.footer === true){
19282
this.elements += ',footer';
19283
delete this.footer;
19287
this.elements += ',footer';
19288
var btns = this.buttons;
19291
for(var i = 0, len = btns.length; i < len; i++) {
19292
if(btns[i].render){ // button instance
19293
this.buttons.push(btns[i]);
19294
}else if(btns[i].xtype){
19295
this.buttons.push(Ext.create(btns[i], 'button'));
19297
this.addButton(btns[i]);
19302
this.elements += ',footer';
19305
this.on('render', this.doAutoLoad, this, {delay:10});
19310
createElement : function(name, pnode){
19312
pnode.appendChild(this[name].dom);
19316
if(name === 'bwrap' || this.elements.indexOf(name) != -1){
19317
if(this[name+'Cfg']){
19318
this[name] = Ext.fly(pnode).createChild(this[name+'Cfg']);
19320
var el = document.createElement('div');
19321
el.className = this[name+'Cls'];
19322
this[name] = Ext.get(pnode.appendChild(el));
19324
if(this[name+'CssClass']){
19325
this[name].addClass(this[name+'CssClass']);
19327
if(this[name+'Style']){
19328
this[name].applyStyles(this[name+'Style']);
19334
onRender : function(ct, position){
19335
Ext.Panel.superclass.onRender.call(this, ct, position);
19336
this.createClasses();
19338
var el = this.el, d = el.dom;
19339
el.addClass(this.baseCls);
19340
if(d.firstChild){ // existing markup
19341
this.header = el.down('.'+this.headerCls);
19342
this.bwrap = el.down('.'+this.bwrapCls);
19343
var cp = this.bwrap ? this.bwrap : el;
19344
this.tbar = cp.down('.'+this.tbarCls);
19345
this.body = cp.down('.'+this.bodyCls);
19346
this.bbar = cp.down('.'+this.bbarCls);
19347
this.footer = cp.down('.'+this.footerCls);
19348
this.fromMarkup = true;
19350
if (this.preventBodyReset === true) {
19351
el.addClass('x-panel-reset');
19354
el.addClass(this.cls);
19358
this.elements += ',footer';
19361
// This block allows for maximum flexibility and performance when using existing markup
19363
// framing requires special markup
19365
el.insertHtml('afterBegin', String.format(Ext.Element.boxMarkup, this.baseCls));
19367
this.createElement('header', d.firstChild.firstChild.firstChild);
19368
this.createElement('bwrap', d);
19370
// append the mid and bottom frame to the bwrap
19371
var bw = this.bwrap.dom;
19372
var ml = d.childNodes[1], bl = d.childNodes[2];
19373
bw.appendChild(ml);
19374
bw.appendChild(bl);
19376
var mc = bw.firstChild.firstChild.firstChild;
19377
this.createElement('tbar', mc);
19378
this.createElement('body', mc);
19379
this.createElement('bbar', mc);
19380
this.createElement('footer', bw.lastChild.firstChild.firstChild);
19383
this.bwrap.dom.lastChild.className += ' x-panel-nofooter';
19386
this.createElement('header', d);
19387
this.createElement('bwrap', d);
19389
// append the mid and bottom frame to the bwrap
19390
var bw = this.bwrap.dom;
19391
this.createElement('tbar', bw);
19392
this.createElement('body', bw);
19393
this.createElement('bbar', bw);
19394
this.createElement('footer', bw);
19397
this.body.addClass(this.bodyCls + '-noheader');
19399
this.tbar.addClass(this.tbarCls + '-noheader');
19404
if(this.padding !== undefined) {
19405
this.body.setStyle('padding', this.body.addUnits(this.padding));
19408
if(this.border === false){
19409
this.el.addClass(this.baseCls + '-noborder');
19410
this.body.addClass(this.bodyCls + '-noborder');
19412
this.header.addClass(this.headerCls + '-noborder');
19415
this.footer.addClass(this.footerCls + '-noborder');
19418
this.tbar.addClass(this.tbarCls + '-noborder');
19421
this.bbar.addClass(this.bbarCls + '-noborder');
19425
if(this.bodyBorder === false){
19426
this.body.addClass(this.bodyCls + '-noborder');
19429
this.bwrap.enableDisplayMode('block');
19432
this.header.unselectable();
19434
// for tools, we need to wrap any existing header markup
19435
if(this.headerAsText){
19436
this.header.dom.innerHTML =
19437
'<span class="' + this.headerTextCls + '">'+this.header.dom.innerHTML+'</span>';
19440
this.setIconClass(this.iconCls);
19446
this.makeFloating(this.floating);
19449
if(this.collapsible){
19450
this.tools = this.tools ? this.tools.slice(0) : [];
19451
if(!this.hideCollapseTool){
19452
this.tools[this.collapseFirst?'unshift':'push']({
19454
handler : this.toggleCollapse,
19458
if(this.titleCollapse && this.header){
19459
this.mon(this.header, 'click', this.toggleCollapse, this);
19460
this.header.setStyle('cursor', 'pointer');
19464
var ts = this.tools;
19466
this.addTool.apply(this, ts);
19471
if(this.buttons && this.buttons.length > 0){
19472
this.fbar = new Ext.Toolbar({
19473
items: this.buttons,
19474
toolbarCls: 'x-panel-fbar'
19477
this.toolbars = [];
19479
this.fbar = Ext.create(this.fbar, 'toolbar');
19480
this.fbar.enableOverflow = false;
19481
if(this.fbar.items){
19482
this.fbar.items.each(function(c){
19483
c.minWidth = c.minWidth || this.minButtonWidth;
19486
this.fbar.toolbarCls = 'x-panel-fbar';
19488
var bct = this.footer.createChild({cls: 'x-panel-btns x-panel-btns-'+this.buttonAlign});
19489
this.fbar.ownerCt = this;
19490
this.fbar.render(bct);
19491
bct.createChild({cls:'x-clear'});
19492
this.toolbars.push(this.fbar);
19495
if(this.tbar && this.topToolbar){
19496
if(Ext.isArray(this.topToolbar)){
19497
this.topToolbar = new Ext.Toolbar(this.topToolbar);
19498
}else if(!this.topToolbar.events){
19499
this.topToolbar = Ext.create(this.topToolbar, 'toolbar');
19501
this.topToolbar.ownerCt = this;
19502
this.topToolbar.render(this.tbar);
19503
this.toolbars.push(this.topToolbar);
19505
if(this.bbar && this.bottomToolbar){
19506
if(Ext.isArray(this.bottomToolbar)){
19507
this.bottomToolbar = new Ext.Toolbar(this.bottomToolbar);
19508
}else if(!this.bottomToolbar.events){
19509
this.bottomToolbar = Ext.create(this.bottomToolbar, 'toolbar');
19511
this.bottomToolbar.ownerCt = this;
19512
this.bottomToolbar.render(this.bbar);
19513
this.toolbars.push(this.bottomToolbar);
19515
Ext.each(this.toolbars, function(tb){
19518
afterlayout: this.syncHeight,
19519
remove: this.syncHeight
19525
setIconClass : function(cls){
19526
var old = this.iconCls;
19527
this.iconCls = cls;
19528
if(this.rendered && this.header){
19530
this.header.addClass('x-panel-icon');
19531
this.header.replaceClass(old, this.iconCls);
19533
var hd = this.header.dom;
19534
var img = hd.firstChild && String(hd.firstChild.tagName).toLowerCase() == 'img' ? hd.firstChild : null;
19536
Ext.fly(img).replaceClass(old, this.iconCls);
19538
Ext.DomHelper.insertBefore(hd.firstChild, {
19539
tag:'img', src: Ext.BLANK_IMAGE_URL, cls:'x-panel-inline-icon '+this.iconCls
19544
this.fireEvent('iconchange', this, cls, old);
19548
makeFloating : function(cfg){
19549
this.floating = true;
19550
this.el = new Ext.Layer(
19551
Ext.isObject(cfg) ? cfg : {
19552
shadow: this.shadow !== undefined ? this.shadow : 'sides',
19553
shadowOffset: this.shadowOffset,
19555
shim: this.shim === false ? false : undefined
19561
getTopToolbar : function(){
19562
return this.topToolbar;
19566
getBottomToolbar : function(){
19567
return this.bottomToolbar;
19571
addButton : function(config, handler, scope){
19575
minWidth: this.minButtonWidth,
19578
if(typeof config == "string"){
19581
Ext.apply(bc, config);
19583
var btn = new Ext.Button(bc);
19587
this.buttons.push(btn);
19592
addTool : function(){
19593
if(!this[this.toolTarget]) { // no where to render tools!
19596
if(!this.toolTemplate){
19597
// initialize the global tool template on first use
19598
var tt = new Ext.Template(
19599
'<div class="x-tool x-tool-{id}"> </div>'
19601
tt.disableFormats = true;
19603
Ext.Panel.prototype.toolTemplate = tt;
19605
for(var i = 0, a = arguments, len = a.length; i < len; i++) {
19607
if(!this.tools[tc.id]){
19608
var overCls = 'x-tool-'+tc.id+'-over';
19609
var t = this.toolTemplate.insertFirst((tc.align !== 'left') ? this[this.toolTarget] : this[this.toolTarget].child('span'), tc, true);
19610
this.tools[tc.id] = t;
19611
t.enableDisplayMode('block');
19612
this.mon(t, 'click', this.createToolHandler(t, tc, overCls, this));
19614
this.mon(t, tc.on);
19620
if(Ext.isObject(tc.qtip)){
19621
Ext.QuickTips.register(Ext.apply({
19625
t.dom.qtip = tc.qtip;
19628
t.addClassOnOver(overCls);
19633
onLayout : function(){
19634
if(this.toolbars.length > 0){
19635
this.duringLayout = true;
19636
Ext.each(this.toolbars, function(tb){
19639
delete this.duringLayout;
19644
syncHeight: function(){
19645
if(!this.duringLayout){
19646
var last = this.lastSize;
19647
if(last && !Ext.isEmpty(last.height)){
19648
var old = last.height, h = this.el.getHeight();
19649
if(old != 'auto' && old != h){
19651
var bd = this.body;
19652
bd.setHeight(bd.getHeight() + h);
19653
var sz = bd.getSize();
19654
this.fireEvent('bodyresize', sz.width, sz.height);
19661
onShow : function(){
19663
return this.el.show();
19665
Ext.Panel.superclass.onShow.call(this);
19669
onHide : function(){
19671
return this.el.hide();
19673
Ext.Panel.superclass.onHide.call(this);
19677
createToolHandler : function(t, tc, overCls, panel){
19678
return function(e){
19679
t.removeClass(overCls);
19680
if(tc.stopEvent !== false){
19684
tc.handler.call(tc.scope || t, e, t, panel, tc);
19690
afterRender : function(){
19691
if(this.floating && !this.hidden){
19695
this.setTitle(this.title);
19697
this.setAutoScroll();
19699
this.body.update(Ext.isObject(this.html) ?
19700
Ext.DomHelper.markup(this.html) :
19704
if(this.contentEl){
19705
var ce = Ext.getDom(this.contentEl);
19706
Ext.fly(ce).removeClass(['x-hidden', 'x-hide-display']);
19707
this.body.dom.appendChild(ce);
19709
if(this.collapsed){
19710
this.collapsed = false;
19711
this.collapse(false);
19713
Ext.Panel.superclass.afterRender.call(this); // do sizing calcs last
19718
setAutoScroll : function(){
19719
if(this.rendered && this.autoScroll){
19720
var el = this.body || this.el;
19722
el.setOverflow('auto');
19728
getKeyMap : function(){
19730
this.keyMap = new Ext.KeyMap(this.el, this.keys);
19732
return this.keyMap;
19736
initEvents : function(){
19740
if(this.draggable){
19741
this.initDraggable();
19746
initDraggable : function(){
19748
this.dd = new Ext.Panel.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
19752
beforeEffect : function(){
19754
this.el.beforeAction();
19756
this.el.addClass('x-panel-animated');
19760
afterEffect : function(){
19762
this.el.removeClass('x-panel-animated');
19765
// private - wraps up an animation param with internal callbacks
19766
createEffect : function(a, cb, scope){
19774
}else if(!a.callback){
19776
}else { // wrap it up
19777
o.callback = function(){
19779
Ext.callback(a.callback, a.scope);
19782
return Ext.applyIf(o, a);
19786
collapse : function(animate){
19787
if(this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforecollapse', this, animate) === false){
19790
var doAnim = animate === true || (animate !== false && this.animCollapse);
19792
this.beforeEffect();
19794
this.onCollapse(doAnim, animate);
19799
onCollapse : function(doAnim, animArg){
19801
this[this.collapseEl].slideOut(this.slideAnchor,
19802
Ext.apply(this.createEffect(animArg||true, this.afterCollapse, this),
19803
this.collapseDefaults));
19805
this[this.collapseEl].hide();
19806
this.afterCollapse(doAnim);
19811
afterCollapse : function(doAnim){
19812
this.collapsed = true;
19813
this.el.addClass(this.collapsedCls);
19815
this.afterEffect();
19817
this.fireEvent('collapse', this);
19821
expand : function(animate){
19822
if(!this.collapsed || this.el.hasFxBlock() || this.fireEvent('beforeexpand', this, animate) === false){
19825
var doAnim = animate === true || (animate !== false && this.animCollapse);
19826
this.el.removeClass(this.collapsedCls);
19827
this.beforeEffect();
19828
this.onExpand(doAnim, animate);
19833
onExpand : function(doAnim, animArg){
19835
this[this.collapseEl].slideIn(this.slideAnchor,
19836
Ext.apply(this.createEffect(animArg||true, this.afterExpand, this),
19837
this.expandDefaults));
19839
this[this.collapseEl].show();
19840
this.afterExpand();
19845
afterExpand: function(){
19846
this.collapsed = false;
19847
this.afterEffect();
19848
if(this.deferLayout !== undefined){
19849
this.doLayout(true);
19851
this.fireEvent('expand', this);
19855
toggleCollapse : function(animate){
19856
this[this.collapsed ? 'expand' : 'collapse'](animate);
19861
onDisable : function(){
19862
if(this.rendered && this.maskDisabled){
19865
Ext.Panel.superclass.onDisable.call(this);
19869
onEnable : function(){
19870
if(this.rendered && this.maskDisabled){
19873
Ext.Panel.superclass.onEnable.call(this);
19877
onResize : function(w, h){
19878
if(w !== undefined || h !== undefined){
19879
if(!this.collapsed){
19880
if(typeof w == 'number'){
19881
w = this.adjustBodyWidth(w - this.getFrameWidth());
19883
this.tbar.setWidth(w);
19884
if(this.topToolbar){
19885
this.topToolbar.setSize(w);
19889
this.bbar.setWidth(w);
19890
if(this.bottomToolbar){
19891
this.bottomToolbar.setSize(w);
19895
var f = this.fbar, fWidth = 1; strict = Ext.isStrict;
19896
if(this.buttonAlign == 'left'){
19897
fWidth = w - f.container.getFrameWidth('lr');
19899
//center/right alignment off in webkit
19900
if(Ext.isIE || Ext.isWebKit){
19901
//center alignment ok on webkit.
19902
//right broken in both, center on IE
19903
if(!(this.buttonAlign == 'center' && Ext.isWebKit) && (!strict || (!Ext.isIE8 && strict))){
19905
f.setWidth(f.getEl().child('.x-toolbar-ct').getWidth());
19914
f.setWidth(fWidth);
19916
this.body.setWidth(w);
19917
}else if(w == 'auto'){
19918
this.body.setWidth(w);
19921
if(typeof h == 'number'){
19922
h = this.adjustBodyHeight(h - this.getFrameHeight());
19923
this.body.setHeight(h);
19924
}else if(h == 'auto'){
19925
this.body.setHeight(h);
19928
if(this.disabled && this.el._mask){
19929
this.el._mask.setSize(this.el.dom.clientWidth, this.el.getHeight());
19932
this.queuedBodySize = {width: w, height: h};
19933
if(!this.queuedExpand && this.allowQueuedExpand !== false){
19934
this.queuedExpand = true;
19935
this.on('expand', function(){
19936
delete this.queuedExpand;
19937
this.onResize(this.queuedBodySize.width, this.queuedBodySize.height);
19939
}, this, {single:true});
19942
this.fireEvent('bodyresize', this, w, h);
19948
adjustBodyHeight : function(h){
19953
adjustBodyWidth : function(w){
19958
onPosition : function(){
19963
getFrameWidth : function(){
19964
var w = this.el.getFrameWidth('lr')+this.bwrap.getFrameWidth('lr');
19967
var l = this.bwrap.dom.firstChild;
19968
w += (Ext.fly(l).getFrameWidth('l') + Ext.fly(l.firstChild).getFrameWidth('r'));
19969
var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
19970
w += Ext.fly(mc).getFrameWidth('lr');
19976
getFrameHeight : function(){
19977
var h = this.el.getFrameWidth('tb')+this.bwrap.getFrameWidth('tb');
19978
h += (this.tbar ? this.tbar.getHeight() : 0) +
19979
(this.bbar ? this.bbar.getHeight() : 0);
19982
var hd = this.el.dom.firstChild;
19983
var ft = this.bwrap.dom.lastChild;
19984
h += (hd.offsetHeight + ft.offsetHeight);
19985
var mc = this.bwrap.dom.firstChild.firstChild.firstChild;
19986
h += Ext.fly(mc).getFrameWidth('tb');
19988
h += (this.header ? this.header.getHeight() : 0) +
19989
(this.footer ? this.footer.getHeight() : 0);
19995
getInnerWidth : function(){
19996
return this.getSize().width - this.getFrameWidth();
20000
getInnerHeight : function(){
20001
return this.getSize().height - this.getFrameHeight();
20005
syncShadow : function(){
20007
this.el.sync(true);
20012
getLayoutTarget : function(){
20017
setTitle : function(title, iconCls){
20018
this.title = title;
20019
if(this.header && this.headerAsText){
20020
this.header.child('span').update(title);
20023
this.setIconClass(iconCls);
20025
this.fireEvent('titlechange', this, title);
20030
getUpdater : function(){
20031
return this.body.getUpdater();
20036
var um = this.body.getUpdater();
20037
um.update.apply(um, arguments);
20042
beforeDestroy : function(){
20044
this.header.removeAllListeners();
20045
if(this.headerAsText){
20046
Ext.Element.uncache(this.header.child('span'));
20049
Ext.Element.uncache(
20058
for(var k in this.tools){
20059
Ext.destroy(this.tools[k]);
20063
for(var b in this.buttons){
20064
Ext.destroy(this.buttons[b]);
20069
this.bottomToolbar,
20072
Ext.Panel.superclass.beforeDestroy.call(this);
20076
createClasses : function(){
20077
this.headerCls = this.baseCls + '-header';
20078
this.headerTextCls = this.baseCls + '-header-text';
20079
this.bwrapCls = this.baseCls + '-bwrap';
20080
this.tbarCls = this.baseCls + '-tbar';
20081
this.bodyCls = this.baseCls + '-body';
20082
this.bbarCls = this.baseCls + '-bbar';
20083
this.footerCls = this.baseCls + '-footer';
20087
createGhost : function(cls, useShim, appendTo){
20088
var el = document.createElement('div');
20089
el.className = 'x-panel-ghost ' + (cls ? cls : '');
20091
el.appendChild(this.el.dom.firstChild.cloneNode(true));
20093
Ext.fly(el.appendChild(document.createElement('ul'))).setHeight(this.bwrap.getHeight());
20094
el.style.width = this.el.dom.offsetWidth + 'px';;
20096
this.container.dom.appendChild(el);
20098
Ext.getDom(appendTo).appendChild(el);
20100
if(useShim !== false && this.el.useShim !== false){
20101
var layer = new Ext.Layer({shadow:false, useDisplay:true, constrain:false}, el);
20105
return new Ext.Element(el);
20110
doAutoLoad : function(){
20111
var u = this.body.getUpdater();
20113
u.setRenderer(this.renderer);
20115
u.update(Ext.isObject(this.autoLoad) ? this.autoLoad : {url: this.autoLoad});
20119
getTool: function(id) {
20120
return this.tools[id];
20125
Ext.reg('panel', Ext.Panel);
20128
Ext.Window = Ext.extend(Ext.Panel, {
20141
baseCls : 'x-window',
20151
constrainHeader : false,
20155
minimizable : false,
20157
maximizable : false,
20163
expandOnShow : true,
20165
closeAction : 'close',
20167
// inherited docs, same default
20168
collapsible : false,
20173
monitorResize : true,
20175
// The following configs are set to provide the basic functionality of a window.
20176
// Changing them would require additional code to handle correctly and should
20177
// usually only be done in subclasses that can provide custom behavior. Changing them
20178
// may have unexpected or undesirable results.
20180
elements : 'header,body',
20187
initComponent : function(){
20188
Ext.Window.superclass.initComponent.call(this);
20201
if(this.initHidden === false){
20204
this.hidden = true;
20209
getState : function(){
20210
return Ext.apply(Ext.Window.superclass.getState.call(this) || {}, this.getBox(true));
20214
onRender : function(ct, position){
20215
Ext.Window.superclass.onRender.call(this, ct, position);
20218
this.el.addClass('x-window-plain');
20221
// this element allows the Window to be focused for keyboard events
20222
this.focusEl = this.el.createChild({
20223
tag: "a", href:"#", cls:"x-dlg-focus",
20224
tabIndex:"-1", html: " "});
20225
this.focusEl.swallowEvent('click', true);
20227
this.proxy = this.el.createProxy("x-window-proxy");
20228
this.proxy.enableDisplayMode('block');
20231
this.mask = this.container.createChild({cls:"ext-el-mask"}, this.el.dom);
20232
this.mask.enableDisplayMode("block");
20234
this.mon(this.mask, 'click', this.focus, this);
20240
initEvents : function(){
20241
Ext.Window.superclass.initEvents.call(this);
20242
if(this.animateTarget){
20243
this.setAnimateTarget(this.animateTarget);
20246
if(this.resizable){
20247
this.resizer = new Ext.Resizable(this.el, {
20248
minWidth: this.minWidth,
20249
minHeight:this.minHeight,
20250
handles: this.resizeHandles || "all",
20252
resizeElement : this.resizerAction
20254
this.resizer.window = this;
20255
this.mon(this.resizer, 'beforeresize', this.beforeResize, this);
20258
if(this.draggable){
20259
this.header.addClass("x-window-draggable");
20261
this.mon(this.el, 'mousedown', this.toFront, this);
20262
this.manager = this.manager || Ext.WindowMgr;
20263
this.manager.register(this);
20264
if(this.maximized){
20265
this.maximized = false;
20269
var km = this.getKeyMap();
20270
km.on(27, this.onEsc, this);
20275
initDraggable : function(){
20277
this.dd = new Ext.Window.DD(this);
20281
onEsc : function(){
20282
this[this.closeAction]();
20286
beforeDestroy : function(){
20287
if (this.rendered){
20290
Ext.EventManager.removeResizeListener(this.doAnchor, this);
20291
Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
20301
Ext.Window.superclass.beforeDestroy.call(this);
20305
onDestroy : function(){
20307
this.manager.unregister(this);
20309
Ext.Window.superclass.onDestroy.call(this);
20313
initTools : function(){
20314
if(this.minimizable){
20317
handler: this.minimize.createDelegate(this, [])
20320
if(this.maximizable){
20323
handler: this.maximize.createDelegate(this, [])
20327
handler: this.restore.createDelegate(this, []),
20330
this.mon(this.header, 'dblclick', this.toggleMaximize, this);
20335
handler: this[this.closeAction].createDelegate(this, [])
20341
resizerAction : function(){
20342
var box = this.proxy.getBox();
20344
this.window.handleResize(box);
20349
beforeResize : function(){
20350
this.resizer.minHeight = Math.max(this.minHeight, this.getFrameHeight() + 40); // 40 is a magic minimum content size?
20351
this.resizer.minWidth = Math.max(this.minWidth, this.getFrameWidth() + 40);
20352
this.resizeBox = this.el.getBox();
20356
updateHandles : function(){
20357
if(Ext.isIE && this.resizer){
20358
this.resizer.syncHandleHeight();
20364
handleResize : function(box){
20365
var rz = this.resizeBox;
20366
if(rz.x != box.x || rz.y != box.y){
20367
this.updateBox(box);
20372
this.updateHandles();
20377
this.fireEvent("resize", this, box.width, box.height);
20381
focus : function(){
20382
var f = this.focusEl, db = this.defaultButton, t = typeof db;
20383
if(t != 'undefined'){
20384
if(t == 'number' && this.fbar){
20385
f = this.fbar.items.get(db);
20386
}else if(t == 'string'){
20387
f = Ext.getCmp(db);
20392
f = f || this.focusEl;
20393
f.focus.defer(10, f);
20397
setAnimateTarget : function(el){
20399
this.animateTarget = el;
20403
beforeShow : function(){
20404
delete this.el.lastXY;
20405
delete this.el.lastLT;
20406
if(this.x === undefined || this.y === undefined){
20407
var xy = this.el.getAlignToXY(this.container, 'c-c');
20408
var pos = this.el.translatePoints(xy[0], xy[1]);
20409
this.x = this.x === undefined? pos.left : this.x;
20410
this.y = this.y === undefined? pos.top : this.y;
20412
this.el.setLeftTop(this.x, this.y);
20414
if(this.expandOnShow){
20415
this.expand(false);
20419
Ext.getBody().addClass("x-body-masked");
20420
this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
20426
show : function(animateTarget, cb, scope){
20427
if(!this.rendered){
20428
this.render(Ext.getBody());
20430
if(this.hidden === false){
20434
if(this.fireEvent("beforeshow", this) === false){
20438
this.on('show', cb, scope, {single:true});
20440
this.hidden = false;
20441
if(animateTarget !== undefined){
20442
this.setAnimateTarget(animateTarget);
20445
if(this.animateTarget){
20454
afterShow : function(isAnim){
20456
this.el.setStyle('display', 'block');
20458
if(this.maximized){
20459
this.fitContainer();
20461
if(Ext.isMac && Ext.isGecko){ // work around stupid FF 2.0/Mac scroll bar bug
20462
this.cascade(this.setAutoScroll);
20465
if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
20466
Ext.EventManager.onWindowResize(this.onWindowResize, this);
20468
this.doConstrain();
20473
this.keyMap.enable();
20476
this.updateHandles();
20477
if(isAnim && (Ext.isIE || Ext.isWebKit)){
20478
var sz = this.getSize();
20479
this.onResize(sz.width, sz.height);
20481
this.fireEvent("show", this);
20485
animShow : function(){
20487
this.proxy.setBox(this.animateTarget.getBox());
20488
this.proxy.setOpacity(0);
20489
var b = this.getBox(false);
20490
b.callback = this.afterShow.createDelegate(this, [true], false);
20493
b.easing = 'easeNone';
20496
this.el.setStyle('display', 'none');
20497
this.proxy.shift(b);
20501
hide : function(animateTarget, cb, scope){
20502
if(this.hidden || this.fireEvent("beforehide", this) === false){
20506
this.on('hide', cb, scope, {single:true});
20508
this.hidden = true;
20509
if(animateTarget !== undefined){
20510
this.setAnimateTarget(animateTarget);
20514
Ext.getBody().removeClass("x-body-masked");
20516
if(this.animateTarget){
20526
afterHide : function(){
20528
if(this.monitorResize || this.modal || this.constrain || this.constrainHeader){
20529
Ext.EventManager.removeResizeListener(this.onWindowResize, this);
20532
this.keyMap.disable();
20534
this.fireEvent("hide", this);
20538
animHide : function(){
20539
this.proxy.setOpacity(.5);
20541
var tb = this.getBox(false);
20542
this.proxy.setBox(tb);
20544
var b = this.animateTarget.getBox();
20545
b.callback = this.afterHide;
20548
b.easing = 'easeNone';
20551
this.proxy.shift(b);
20555
onWindowResize : function(){
20556
if(this.maximized){
20557
this.fitContainer();
20560
this.mask.setSize('100%', '100%');
20561
var force = this.mask.dom.offsetHeight;
20562
this.mask.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
20564
this.doConstrain();
20568
doConstrain : function(){
20569
if(this.constrain || this.constrainHeader){
20571
if(this.constrain){
20573
right:this.el.shadowOffset,
20574
left:this.el.shadowOffset,
20575
bottom:this.el.shadowOffset
20578
var s = this.getSize();
20580
right:-(s.width - 100),
20581
bottom:-(s.height - 25)
20585
var xy = this.el.getConstrainToXY(this.container, true, offsets);
20587
this.setPosition(xy[0], xy[1]);
20592
// private - used for dragging
20593
ghost : function(cls){
20594
var ghost = this.createGhost(cls);
20595
var box = this.getBox(true);
20596
ghost.setLeftTop(box.x, box.y);
20597
ghost.setWidth(box.width);
20599
this.activeGhost = ghost;
20604
unghost : function(show, matchPosition){
20605
if(!this.activeGhost) {
20608
if(show !== false){
20611
if(Ext.isMac && Ext.isGecko){ // work around stupid FF 2.0/Mac scroll bar bug
20612
this.cascade(this.setAutoScroll);
20615
if(matchPosition !== false){
20616
this.setPosition(this.activeGhost.getLeft(true), this.activeGhost.getTop(true));
20618
this.activeGhost.hide();
20619
this.activeGhost.remove();
20620
delete this.activeGhost;
20624
minimize : function(){
20625
this.fireEvent('minimize', this);
20630
close : function(){
20631
if(this.fireEvent("beforeclose", this) !== false){
20632
this.hide(null, function(){
20633
this.fireEvent('close', this);
20640
maximize : function(){
20641
if(!this.maximized){
20642
this.expand(false);
20643
this.restoreSize = this.getSize();
20644
this.restorePos = this.getPosition(true);
20645
if (this.maximizable){
20646
this.tools.maximize.hide();
20647
this.tools.restore.show();
20649
this.maximized = true;
20650
this.el.disableShadow();
20655
if(this.collapsible){
20656
this.tools.toggle.hide();
20658
this.el.addClass('x-window-maximized');
20659
this.container.addClass('x-window-maximized-ct');
20661
this.setPosition(0, 0);
20662
this.fitContainer();
20663
this.fireEvent('maximize', this);
20669
restore : function(){
20670
if(this.maximized){
20671
this.el.removeClass('x-window-maximized');
20672
this.tools.restore.hide();
20673
this.tools.maximize.show();
20674
this.setPosition(this.restorePos[0], this.restorePos[1]);
20675
this.setSize(this.restoreSize.width, this.restoreSize.height);
20676
delete this.restorePos;
20677
delete this.restoreSize;
20678
this.maximized = false;
20679
this.el.enableShadow(true);
20684
if(this.collapsible){
20685
this.tools.toggle.show();
20687
this.container.removeClass('x-window-maximized-ct');
20689
this.doConstrain();
20690
this.fireEvent('restore', this);
20696
toggleMaximize : function(){
20697
return this[this.maximized ? 'restore' : 'maximize']();
20701
fitContainer : function(){
20702
var vs = this.container.getViewSize();
20703
this.setSize(vs.width, vs.height);
20707
// z-index is managed by the WindowManager and may be overwritten at any time
20708
setZIndex : function(index){
20710
this.mask.setStyle("z-index", index);
20712
this.el.setZIndex(++index);
20716
this.resizer.proxy.setStyle("z-index", ++index);
20719
this.lastZIndex = index;
20723
alignTo : function(element, position, offsets){
20724
var xy = this.el.getAlignToXY(element, position, offsets);
20725
this.setPagePosition(xy[0], xy[1]);
20730
anchorTo : function(el, alignment, offsets, monitorScroll){
20732
Ext.EventManager.removeResizeListener(this.doAnchor, this);
20733
Ext.EventManager.un(window, 'scroll', this.doAnchor, this);
20735
this.doAnchor = function(){
20736
this.alignTo(el, alignment, offsets);
20738
Ext.EventManager.onWindowResize(this.doAnchor, this);
20740
var tm = typeof monitorScroll;
20741
if(tm != 'undefined'){
20742
Ext.EventManager.on(window, 'scroll', this.doAnchor, this,
20743
{buffer: tm == 'number' ? monitorScroll : 50});
20750
toFront : function(e){
20751
if(this.manager.bringToFront(this)){
20752
if(!e || !e.getTarget().focus){
20760
setActive : function(active){
20762
if(!this.maximized){
20763
this.el.enableShadow(true);
20765
this.fireEvent('activate', this);
20767
this.el.disableShadow();
20768
this.fireEvent('deactivate', this);
20773
toBack : function(){
20774
this.manager.sendToBack(this);
20779
center : function(){
20780
var xy = this.el.getAlignToXY(this.container, 'c-c');
20781
this.setPagePosition(xy[0], xy[1]);
20787
Ext.reg('window', Ext.Window);
20789
// private - custom Window DD implementation
20790
Ext.Window.DD = function(win){
20792
Ext.Window.DD.superclass.constructor.call(this, win.el.id, 'WindowDD-'+win.id);
20793
this.setHandleElId(win.header.id);
20794
this.scroll = false;
20797
Ext.extend(Ext.Window.DD, Ext.dd.DD, {
20799
headerOffsets:[100, 25],
20800
startDrag : function(){
20802
this.proxy = w.ghost();
20803
if(w.constrain !== false){
20804
var so = w.el.shadowOffset;
20805
this.constrainTo(w.container, {right: so, left: so, bottom: so});
20806
}else if(w.constrainHeader !== false){
20807
var s = this.proxy.getSize();
20808
this.constrainTo(w.container, {right: -(s.width-this.headerOffsets[0]), bottom: -(s.height-this.headerOffsets[1])});
20811
b4Drag : Ext.emptyFn,
20813
onDrag : function(e){
20814
this.alignElWithMouse(this.proxy, e.getPageX(), e.getPageY());
20817
endDrag : function(e){
20818
this.win.unghost();
20819
this.win.saveState();
20824
Ext.WindowGroup = function(){
20826
var accessList = [];
20830
var sortWindows = function(d1, d2){
20831
return (!d1._lastAccess || d1._lastAccess < d2._lastAccess) ? -1 : 1;
20835
var orderWindows = function(){
20836
var a = accessList, len = a.length;
20838
a.sort(sortWindows);
20839
var seed = a[0].manager.zseed;
20840
for(var i = 0; i < len; i++){
20842
if(win && !win.hidden){
20843
win.setZIndex(seed + (i*10));
20851
var setActiveWin = function(win){
20854
front.setActive(false);
20858
win.setActive(true);
20864
var activateLast = function(){
20865
for(var i = accessList.length-1; i >=0; --i) {
20866
if(!accessList[i].hidden){
20867
setActiveWin(accessList[i]);
20871
// none to activate
20872
setActiveWin(null);
20880
register : function(win){
20881
list[win.id] = win;
20882
accessList.push(win);
20883
win.on('hide', activateLast);
20887
unregister : function(win){
20888
delete list[win.id];
20889
win.un('hide', activateLast);
20890
accessList.remove(win);
20894
get : function(id){
20895
return typeof id == "object" ? id : list[id];
20899
bringToFront : function(win){
20900
win = this.get(win);
20902
win._lastAccess = new Date().getTime();
20910
sendToBack : function(win){
20911
win = this.get(win);
20912
win._lastAccess = -(new Date().getTime());
20918
hideAll : function(){
20919
for(var id in list){
20920
if(list[id] && typeof list[id] != "function" && list[id].isVisible()){
20927
getActive : function(){
20932
getBy : function(fn, scope){
20934
for(var i = accessList.length-1; i >=0; --i) {
20935
var win = accessList[i];
20936
if(fn.call(scope||win, win) !== false){
20944
each : function(fn, scope){
20945
for(var id in list){
20946
if(list[id] && typeof list[id] != "function"){
20947
if(fn.call(scope || list[id], list[id]) === false){
20958
Ext.WindowMgr = new Ext.WindowGroup();
20960
Ext.dd.PanelProxy = function(panel, config){
20961
this.panel = panel;
20962
this.id = this.panel.id +'-ddproxy';
20963
Ext.apply(this, config);
20966
Ext.dd.PanelProxy.prototype = {
20968
insertProxy : true,
20970
// private overrides
20971
setStatus : Ext.emptyFn,
20972
reset : Ext.emptyFn,
20973
update : Ext.emptyFn,
20974
stop : Ext.emptyFn,
20978
getEl : function(){
20983
getGhost : function(){
20988
getProxy : function(){
20996
this.proxy.remove();
20999
this.panel.el.dom.style.display = '';
21000
this.ghost.remove();
21008
this.ghost = this.panel.createGhost(undefined, undefined, Ext.getBody());
21009
this.ghost.setXY(this.panel.el.getXY())
21010
if(this.insertProxy){
21011
this.proxy = this.panel.el.insertSibling({cls:'x-panel-dd-spacer'});
21012
this.proxy.setSize(this.panel.getSize());
21014
this.panel.el.dom.style.display = 'none';
21019
repair : function(xy, callback, scope){
21021
if(typeof callback == "function"){
21022
callback.call(scope || this);
21027
moveProxy : function(parentNode, before){
21029
parentNode.insertBefore(this.proxy.dom, before);
21034
// private - DD implementation for Panels
21035
Ext.Panel.DD = function(panel, cfg){
21036
this.panel = panel;
21037
this.dragData = {panel: panel};
21038
this.proxy = new Ext.dd.PanelProxy(panel, cfg);
21039
Ext.Panel.DD.superclass.constructor.call(this, panel.el, cfg);
21040
var h = panel.header;
21042
this.setHandleElId(h.id);
21044
(h ? h : this.panel.body).setStyle('cursor', 'move');
21045
this.scroll = false;
21048
Ext.extend(Ext.Panel.DD, Ext.dd.DragSource, {
21049
showFrame: Ext.emptyFn,
21050
startDrag: Ext.emptyFn,
21051
b4StartDrag: function(x, y) {
21054
b4MouseDown: function(e) {
21055
var x = e.getPageX();
21056
var y = e.getPageY();
21057
this.autoOffset(x, y);
21059
onInitDrag : function(x, y){
21060
this.onStartDrag(x, y);
21063
createFrame : Ext.emptyFn,
21064
getDragEl : function(e){
21065
return this.proxy.ghost.dom;
21067
endDrag : function(e){
21069
this.panel.saveState();
21072
autoOffset : function(x, y) {
21073
x -= this.startPageX;
21074
y -= this.startPageY;
21075
this.setDelta(x, y);
21079
Ext.state.Provider = function(){
21081
this.addEvents("statechange");
21083
Ext.state.Provider.superclass.constructor.call(this);
21085
Ext.extend(Ext.state.Provider, Ext.util.Observable, {
21087
get : function(name, defaultValue){
21088
return typeof this.state[name] == "undefined" ?
21089
defaultValue : this.state[name];
21093
clear : function(name){
21094
delete this.state[name];
21095
this.fireEvent("statechange", this, name, null);
21099
set : function(name, value){
21100
this.state[name] = value;
21101
this.fireEvent("statechange", this, name, value);
21105
decodeValue : function(cookie){
21106
var re = /^(a|n|d|b|s|o)\:(.*)$/;
21107
var matches = re.exec(unescape(cookie));
21108
if(!matches || !matches[1]) return; // non state cookie
21109
var type = matches[1];
21110
var v = matches[2];
21113
return parseFloat(v);
21115
return new Date(Date.parse(v));
21120
var values = v.split("^");
21121
for(var i = 0, len = values.length; i < len; i++){
21122
all.push(this.decodeValue(values[i]));
21127
var values = v.split("^");
21128
for(var i = 0, len = values.length; i < len; i++){
21129
var kv = values[i].split("=");
21130
all[kv[0]] = this.decodeValue(kv[1]);
21139
encodeValue : function(v){
21141
if(typeof v == "number"){
21143
}else if(typeof v == "boolean"){
21144
enc = "b:" + (v ? "1" : "0");
21145
}else if(Ext.isDate(v)){
21146
enc = "d:" + v.toGMTString();
21147
}else if(Ext.isArray(v)){
21149
for(var i = 0, len = v.length; i < len; i++){
21150
flat += this.encodeValue(v[i]);
21151
if(i != len-1) flat += "^";
21154
}else if(typeof v == "object"){
21157
if(typeof v[key] != "function" && v[key] !== undefined){
21158
flat += key + "=" + this.encodeValue(v[key]) + "^";
21161
enc = "o:" + flat.substring(0, flat.length-1);
21165
return escape(enc);
21170
Ext.state.Manager = function(){
21171
var provider = new Ext.state.Provider();
21175
setProvider : function(stateProvider){
21176
provider = stateProvider;
21180
get : function(key, defaultValue){
21181
return provider.get(key, defaultValue);
21185
set : function(key, value){
21186
provider.set(key, value);
21190
clear : function(key){
21191
provider.clear(key);
21195
getProvider : function(){
21202
Ext.state.CookieProvider = function(config){
21203
Ext.state.CookieProvider.superclass.constructor.call(this);
21205
this.expires = new Date(new Date().getTime()+(1000*60*60*24*7)); //7 days
21206
this.domain = null;
21207
this.secure = false;
21208
Ext.apply(this, config);
21209
this.state = this.readCookies();
21212
Ext.extend(Ext.state.CookieProvider, Ext.state.Provider, {
21214
set : function(name, value){
21215
if(typeof value == "undefined" || value === null){
21219
this.setCookie(name, value);
21220
Ext.state.CookieProvider.superclass.set.call(this, name, value);
21224
clear : function(name){
21225
this.clearCookie(name);
21226
Ext.state.CookieProvider.superclass.clear.call(this, name);
21230
readCookies : function(){
21232
var c = document.cookie + ";";
21233
var re = /\s?(.*?)=(.*?);/g;
21235
while((matches = re.exec(c)) != null){
21236
var name = matches[1];
21237
var value = matches[2];
21238
if(name && name.substring(0,3) == "ys-"){
21239
cookies[name.substr(3)] = this.decodeValue(value);
21246
setCookie : function(name, value){
21247
document.cookie = "ys-"+ name + "=" + this.encodeValue(value) +
21248
((this.expires == null) ? "" : ("; expires=" + this.expires.toGMTString())) +
21249
((this.path == null) ? "" : ("; path=" + this.path)) +
21250
((this.domain == null) ? "" : ("; domain=" + this.domain)) +
21251
((this.secure == true) ? "; secure" : "");
21255
clearCookie : function(name){
21256
document.cookie = "ys-" + name + "=null; expires=Thu, 01-Jan-70 00:00:01 GMT" +
21257
((this.path == null) ? "" : ("; path=" + this.path)) +
21258
((this.domain == null) ? "" : ("; domain=" + this.domain)) +
21259
((this.secure == true) ? "; secure" : "");
21263
Ext.DataView = Ext.extend(Ext.BoxComponent, {
21273
selectedClass : "x-view-selected",
21278
deferEmptyText: true,
21286
initComponent : function(){
21287
Ext.DataView.superclass.initComponent.call(this);
21288
if(typeof this.tpl == "string" || Ext.isArray(this.tpl)){
21289
this.tpl = new Ext.XTemplate(this.tpl);
21308
"containercontextmenu",
21316
this.all = new Ext.CompositeElementLite();
21317
this.selected = new Ext.CompositeElementLite();
21321
afterRender : function(){
21322
Ext.DataView.superclass.afterRender.call(this);
21324
this.mon(this.getTemplateTarget(), {
21325
"click": this.onClick,
21326
"dblclick": this.onDblClick,
21327
"contextmenu": this.onContextMenu,
21331
if(this.overClass || this.trackOver){
21332
this.mon(this.getTemplateTarget(), {
21333
"mouseover": this.onMouseOver,
21334
"mouseout": this.onMouseOut,
21340
this.bindStore(this.store, true);
21345
refresh : function(){
21346
this.clearSelections(false, true);
21347
var el = this.getTemplateTarget();
21349
var records = this.store.getRange();
21350
if(records.length < 1){
21351
if(!this.deferEmptyText || this.hasSkippedEmptyText){
21352
el.update(this.emptyText);
21356
this.tpl.overwrite(el, this.collectData(records, 0));
21357
this.all.fill(Ext.query(this.itemSelector, el.dom));
21358
this.updateIndexes(0);
21360
this.hasSkippedEmptyText = true;
21363
getTemplateTarget: function(){
21368
prepareData : function(data){
21373
collectData : function(records, startIndex){
21375
for(var i = 0, len = records.length; i < len; i++){
21376
r[r.length] = this.prepareData(records[i].data, startIndex+i, records[i]);
21382
bufferRender : function(records){
21383
var div = document.createElement('div');
21384
this.tpl.overwrite(div, this.collectData(records));
21385
return Ext.query(this.itemSelector, div);
21389
onUpdate : function(ds, record){
21390
var index = this.store.indexOf(record);
21391
var sel = this.isSelected(index);
21392
var original = this.all.elements[index];
21393
var node = this.bufferRender([record], index)[0];
21395
this.all.replaceElement(index, node, true);
21397
this.selected.replaceElement(original, node);
21398
this.all.item(index).addClass(this.selectedClass);
21400
this.updateIndexes(index, index);
21404
onAdd : function(ds, records, index){
21405
if(this.all.getCount() == 0){
21409
var nodes = this.bufferRender(records, index), n, a = this.all.elements;
21410
if(index < this.all.getCount()){
21411
n = this.all.item(index).insertSibling(nodes, 'before', true);
21412
a.splice.apply(a, [index, 0].concat(nodes));
21414
n = this.all.last().insertSibling(nodes, 'after', true);
21415
a.push.apply(a, nodes);
21417
this.updateIndexes(index);
21421
onRemove : function(ds, record, index){
21422
this.deselect(index);
21423
this.all.removeElement(index, true);
21424
this.updateIndexes(index);
21425
if (this.store.getCount() == 0){
21431
refreshNode : function(index){
21432
this.onUpdate(this.store, this.store.getAt(index));
21436
updateIndexes : function(startIndex, endIndex){
21437
var ns = this.all.elements;
21438
startIndex = startIndex || 0;
21439
endIndex = endIndex || ((endIndex === 0) ? 0 : (ns.length - 1));
21440
for(var i = startIndex; i <= endIndex; i++){
21441
ns[i].viewIndex = i;
21446
getStore : function(){
21451
bindStore : function(store, initial){
21452
if(!initial && this.store){
21453
this.store.un("beforeload", this.onBeforeLoad, this);
21454
this.store.un("datachanged", this.refresh, this);
21455
this.store.un("add", this.onAdd, this);
21456
this.store.un("remove", this.onRemove, this);
21457
this.store.un("update", this.onUpdate, this);
21458
this.store.un("clear", this.refresh, this);
21459
if(store !== this.store && this.store.autoDestroy){
21460
this.store.destroy();
21464
store = Ext.StoreMgr.lookup(store);
21467
beforeload: this.onBeforeLoad,
21468
datachanged: this.refresh,
21470
remove: this.onRemove,
21471
update: this.onUpdate,
21472
clear: this.refresh
21475
this.store = store;
21482
findItemFromChild : function(node){
21483
return Ext.fly(node).findParent(this.itemSelector, this.getTemplateTarget());
21487
onClick : function(e){
21488
var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
21490
var index = this.indexOf(item);
21491
if(this.onItemClick(item, index, e) !== false){
21492
this.fireEvent("click", this, index, item, e);
21495
if(this.fireEvent("containerclick", this, e) !== false){
21496
this.onContainerClick(e);
21501
onContainerClick : function(e){
21502
this.clearSelections();
21506
onContextMenu : function(e){
21507
var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
21509
this.fireEvent("contextmenu", this, this.indexOf(item), item, e);
21511
this.fireEvent("containercontextmenu", this, e)
21516
onDblClick : function(e){
21517
var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
21519
this.fireEvent("dblclick", this, this.indexOf(item), item, e);
21524
onMouseOver : function(e){
21525
var item = e.getTarget(this.itemSelector, this.getTemplateTarget());
21526
if(item && item !== this.lastItem){
21527
this.lastItem = item;
21528
Ext.fly(item).addClass(this.overClass);
21529
this.fireEvent("mouseenter", this, this.indexOf(item), item, e);
21534
onMouseOut : function(e){
21536
if(!e.within(this.lastItem, true, true)){
21537
Ext.fly(this.lastItem).removeClass(this.overClass);
21538
this.fireEvent("mouseleave", this, this.indexOf(this.lastItem), this.lastItem, e);
21539
delete this.lastItem;
21545
onItemClick : function(item, index, e){
21546
if(this.fireEvent("beforeclick", this, index, item, e) === false){
21549
if(this.multiSelect){
21550
this.doMultiSelection(item, index, e);
21551
e.preventDefault();
21552
}else if(this.singleSelect){
21553
this.doSingleSelection(item, index, e);
21554
e.preventDefault();
21560
doSingleSelection : function(item, index, e){
21561
if(e.ctrlKey && this.isSelected(index)){
21562
this.deselect(index);
21564
this.select(index, false);
21569
doMultiSelection : function(item, index, e){
21570
if(e.shiftKey && this.last !== false){
21571
var last = this.last;
21572
this.selectRange(last, index, e.ctrlKey);
21573
this.last = last; // reset the last
21575
if((e.ctrlKey||this.simpleSelect) && this.isSelected(index)){
21576
this.deselect(index);
21578
this.select(index, e.ctrlKey || e.shiftKey || this.simpleSelect);
21584
getSelectionCount : function(){
21585
return this.selected.getCount()
21589
getSelectedNodes : function(){
21590
return this.selected.elements;
21594
getSelectedIndexes : function(){
21595
var indexes = [], s = this.selected.elements;
21596
for(var i = 0, len = s.length; i < len; i++){
21597
indexes.push(s[i].viewIndex);
21603
getSelectedRecords : function(){
21604
var r = [], s = this.selected.elements;
21605
for(var i = 0, len = s.length; i < len; i++){
21606
r[r.length] = this.store.getAt(s[i].viewIndex);
21612
getRecords : function(nodes){
21613
var r = [], s = nodes;
21614
for(var i = 0, len = s.length; i < len; i++){
21615
r[r.length] = this.store.getAt(s[i].viewIndex);
21621
getRecord : function(node){
21622
return this.store.getAt(node.viewIndex);
21626
clearSelections : function(suppressEvent, skipUpdate){
21627
if((this.multiSelect || this.singleSelect) && this.selected.getCount() > 0){
21629
this.selected.removeClass(this.selectedClass);
21631
this.selected.clear();
21633
if(!suppressEvent){
21634
this.fireEvent("selectionchange", this, this.selected.elements);
21640
isSelected : function(node){
21641
return this.selected.contains(this.getNode(node));
21645
deselect : function(node){
21646
if(this.isSelected(node)){
21647
node = this.getNode(node);
21648
this.selected.removeElement(node);
21649
if(this.last == node.viewIndex){
21652
Ext.fly(node).removeClass(this.selectedClass);
21653
this.fireEvent("selectionchange", this, this.selected.elements);
21658
select : function(nodeInfo, keepExisting, suppressEvent){
21659
if(Ext.isArray(nodeInfo)){
21661
this.clearSelections(true);
21663
for(var i = 0, len = nodeInfo.length; i < len; i++){
21664
this.select(nodeInfo[i], true, true);
21666
if(!suppressEvent){
21667
this.fireEvent("selectionchange", this, this.selected.elements);
21670
var node = this.getNode(nodeInfo);
21672
this.clearSelections(true);
21674
if(node && !this.isSelected(node)){
21675
if(this.fireEvent("beforeselect", this, node, this.selected.elements) !== false){
21676
Ext.fly(node).addClass(this.selectedClass);
21677
this.selected.add(node);
21678
this.last = node.viewIndex;
21679
if(!suppressEvent){
21680
this.fireEvent("selectionchange", this, this.selected.elements);
21688
selectRange : function(start, end, keepExisting){
21690
this.clearSelections(true);
21692
this.select(this.getNodes(start, end), true);
21696
getNode : function(nodeInfo){
21697
if(typeof nodeInfo == "string"){
21698
return document.getElementById(nodeInfo);
21699
}else if(typeof nodeInfo == "number"){
21700
return this.all.elements[nodeInfo];
21706
getNodes : function(start, end){
21707
var ns = this.all.elements;
21708
start = start || 0;
21709
end = typeof end == "undefined" ? Math.max(ns.length - 1, 0) : end;
21712
for(i = start; i <= end && ns[i]; i++){
21716
for(i = start; i >= end && ns[i]; i--){
21724
indexOf : function(node){
21725
node = this.getNode(node);
21726
if(typeof node.viewIndex == "number"){
21727
return node.viewIndex;
21729
return this.all.indexOf(node);
21733
onBeforeLoad : function(){
21734
if(this.loadingText){
21735
this.clearSelections(false, true);
21736
this.getTemplateTarget().update('<div class="loading-indicator">'+this.loadingText+'</div>');
21741
onDestroy : function(){
21742
Ext.DataView.superclass.onDestroy.call(this);
21743
this.bindStore(null);
21748
Ext.DataView.prototype.setStore = Ext.DataView.prototype.bindStore;
21750
Ext.reg('dataview', Ext.DataView);
21752
Ext.ListView = Ext.extend(Ext.DataView, {
21756
itemSelector: 'dl',
21758
selectedClass:'x-list-selected',
21760
overClass:'x-list-over',
21765
columnResize: true,
21771
initComponent : function(){
21772
if(this.columnResize){
21773
this.colResizer = new Ext.ListView.ColumnResizer(this.colResizer);
21774
this.colResizer.init(this);
21776
if(this.columnSort){
21777
this.colSorter = new Ext.ListView.Sorter(this.columnSort);
21778
this.colSorter.init(this);
21780
if(!this.internalTpl){
21781
this.internalTpl = new Ext.XTemplate(
21782
'<div class="x-list-header"><div class="x-list-header-inner">',
21783
'<tpl for="columns">',
21784
'<div style="width:{width}%;text-align:{align};"><em unselectable="on" id="',this.id, '-xlhd-{#}">',
21788
'<div class="x-clear"></div>',
21790
'<div class="x-list-body"><div class="x-list-body-inner">',
21795
this.tpl = new Ext.XTemplate(
21796
'<tpl for="rows">',
21798
'<tpl for="parent.columns">',
21799
'<dt style="width:{width}%;text-align:{align};"><em unselectable="on">',
21800
'{[values.tpl.apply(parent)]}',
21803
'<div class="x-clear"></div>',
21808
var cs = this.columns, allocatedWidth = 0, colsWithWidth = 0, len = cs.length;
21809
for(var i = 0; i < len; i++){
21812
c.tpl = new Ext.XTemplate('{' + c.dataIndex + '}');
21813
}else if(typeof c.tpl == 'string'){
21814
c.tpl = new Ext.XTemplate(c.tpl);
21816
c.align = c.align || 'left';
21817
if(typeof c.width == 'number'){
21819
allocatedWidth += c.width;
21823
// auto calculate missing column widths
21824
if(colsWithWidth < len){
21825
var remaining = len - colsWithWidth;
21826
if(allocatedWidth < 100){
21827
var perCol = ((100-allocatedWidth) / remaining);
21828
for(var j = 0; j < len; j++){
21830
if(typeof c.width != 'number'){
21836
Ext.ListView.superclass.initComponent.call(this);
21839
onRender : function(){
21840
Ext.ListView.superclass.onRender.apply(this, arguments);
21842
this.internalTpl.overwrite(this.el, {columns: this.columns});
21844
this.innerBody = Ext.get(this.el.dom.childNodes[1].firstChild);
21845
this.innerHd = Ext.get(this.el.dom.firstChild.firstChild);
21847
if(this.hideHeaders){
21848
this.el.dom.firstChild.style.display = 'none';
21852
getTemplateTarget : function(){
21853
return this.innerBody;
21857
collectData : function(){
21858
var rs = Ext.ListView.superclass.collectData.apply(this, arguments);
21860
columns: this.columns,
21865
verifyInternalSize : function(){
21867
this.onResize(this.lastSize.width, this.lastSize.height);
21872
onResize : function(w, h){
21873
var bd = this.innerBody.dom;
21874
var hd = this.innerHd.dom
21878
var bdp = bd.parentNode;
21879
if(typeof w == 'number'){
21880
var sw = w - this.scrollOffset;
21881
if(this.reserveScrollOffset || ((bdp.offsetWidth - bdp.clientWidth) > 10)){
21882
bd.style.width = sw + 'px';
21883
hd.style.width = sw + 'px';
21885
bd.style.width = w + 'px';
21886
hd.style.width = w + 'px';
21887
setTimeout(function(){
21888
if((bdp.offsetWidth - bdp.clientWidth) > 10){
21889
bd.style.width = sw + 'px';
21890
hd.style.width = sw + 'px';
21895
if(typeof h == 'number'){
21896
bdp.style.height = (h - hd.parentNode.offsetHeight) + 'px';
21900
updateIndexes : function(){
21901
Ext.ListView.superclass.updateIndexes.apply(this, arguments);
21902
this.verifyInternalSize();
21905
findHeaderIndex : function(hd){
21907
var pn = hd.parentNode, cs = pn.parentNode.childNodes;
21908
for(var i = 0, c; c = cs[i]; i++){
21916
setHdWidths : function(){
21917
var els = this.innerHd.dom.getElementsByTagName('div');
21918
for(var i = 0, cs = this.columns, len = cs.length; i < len; i++){
21919
els[i].style.width = cs[i].width + '%';
21924
Ext.reg('listview', Ext.ListView);
21926
Ext.ListView.ColumnResizer = Ext.extend(Ext.util.Observable, {
21930
constructor: function(config){
21931
Ext.apply(this, config);
21932
Ext.ListView.ColumnResizer.superclass.constructor.call(this);
21934
init : function(listView){
21935
this.view = listView;
21936
listView.on('render', this.initEvents, this);
21939
initEvents : function(view){
21940
view.mon(view.innerHd, 'mousemove', this.handleHdMove, this);
21941
this.tracker = new Ext.dd.DragTracker({
21942
onBeforeStart: this.onBeforeStart.createDelegate(this),
21943
onStart: this.onStart.createDelegate(this),
21944
onDrag: this.onDrag.createDelegate(this),
21945
onEnd: this.onEnd.createDelegate(this),
21949
this.tracker.initEl(view.innerHd);
21950
view.on('beforedestroy', this.tracker.destroy, this.tracker);
21953
handleHdMove : function(e, t){
21955
var x = e.getPageX();
21956
var hd = e.getTarget('em', 3, true);
21958
var r = hd.getRegion();
21959
var ss = hd.dom.style;
21960
var pn = hd.dom.parentNode;
21962
if(x - r.left <= hw && pn != pn.parentNode.firstChild){
21963
this.activeHd = Ext.get(pn.previousSibling.firstChild);
21964
ss.cursor = Ext.isWebKit ? 'e-resize' : 'col-resize';
21965
} else if(r.right - x <= hw && pn != pn.parentNode.lastChild.previousSibling){
21966
this.activeHd = hd;
21967
ss.cursor = Ext.isWebKit ? 'w-resize' : 'col-resize';
21969
delete this.activeHd;
21975
onBeforeStart : function(e){
21976
this.dragHd = this.activeHd;
21977
return !!this.dragHd;
21980
onStart: function(e){
21981
this.view.disableHeaders = true;
21982
this.proxy = this.view.el.createChild({cls:'x-list-resizer'});
21983
this.proxy.setHeight(this.view.el.getHeight());
21985
var x = this.tracker.getXY()[0];
21986
var w = this.view.innerHd.getWidth();
21988
this.hdX = this.dragHd.getX();
21989
this.hdIndex = this.view.findHeaderIndex(this.dragHd);
21991
this.proxy.setX(this.hdX);
21992
this.proxy.setWidth(x-this.hdX);
21994
this.minWidth = w*this.minPct;
21995
this.maxWidth = w - (this.minWidth*(this.view.columns.length-1-this.hdIndex));
21998
onDrag: function(e){
21999
var cursorX = this.tracker.getXY()[0];
22000
this.proxy.setWidth((cursorX-this.hdX).constrain(this.minWidth, this.maxWidth));
22003
onEnd: function(e){
22004
var nw = this.proxy.getWidth();
22005
this.proxy.remove();
22007
var index = this.hdIndex;
22008
var vw = this.view, cs = vw.columns, len = cs.length;
22009
var w = this.view.innerHd.getWidth(), minPct = this.minPct * 100;
22011
var pct = Math.ceil((nw*100) / w);
22012
var diff = cs[index].width - pct;
22013
var each = Math.floor(diff / (len-1-index));
22014
var mod = diff - (each * (len-1-index));
22016
for(var i = index+1; i < len; i++){
22017
var cw = cs[i].width + each;
22018
var ncw = Math.max(minPct, cw);
22024
cs[index].width = pct;
22025
cs[index+1].width += mod;
22026
delete this.dragHd;
22027
this.view.setHdWidths();
22028
this.view.refresh();
22029
setTimeout(function(){
22030
vw.disableHeaders = false;
22035
Ext.ListView.Sorter = Ext.extend(Ext.util.Observable, {
22037
sortClasses : ["sort-asc", "sort-desc"],
22039
constructor: function(config){
22040
Ext.apply(this, config);
22041
Ext.ListView.Sorter.superclass.constructor.call(this);
22044
init : function(listView){
22045
this.view = listView;
22046
listView.on('render', this.initEvents, this);
22049
initEvents : function(view){
22050
view.mon(view.innerHd, 'click', this.onHdClick, this);
22051
view.innerHd.setStyle('cursor', 'pointer');
22052
view.mon(view.store, 'datachanged', this.updateSortState, this);
22053
this.updateSortState.defer(10, this, [view.store]);
22056
updateSortState : function(store){
22057
var state = store.getSortState();
22061
this.sortState = state;
22062
var cs = this.view.columns, sortColumn = -1;
22063
for(var i = 0, len = cs.length; i < len; i++){
22064
if(cs[i].dataIndex == state.field){
22069
if(sortColumn != -1){
22070
var sortDir = state.direction;
22071
this.updateSortIcon(sortColumn, sortDir);
22075
updateSortIcon : function(col, dir){
22076
var sc = this.sortClasses;
22077
var hds = this.view.innerHd.select('em').removeClass(sc);
22078
hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
22081
onHdClick : function(e){
22082
var hd = e.getTarget('em', 3);
22083
if(hd && !this.view.disableHeaders){
22084
var index = this.view.findHeaderIndex(hd);
22085
this.view.store.sort(this.view.columns[index].dataIndex);
22090
Ext.ColorPalette = function(config){
22091
Ext.ColorPalette.superclass.constructor.call(this, config);
22098
this.on("select", this.handler, this.scope, true);
22101
Ext.extend(Ext.ColorPalette, Ext.Component, {
22104
itemCls : "x-color-palette",
22107
clickEvent:'click',
22109
ctype: "Ext.ColorPalette",
22112
allowReselect : false,
22116
"000000", "993300", "333300", "003300", "003366", "000080", "333399", "333333",
22117
"800000", "FF6600", "808000", "008000", "008080", "0000FF", "666699", "808080",
22118
"FF0000", "FF9900", "99CC00", "339966", "33CCCC", "3366FF", "800080", "969696",
22119
"FF00FF", "FFCC00", "FFFF00", "00FF00", "00FFFF", "00CCFF", "993366", "C0C0C0",
22120
"FF99CC", "FFCC99", "FFFF99", "CCFFCC", "CCFFFF", "99CCFF", "CC99FF", "FFFFFF"
22124
onRender : function(container, position){
22125
var t = this.tpl || new Ext.XTemplate(
22126
'<tpl for="."><a href="#" class="color-{.}" hidefocus="on"><em><span style="background:#{.}" unselectable="on"> </span></em></a></tpl>'
22128
var el = document.createElement("div");
22129
el.id = this.getId();
22130
el.className = this.itemCls;
22131
t.overwrite(el, this.colors);
22132
container.dom.insertBefore(el, position);
22133
this.el = Ext.get(el);
22134
this.mon(this.el, this.clickEvent, this.handleClick, this, {delegate: 'a'});
22135
if(this.clickEvent != 'click'){
22136
this.mon(this.el, 'click', Ext.emptyFn, this, {delegate: 'a', preventDefault: true});
22141
afterRender : function(){
22142
Ext.ColorPalette.superclass.afterRender.call(this);
22144
var s = this.value;
22151
handleClick : function(e, t){
22152
e.preventDefault();
22153
if(!this.disabled){
22154
var c = t.className.match(/(?:^|\s)color-(.{6})(?:\s|$)/)[1];
22155
this.select(c.toUpperCase());
22160
select : function(color){
22161
color = color.replace("#", "");
22162
if(color != this.value || this.allowReselect){
22165
el.child("a.color-"+this.value).removeClass("x-color-palette-sel");
22167
el.child("a.color-"+color).addClass("x-color-palette-sel");
22168
this.value = color;
22169
this.fireEvent("select", this, color);
22175
Ext.reg('colorpalette', Ext.ColorPalette);
22177
Ext.DatePicker = Ext.extend(Ext.BoxComponent, {
22179
todayText : "Today",
22181
okText : " OK ", //   to give the user extra clicking room
22183
cancelText : "Cancel",
22185
todayTip : "{0} (Spacebar)",
22187
minText : "This date is before the minimum date",
22189
maxText : "This date is after the maximum date",
22193
disabledDaysText : "Disabled",
22195
disabledDatesText : "Disabled",
22197
monthNames : Date.monthNames,
22199
dayNames : Date.dayNames,
22201
nextText: 'Next Month (Control+Right)',
22203
prevText: 'Previous Month (Control+Left)',
22205
monthYearText: 'Choose a month (Control+Up/Down to move years)',
22217
initComponent : function(){
22218
Ext.DatePicker.superclass.initComponent.call(this);
22220
this.value = this.value ?
22221
this.value.clearTime() : new Date().clearTime();
22229
this.on("select", this.handler, this.scope || this);
22232
this.initDisabledDays();
22236
initDisabledDays : function(){
22237
if(!this.disabledDatesRE && this.disabledDates){
22238
var dd = this.disabledDates;
22240
for(var i = 0; i < dd.length; i++){
22242
if(i != dd.length-1) re += "|";
22244
this.disabledDatesRE = new RegExp(re + ")");
22249
setDisabledDates : function(dd){
22250
if(Ext.isArray(dd)){
22251
this.disabledDates = dd;
22252
this.disabledDatesRE = null;
22254
this.disabledDatesRE = dd;
22256
this.initDisabledDays();
22257
this.update(this.value, true);
22261
setDisabledDays : function(dd){
22262
this.disabledDays = dd;
22263
this.update(this.value, true);
22267
setMinDate : function(dt){
22269
this.update(this.value, true);
22273
setMaxDate : function(dt){
22275
this.update(this.value, true);
22279
setValue : function(value){
22280
var old = this.value;
22281
this.value = value.clearTime(true);
22283
this.update(this.value);
22288
getValue : function(){
22293
focus : function(){
22295
this.update(this.activeDate);
22300
onRender : function(container, position){
22302
'<table cellspacing="0">',
22303
'<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>',
22304
'<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'];
22305
var dn = this.dayNames;
22306
for(var i = 0; i < 7; i++){
22307
var d = this.startDay+i;
22311
m.push("<th><span>", dn[d].substr(0,1), "</span></th>");
22313
m[m.length] = "</tr></thead><tbody><tr>";
22314
for(var i = 0; i < 42; i++) {
22315
if(i % 7 == 0 && i != 0){
22316
m[m.length] = "</tr><tr>";
22318
m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
22320
m.push('</tr></tbody></table></td></tr>',
22321
this.showToday ? '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>' : '',
22322
'</table><div class="x-date-mp"></div>');
22324
var el = document.createElement("div");
22325
el.className = "x-date-picker";
22326
el.innerHTML = m.join("");
22328
container.dom.insertBefore(el, position);
22330
this.el = Ext.get(el);
22331
this.eventEl = Ext.get(el.firstChild);
22333
new Ext.util.ClickRepeater(this.el.child("td.x-date-left a"), {
22334
handler: this.showPrevMonth,
22336
preventDefault:true,
22340
new Ext.util.ClickRepeater(this.el.child("td.x-date-right a"), {
22341
handler: this.showNextMonth,
22343
preventDefault:true,
22347
this.mon(this.eventEl, "mousewheel", this.handleMouseWheel, this);
22349
this.monthPicker = this.el.down('div.x-date-mp');
22350
this.monthPicker.enableDisplayMode('block');
22352
var kn = new Ext.KeyNav(this.eventEl, {
22353
"left" : function(e){
22355
this.showPrevMonth() :
22356
this.update(this.activeDate.add("d", -1));
22359
"right" : function(e){
22361
this.showNextMonth() :
22362
this.update(this.activeDate.add("d", 1));
22365
"up" : function(e){
22367
this.showNextYear() :
22368
this.update(this.activeDate.add("d", -7));
22371
"down" : function(e){
22373
this.showPrevYear() :
22374
this.update(this.activeDate.add("d", 7));
22377
"pageUp" : function(e){
22378
this.showNextMonth();
22381
"pageDown" : function(e){
22382
this.showPrevMonth();
22385
"enter" : function(e){
22386
e.stopPropagation();
22393
this.mon(this.eventEl, "click", this.handleDateClick, this, {delegate: "a.x-date-date"});
22395
this.el.unselectable();
22397
this.cells = this.el.select("table.x-date-inner tbody td");
22398
this.textNodes = this.el.query("table.x-date-inner tbody span");
22400
this.mbtn = new Ext.Button({
22402
tooltip: this.monthYearText,
22403
renderTo: this.el.child("td.x-date-middle", true)
22406
this.mon(this.mbtn, 'click', this.showMonthPicker, this);
22407
this.mbtn.el.child('em').addClass("x-btn-arrow");
22409
if(this.showToday){
22410
this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, this);
22411
var today = (new Date()).dateFormat(this.format);
22412
this.todayBtn = new Ext.Button({
22413
renderTo: this.el.child("td.x-date-bottom", true),
22414
text: String.format(this.todayText, today),
22415
tooltip: String.format(this.todayTip, today),
22416
handler: this.selectToday,
22424
this.update(this.value);
22428
createMonthPicker : function(){
22429
if(!this.monthPicker.dom.firstChild){
22430
var buf = ['<table border="0" cellspacing="0">'];
22431
for(var i = 0; i < 6; i++){
22433
'<tr><td class="x-date-mp-month"><a href="#">', this.monthNames[i].substr(0, 3), '</a></td>',
22434
'<td class="x-date-mp-month x-date-mp-sep"><a href="#">', this.monthNames[i+6].substr(0, 3), '</a></td>',
22436
'<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>' :
22437
'<td class="x-date-mp-year"><a href="#"></a></td><td class="x-date-mp-year"><a href="#"></a></td></tr>'
22441
'<tr class="x-date-mp-btns"><td colspan="4"><button type="button" class="x-date-mp-ok">',
22443
'</button><button type="button" class="x-date-mp-cancel">',
22445
'</button></td></tr>',
22448
this.monthPicker.update(buf.join(''));
22450
this.mon(this.monthPicker, 'click', this.onMonthClick, this);
22451
this.mon(this.monthPicker, 'dblclick', this.onMonthDblClick, this);
22453
this.mpMonths = this.monthPicker.select('td.x-date-mp-month');
22454
this.mpYears = this.monthPicker.select('td.x-date-mp-year');
22456
this.mpMonths.each(function(m, a, i){
22459
m.dom.xmonth = 5 + Math.round(i * .5);
22461
m.dom.xmonth = Math.round((i-1) * .5);
22468
showMonthPicker : function(){
22469
this.createMonthPicker();
22470
var size = this.el.getSize();
22471
this.monthPicker.setSize(size);
22472
this.monthPicker.child('table').setSize(size);
22474
this.mpSelMonth = (this.activeDate || this.value).getMonth();
22475
this.updateMPMonth(this.mpSelMonth);
22476
this.mpSelYear = (this.activeDate || this.value).getFullYear();
22477
this.updateMPYear(this.mpSelYear);
22479
this.monthPicker.slideIn('t', {duration:.2});
22483
updateMPYear : function(y){
22485
var ys = this.mpYears.elements;
22486
for(var i = 1; i <= 10; i++){
22487
var td = ys[i-1], y2;
22489
y2 = y + Math.round(i * .5);
22490
td.firstChild.innerHTML = y2;
22493
y2 = y - (5-Math.round(i * .5));
22494
td.firstChild.innerHTML = y2;
22497
this.mpYears.item(i-1)[y2 == this.mpSelYear ? 'addClass' : 'removeClass']('x-date-mp-sel');
22502
updateMPMonth : function(sm){
22503
this.mpMonths.each(function(m, a, i){
22504
m[m.dom.xmonth == sm ? 'addClass' : 'removeClass']('x-date-mp-sel');
22509
selectMPMonth: function(m){
22514
onMonthClick : function(e, t){
22516
var el = new Ext.Element(t), pn;
22517
if(el.is('button.x-date-mp-cancel')){
22518
this.hideMonthPicker();
22520
else if(el.is('button.x-date-mp-ok')){
22521
var d = new Date(this.mpSelYear, this.mpSelMonth, (this.activeDate || this.value).getDate());
22522
if(d.getMonth() != this.mpSelMonth){
22523
// "fix" the JS rolling date conversion if needed
22524
d = new Date(this.mpSelYear, this.mpSelMonth, 1).getLastDateOfMonth();
22527
this.hideMonthPicker();
22529
else if(pn = el.up('td.x-date-mp-month', 2)){
22530
this.mpMonths.removeClass('x-date-mp-sel');
22531
pn.addClass('x-date-mp-sel');
22532
this.mpSelMonth = pn.dom.xmonth;
22534
else if(pn = el.up('td.x-date-mp-year', 2)){
22535
this.mpYears.removeClass('x-date-mp-sel');
22536
pn.addClass('x-date-mp-sel');
22537
this.mpSelYear = pn.dom.xyear;
22539
else if(el.is('a.x-date-mp-prev')){
22540
this.updateMPYear(this.mpyear-10);
22542
else if(el.is('a.x-date-mp-next')){
22543
this.updateMPYear(this.mpyear+10);
22548
onMonthDblClick : function(e, t){
22550
var el = new Ext.Element(t), pn;
22551
if(pn = el.up('td.x-date-mp-month', 2)){
22552
this.update(new Date(this.mpSelYear, pn.dom.xmonth, (this.activeDate || this.value).getDate()));
22553
this.hideMonthPicker();
22555
else if(pn = el.up('td.x-date-mp-year', 2)){
22556
this.update(new Date(pn.dom.xyear, this.mpSelMonth, (this.activeDate || this.value).getDate()));
22557
this.hideMonthPicker();
22562
hideMonthPicker : function(disableAnim){
22563
if(this.monthPicker){
22564
if(disableAnim === true){
22565
this.monthPicker.hide();
22567
this.monthPicker.slideOut('t', {duration:.2});
22573
showPrevMonth : function(e){
22574
this.update(this.activeDate.add("mo", -1));
22578
showNextMonth : function(e){
22579
this.update(this.activeDate.add("mo", 1));
22583
showPrevYear : function(){
22584
this.update(this.activeDate.add("y", -1));
22588
showNextYear : function(){
22589
this.update(this.activeDate.add("y", 1));
22593
handleMouseWheel : function(e){
22594
var delta = e.getWheelDelta();
22596
this.showPrevMonth();
22598
} else if(delta < 0){
22599
this.showNextMonth();
22605
handleDateClick : function(e, t){
22607
if(t.dateValue && !Ext.fly(t.parentNode).hasClass("x-date-disabled")){
22608
this.setValue(new Date(t.dateValue));
22609
this.fireEvent("select", this, this.value);
22614
selectToday : function(){
22615
if(this.todayBtn && !this.todayBtn.disabled){
22616
this.setValue(new Date().clearTime());
22617
this.fireEvent("select", this, this.value);
22622
update : function(date, forceRefresh){
22623
var vd = this.activeDate, vis = this.isVisible();
22624
this.activeDate = date;
22625
if(!forceRefresh && vd && this.el){
22626
var t = date.getTime();
22627
if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
22628
this.cells.removeClass("x-date-selected");
22629
this.cells.each(function(c){
22630
if(c.dom.firstChild.dateValue == t){
22631
c.addClass("x-date-selected");
22633
Ext.fly(c.dom.firstChild).focus(50);
22641
var days = date.getDaysInMonth();
22642
var firstOfMonth = date.getFirstDateOfMonth();
22643
var startingPos = firstOfMonth.getDay()-this.startDay;
22645
if(startingPos <= this.startDay){
22649
var pm = date.add("mo", -1);
22650
var prevStart = pm.getDaysInMonth()-startingPos;
22652
var cells = this.cells.elements;
22653
var textEls = this.textNodes;
22654
days += startingPos;
22656
// convert everything to numbers so it's fast
22657
var day = 86400000;
22658
var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
22659
var today = new Date().clearTime().getTime();
22660
var sel = date.clearTime().getTime();
22661
var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
22662
var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
22663
var ddMatch = this.disabledDatesRE;
22664
var ddText = this.disabledDatesText;
22665
var ddays = this.disabledDays ? this.disabledDays.join("") : false;
22666
var ddaysText = this.disabledDaysText;
22667
var format = this.format;
22669
if(this.showToday){
22670
var td = new Date().clearTime();
22671
var disable = (td < min || td > max ||
22672
(ddMatch && format && ddMatch.test(td.dateFormat(format))) ||
22673
(ddays && ddays.indexOf(td.getDay()) != -1));
22675
this.todayBtn.setDisabled(disable);
22676
this.todayKeyListener[disable ? 'disable' : 'enable']();
22679
var setCellClass = function(cal, cell){
22681
var t = d.getTime();
22682
cell.firstChild.dateValue = t;
22684
cell.className += " x-date-today";
22685
cell.title = cal.todayText;
22688
cell.className += " x-date-selected";
22690
Ext.fly(cell.firstChild).focus(50);
22695
cell.className = " x-date-disabled";
22696
cell.title = cal.minText;
22700
cell.className = " x-date-disabled";
22701
cell.title = cal.maxText;
22705
if(ddays.indexOf(d.getDay()) != -1){
22706
cell.title = ddaysText;
22707
cell.className = " x-date-disabled";
22710
if(ddMatch && format){
22711
var fvalue = d.dateFormat(format);
22712
if(ddMatch.test(fvalue)){
22713
cell.title = ddText.replace("%0", fvalue);
22714
cell.className = " x-date-disabled";
22720
for(; i < startingPos; i++) {
22721
textEls[i].innerHTML = (++prevStart);
22722
d.setDate(d.getDate()+1);
22723
cells[i].className = "x-date-prevday";
22724
setCellClass(this, cells[i]);
22726
for(; i < days; i++){
22727
var intDay = i - startingPos + 1;
22728
textEls[i].innerHTML = (intDay);
22729
d.setDate(d.getDate()+1);
22730
cells[i].className = "x-date-active";
22731
setCellClass(this, cells[i]);
22734
for(; i < 42; i++) {
22735
textEls[i].innerHTML = (++extraDays);
22736
d.setDate(d.getDate()+1);
22737
cells[i].className = "x-date-nextday";
22738
setCellClass(this, cells[i]);
22741
this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear());
22743
if(!this.internalRender){
22744
var main = this.el.dom.firstChild;
22745
var w = main.offsetWidth;
22746
this.el.setWidth(w + this.el.getBorderWidth("lr"));
22747
Ext.fly(main).setWidth(w);
22748
this.internalRender = true;
22749
// opera does not respect the auto grow header center column
22750
// then, after it gets a width opera refuses to recalculate
22751
// without a second pass
22752
if(Ext.isOpera && !this.secondPass){
22753
main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + "px";
22754
this.secondPass = true;
22755
this.update.defer(10, this, [date]);
22761
beforeDestroy : function() {
22765
this.rightClickRpt,
22776
Ext.reg('datepicker', Ext.DatePicker);
22778
Ext.TabPanel = Ext.extend(Ext.Panel, {
22782
monitorResize : true,
22784
deferredRender : true,
22790
resizeTabs : false,
22792
enableTabScroll : false,
22794
scrollIncrement : 0,
22796
scrollRepeatInterval : 400,
22798
scrollDuration : .35,
22802
tabPosition : 'top',
22804
baseCls : 'x-tab-panel',
22808
autoTabSelector : 'div.x-tab',
22816
wheelIncrement : 20,
22819
idDelimiter : '__',
22822
itemCls : 'x-tab-item',
22824
// private config overrides
22826
headerAsText : false,
22831
initComponent : function(){
22832
this.frame = false;
22833
Ext.TabPanel.superclass.initComponent.call(this);
22843
this.setLayout(new Ext.layout.CardLayout(Ext.apply({
22844
layoutOnCardChange: this.layoutOnTabChange,
22845
deferredRender: this.deferredRender
22846
}, this.layoutConfig)));
22848
if(this.tabPosition == 'top'){
22849
this.elements += ',header';
22850
this.stripTarget = 'header';
22852
this.elements += ',footer';
22853
this.stripTarget = 'footer';
22856
this.stack = Ext.TabPanel.AccessStack();
22862
onRender : function(ct, position){
22863
Ext.TabPanel.superclass.onRender.call(this, ct, position);
22866
var pos = this.tabPosition == 'top' ? 'header' : 'footer';
22867
this[pos].addClass('x-tab-panel-'+pos+'-plain');
22870
var st = this[this.stripTarget];
22872
this.stripWrap = st.createChild({cls:'x-tab-strip-wrap', cn:{
22873
tag:'ul', cls:'x-tab-strip x-tab-strip-'+this.tabPosition}});
22875
var beforeEl = (this.tabPosition=='bottom' ? this.stripWrap : null);
22876
this.stripSpacer = st.createChild({cls:'x-tab-strip-spacer'}, beforeEl);
22877
this.strip = new Ext.Element(this.stripWrap.dom.firstChild);
22879
this.edge = this.strip.createChild({tag:'li', cls:'x-tab-edge'});
22880
this.strip.createChild({cls:'x-clear'});
22882
this.body.addClass('x-tab-panel-body-'+this.tabPosition);
22886
var tt = new Ext.Template(
22887
'<li class="{cls}" id="{id}"><a class="x-tab-strip-close" onclick="return false;"></a>',
22888
'<a class="x-tab-right" href="#" onclick="return false;"><em class="x-tab-left">',
22889
'<span class="x-tab-strip-inner"><span class="x-tab-strip-text {iconCls}">{text}</span></span>',
22892
tt.disableFormats = true;
22894
Ext.TabPanel.prototype.itemTpl = tt;
22897
this.items.each(this.initTab, this);
22901
afterRender : function(){
22902
Ext.TabPanel.superclass.afterRender.call(this);
22904
this.readTabs(false);
22906
if(this.activeTab !== undefined){
22907
var item = (typeof this.activeTab == 'object') ? this.activeTab : this.items.get(this.activeTab);
22908
delete this.activeTab;
22909
this.setActiveTab(item);
22914
initEvents : function(){
22915
Ext.TabPanel.superclass.initEvents.call(this);
22916
this.on('add', this.onAdd, this, {target: this});
22917
this.on('remove', this.onRemove, this, {target: this});
22919
this.mon(this.strip, 'mousedown', this.onStripMouseDown, this);
22920
this.mon(this.strip, 'contextmenu', this.onStripContextMenu, this);
22921
if(this.enableTabScroll){
22922
this.mon(this.strip, 'mousewheel', this.onWheel, this);
22927
findTargets : function(e){
22929
var itemEl = e.getTarget('li', this.strip);
22931
item = this.getComponent(itemEl.id.split(this.idDelimiter)[1]);
22941
close : e.getTarget('.x-tab-strip-close', this.strip),
22948
onStripMouseDown : function(e){
22952
e.preventDefault();
22953
var t = this.findTargets(e);
22955
if (t.item.fireEvent('beforeclose', t.item) !== false) {
22956
t.item.fireEvent('close', t.item);
22957
this.remove(t.item);
22961
if(t.item && t.item != this.activeTab){
22962
this.setActiveTab(t.item);
22967
onStripContextMenu : function(e){
22968
e.preventDefault();
22969
var t = this.findTargets(e);
22971
this.fireEvent('contextmenu', this, t.item, e);
22976
readTabs : function(removeExisting){
22977
if(removeExisting === true){
22978
this.items.each(function(item){
22982
var tabs = this.el.query(this.autoTabSelector);
22983
for(var i = 0, len = tabs.length; i < len; i++){
22985
var title = tab.getAttribute('title');
22986
tab.removeAttribute('title');
22995
initTab : function(item, index){
22996
var before = this.strip.dom.childNodes[index];
22997
var p = this.getTemplateArgs(item);
22999
this.itemTpl.insertBefore(before, p) :
23000
this.itemTpl.append(this.strip, p);
23002
Ext.fly(el).addClassOnOver('x-tab-strip-over');
23005
Ext.fly(el).child('span.x-tab-strip-text', true).qtip = item.tabTip;
23009
item.on('disable', this.onItemDisabled, this);
23010
item.on('enable', this.onItemEnabled, this);
23011
item.on('titlechange', this.onItemTitleChanged, this);
23012
item.on('iconchange', this.onItemIconChanged, this);
23013
item.on('beforeshow', this.onBeforeShowItem, this);
23017
getTemplateArgs : function(item) {
23018
var cls = item.closable ? 'x-tab-strip-closable' : '';
23020
cls += ' x-item-disabled';
23023
cls += ' x-tab-with-icon';
23026
cls += ' ' + item.tabCls;
23030
id: this.id + this.idDelimiter + item.getItemId(),
23033
iconCls: item.iconCls || ''
23038
onAdd : function(tp, item, index){
23039
this.initTab(item, index);
23040
if(this.items.getCount() == 1){
23043
this.delegateUpdates();
23047
onBeforeAdd : function(item){
23048
var existing = item.events ? (this.items.containsKey(item.getItemId()) ? item : null) : this.items.get(item);
23050
this.setActiveTab(item);
23053
Ext.TabPanel.superclass.onBeforeAdd.apply(this, arguments);
23054
var es = item.elements;
23055
item.elements = es ? es.replace(',header', '') : es;
23056
item.border = (item.border === true);
23060
onRemove : function(tp, item){
23061
Ext.destroy(Ext.get(this.getTabEl(item)));
23062
this.stack.remove(item);
23063
item.un('disable', this.onItemDisabled, this);
23064
item.un('enable', this.onItemEnabled, this);
23065
item.un('titlechange', this.onItemTitleChanged, this);
23066
item.un('iconchange', this.onItemIconChanged, this);
23067
item.un('beforeshow', this.onBeforeShowItem, this);
23068
if(item == this.activeTab){
23069
var next = this.stack.next();
23071
this.setActiveTab(next);
23072
}else if(this.items.getCount() > 0){
23073
this.setActiveTab(0);
23075
this.activeTab = null;
23078
this.delegateUpdates();
23082
onBeforeShowItem : function(item){
23083
if(item != this.activeTab){
23084
this.setActiveTab(item);
23090
onItemDisabled : function(item){
23091
var el = this.getTabEl(item);
23093
Ext.fly(el).addClass('x-item-disabled');
23095
this.stack.remove(item);
23099
onItemEnabled : function(item){
23100
var el = this.getTabEl(item);
23102
Ext.fly(el).removeClass('x-item-disabled');
23107
onItemTitleChanged : function(item){
23108
var el = this.getTabEl(item);
23110
Ext.fly(el).child('span.x-tab-strip-text', true).innerHTML = item.title;
23115
onItemIconChanged : function(item, iconCls, oldCls){
23116
var el = this.getTabEl(item);
23118
Ext.fly(el).child('span.x-tab-strip-text').replaceClass(oldCls, iconCls);
23123
getTabEl : function(item){
23124
var itemId = (Ext.isObject(item) ? item : this.getComponent(item)).getItemId();
23125
return document.getElementById(this.id+this.idDelimiter+itemId);
23129
onResize : function(){
23130
Ext.TabPanel.superclass.onResize.apply(this, arguments);
23131
this.delegateUpdates();
23135
beginUpdate : function(){
23136
this.suspendUpdates = true;
23140
endUpdate : function(){
23141
this.suspendUpdates = false;
23142
this.delegateUpdates();
23146
hideTabStripItem : function(item){
23147
item = this.getComponent(item);
23148
var el = this.getTabEl(item);
23150
el.style.display = 'none';
23151
this.delegateUpdates();
23153
this.stack.remove(item);
23157
unhideTabStripItem : function(item){
23158
item = this.getComponent(item);
23159
var el = this.getTabEl(item);
23161
el.style.display = '';
23162
this.delegateUpdates();
23167
delegateUpdates : function(){
23168
if(this.suspendUpdates){
23171
if(this.resizeTabs && this.rendered){
23172
this.autoSizeTabs();
23174
if(this.enableTabScroll && this.rendered){
23175
this.autoScrollTabs();
23180
autoSizeTabs : function(){
23181
var count = this.items.length;
23182
var ce = this.tabPosition != 'bottom' ? 'header' : 'footer';
23183
var ow = this[ce].dom.offsetWidth;
23184
var aw = this[ce].dom.clientWidth;
23186
if(!this.resizeTabs || count < 1 || !aw){ // !aw for display:none
23190
var each = Math.max(Math.min(Math.floor((aw-4) / count) - this.tabMargin, this.tabWidth), this.minTabWidth); // -4 for float errors in IE
23191
this.lastTabWidth = each;
23192
var lis = this.strip.query("li:not([className^=x-tab-edge])");
23193
for(var i = 0, len = lis.length; i < len; i++) {
23195
var inner = Ext.fly(li).child('.x-tab-strip-inner', true);
23196
var tw = li.offsetWidth;
23197
var iw = inner.offsetWidth;
23198
inner.style.width = (each - (tw-iw)) + 'px';
23203
adjustBodyWidth : function(w){
23205
this.header.setWidth(w);
23208
this.footer.setWidth(w);
23214
setActiveTab : function(item){
23215
item = this.getComponent(item);
23216
if(!item || this.fireEvent('beforetabchange', this, item, this.activeTab) === false){
23219
if(!this.rendered){
23220
this.activeTab = item;
23223
if(this.activeTab != item){
23224
if(this.activeTab){
23225
var oldEl = this.getTabEl(this.activeTab);
23227
Ext.fly(oldEl).removeClass('x-tab-strip-active');
23229
this.activeTab.fireEvent('deactivate', this.activeTab);
23231
var el = this.getTabEl(item);
23232
Ext.fly(el).addClass('x-tab-strip-active');
23233
this.activeTab = item;
23234
this.stack.add(item);
23236
this.layout.setActiveItem(item);
23237
if(this.scrolling){
23238
this.scrollToTab(item, this.animScroll);
23241
item.fireEvent('activate', item);
23242
this.fireEvent('tabchange', this, item);
23247
getActiveTab : function(){
23248
return this.activeTab || null;
23252
getItem : function(item){
23253
return this.getComponent(item);
23257
autoScrollTabs : function(){
23258
this.pos = this.tabPosition=='bottom' ? this.footer : this.header;
23259
var count = this.items.length;
23260
var ow = this.pos.dom.offsetWidth;
23261
var tw = this.pos.dom.clientWidth;
23263
var wrap = this.stripWrap;
23265
var cw = wd.offsetWidth;
23266
var pos = this.getScrollPos();
23267
var l = this.edge.getOffsetsTo(this.stripWrap)[0] + pos;
23269
if(!this.enableTabScroll || count < 1 || cw < 20){ // 20 to prevent display:none issues
23275
if(this.scrolling){
23276
this.scrolling = false;
23277
this.pos.removeClass('x-tab-scrolling');
23278
this.scrollLeft.hide();
23279
this.scrollRight.hide();
23280
// See here: http://extjs.com/forum/showthread.php?t=49308&highlight=isSafari
23281
if(Ext.isAir || Ext.isWebKit){
23282
wd.style.marginLeft = '';
23283
wd.style.marginRight = '';
23287
if(!this.scrolling){
23288
this.pos.addClass('x-tab-scrolling');
23289
// See here: http://extjs.com/forum/showthread.php?t=49308&highlight=isSafari
23290
if(Ext.isAir || Ext.isWebKit){
23291
wd.style.marginLeft = '18px';
23292
wd.style.marginRight = '18px';
23295
tw -= wrap.getMargins('lr');
23296
wrap.setWidth(tw > 20 ? tw : 20);
23297
if(!this.scrolling){
23298
if(!this.scrollLeft){
23299
this.createScrollers();
23301
this.scrollLeft.show();
23302
this.scrollRight.show();
23305
this.scrolling = true;
23306
if(pos > (l-tw)){ // ensure it stays within bounds
23307
wd.scrollLeft = l-tw;
23308
}else{ // otherwise, make sure the active tab is still visible
23309
this.scrollToTab(this.activeTab, false);
23311
this.updateScrollButtons();
23316
createScrollers : function(){
23317
this.pos.addClass('x-tab-scrolling-' + this.tabPosition);
23318
var h = this.stripWrap.dom.offsetHeight;
23321
var sl = this.pos.insertFirst({
23322
cls:'x-tab-scroller-left'
23325
sl.addClassOnOver('x-tab-scroller-left-over');
23326
this.leftRepeater = new Ext.util.ClickRepeater(sl, {
23327
interval : this.scrollRepeatInterval,
23328
handler: this.onScrollLeft,
23331
this.scrollLeft = sl;
23334
var sr = this.pos.insertFirst({
23335
cls:'x-tab-scroller-right'
23338
sr.addClassOnOver('x-tab-scroller-right-over');
23339
this.rightRepeater = new Ext.util.ClickRepeater(sr, {
23340
interval : this.scrollRepeatInterval,
23341
handler: this.onScrollRight,
23344
this.scrollRight = sr;
23348
getScrollWidth : function(){
23349
return this.edge.getOffsetsTo(this.stripWrap)[0] + this.getScrollPos();
23353
getScrollPos : function(){
23354
return parseInt(this.stripWrap.dom.scrollLeft, 10) || 0;
23358
getScrollArea : function(){
23359
return parseInt(this.stripWrap.dom.clientWidth, 10) || 0;
23363
getScrollAnim : function(){
23364
return {duration:this.scrollDuration, callback: this.updateScrollButtons, scope: this};
23368
getScrollIncrement : function(){
23369
return this.scrollIncrement || (this.resizeTabs ? this.lastTabWidth+2 : 100);
23374
scrollToTab : function(item, animate){
23375
if(!item){ return; }
23376
var el = this.getTabEl(item);
23377
var pos = this.getScrollPos(), area = this.getScrollArea();
23378
var left = Ext.fly(el).getOffsetsTo(this.stripWrap)[0] + pos;
23379
var right = left + el.offsetWidth;
23381
this.scrollTo(left, animate);
23382
}else if(right > (pos + area)){
23383
this.scrollTo(right - area, animate);
23388
scrollTo : function(pos, animate){
23389
this.stripWrap.scrollTo('left', pos, animate ? this.getScrollAnim() : false);
23391
this.updateScrollButtons();
23395
onWheel : function(e){
23396
var d = e.getWheelDelta()*this.wheelIncrement*-1;
23399
var pos = this.getScrollPos();
23400
var newpos = pos + d;
23401
var sw = this.getScrollWidth()-this.getScrollArea();
23403
var s = Math.max(0, Math.min(sw, newpos));
23405
this.scrollTo(s, false);
23410
onScrollRight : function(){
23411
var sw = this.getScrollWidth()-this.getScrollArea();
23412
var pos = this.getScrollPos();
23413
var s = Math.min(sw, pos + this.getScrollIncrement());
23415
this.scrollTo(s, this.animScroll);
23420
onScrollLeft : function(){
23421
var pos = this.getScrollPos();
23422
var s = Math.max(0, pos - this.getScrollIncrement());
23424
this.scrollTo(s, this.animScroll);
23429
updateScrollButtons : function(){
23430
var pos = this.getScrollPos();
23431
this.scrollLeft[pos == 0 ? 'addClass' : 'removeClass']('x-tab-scroller-left-disabled');
23432
this.scrollRight[pos >= (this.getScrollWidth()-this.getScrollArea()) ? 'addClass' : 'removeClass']('x-tab-scroller-right-disabled');
23436
beforeDestroy : function() {
23438
this.items.each(function(item){
23439
if(item && item.tabEl){
23440
Ext.get(item.tabEl).removeAllListeners();
23446
this.strip.removeAllListeners();
23448
Ext.TabPanel.superclass.beforeDestroy.apply(this);
23463
Ext.reg('tabpanel', Ext.TabPanel);
23466
Ext.TabPanel.prototype.activate = Ext.TabPanel.prototype.setActiveTab;
23468
// private utility class used by TabPanel
23469
Ext.TabPanel.AccessStack = function(){
23472
add : function(item){
23474
if(items.length > 10){
23479
remove : function(item){
23481
for(var i = 0, len = items.length; i < len; i++) {
23482
if(items[i] != item){
23490
return items.pop();
23496
Ext.Button = Ext.extend(Ext.BoxComponent, {
23510
enableToggle: false,
23514
menuAlign : "tl-bl?",
23521
menuClassTarget: 'tr:nth(2)',
23524
clickEvent : 'click',
23527
handleMouseEvents : true,
23530
tooltipType : 'qtip',
23533
buttonSelector : "button:first-child",
23539
iconAlign : 'left',
23542
arrowAlign : 'right',
23548
initComponent : function(){
23549
Ext.Button.superclass.initComponent.call(this);
23570
this.menu = Ext.menu.MenuMgr.get(this.menu);
23572
if(typeof this.toggleGroup === 'string'){
23573
this.enableToggle = true;
23578
getTemplateArgs : function(){
23579
var cls = (this.cls || '');
23580
cls += (this.iconCls || this.icon) ? (this.text ? ' x-btn-text-icon' : ' x-btn-icon') : ' x-btn-noicon';
23582
cls += ' x-btn-pressed';
23584
return [this.text || ' ', this.type, this.iconCls || '', cls, 'x-btn-' + this.scale + ' x-btn-icon-' + this.scale + '-' + this.iconAlign, this.getMenuClass()];
23588
getMenuClass : function(){
23589
return this.menu ? (this.arrowAlign != 'bottom' ? 'x-btn-arrow' : 'x-btn-arrow-bottom') : '';
23593
onRender : function(ct, position){
23594
if(!this.template){
23595
if(!Ext.Button.buttonTemplate){
23596
// hideous table template
23597
Ext.Button.buttonTemplate = new Ext.Template(
23598
'<table cellspacing="0" class="x-btn {3}"><tbody class="{4}">',
23599
'<tr><td class="x-btn-tl"><i> </i></td><td class="x-btn-tc"></td><td class="x-btn-tr"><i> </i></td></tr>',
23600
'<tr><td class="x-btn-ml"><i> </i></td><td class="x-btn-mc"><em class="{5}" unselectable="on"><button class="x-btn-text {2}" type="{1}">{0}</button></em></td><td class="x-btn-mr"><i> </i></td></tr>',
23601
'<tr><td class="x-btn-bl"><i> </i></td><td class="x-btn-bc"></td><td class="x-btn-br"><i> </i></td></tr>',
23602
"</tbody></table>");
23603
Ext.Button.buttonTemplate.compile();
23605
this.template = Ext.Button.buttonTemplate;
23608
var btn, targs = this.getTemplateArgs();
23611
btn = this.template.insertBefore(position, targs, true);
23613
btn = this.template.append(ct, targs, true);
23616
var btnEl = this.btnEl = btn.child(this.buttonSelector);
23617
this.mon(btnEl, 'focus', this.onFocus, this);
23618
this.mon(btnEl, 'blur', this.onBlur, this);
23620
this.initButtonEl(btn, btnEl);
23622
Ext.ButtonToggleMgr.register(this);
23626
initButtonEl : function(btn, btnEl){
23630
this.el.dom.id = this.el.id = this.id;
23633
btnEl.setStyle('background-image', 'url(' +this.icon +')');
23635
if(this.tabIndex !== undefined){
23636
btnEl.dom.tabIndex = this.tabIndex;
23639
this.setTooltip(this.tooltip);
23642
if(this.handleMouseEvents){
23643
this.mon(btn, 'mouseover', this.onMouseOver, this);
23644
this.mon(btn, 'mousedown', this.onMouseDown, this);
23646
// new functionality for monitoring on the document level
23647
//this.mon(btn, "mouseout", this.onMouseOut, this);
23651
this.mon(this.menu, 'show', this.onMenuShow, this);
23652
this.mon(this.menu, 'hide', this.onMenuHide, this);
23656
var repeater = new Ext.util.ClickRepeater(btn,
23657
typeof this.repeat == "object" ? this.repeat : {}
23659
this.mon(repeater, 'click', this.onClick, this);
23662
this.mon(btn, this.clickEvent, this.onClick, this);
23666
afterRender : function(){
23667
Ext.Button.superclass.afterRender.call(this);
23669
this.doAutoWidth.defer(1, this);
23671
this.doAutoWidth();
23676
setIconClass : function(cls){
23678
this.btnEl.replaceClass(this.iconCls, cls);
23680
this.iconCls = cls;
23685
setTooltip : function(tooltip){
23686
if(Ext.isObject(tooltip)){
23687
Ext.QuickTips.register(Ext.apply({
23688
target: this.btnEl.id
23691
this.btnEl.dom[this.tooltipType] = tooltip;
23697
beforeDestroy: function(){
23700
if(typeof this.tooltip == 'object'){
23701
Ext.QuickTips.unregister(this.btnEl);
23705
Ext.destroy(this.menu);
23709
onDestroy : function(){
23711
Ext.ButtonToggleMgr.unregister(this);
23716
doAutoWidth : function(){
23717
if(this.el && this.text && typeof this.width == 'undefined'){
23718
this.el.setWidth("auto");
23719
if(Ext.isIE7 && Ext.isStrict){
23720
var ib = this.btnEl;
23721
if(ib && ib.getWidth() > 20){
23723
ib.setWidth(Ext.util.TextMetrics.measure(ib, this.text).width+ib.getFrameWidth('lr'));
23727
if(this.el.getWidth() < this.minWidth){
23728
this.el.setWidth(this.minWidth);
23735
setHandler : function(handler, scope){
23736
this.handler = handler;
23737
this.scope = scope;
23742
setText : function(text){
23745
this.el.child("td.x-btn-mc " + this.buttonSelector).update(text);
23747
this.doAutoWidth();
23752
getText : function(){
23757
toggle : function(state, suppressEvent){
23758
state = state === undefined ? !this.pressed : !!state;
23759
if(state != this.pressed){
23760
this.el[state ? 'addClass' : 'removeClass']("x-btn-pressed");
23761
this.pressed = state;
23762
if(!suppressEvent){
23763
this.fireEvent("toggle", this, state);
23764
if(this.toggleHandler){
23765
this.toggleHandler.call(this.scope || this, this, state);
23773
focus : function(){
23774
this.btnEl.focus();
23778
onDisable : function(){
23779
this.onDisableChange(true);
23783
onEnable : function(){
23784
this.onDisableChange(false);
23787
onDisableChange : function(disabled){
23789
if(!Ext.isIE6 || !this.text){
23790
this.el[disabled ? 'addClass' : 'removeClass'](this.disabledClass);
23792
this.el.dom.disabled = disabled;
23794
this.disabled = disabled;
23798
showMenu : function(){
23800
this.menu.show(this.el, this.menuAlign);
23806
hideMenu : function(){
23814
hasVisibleMenu : function(){
23815
return this.menu && this.menu.isVisible();
23819
onClick : function(e){
23821
e.preventDefault();
23826
if(!this.disabled){
23827
if(this.enableToggle && (this.allowDepress !== false || !this.pressed)){
23830
if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
23833
this.fireEvent("click", this, e);
23835
//this.el.removeClass("x-btn-over");
23836
this.handler.call(this.scope || this, this, e);
23842
isMenuTriggerOver : function(e, internal){
23843
return this.menu && !internal;
23847
isMenuTriggerOut : function(e, internal){
23848
return this.menu && !internal;
23852
onMouseOver : function(e){
23853
if(!this.disabled){
23854
var internal = e.within(this.el, true);
23856
this.el.addClass("x-btn-over");
23857
if(!this.monitoringMouseOver){
23858
Ext.getDoc().on('mouseover', this.monitorMouseOver, this);
23859
this.monitoringMouseOver = true;
23861
this.fireEvent('mouseover', this, e);
23863
if(this.isMenuTriggerOver(e, internal)){
23864
this.fireEvent('menutriggerover', this, this.menu, e);
23870
monitorMouseOver : function(e){
23871
if(e.target != this.el.dom && !e.within(this.el)){
23872
if(this.monitoringMouseOver){
23873
Ext.getDoc().un('mouseover', this.monitorMouseOver, this);
23874
this.monitoringMouseOver = false;
23876
this.onMouseOut(e);
23881
onMouseOut : function(e){
23882
var internal = e.within(this.el) && e.target != this.el.dom;
23883
this.el.removeClass("x-btn-over");
23884
this.fireEvent('mouseout', this, e);
23885
if(this.isMenuTriggerOut(e, internal)){
23886
this.fireEvent('menutriggerout', this, this.menu, e);
23890
onFocus : function(e){
23891
if(!this.disabled){
23892
this.el.addClass("x-btn-focus");
23896
onBlur : function(e){
23897
this.el.removeClass("x-btn-focus");
23901
getClickEl : function(e, isUp){
23906
onMouseDown : function(e){
23907
if(!this.disabled && e.button == 0){
23908
this.getClickEl(e).addClass("x-btn-click");
23909
Ext.getDoc().on('mouseup', this.onMouseUp, this);
23913
onMouseUp : function(e){
23915
this.getClickEl(e, true).removeClass("x-btn-click");
23916
Ext.getDoc().un('mouseup', this.onMouseUp, this);
23920
onMenuShow : function(e){
23921
this.ignoreNextClick = 0;
23922
this.el.addClass("x-btn-menu-active");
23923
this.fireEvent('menushow', this, this.menu);
23926
onMenuHide : function(e){
23927
this.el.removeClass("x-btn-menu-active");
23928
this.ignoreNextClick = this.restoreClick.defer(250, this);
23929
this.fireEvent('menuhide', this, this.menu);
23933
restoreClick : function(){
23934
this.ignoreNextClick = 0;
23941
Ext.reg('button', Ext.Button);
23943
// Private utility class used by Button
23944
Ext.ButtonToggleMgr = function(){
23947
function toggleGroup(btn, state){
23949
var g = groups[btn.toggleGroup];
23950
for(var i = 0, l = g.length; i < l; i++){
23952
g[i].toggle(false);
23959
register : function(btn){
23960
if(!btn.toggleGroup){
23963
var g = groups[btn.toggleGroup];
23965
g = groups[btn.toggleGroup] = [];
23968
btn.on("toggle", toggleGroup);
23971
unregister : function(btn){
23972
if(!btn.toggleGroup){
23975
var g = groups[btn.toggleGroup];
23978
btn.un("toggle", toggleGroup);
23983
getPressed : function(group){
23984
var g = groups[group];
23986
for(var i = 0, len = g.length; i < len; i++){
23987
if(g[i].pressed === true){
23997
Ext.SplitButton = Ext.extend(Ext.Button, {
23999
arrowSelector : 'em',
24003
initComponent : function(){
24004
Ext.SplitButton.superclass.initComponent.call(this);
24006
this.addEvents("arrowclick");
24010
onRender : function(){
24011
Ext.SplitButton.superclass.onRender.apply(this, arguments);
24012
if(this.arrowTooltip){
24013
btn.child(this.arrowSelector).dom[this.tooltipType] = this.arrowTooltip;
24018
setArrowHandler : function(handler, scope){
24019
this.arrowHandler = handler;
24020
this.scope = scope;
24023
getMenuClass : function(){
24024
return this.menu && this.arrowAlign != 'bottom' ? 'x-btn-split' : 'x-btn-split-bottom';
24027
isClickOnArrow : function(e){
24028
return this.arrowAlign != 'bottom' ?
24029
e.getPageX() > this.el.child(this.buttonSelector).getRegion().right :
24030
e.getPageY() > this.el.child(this.buttonSelector).getRegion().bottom;
24034
onClick : function(e, t){
24035
e.preventDefault();
24036
if(!this.disabled){
24037
if(this.isClickOnArrow(e)){
24038
if(this.menu && !this.menu.isVisible() && !this.ignoreNextClick){
24041
this.fireEvent("arrowclick", this, e);
24042
if(this.arrowHandler){
24043
this.arrowHandler.call(this.scope || this, this, e);
24046
if(this.enableToggle){
24049
this.fireEvent("click", this, e);
24051
this.handler.call(this.scope || this, this, e);
24058
isMenuTriggerOver : function(e){
24059
return this.menu && e.target.tagName == 'em';
24063
isMenuTriggerOut : function(e, internal){
24064
return this.menu && e.target.tagName != 'em';
24068
Ext.reg('splitbutton', Ext.SplitButton);
24070
Ext.CycleButton = Ext.extend(Ext.SplitButton, {
24079
getItemText : function(item){
24080
if(item && this.showText === true){
24082
if(this.prependText){
24083
text += this.prependText;
24092
setActiveItem : function(item, suppressEvent){
24093
if(typeof item != 'object'){
24094
item = this.menu.items.get(item);
24097
if(!this.rendered){
24098
this.text = this.getItemText(item);
24099
this.iconCls = item.iconCls;
24101
var t = this.getItemText(item);
24105
this.setIconClass(item.iconCls);
24107
this.activeItem = item;
24109
item.setChecked(true, true);
24111
if(this.forceIcon){
24112
this.setIconClass(this.forceIcon);
24114
if(!suppressEvent){
24115
this.fireEvent('change', this, item);
24121
getActiveItem : function(){
24122
return this.activeItem;
24126
initComponent : function(){
24132
if(this.changeHandler){
24133
this.on('change', this.changeHandler, this.scope||this);
24134
delete this.changeHandler;
24137
this.itemCount = this.items.length;
24139
this.menu = {cls:'x-cycle-menu', items:[]};
24141
for(var i = 0, len = this.itemCount; i < len; i++){
24142
var item = this.items[i];
24143
item.group = item.group || this.id;
24144
item.itemIndex = i;
24145
item.checkHandler = this.checkHandler;
24147
item.checked = item.checked || false;
24148
this.menu.items.push(item);
24153
this.setActiveItem(checked, true);
24154
Ext.CycleButton.superclass.initComponent.call(this);
24156
this.on('click', this.toggleSelected, this);
24160
checkHandler : function(item, pressed){
24162
this.setActiveItem(item);
24167
toggleSelected : function(){
24168
this.menu.render();
24170
var nextIdx, checkItem;
24171
for (var i = 1; i < this.itemCount; i++) {
24172
nextIdx = (this.activeItem.itemIndex + i) % this.itemCount;
24173
// check the potential item
24174
checkItem = this.menu.items.itemAt(nextIdx);
24175
// if its not disabled then check it.
24176
if (!checkItem.disabled) {
24177
checkItem.setChecked(true);
24183
Ext.reg('cycle', Ext.CycleButton);
24185
Ext.layout.ToolbarLayout = Ext.extend(Ext.layout.ContainerLayout, {
24186
monitorResize: true,
24188
lastOverflow: false,
24190
noItemsMenuText: '<div class="x-toolbar-no-items">(None)</div>',
24192
onLayout : function(ct, target){
24194
target.addClass('x-toolbar-layout-ct');
24195
target.insertHtml('beforeEnd',
24196
'<table cellspacing="0" class="x-toolbar-ct"><tbody><tr><td class="x-toolbar-left" align="left"><table cellspacing="0"><tbody><tr class="x-toolbar-left-row"></tr></tbody></table></td><td class="x-toolbar-right" align="right"><table cellspacing="0" class="x-toolbar-right-ct"><tbody><tr><td><table cellspacing="0"><tbody><tr class="x-toolbar-right-row"></tr></tbody></table></td><td><table cellspacing="0"><tbody><tr class="x-toolbar-extras-row"></tr></tbody></table></td></tr></tbody></table></td></tr></tbody></table>');
24197
this.leftTr = target.child('tr.x-toolbar-left-row', true);
24198
this.rightTr = target.child('tr.x-toolbar-right-row', true);
24199
this.extrasTr = target.child('tr.x-toolbar-extras-row', true);
24201
var side = this.leftTr;
24204
var items = ct.items.items;
24205
for(var i = 0, len = items.length, c; i < len; i++, pos++) {
24208
side = this.rightTr;
24210
}else if(!c.rendered){
24211
c.render(this.insertCell(c, side, pos));
24213
if(!c.xtbHidden && !this.isValidParent(c, side.childNodes[pos])){
24214
var td = this.insertCell(c, side, pos);
24215
td.appendChild(c.getDomPositionEl().dom);
24216
c.container = Ext.get(td);
24220
//strip extra empty cells
24221
this.cleanup(this.leftTr);
24222
this.cleanup(this.rightTr);
24223
this.cleanup(this.extrasTr);
24224
this.fitToSize(target);
24227
cleanup : function(row){
24228
var cn = row.childNodes;
24229
for(var i = cn.length-1, c; i >= 0 && (c = cn[i]); i--){
24231
row.removeChild(c);
24236
insertCell : function(c, side, pos){
24237
var td = document.createElement('td');
24238
td.className='x-toolbar-cell';
24239
side.insertBefore(td, side.childNodes[pos]||null);
24243
hideItem: function(item){
24244
var h = (this.hiddens = this.hiddens || []);
24246
item.xtbHidden = true;
24247
item.xtbWidth = item.getDomPositionEl().dom.parentNode.offsetWidth;
24251
unhideItem: function(item){
24253
item.xtbHidden = false;
24254
this.hiddens.remove(item);
24255
if(this.hiddens.length < 1){
24256
delete this.hiddens;
24260
getItemWidth : function(c){
24261
return c.hidden ? (c.xtbWidth || 0) : c.getDomPositionEl().dom.parentNode.offsetWidth;
24264
fitToSize :function(t){
24265
if(this.container.enableOverflow === false){
24268
var w = t.dom.clientWidth;
24269
var lw = this.lastWidth || 0;
24270
this.lastWidth = w;
24271
var iw = t.dom.firstChild.offsetWidth;
24273
var clipWidth = w - this.triggerWidth;
24274
var hideIndex = -1;
24276
if(iw > w || (this.hiddens && w >= lw)){
24277
var i, items = this.container.items.items, len = items.length, c;
24279
for(i = 0; i < len; i++) {
24282
loopWidth += this.getItemWidth(c);
24283
if(loopWidth > clipWidth){
24289
this.unhideItem(c);
24297
if(!this.lastOverflow){
24298
this.container.fireEvent('overflowchange', this.container, true);
24299
this.lastOverflow = true;
24301
}else if(this.more){
24303
this.more.destroy();
24305
if(this.lastOverflow){
24306
this.container.fireEvent('overflowchange', this.container, false);
24307
this.lastOverflow = false;
24312
createMenuConfig: function(c, hideOnClick){
24313
var cfg = Ext.apply({}, c.initialConfig),
24314
group = c.toggleGroup;
24317
text: c.overflowText || c.text,
24318
iconCls: c.iconCls,
24321
disabled: c.disabled,
24322
handler: c.handler,
24325
hideOnClick: hideOnClick
24327
if(group || c.enableToggle){
24330
checked: c.pressed,
24332
checkchange: function(item, checked){
24344
addComponentToMenu: function(m, c){
24345
if(c instanceof Ext.Toolbar.Separator){
24347
}else if(Ext.isFunction(c.isXType)){
24348
if(c.isXType('splitbutton')){
24349
m.add(this.createMenuConfig(c, true));
24350
}else if(c.isXType('button')){
24351
m.add(this.createMenuConfig(c, !c.menu));
24352
}else if(c.isXType('buttongroup')){
24354
c.items.each(function(item){
24355
this.addComponentToMenu(m, item);
24362
clearMenu: function(){
24363
var m = this.moreMenu;
24365
this.moreMenu.items.each(function(item){
24372
beforeMoreShow : function(m){
24375
for(var i = 0, h = this.container.items.items, len = h.length, c; i < len; i++){
24378
this.addComponentToMenu(m, c);
24381
// put something so the menu isn't empty
24382
// if no compatible items found
24383
if(m.items.length < 1){
24384
m.add(this.noItemsMenuText);
24388
initMore : function(){
24390
this.moreMenu = new Ext.menu.Menu({
24392
beforeshow: this.beforeMoreShow,
24396
this.more = new Ext.Button({
24397
iconCls: 'x-toolbar-more-icon',
24398
cls: 'x-toolbar-more',
24399
menu: this.moreMenu
24401
var td = this.insertCell(this.more, this.extrasTr, 100);
24402
this.more.render(td);
24406
destroy: function(){
24407
Ext.destroy(this.more, this.moreMenu);
24408
Ext.layout.ToolbarLayout.superclass.destroy.call(this);
24413
Ext.Container.LAYOUTS['toolbar'] = Ext.layout.ToolbarLayout;
24416
Ext.Toolbar = function(config){
24417
if(Ext.isArray(config)){
24418
config = {items: config, layout: 'toolbar'};
24420
config = Ext.apply({
24423
if(config.buttons) {
24424
config.items = config.buttons;
24427
Ext.Toolbar.superclass.constructor.call(this, config);
24432
var T = Ext.Toolbar;
24434
Ext.extend(T, Ext.Container, {
24436
defaultType: 'button',
24439
internalDefaults: {removeMode: 'container', hideParent: true},
24440
toolbarCls: 'x-toolbar',
24442
initComponent : function(){
24443
T.superclass.initComponent.call(this);
24446
this.addEvents('overflowchange');
24450
onRender : function(ct, position){
24452
if(!this.autoCreate){
24453
this.autoCreate = {
24454
cls: this.toolbarCls + ' x-small-editor'
24457
this.el = ct.createChild(Ext.apply({ id: this.id },this.autoCreate), position);
24463
//probably not needed, left here so documentation will still generate.
24464
Ext.Toolbar.superclass.add.apply(this, arguments);
24468
lookupComponent: function(c){
24469
if(typeof c == 'string'){
24471
c = new T.Separator();
24472
}else if(c == ' '){
24473
c = new T.Spacer();
24474
}else if(c == '->'){
24477
c = new T.TextItem(c);
24479
this.applyDefaults(c);
24481
if(c.isFormField || c.render){ // some kind of form field, some kind of Toolbar.Item
24482
c = this.constructItem(c);
24483
}else if(c.tag){ // DomHelper spec
24484
c = new T.Item({autoEl: c});
24485
}else if(c.tagName){ // element
24486
c = new T.Item({el:c});
24487
}else if(Ext.isObject(c)){ // must be button config?
24488
c = c.xtype ? this.constructItem(c) : this.constructButton(c);
24495
applyDefaults : function(c){
24496
if(typeof c != 'string'){
24497
c = Ext.Toolbar.superclass.applyDefaults.call(this, c);
24498
var d = this.internalDefaults;
24500
Ext.applyIf(c.initialConfig, d);
24510
constructItem : function(item){
24511
return Ext.create(item, 'button');
24515
addSeparator : function(){
24516
return this.add(new T.Separator());
24520
addSpacer : function(){
24521
return this.add(new T.Spacer());
24525
addFill : function(){
24526
this.add(new T.Fill());
24530
addElement : function(el){
24531
return this.addItem(new T.Item({el:el}));
24535
addItem : function(item){
24536
return Ext.Toolbar.superclass.add.apply(this, arguments);
24540
addButton : function(config){
24541
if(Ext.isArray(config)){
24543
for(var i = 0, len = config.length; i < len; i++) {
24544
buttons.push(this.addButton(config[i]));
24548
return this.add(this.constructButton(config));
24552
addText : function(text){
24553
return this.addItem(new T.TextItem(text));
24557
addDom : function(config){
24558
return this.add(new T.Item({autoEl: config}));
24562
addField : function(field){
24563
return this.add(field);
24567
insertButton : function(index, item){
24568
if(Ext.isArray(item)){
24570
for(var i = 0, len = item.length; i < len; i++) {
24571
buttons.push(this.insertButton(index + i, item[i]));
24575
return Ext.Toolbar.superclass.insert.call(this, index, item);
24579
initMenuTracking : function(item){
24580
if(this.trackMenus && item.menu){
24582
'menutriggerover' : this.onButtonTriggerOver,
24583
'menushow' : this.onButtonMenuShow,
24584
'menuhide' : this.onButtonMenuHide,
24591
constructButton: function(item){
24592
var b = item.events ? item : this.constructItem(item);
24593
this.initMenuTracking(b);
24598
onDisable : function(){
24599
this.items.each(function(item){
24607
onEnable : function(){
24608
this.items.each(function(item){
24616
onButtonTriggerOver : function(btn){
24617
if(this.activeMenuBtn && this.activeMenuBtn != btn){
24618
this.activeMenuBtn.hideMenu();
24620
this.activeMenuBtn = btn;
24625
onButtonMenuShow : function(btn){
24626
this.activeMenuBtn = btn;
24630
onButtonMenuHide : function(btn){
24631
delete this.activeMenuBtn;
24634
Ext.reg('toolbar', Ext.Toolbar);
24637
T.Item = Ext.extend(Ext.BoxComponent, {
24638
hideParent: true, // Hiding a Toolbar.Item hides its containing TD
24639
enable:Ext.emptyFn,
24640
disable:Ext.emptyFn,
24644
Ext.reg('tbitem', T.Item);
24647
T.Separator = Ext.extend(T.Item, {
24648
onRender : function(ct, position){
24649
this.el = ct.createChild({tag:'span', cls:'xtb-sep'}, position);
24652
Ext.reg('tbseparator', T.Separator);
24655
T.Spacer = Ext.extend(T.Item, {
24658
onRender : function(ct, position){
24659
this.el = ct.createChild({tag:'div', cls:'xtb-spacer', style: this.width?'width:'+this.width+'px':''}, position);
24662
Ext.reg('tbspacer', T.Spacer);
24665
T.Fill = Ext.extend(T.Item, {
24667
render : Ext.emptyFn,
24670
Ext.reg('tbfill', T.Fill);
24673
T.TextItem = Ext.extend(T.Item, {
24674
constructor: function(config){
24675
if (typeof config == 'string') {
24676
config = { autoEl: {cls: 'xtb-text', html: config }};
24678
config.autoEl = {cls: 'xtb-text', html: config.text || ''};
24680
T.TextItem.superclass.constructor.call(this, config);
24683
setText: function(t) {
24684
if (this.rendered) {
24685
this.el.dom.innerHTML = t;
24687
this.autoEl.html = t;
24691
Ext.reg('tbtext', T.TextItem);
24693
// backwards compat
24694
T.Button = Ext.extend(Ext.Button, {});
24695
T.SplitButton = Ext.extend(Ext.SplitButton, {});
24696
Ext.reg('tbbutton', T.Button);
24697
Ext.reg('tbsplit', T.SplitButton);
24702
Ext.ButtonGroup = Ext.extend(Ext.Panel, {
24705
baseCls: 'x-btn-group',
24708
defaultType: 'button',
24711
internalDefaults: {removeMode: 'container', hideParent: true},
24713
initComponent : function(){
24714
this.layoutConfig = this.layoutConfig || {};
24715
Ext.applyIf(this.layoutConfig, {
24716
columns : this.columns
24719
this.addClass('x-btn-group-notitle');
24721
this.on('afterlayout', this.onAfterLayout, this);
24722
Ext.ButtonGroup.superclass.initComponent.call(this);
24725
applyDefaults : function(c){
24726
c = Ext.ButtonGroup.superclass.applyDefaults.call(this, c);
24727
var d = this.internalDefaults;
24729
Ext.applyIf(c.initialConfig, d);
24737
onAfterLayout : function(){
24738
var bodyWidth = this.body.getFrameWidth('lr') + this.body.dom.firstChild.offsetWidth;
24739
this.body.setWidth(bodyWidth);
24740
this.el.setWidth(bodyWidth + this.getFrameWidth());
24745
Ext.reg('buttongroup', Ext.ButtonGroup);
24749
var T = Ext.Toolbar;
24751
Ext.PagingToolbar = Ext.extend(Ext.Toolbar, {
24758
displayMsg : 'Displaying {0} - {1} of {2}',
24760
emptyMsg : 'No data to display',
24762
beforePageText : "Page",
24764
afterPageText : "of {0}",
24766
firstText : "First Page",
24768
prevText : "Previous Page",
24770
nextText : "Next Page",
24772
lastText : "Last Page",
24774
refreshText : "Refresh",
24777
paramNames : {start: 'start', limit: 'limit'},
24783
initComponent: function(){
24784
var pagingItems = [this.first = new T.Button({
24785
tooltip: this.firstText,
24786
iconCls: "x-tbar-page-first",
24788
handler: this.onClick,
24790
}), this.prev = new T.Button({
24791
tooltip: this.prevText,
24792
iconCls: "x-tbar-page-prev",
24794
handler: this.onClick,
24796
}), '-', this.beforePageText,
24797
this.inputItem = new T.Item({
24804
cls: "x-tbar-page-number"
24806
}), this.afterTextItem = new T.TextItem({
24807
text: String.format(this.afterPageText, 1)
24808
}), '-', this.next = new T.Button({
24809
tooltip: this.nextText,
24810
iconCls: "x-tbar-page-next",
24812
handler: this.onClick,
24814
}), this.last = new T.Button({
24815
tooltip: this.lastText,
24816
iconCls: "x-tbar-page-last",
24818
handler: this.onClick,
24820
}), '-', this.refresh = new T.Button({
24821
tooltip: this.refreshText,
24822
iconCls: "x-tbar-loading",
24823
handler: this.onClick,
24828
var userItems = this.items || this.buttons || [];
24829
if (this.prependButtons) {
24830
this.items = userItems.concat(pagingItems);
24832
this.items = pagingItems.concat(userItems);
24834
delete this.buttons;
24835
if(this.displayInfo){
24836
this.items.push('->');
24837
this.items.push(this.displayItem = new T.TextItem({}));
24839
Ext.PagingToolbar.superclass.initComponent.call(this);
24846
this.on('afterlayout', this.onFirstLayout, this, {single: true});
24848
this.bindStore(this.store);
24852
onFirstLayout: function(ii) {
24853
this.mon(this.inputItem.el, "keydown", this.onPagingKeyDown, this);
24854
this.mon(this.inputItem.el, "blur", this.onPagingBlur, this);
24855
this.mon(this.inputItem.el, "focus", this.onPagingFocus, this);
24857
this.field = this.inputItem.el.dom;
24859
this.onLoad.apply(this, this.dsLoaded);
24864
updateInfo : function(){
24865
if(this.displayItem){
24866
var count = this.store.getCount();
24867
var msg = count == 0 ?
24871
this.cursor+1, this.cursor+count, this.store.getTotalCount()
24873
this.displayItem.setText(msg);
24878
onLoad : function(store, r, o){
24879
if(!this.rendered){
24880
this.dsLoaded = [store, r, o];
24883
this.cursor = (o.params && o.params[this.paramNames.start]) ? o.params[this.paramNames.start] : 0;
24884
var d = this.getPageData(), ap = d.activePage, ps = d.pages;
24886
this.afterTextItem.setText(String.format(this.afterPageText, d.pages));
24887
this.field.value = ap;
24888
this.first.setDisabled(ap == 1);
24889
this.prev.setDisabled(ap == 1);
24890
this.next.setDisabled(ap == ps);
24891
this.last.setDisabled(ap == ps);
24892
this.refresh.enable();
24894
this.fireEvent('change', this, d);
24898
getPageData : function(){
24899
var total = this.store.getTotalCount();
24902
activePage : Math.ceil((this.cursor+this.pageSize)/this.pageSize),
24903
pages : total < this.pageSize ? 1 : Math.ceil(total/this.pageSize)
24908
changePage: function(page){
24909
this.doLoad(((page-1) * this.pageSize).constrain(0, this.store.getTotalCount()));
24913
onLoadError : function(){
24914
if(!this.rendered){
24917
this.refresh.enable();
24921
readPage : function(d){
24922
var v = this.field.value, pageNum;
24923
if (!v || isNaN(pageNum = parseInt(v, 10))) {
24924
this.field.value = d.activePage;
24930
onPagingFocus: function(){
24931
this.field.select();
24935
onPagingBlur: function(e){
24936
this.field.value = this.getPageData().activePage;
24940
onPagingKeyDown : function(e){
24941
var k = e.getKey(), d = this.getPageData(), pageNum;
24942
if (k == e.RETURN) {
24944
pageNum = this.readPage(d);
24945
if(pageNum !== false){
24946
pageNum = Math.min(Math.max(1, pageNum), d.pages) - 1;
24947
this.doLoad(pageNum * this.pageSize);
24949
}else if (k == e.HOME || k == e.END){
24951
pageNum = k == e.HOME ? 1 : d.pages;
24952
this.field.value = pageNum;
24953
}else if (k == e.UP || k == e.PAGEUP || k == e.DOWN || k == e.PAGEDOWN){
24955
if((pageNum = this.readPage(d))){
24956
var increment = e.shiftKey ? 10 : 1;
24957
if(k == e.DOWN || k == e.PAGEDOWN){
24960
pageNum += increment;
24961
if(pageNum >= 1 & pageNum <= d.pages){
24962
this.field.value = pageNum;
24969
beforeLoad : function(){
24970
if(this.rendered && this.refresh){
24971
this.refresh.disable();
24976
doLoad : function(start){
24977
var o = {}, pn = this.paramNames;
24978
o[pn.start] = start;
24979
o[pn.limit] = this.pageSize;
24980
if(this.fireEvent('beforechange', this, o) !== false){
24981
this.store.load({params:o});
24986
onClick : function(button){
24987
var store = this.store;
24993
this.doLoad(Math.max(0, this.cursor-this.pageSize));
24996
this.doLoad(this.cursor+this.pageSize);
24999
var total = store.getTotalCount();
25000
var extra = total % this.pageSize;
25001
var lastStart = extra ? (total - extra) : total-this.pageSize;
25002
this.doLoad(lastStart);
25005
this.doLoad(this.cursor);
25011
bindStore : function(store, initial){
25012
if(!initial && this.store){
25013
this.store.un("beforeload", this.beforeLoad, this);
25014
this.store.un("load", this.onLoad, this);
25015
this.store.un("loadexception", this.onLoadError, this);
25016
this.store.un("exception", this.onLoadError, this);
25017
if(store !== this.store && this.store.autoDestroy){
25018
this.store.destroy();
25022
store = Ext.StoreMgr.lookup(store);
25025
beforeload: this.beforeLoad,
25027
loadexception: this.onLoadError,
25028
exception: this.onLoadError
25030
this.paramNames.start = store.paramNames.start;
25031
this.paramNames.limit = store.paramNames.limit;
25033
if (store.getCount() > 0){
25034
this.onLoad(store, null, {});
25037
this.store = store;
25041
unbind : function(store){
25042
this.bindStore(null);
25046
bind : function(store){
25047
this.bindStore(store);
25051
onDestroy : function(){
25052
this.bindStore(null);
25053
Ext.PagingToolbar.superclass.onDestroy.call(this);
25058
Ext.reg('paging', Ext.PagingToolbar);
25060
Ext.Resizable = function(el, config){
25061
this.el = Ext.get(el);
25063
if(config && config.wrap){
25064
config.resizeChild = this.el;
25065
this.el = this.el.wrap(typeof config.wrap == "object" ? config.wrap : {cls:"xresizable-wrap"});
25066
this.el.id = this.el.dom.id = config.resizeChild.id + "-rzwrap";
25067
this.el.setStyle("overflow", "hidden");
25068
this.el.setPositioning(config.resizeChild.getPositioning());
25069
config.resizeChild.clearPositioning();
25070
if(!config.width || !config.height){
25071
var csize = config.resizeChild.getSize();
25072
this.el.setSize(csize.width, csize.height);
25074
if(config.pinned && !config.adjustments){
25075
config.adjustments = "auto";
25080
this.proxy = this.el.createProxy({tag: "div", cls: "x-resizable-proxy", id: this.el.id + "-rzproxy"}, Ext.getBody());
25081
this.proxy.unselectable();
25082
this.proxy.enableDisplayMode('block');
25084
Ext.apply(this, config);
25087
this.disableTrackOver = true;
25088
this.el.addClass("x-resizable-pinned");
25090
// if the element isn't positioned, make it relative
25091
var position = this.el.getStyle("position");
25092
if(position != "absolute" && position != "fixed"){
25093
this.el.setStyle("position", "relative");
25095
if(!this.handles){ // no handles passed, must be legacy style
25096
this.handles = 's,e,se';
25097
if(this.multiDirectional){
25098
this.handles += ',n,w';
25101
if(this.handles == "all"){
25102
this.handles = "n s e w ne nw se sw";
25104
var hs = this.handles.split(/\s*?[,;]\s*?| /);
25105
var ps = Ext.Resizable.positions;
25106
for(var i = 0, len = hs.length; i < len; i++){
25107
if(hs[i] && ps[hs[i]]){
25108
var pos = ps[hs[i]];
25109
this[pos] = new Ext.Resizable.Handle(this, pos, this.disableTrackOver, this.transparent);
25113
this.corner = this.southeast;
25115
if(this.handles.indexOf("n") != -1 || this.handles.indexOf("w") != -1){
25116
this.updateBox = true;
25119
this.activeHandle = null;
25121
if(this.resizeChild){
25122
if(typeof this.resizeChild == "boolean"){
25123
this.resizeChild = Ext.get(this.el.dom.firstChild, true);
25125
this.resizeChild = Ext.get(this.resizeChild, true);
25129
if(this.adjustments == "auto"){
25130
var rc = this.resizeChild;
25131
var hw = this.west, he = this.east, hn = this.north, hs = this.south;
25132
if(rc && (hw || hn)){
25133
rc.position("relative");
25134
rc.setLeft(hw ? hw.el.getWidth() : 0);
25135
rc.setTop(hn ? hn.el.getHeight() : 0);
25137
this.adjustments = [
25138
(he ? -he.el.getWidth() : 0) + (hw ? -hw.el.getWidth() : 0),
25139
(hn ? -hn.el.getHeight() : 0) + (hs ? -hs.el.getHeight() : 0) -1
25143
if(this.draggable){
25144
this.dd = this.dynamic ?
25145
this.el.initDD(null) : this.el.initDDProxy(null, {dragElId: this.proxy.id});
25146
this.dd.setHandleElId(this.resizeChild ? this.resizeChild.id : this.el.id);
25155
if(this.width !== null && this.height !== null){
25156
this.resizeTo(this.width, this.height);
25158
this.updateChildSize();
25161
this.el.dom.style.zoom = 1;
25163
Ext.Resizable.superclass.constructor.call(this);
25166
Ext.extend(Ext.Resizable, Ext.util.Observable, {
25167
resizeChild : false,
25168
adjustments : [0, 0],
25178
multiDirectional : false,
25179
disableTrackOver : false,
25180
easing : 'easeOutStrong',
25181
widthIncrement : 0,
25182
heightIncrement : 0,
25186
preserveRatio : false,
25187
transparent: false,
25199
resizeTo : function(width, height){
25200
this.el.setSize(width, height);
25201
this.updateChildSize();
25202
this.fireEvent("resize", this, width, height, null);
25206
startSizing : function(e, handle){
25207
this.fireEvent("beforeresize", this, e);
25208
if(this.enabled){ // 2nd enabled check in case disabled before beforeresize handler
25211
this.overlay = this.el.createProxy({tag: "div", cls: "x-resizable-overlay", html: " "}, Ext.getBody());
25212
this.overlay.unselectable();
25213
this.overlay.enableDisplayMode("block");
25214
this.overlay.on("mousemove", this.onMouseMove, this);
25215
this.overlay.on("mouseup", this.onMouseUp, this);
25217
this.overlay.setStyle("cursor", handle.el.getStyle("cursor"));
25219
this.resizing = true;
25220
this.startBox = this.el.getBox();
25221
this.startPoint = e.getXY();
25222
this.offsets = [(this.startBox.x + this.startBox.width) - this.startPoint[0],
25223
(this.startBox.y + this.startBox.height) - this.startPoint[1]];
25225
this.overlay.setSize(Ext.lib.Dom.getViewWidth(true), Ext.lib.Dom.getViewHeight(true));
25226
this.overlay.show();
25228
if(this.constrainTo) {
25229
var ct = Ext.get(this.constrainTo);
25230
this.resizeRegion = ct.getRegion().adjust(
25231
ct.getFrameWidth('t'),
25232
ct.getFrameWidth('l'),
25233
-ct.getFrameWidth('b'),
25234
-ct.getFrameWidth('r')
25238
this.proxy.setStyle('visibility', 'hidden'); // workaround display none
25240
this.proxy.setBox(this.startBox);
25242
this.proxy.setStyle('visibility', 'visible');
25248
onMouseDown : function(handle, e){
25251
this.activeHandle = handle;
25252
this.startSizing(e, handle);
25257
onMouseUp : function(e){
25258
var size = this.resizeElement();
25259
this.resizing = false;
25261
this.overlay.hide();
25263
this.fireEvent("resize", this, size.width, size.height, e);
25267
updateChildSize : function(){
25268
if(this.resizeChild){
25270
var child = this.resizeChild;
25271
var adj = this.adjustments;
25272
if(el.dom.offsetWidth){
25273
var b = el.getSize(true);
25274
child.setSize(b.width+adj[0], b.height+adj[1]);
25276
// Second call here for IE
25277
// The first call enables instant resizing and
25278
// the second call corrects scroll bars if they
25281
setTimeout(function(){
25282
if(el.dom.offsetWidth){
25283
var b = el.getSize(true);
25284
child.setSize(b.width+adj[0], b.height+adj[1]);
25292
snap : function(value, inc, min){
25293
if(!inc || !value) return value;
25294
var newValue = value;
25295
var m = value % inc;
25298
newValue = value + (inc-m);
25300
newValue = value - m;
25303
return Math.max(min, newValue);
25307
resizeElement : function(){
25308
var box = this.proxy.getBox();
25309
if(this.updateBox){
25310
this.el.setBox(box, false, this.animate, this.duration, null, this.easing);
25312
this.el.setSize(box.width, box.height, this.animate, this.duration, null, this.easing);
25314
this.updateChildSize();
25322
constrain : function(v, diff, m, mx){
25325
}else if(v - diff > mx){
25332
onMouseMove : function(e){
25334
try{// try catch so if something goes wrong the user doesn't get hung
25336
if(this.resizeRegion && !this.resizeRegion.contains(e.getPoint())) {
25340
//var curXY = this.startPoint;
25341
var curSize = this.curSize || this.startBox;
25342
var x = this.startBox.x, y = this.startBox.y;
25343
var ox = x, oy = y;
25344
var w = curSize.width, h = curSize.height;
25345
var ow = w, oh = h;
25346
var mw = this.minWidth, mh = this.minHeight;
25347
var mxw = this.maxWidth, mxh = this.maxHeight;
25348
var wi = this.widthIncrement;
25349
var hi = this.heightIncrement;
25351
var eventXY = e.getXY();
25352
var diffX = -(this.startPoint[0] - Math.max(this.minX, eventXY[0]));
25353
var diffY = -(this.startPoint[1] - Math.max(this.minY, eventXY[1]));
25355
var pos = this.activeHandle.position;
25360
w = Math.min(Math.max(mw, w), mxw);
25364
h = Math.min(Math.max(mh, h), mxh);
25369
w = Math.min(Math.max(mw, w), mxw);
25370
h = Math.min(Math.max(mh, h), mxh);
25373
diffY = this.constrain(h, diffY, mh, mxh);
25378
diffX = this.constrain(w, diffX, mw, mxw);
25384
w = Math.min(Math.max(mw, w), mxw);
25385
diffY = this.constrain(h, diffY, mh, mxh);
25390
diffX = this.constrain(w, diffX, mw, mxw);
25391
diffY = this.constrain(h, diffY, mh, mxh);
25398
diffX = this.constrain(w, diffX, mw, mxw);
25400
h = Math.min(Math.max(mh, h), mxh);
25406
var sw = this.snap(w, wi, mw);
25407
var sh = this.snap(h, hi, mh);
25408
if(sw != w || sh != h){
25431
if(this.preserveRatio){
25436
h = Math.min(Math.max(mh, h), mxh);
25441
w = Math.min(Math.max(mw, w), mxw);
25446
w = Math.min(Math.max(mw, w), mxw);
25452
w = Math.min(Math.max(mw, w), mxw);
25458
h = Math.min(Math.max(mh, h), mxh);
25466
h = Math.min(Math.max(mh, h), mxh);
25476
h = Math.min(Math.max(mh, h), mxh);
25484
this.proxy.setBounds(x, y, w, h);
25486
this.resizeElement();
25493
handleOver : function(){
25495
this.el.addClass("x-resizable-over");
25500
handleOut : function(){
25501
if(!this.resizing){
25502
this.el.removeClass("x-resizable-over");
25507
getEl : function(){
25512
getResizeChild : function(){
25513
return this.resizeChild;
25517
destroy : function(removeEl){
25522
Ext.destroy(this.overlay);
25523
this.overlay = null;
25525
Ext.destroy(this.proxy);
25528
var ps = Ext.Resizable.positions;
25530
if(typeof ps[k] != "function" && this[ps[k]]){
25531
this[ps[k]].destroy();
25535
this.el.update("");
25536
Ext.destroy(this.el);
25541
syncHandleHeight : function(){
25542
var h = this.el.getHeight(true);
25544
this.west.el.setHeight(h);
25547
this.east.el.setHeight(h);
25553
// hash to map config positions to true positions
25554
Ext.Resizable.positions = {
25555
n: "north", s: "south", e: "east", w: "west", se: "southeast", sw: "southwest", nw: "northwest", ne: "northeast"
25559
Ext.Resizable.Handle = function(rz, pos, disableTrackOver, transparent){
25561
// only initialize the template if resizable is used
25562
var tpl = Ext.DomHelper.createTemplate(
25563
{tag: "div", cls: "x-resizable-handle x-resizable-handle-{0}"}
25566
Ext.Resizable.Handle.prototype.tpl = tpl;
25568
this.position = pos;
25570
this.el = this.tpl.append(rz.el.dom, [this.position], true);
25571
this.el.unselectable();
25573
this.el.setOpacity(0);
25575
this.el.on("mousedown", this.onMouseDown, this);
25576
if(!disableTrackOver){
25577
this.el.on("mouseover", this.onMouseOver, this);
25578
this.el.on("mouseout", this.onMouseOut, this);
25583
Ext.Resizable.Handle.prototype = {
25585
afterResize : function(rz){
25589
onMouseDown : function(e){
25590
this.rz.onMouseDown(this, e);
25593
onMouseOver : function(e){
25594
this.rz.handleOver(this, e);
25597
onMouseOut : function(e){
25598
this.rz.handleOut(this, e);
25601
destroy : function(){
25602
Ext.destroy(this.el);
25611
Ext.Editor = function(field, config){
25613
this.field = Ext.create(field.field, 'textfield');
25614
config = Ext.apply({}, field); // copy so we don't disturb original config
25615
delete config.field;
25617
this.field = field;
25619
Ext.Editor.superclass.constructor.call(this, config);
25622
Ext.extend(Ext.Editor, Ext.Component, {
25637
swallowKeys : true,
25639
completeOnEnter : false,
25641
cancelOnEsc : false,
25645
initComponent : function(){
25646
Ext.Editor.superclass.initComponent.call(this);
25664
onRender : function(ct, position){
25665
this.el = new Ext.Layer({
25666
shadow: this.shadow,
25670
shadowOffset: this.shadowOffset || 4,
25672
constrain: this.constrain
25675
this.el.setZIndex(this.zIndex);
25677
this.el.setStyle("overflow", Ext.isGecko ? "auto" : "hidden");
25678
if(this.field.msgTarget != 'title'){
25679
this.field.msgTarget = 'qtip';
25681
this.field.inEditor = true;
25682
this.field.render(this.el);
25684
this.field.el.dom.setAttribute('autocomplete', 'off');
25686
this.mon(this.field, "specialkey", this.onSpecialKey, this);
25687
if(this.swallowKeys){
25688
this.field.el.swallowEvent(['keydown','keypress']);
25691
this.mon(this.field, "blur", this.onBlur, this);
25692
if(this.field.grow){
25693
this.mon(this.field, "autosize", this.el.sync, this.el, {delay:1});
25698
onSpecialKey : function(field, e){
25699
var key = e.getKey();
25700
if(this.completeOnEnter && key == e.ENTER){
25702
this.completeEdit();
25703
}else if(this.cancelOnEsc && key == e.ESC){
25706
this.fireEvent('specialkey', field, e);
25708
if(this.field.triggerBlur && (key == e.ENTER || key == e.ESC || key == e.TAB)){
25709
this.field.triggerBlur();
25714
startEdit : function(el, value){
25716
this.completeEdit();
25718
this.boundEl = Ext.get(el);
25719
var v = value !== undefined ? value : this.boundEl.dom.innerHTML;
25720
if(!this.rendered){
25721
this.render(this.parentEl || document.body);
25723
if(this.fireEvent("beforestartedit", this, this.boundEl, v) === false){
25726
this.startValue = v;
25727
this.field.setValue(v);
25729
this.el.alignTo(this.boundEl, this.alignment);
25730
this.editing = true;
25735
doAutoSize : function(){
25737
var sz = this.boundEl.getSize();
25738
switch(this.autoSize){
25740
this.setSize(sz.width, "");
25743
this.setSize("", sz.height);
25746
this.setSize(sz.width, sz.height);
25752
setSize : function(w, h){
25753
delete this.field.lastSize;
25754
this.field.setSize(w, h);
25756
if(Ext.isGecko2 || Ext.isOpera){
25757
// prevent layer scrollbars
25758
this.el.setSize(w, h);
25765
realign : function(){
25766
this.el.alignTo(this.boundEl, this.alignment);
25770
completeEdit : function(remainVisible){
25774
var v = this.getValue();
25775
if(!this.field.isValid()){
25776
if(this.revertInvalid !== false){
25777
this.cancelEdit(remainVisible);
25781
if(String(v) === String(this.startValue) && this.ignoreNoChange){
25782
this.hideEdit(remainVisible);
25785
if(this.fireEvent("beforecomplete", this, v, this.startValue) !== false){
25786
v = this.getValue();
25787
if(this.updateEl && this.boundEl){
25788
this.boundEl.update(v);
25790
this.hideEdit(remainVisible);
25791
this.fireEvent("complete", this, v, this.startValue);
25796
onShow : function(){
25798
if(this.hideEl !== false){
25799
this.boundEl.hide();
25802
if(Ext.isIE && !this.fixIEFocus){ // IE has problems with focusing the first time
25803
this.fixIEFocus = true;
25804
this.deferredFocus.defer(50, this);
25806
this.field.focus();
25808
this.fireEvent("startedit", this.boundEl, this.startValue);
25811
deferredFocus : function(){
25813
this.field.focus();
25818
cancelEdit : function(remainVisible){
25820
var v = this.getValue();
25821
this.setValue(this.startValue);
25822
this.hideEdit(remainVisible);
25823
this.fireEvent("canceledit", this, v, this.startValue);
25828
hideEdit: function(remainVisible){
25829
if(remainVisible !== true){
25830
this.editing = false;
25836
onBlur : function(){
25837
if(this.allowBlur !== true && this.editing){
25838
this.completeEdit();
25843
onHide : function(){
25845
this.completeEdit();
25849
if(this.field.collapse){
25850
this.field.collapse();
25853
if(this.hideEl !== false){
25854
this.boundEl.show();
25859
setValue : function(v){
25860
this.field.setValue(v);
25864
getValue : function(){
25865
return this.field.getValue();
25868
beforeDestroy : function(){
25869
Ext.destroy(this.field);
25873
Ext.reg('editor', Ext.Editor);
25875
Ext.MessageBox = function(){
25876
var dlg, opt, mask, waitTimer;
25877
var bodyEl, msgEl, textboxEl, textareaEl, progressBar, pp, iconEl, spacerEl;
25878
var buttons, activeTextEl, bwidth, iconCls = '';
25881
var handleButton = function(button){
25882
if(dlg.isVisible()){
25885
Ext.callback(opt.fn, opt.scope||window, [button, activeTextEl.dom.value, opt], 1);
25890
var handleHide = function(){
25891
if(opt && opt.cls){
25892
dlg.el.removeClass(opt.cls);
25894
progressBar.reset();
25898
var handleEsc = function(d, k, e){
25899
if(opt && opt.closable !== false){
25909
var updateButtons = function(b){
25912
buttons["ok"].hide();
25913
buttons["cancel"].hide();
25914
buttons["yes"].hide();
25915
buttons["no"].hide();
25918
dlg.footer.dom.style.display = '';
25919
for(var k in buttons){
25920
if(typeof buttons[k] != "function"){
25923
buttons[k].setText(typeof b[k] == "string" ? b[k] : Ext.MessageBox.buttonText[k]);
25924
width += buttons[k].el.getWidth()+15;
25935
getDialog : function(titleText){
25937
dlg = new Ext.Window({
25942
constrainHeader:true,
25943
minimizable : false,
25944
maximizable : false,
25948
buttonAlign:"center",
25955
close : function(){
25956
if(opt && opt.buttons && opt.buttons.no && !opt.buttons.cancel){
25957
handleButton("no");
25959
handleButton("cancel");
25964
var bt = this.buttonText;
25965
//TODO: refactor this block into a buttons config to pass into the Window constructor
25966
buttons["ok"] = dlg.addButton(bt["ok"], handleButton.createCallback("ok"));
25967
buttons["yes"] = dlg.addButton(bt["yes"], handleButton.createCallback("yes"));
25968
buttons["no"] = dlg.addButton(bt["no"], handleButton.createCallback("no"));
25969
buttons["cancel"] = dlg.addButton(bt["cancel"], handleButton.createCallback("cancel"));
25970
buttons["ok"].hideMode = buttons["yes"].hideMode = buttons["no"].hideMode = buttons["cancel"].hideMode = 'offsets';
25971
dlg.render(document.body);
25972
dlg.getEl().addClass('x-window-dlg');
25974
bodyEl = dlg.body.createChild({
25975
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>'
25977
iconEl = Ext.get(bodyEl.dom.firstChild);
25978
var contentEl = bodyEl.dom.childNodes[1];
25979
msgEl = Ext.get(contentEl.firstChild);
25980
textboxEl = Ext.get(contentEl.childNodes[2].firstChild);
25981
textboxEl.enableDisplayMode();
25982
textboxEl.addKeyListener([10,13], function(){
25983
if(dlg.isVisible() && opt && opt.buttons){
25984
if(opt.buttons.ok){
25985
handleButton("ok");
25986
}else if(opt.buttons.yes){
25987
handleButton("yes");
25991
textareaEl = Ext.get(contentEl.childNodes[2].childNodes[1]);
25992
textareaEl.enableDisplayMode();
25993
progressBar = new Ext.ProgressBar({
25996
bodyEl.createChild({cls:'x-clear'});
26002
updateText : function(text){
26003
if(!dlg.isVisible() && !opt.width){
26004
dlg.setSize(this.maxWidth, 100); // resize first so content is never clipped from previous shows
26006
msgEl.update(text || ' ');
26008
var iw = iconCls != '' ? (iconEl.getWidth() + iconEl.getMargins('lr')) : 0;
26009
var mw = msgEl.getWidth() + msgEl.getMargins('lr');
26010
var fw = dlg.getFrameWidth('lr');
26011
var bw = dlg.body.getFrameWidth('lr');
26012
if (Ext.isIE && iw > 0){
26013
//3 pixels get subtracted in the icon CSS for an IE margin issue,
26014
//so we have to add it back here for the overall width to be consistent
26017
var w = Math.max(Math.min(opt.width || iw+mw+fw+bw, this.maxWidth),
26018
Math.max(opt.minWidth || this.minWidth, bwidth || 0));
26020
if(opt.prompt === true){
26021
activeTextEl.setWidth(w-iw-fw-bw);
26023
if(opt.progress === true || opt.wait === true){
26024
progressBar.setSize(w-iw-fw-bw);
26026
if(Ext.isIE && w == bwidth){
26027
w += 4; //Add offset when the content width is smaller than the buttons.
26029
dlg.setSize(w, 'auto').center();
26034
updateProgress : function(value, progressText, msg){
26035
progressBar.updateProgress(value, progressText);
26037
this.updateText(msg);
26043
isVisible : function(){
26044
return dlg && dlg.isVisible();
26049
var proxy = dlg ? dlg.activeGhost : null;
26050
if(this.isVisible() || proxy){
26054
// unghost is a private function, but i saw no better solution
26055
// to fix the locking problem when dragging while it closes
26056
dlg.unghost(false, false);
26063
show : function(options){
26064
if(this.isVisible()){
26068
var d = this.getDialog(opt.title || " ");
26070
d.setTitle(opt.title || " ");
26071
var allowClose = (opt.closable !== false && opt.progress !== true && opt.wait !== true);
26072
d.tools.close.setDisplayed(allowClose);
26073
activeTextEl = textboxEl;
26074
opt.prompt = opt.prompt || (opt.multiline ? true : false);
26079
textareaEl.setHeight(typeof opt.multiline == "number" ?
26080
opt.multiline : this.defaultTextHeight);
26081
activeTextEl = textareaEl;
26090
activeTextEl.dom.value = opt.value || "";
26092
d.focusEl = activeTextEl;
26094
var bs = opt.buttons;
26097
db = buttons["ok"];
26098
}else if(bs && bs.yes){
26099
db = buttons["yes"];
26106
d.setIconClass(opt.iconCls);
26108
this.setIcon(opt.icon);
26109
bwidth = updateButtons(opt.buttons);
26110
progressBar.setVisible(opt.progress === true || opt.wait === true);
26111
this.updateProgress(0, opt.progressText);
26112
this.updateText(opt.msg);
26114
d.el.addClass(opt.cls);
26116
d.proxyDrag = opt.proxyDrag === true;
26117
d.modal = opt.modal !== false;
26118
d.mask = opt.modal !== false ? mask : false;
26119
if(!d.isVisible()){
26120
// force it to the end of the z-index stack so it gets a cursor in FF
26121
document.body.appendChild(dlg.el.dom);
26122
d.setAnimateTarget(opt.animEl);
26123
d.show(opt.animEl);
26126
//workaround for window internally enabling keymap in afterShow
26127
d.on('show', function(){
26128
if(allowClose === true){
26131
d.keyMap.disable();
26133
}, this, {single:true});
26135
if(opt.wait === true){
26136
progressBar.wait(opt.waitConfig);
26142
setIcon : function(icon){
26143
if(icon && icon != ''){
26144
iconEl.removeClass('x-hidden');
26145
iconEl.replaceClass(iconCls, icon);
26146
bodyEl.addClass('x-dlg-icon');
26149
iconEl.replaceClass(iconCls, 'x-hidden');
26150
bodyEl.removeClass('x-dlg-icon');
26157
progress : function(title, msg, progressText){
26164
minWidth: this.minProgressWidth,
26165
progressText: progressText
26171
wait : function(msg, title, config){
26179
minWidth: this.minProgressWidth,
26186
alert : function(title, msg, fn, scope){
26198
confirm : function(title, msg, fn, scope){
26202
buttons: this.YESNO,
26205
icon: this.QUESTION
26211
prompt : function(title, msg, fn, scope, multiline, value){
26215
buttons: this.OKCANCEL,
26220
multiline: multiline,
26229
CANCEL : {cancel:true},
26231
OKCANCEL : {ok:true, cancel:true},
26233
YESNO : {yes:true, no:true},
26235
YESNOCANCEL : {yes:true, no:true, cancel:true},
26237
INFO : 'ext-mb-info',
26239
WARNING : 'ext-mb-warning',
26241
QUESTION : 'ext-mb-question',
26243
ERROR : 'ext-mb-error',
26246
defaultTextHeight : 75,
26252
minProgressWidth : 250,
26264
Ext.Msg = Ext.MessageBox;
26266
Ext.Tip = Ext.extend(Ext.Panel, {
26276
defaultAlign : "tl-bl?",
26278
quickShowInterval : 250,
26280
// private panel overrides
26284
floating:{shadow:true,shim:true,useDisplay:true,constrain:false},
26287
closeAction: 'hide',
26290
initComponent : function(){
26291
Ext.Tip.superclass.initComponent.call(this);
26292
if(this.closable && !this.title){
26293
this.elements += ',header';
26298
afterRender : function(){
26299
Ext.Tip.superclass.afterRender.call(this);
26303
handler: this[this.closeAction],
26310
showAt : function(xy){
26311
Ext.Tip.superclass.show.call(this);
26312
if(this.measureWidth !== false && (!this.initialConfig || typeof this.initialConfig.width != 'number')){
26313
this.doAutoWidth();
26315
if(this.constrainPosition){
26316
xy = this.el.adjustForConstraints(xy);
26318
this.setPagePosition(xy[0], xy[1]);
26322
doAutoWidth : function(){
26323
var bw = this.body.getTextWidth();
26325
bw = Math.max(bw, this.header.child('span').getTextWidth(this.title));
26327
bw += this.getFrameWidth() + (this.closable ? 20 : 0) + this.body.getPadding("lr");
26328
this.setWidth(bw.constrain(this.minWidth, this.maxWidth));
26330
// IE7 repaint bug on initial show
26331
if(Ext.isIE7 && !this.repainted){
26333
this.repainted = true;
26338
showBy : function(el, pos){
26339
if(!this.rendered){
26340
this.render(Ext.getBody());
26342
this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign));
26345
initDraggable : function(){
26346
this.dd = new Ext.Tip.DD(this, typeof this.draggable == 'boolean' ? null : this.draggable);
26347
this.header.addClass('x-tip-draggable');
26351
// private - custom Tip DD implementation
26352
Ext.Tip.DD = function(tip, config){
26353
Ext.apply(this, config);
26355
Ext.Tip.DD.superclass.constructor.call(this, tip.el.id, 'WindowDD-'+tip.id);
26356
this.setHandleElId(tip.header.id);
26357
this.scroll = false;
26360
Ext.extend(Ext.Tip.DD, Ext.dd.DD, {
26363
headerOffsets:[100, 25],
26364
startDrag : function(){
26365
this.tip.el.disableShadow();
26367
endDrag : function(e){
26368
this.tip.el.enableShadow(true);
26372
Ext.ToolTip = Ext.extend(Ext.Tip, {
26381
dismissDelay: 5000,
26384
trackMouse : false,
26386
anchorToTarget: true,
26394
constrainPosition: false,
26397
initComponent: function(){
26398
Ext.ToolTip.superclass.initComponent.call(this);
26399
this.lastActive = new Date();
26400
this.initTarget(this.target);
26401
this.origAnchor = this.anchor;
26405
onRender : function(ct, position){
26406
Ext.ToolTip.superclass.onRender.call(this, ct, position);
26407
this.anchorCls = 'x-tip-anchor-' + this.getAnchorPosition();
26408
this.anchorEl = this.el.createChild({
26409
cls: 'x-tip-anchor ' + this.anchorCls
26414
afterRender : function(){
26415
Ext.ToolTip.superclass.afterRender.call(this);
26416
this.anchorEl.setStyle('z-index', this.el.getZIndex() + 1);
26420
initTarget : function(target){
26422
if((t = Ext.get(target))){
26424
this.target = Ext.get(this.target);
26425
this.target.un('mouseover', this.onTargetOver, this);
26426
this.target.un('mouseout', this.onTargetOut, this);
26427
this.target.un('mousemove', this.onMouseMove, this);
26430
mouseover: this.onTargetOver,
26431
mouseout: this.onTargetOut,
26432
mousemove: this.onMouseMove,
26438
this.anchorTarget = this.target;
26443
onMouseMove : function(e){
26444
var t = this.delegate ? e.getTarget(this.delegate) : this.triggerElement = true;
26446
this.targetXY = e.getXY();
26447
if (t === this.triggerElement) {
26448
if(!this.hidden && this.trackMouse){
26449
this.setPagePosition(this.getTargetXY());
26453
this.lastActive = new Date(0);
26454
this.onTargetOver(e);
26456
} else if (!this.closable && this.isVisible()) {
26462
getTargetXY : function(){
26464
this.targetCounter++;
26465
var offsets = this.getOffsets();
26466
var xy = (this.anchorToTarget && !this.trackMouse) ?
26467
this.el.getAlignToXY(this.anchorTarget, this.getAnchorAlign()) :
26470
var dw = Ext.lib.Dom.getViewWidth()-5;
26471
var dh = Ext.lib.Dom.getViewHeight()-5;
26472
var scrollX = (document.documentElement.scrollLeft || document.body.scrollLeft || 0)+5;
26473
var scrollY = (document.documentElement.scrollTop || document.body.scrollTop || 0)+5;
26475
var axy = [xy[0] + offsets[0], xy[1] + offsets[1]];
26476
var sz = this.getSize();
26477
this.anchorEl.removeClass(this.anchorCls);
26479
if(this.targetCounter < 2){
26480
if(axy[0] < scrollX){
26481
if(this.anchorToTarget){
26482
this.defaultAlign = 'l-r';
26483
if(this.mouseOffset){this.mouseOffset[0] *= -1;}
26485
this.anchor = 'left';
26486
return this.getTargetXY();
26488
if(axy[0]+sz.width > dw){
26489
if(this.anchorToTarget){
26490
this.defaultAlign = 'r-l';
26491
if(this.mouseOffset){this.mouseOffset[0] *= -1;}
26493
this.anchor = 'right';
26494
return this.getTargetXY();
26496
if(axy[1] < scrollY){
26497
if(this.anchorToTarget){
26498
this.defaultAlign = 't-b';
26499
if(this.mouseOffset){this.mouseOffset[1] *= -1;}
26501
this.anchor = 'top';
26502
return this.getTargetXY();
26504
if(axy[1]+sz.height > dh){
26505
if(this.anchorToTarget){
26506
this.defaultAlign = 'b-t';
26507
if(this.mouseOffset){this.mouseOffset[1] *= -1;}
26509
this.anchor = 'bottom';
26510
return this.getTargetXY();
26514
this.anchorCls = 'x-tip-anchor-'+this.getAnchorPosition();
26515
this.anchorEl.addClass(this.anchorCls);
26516
this.targetCounter = 0;
26519
var mouseOffset = this.getMouseOffset();
26520
return [this.targetXY[0]+mouseOffset[0], this.targetXY[1]+mouseOffset[1]];
26524
getMouseOffset : function(){
26525
var offset = this.anchor ? [0,0] : [15,18];
26526
if(this.mouseOffset){
26527
offset[0] += this.mouseOffset[0];
26528
offset[1] += this.mouseOffset[1];
26534
getAnchorPosition : function(){
26536
this.tipAnchor = this.anchor.charAt(0);
26538
var m = this.defaultAlign.match(/^([a-z]+)-([a-z]+)(\?)?$/);
26540
throw "AnchorTip.defaultAlign is invalid";
26542
this.tipAnchor = m[1].charAt(0);
26545
switch(this.tipAnchor){
26546
case 't': return 'top';
26547
case 'b': return 'bottom';
26548
case 'r': return 'right';
26554
getAnchorAlign : function(){
26555
switch(this.anchor){
26556
case 'top' : return 'tl-bl';
26557
case 'left' : return 'tl-tr';
26558
case 'right': return 'tr-tl';
26559
default : return 'bl-tl';
26564
getOffsets: function(){
26565
var offsets, ap = this.getAnchorPosition().charAt(0);
26566
if(this.anchorToTarget && !this.trackMouse){
26572
offsets = [0, -13];
26575
offsets = [-13, 0];
26584
offsets = [-15-this.anchorOffset, 30];
26587
offsets = [-19-this.anchorOffset, -13-this.el.dom.offsetHeight];
26590
offsets = [-15-this.el.dom.offsetWidth, -13-this.anchorOffset];
26593
offsets = [25, -13-this.anchorOffset];
26597
var mouseOffset = this.getMouseOffset();
26598
offsets[0] += mouseOffset[0];
26599
offsets[1] += mouseOffset[1];
26605
onTargetOver : function(e){
26606
if(this.disabled || e.within(this.target.dom, true)){
26609
var t = e.getTarget(this.delegate);
26611
this.triggerElement = t;
26612
this.clearTimer('hide');
26613
this.targetXY = e.getXY();
26619
delayShow : function(){
26620
if(this.hidden && !this.showTimer){
26621
if(this.lastActive.getElapsed() < this.quickShowInterval){
26624
this.showTimer = this.show.defer(this.showDelay, this);
26626
}else if(!this.hidden && this.autoHide !== false){
26632
onTargetOut : function(e){
26633
if(this.disabled || e.within(this.target.dom, true)){
26636
this.clearTimer('show');
26637
if(this.autoHide !== false){
26643
delayHide : function(){
26644
if(!this.hidden && !this.hideTimer){
26645
this.hideTimer = this.hide.defer(this.hideDelay, this);
26651
this.clearTimer('dismiss');
26652
this.lastActive = new Date();
26653
delete this.triggerElement;
26655
this.anchorEl.hide();
26657
Ext.ToolTip.superclass.hide.call(this);
26663
// pre-show it off screen so that the el will have dimensions
26664
// for positioning calcs when getting xy next
26665
this.showAt([-1000,-1000]);
26666
this.origConstrainPosition = this.constrainPosition;
26667
this.constrainPosition = false;
26668
this.anchor = this.origAnchor;
26670
this.showAt(this.getTargetXY());
26674
this.anchorEl.show();
26675
this.constrainPosition = this.origConstrainPosition;
26677
this.anchorEl.hide();
26682
showAt : function(xy){
26683
this.lastActive = new Date();
26684
this.clearTimers();
26685
Ext.ToolTip.superclass.showAt.call(this, xy);
26686
if(this.dismissDelay && this.autoHide !== false){
26687
this.dismissTimer = this.hide.defer(this.dismissDelay, this);
26692
syncAnchor : function(){
26693
var anchorPos, targetPos, offset;
26694
switch(this.tipAnchor.charAt(0)){
26698
offset = [20+this.anchorOffset, 2];
26703
offset = [-2, 11+this.anchorOffset];
26708
offset = [20+this.anchorOffset, -2];
26713
offset = [2, 11+this.anchorOffset];
26716
this.anchorEl.alignTo(this.el, anchorPos+'-'+targetPos, offset);
26720
setPagePosition : function(x, y){
26721
Ext.ToolTip.superclass.setPagePosition.call(this, x, y);
26728
clearTimer : function(name){
26729
name = name + 'Timer';
26730
clearTimeout(this[name]);
26735
clearTimers : function(){
26736
this.clearTimer('show');
26737
this.clearTimer('dismiss');
26738
this.clearTimer('hide');
26742
onShow : function(){
26743
Ext.ToolTip.superclass.onShow.call(this);
26744
Ext.getDoc().on('mousedown', this.onDocMouseDown, this);
26748
onHide : function(){
26749
Ext.ToolTip.superclass.onHide.call(this);
26750
Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
26754
onDocMouseDown : function(e){
26755
if(this.autoHide !== true && !this.closable && !e.within(this.el.dom)){
26757
this.enable.defer(100, this);
26762
onDisable : function(){
26763
this.clearTimers();
26768
adjustPosition : function(x, y){
26769
if(this.contstrainPosition){
26770
var ay = this.targetXY[1], h = this.getSize().height;
26771
if(y <= ay && (y+h) >= ay){
26775
return {x : x, y: y};
26779
onDestroy : function(){
26780
Ext.getDoc().un('mousedown', this.onDocMouseDown, this);
26781
Ext.ToolTip.superclass.onDestroy.call(this);
26785
Ext.QuickTip = Ext.extend(Ext.ToolTip, {
26788
interceptTitles : false,
26793
attribute : "qtip",
26804
initComponent : function(){
26805
this.target = this.target || Ext.getDoc();
26806
this.targets = this.targets || {};
26807
Ext.QuickTip.superclass.initComponent.call(this);
26811
register : function(config){
26812
var cs = Ext.isArray(config) ? config : arguments;
26813
for(var i = 0, len = cs.length; i < len; i++){
26815
var target = c.target;
26817
if(Ext.isArray(target)){
26818
for(var j = 0, jlen = target.length; j < jlen; j++){
26819
this.targets[Ext.id(target[j])] = c;
26822
this.targets[Ext.id(target)] = c;
26829
unregister : function(el){
26830
delete this.targets[Ext.id(el)];
26834
onTargetOver : function(e){
26838
this.targetXY = e.getXY();
26839
var t = e.getTarget();
26840
if(!t || t.nodeType !== 1 || t == document || t == document.body){
26843
if(this.activeTarget && t == this.activeTarget.el){
26844
this.clearTimer('hide');
26848
if(t && this.targets[t.id]){
26849
this.activeTarget = this.targets[t.id];
26850
this.activeTarget.el = t;
26851
this.anchor = this.activeTarget.anchor;
26853
this.anchorTarget = t;
26859
var ttp, et = Ext.fly(t), cfg = this.tagConfig;
26860
var ns = cfg.namespace;
26861
if(this.interceptTitles && t.title){
26864
t.removeAttribute("title");
26865
e.preventDefault();
26867
ttp = t.qtip || et.getAttribute(cfg.attribute, ns);
26870
var autoHide = et.getAttribute(cfg.hide, ns);
26871
this.activeTarget = {
26874
width: et.getAttribute(cfg.width, ns),
26875
autoHide: autoHide != "user" && autoHide !== 'false',
26876
title: et.getAttribute(cfg.title, ns),
26877
cls: et.getAttribute(cfg.cls, ns),
26878
align: et.getAttribute(cfg.align, ns)
26881
this.anchor = et.getAttribute(cfg.anchor, ns);
26883
this.anchorTarget = t;
26890
onTargetOut : function(e){
26891
this.clearTimer('show');
26892
if(this.autoHide !== false){
26898
showAt : function(xy){
26899
var t = this.activeTarget;
26901
if(!this.rendered){
26902
this.render(Ext.getBody());
26903
this.activeTarget = t;
26906
this.setWidth(t.width);
26907
this.body.setWidth(this.adjustBodyWidth(t.width - this.getFrameWidth()));
26908
this.measureWidth = false;
26910
this.measureWidth = true;
26912
this.setTitle(t.title || '');
26913
this.body.update(t.text);
26914
this.autoHide = t.autoHide;
26915
this.dismissDelay = t.dismissDelay || this.dismissDelay;
26917
this.el.removeClass(this.lastCls);
26918
delete this.lastCls;
26921
this.el.addClass(t.cls);
26922
this.lastCls = t.cls;
26925
this.constrainPosition = false;
26926
}else if(t.align){ // TODO: this doesn't seem to work consistently
26927
xy = this.el.getAlignToXY(t.el, t.align);
26928
this.constrainPosition = false;
26930
this.constrainPosition = true;
26933
Ext.QuickTip.superclass.showAt.call(this, xy);
26938
delete this.activeTarget;
26939
Ext.QuickTip.superclass.hide.call(this);
26943
Ext.QuickTips = function(){
26944
var tip, locks = [];
26947
init : function(autoRender){
26950
Ext.onReady(function(){
26951
Ext.QuickTips.init(autoRender);
26955
tip = new Ext.QuickTip({elements:'header,body'});
26956
if(autoRender !== false){
26957
tip.render(Ext.getBody());
26963
enable : function(){
26966
if(locks.length < 1){
26973
disable : function(){
26981
isEnabled : function(){
26982
return tip !== undefined && !tip.disabled;
26986
getQuickTip : function(){
26991
register : function(){
26992
tip.register.apply(tip, arguments);
26996
unregister : function(){
26997
tip.unregister.apply(tip, arguments);
27002
tip.register.apply(tip, arguments);
27007
Ext.tree.TreePanel = Ext.extend(Ext.Panel, {
27008
rootVisible : true,
27009
animate: Ext.enableFx,
27012
hlDrop : Ext.enableFx,
27013
pathSeparator: "/",
27015
initComponent : function(){
27016
Ext.tree.TreePanel.superclass.initComponent.call(this);
27018
if(!this.eventModel){
27019
this.eventModel = new Ext.tree.TreeEventModel(this);
27022
// initialize the loader
27023
var l = this.loader;
27025
l = new Ext.tree.TreeLoader({
27026
dataUrl: this.dataUrl,
27027
requestMethod: this.requestMethod
27029
}else if(typeof l == 'object' && !l.load){
27030
l = new Ext.tree.TreeLoader(l);
27034
this.nodeHash = {};
27040
this.setRootNode(r);
27070
"beforeexpandnode",
27072
"beforecollapsenode",
27090
"beforechildrenrendered",
27104
if(this.singleExpand){
27105
this.on("beforeexpandnode", this.restrictExpand, this);
27110
proxyNodeEvent : function(ename, a1, a2, a3, a4, a5, a6){
27111
if(ename == 'collapse' || ename == 'expand' || ename == 'beforecollapse' || ename == 'beforeexpand' || ename == 'move' || ename == 'beforemove'){
27112
ename = ename+'node';
27114
// args inline for performance while bubbling events
27115
return this.fireEvent(ename, a1, a2, a3, a4, a5, a6);
27120
getRootNode : function(){
27125
setRootNode : function(node){
27126
Ext.destroy(this.root);
27127
if(!node.render){ // attributes passed
27128
node = this.loader.createNode(node);
27131
node.ownerTree = this;
27132
node.isRoot = true;
27133
this.registerNode(node);
27134
if(!this.rootVisible){
27135
var uiP = node.attributes.uiProvider;
27136
node.ui = uiP ? new uiP(node) : new Ext.tree.RootTreeNodeUI(node);
27138
if (this.innerCt) {
27139
this.innerCt.update('');
27140
this.afterRender();
27146
getNodeById : function(id){
27147
return this.nodeHash[id];
27151
registerNode : function(node){
27152
this.nodeHash[node.id] = node;
27156
unregisterNode : function(node){
27157
delete this.nodeHash[node.id];
27161
toString : function(){
27162
return "[Tree"+(this.id?" "+this.id:"")+"]";
27166
restrictExpand : function(node){
27167
var p = node.parentNode;
27169
if(p.expandedChild && p.expandedChild.parentNode == p){
27170
p.expandedChild.collapse();
27172
p.expandedChild = node;
27177
getChecked : function(a, startNode){
27178
startNode = startNode || this.root;
27180
var f = function(){
27181
if(this.attributes.checked){
27182
r.push(!a ? this : (a == 'id' ? this.id : this.attributes[a]));
27185
startNode.cascade(f);
27190
getEl : function(){
27195
getLoader : function(){
27196
return this.loader;
27200
expandAll : function(){
27201
this.root.expand(true);
27205
collapseAll : function(){
27206
this.root.collapse(true);
27210
getSelectionModel : function(){
27211
if(!this.selModel){
27212
this.selModel = new Ext.tree.DefaultSelectionModel();
27214
return this.selModel;
27218
expandPath : function(path, attr, callback){
27219
attr = attr || "id";
27220
var keys = path.split(this.pathSeparator);
27221
var curNode = this.root;
27222
if(curNode.attributes[attr] != keys[1]){ // invalid root
27224
callback(false, null);
27229
var f = function(){
27230
if(++index == keys.length){
27232
callback(true, curNode);
27236
var c = curNode.findChild(attr, keys[index]);
27239
callback(false, curNode);
27244
c.expand(false, false, f);
27246
curNode.expand(false, false, f);
27250
selectPath : function(path, attr, callback){
27251
attr = attr || "id";
27252
var keys = path.split(this.pathSeparator);
27253
var v = keys.pop();
27254
if(keys.length > 0){
27255
var f = function(success, node){
27256
if(success && node){
27257
var n = node.findChild(attr, v);
27263
}else if(callback){
27264
callback(false, n);
27268
callback(false, n);
27272
this.expandPath(keys.join(this.pathSeparator), attr, f);
27274
this.root.select();
27276
callback(true, this.root);
27282
getTreeEl : function(){
27287
onRender : function(ct, position){
27288
Ext.tree.TreePanel.superclass.onRender.call(this, ct, position);
27289
this.el.addClass('x-tree');
27290
this.innerCt = this.body.createChild({tag:"ul",
27291
cls:"x-tree-root-ct " +
27292
(this.useArrows ? 'x-tree-arrows' : this.lines ? "x-tree-lines" : "x-tree-no-lines")});
27296
initEvents : function(){
27297
Ext.tree.TreePanel.superclass.initEvents.call(this);
27299
if(this.containerScroll){
27300
Ext.dd.ScrollManager.register(this.body);
27302
if((this.enableDD || this.enableDrop) && !this.dropZone){
27304
this.dropZone = new Ext.tree.TreeDropZone(this, this.dropConfig || {
27305
ddGroup: this.ddGroup || "TreeDD", appendOnly: this.ddAppendOnly === true
27308
if((this.enableDD || this.enableDrag) && !this.dragZone){
27310
this.dragZone = new Ext.tree.TreeDragZone(this, this.dragConfig || {
27311
ddGroup: this.ddGroup || "TreeDD",
27312
scroll: this.ddScroll
27315
this.getSelectionModel().init(this);
27319
afterRender : function(){
27320
Ext.tree.TreePanel.superclass.afterRender.call(this);
27321
this.root.render();
27322
if(!this.rootVisible){
27323
this.root.renderChildren();
27327
onDestroy : function(){
27329
this.body.removeAllListeners();
27330
Ext.dd.ScrollManager.unregister(this.body);
27332
this.dropZone.unreg();
27335
this.dragZone.unreg();
27338
this.root.destroy();
27339
this.nodeHash = null;
27340
Ext.tree.TreePanel.superclass.onDestroy.call(this);
27391
Ext.tree.TreePanel.nodeTypes = {};
27393
Ext.reg('treepanel', Ext.tree.TreePanel);
27394
Ext.tree.TreeEventModel = function(tree){
27396
this.tree.on('render', this.initEvents, this);
27399
Ext.tree.TreeEventModel.prototype = {
27400
initEvents : function(){
27401
var el = this.tree.getTreeEl();
27402
el.on('click', this.delegateClick, this);
27403
if(this.tree.trackMouseOver !== false){
27404
this.tree.innerCt.on('mouseover', this.delegateOver, this);
27405
this.tree.innerCt.on('mouseout', this.delegateOut, this);
27407
el.on('dblclick', this.delegateDblClick, this);
27408
el.on('contextmenu', this.delegateContextMenu, this);
27411
getNode : function(e){
27413
if(t = e.getTarget('.x-tree-node-el', 10)){
27414
var id = Ext.fly(t, '_treeEvents').getAttribute('tree-node-id', 'ext');
27416
return this.tree.getNodeById(id);
27422
getNodeTarget : function(e){
27423
var t = e.getTarget('.x-tree-node-icon', 1);
27425
t = e.getTarget('.x-tree-node-el', 6);
27430
delegateOut : function(e, t){
27431
if(!this.beforeEvent(e)){
27434
if(e.getTarget('.x-tree-ec-icon', 1)){
27435
var n = this.getNode(e);
27436
this.onIconOut(e, n);
27437
if(n == this.lastEcOver){
27438
delete this.lastEcOver;
27441
if((t = this.getNodeTarget(e)) && !e.within(t, true)){
27442
this.onNodeOut(e, this.getNode(e));
27446
delegateOver : function(e, t){
27447
if(!this.beforeEvent(e)){
27450
if(Ext.isGecko && !this.trackingDoc){ // prevent hanging in FF
27451
Ext.getBody().on('mouseover', this.trackExit, this);
27452
this.trackingDoc = true;
27454
if(this.lastEcOver){ // prevent hung highlight
27455
this.onIconOut(e, this.lastEcOver);
27456
delete this.lastEcOver;
27458
if(e.getTarget('.x-tree-ec-icon', 1)){
27459
this.lastEcOver = this.getNode(e);
27460
this.onIconOver(e, this.lastEcOver);
27462
if(t = this.getNodeTarget(e)){
27463
this.onNodeOver(e, this.getNode(e));
27467
trackExit : function(e){
27468
if(this.lastOverNode && !e.within(this.lastOverNode.ui.getEl())){
27469
this.onNodeOut(e, this.lastOverNode);
27470
delete this.lastOverNode;
27471
Ext.getBody().un('mouseover', this.trackExit, this);
27472
this.trackingDoc = false;
27476
delegateClick : function(e, t){
27477
if(!this.beforeEvent(e)){
27481
if(e.getTarget('input[type=checkbox]', 1)){
27482
this.onCheckboxClick(e, this.getNode(e));
27484
else if(e.getTarget('.x-tree-ec-icon', 1)){
27485
this.onIconClick(e, this.getNode(e));
27487
else if(this.getNodeTarget(e)){
27488
this.onNodeClick(e, this.getNode(e));
27492
delegateDblClick : function(e, t){
27493
if(this.beforeEvent(e) && this.getNodeTarget(e)){
27494
this.onNodeDblClick(e, this.getNode(e));
27498
delegateContextMenu : function(e, t){
27499
if(this.beforeEvent(e) && this.getNodeTarget(e)){
27500
this.onNodeContextMenu(e, this.getNode(e));
27504
onNodeClick : function(e, node){
27505
node.ui.onClick(e);
27508
onNodeOver : function(e, node){
27509
this.lastOverNode = node;
27513
onNodeOut : function(e, node){
27517
onIconOver : function(e, node){
27518
node.ui.addClass('x-tree-ec-over');
27521
onIconOut : function(e, node){
27522
node.ui.removeClass('x-tree-ec-over');
27525
onIconClick : function(e, node){
27526
node.ui.ecClick(e);
27529
onCheckboxClick : function(e, node){
27530
node.ui.onCheckChange(e);
27533
onNodeDblClick : function(e, node){
27534
node.ui.onDblClick(e);
27537
onNodeContextMenu : function(e, node){
27538
node.ui.onContextMenu(e);
27541
beforeEvent : function(e){
27549
disable: function(){
27550
this.disabled = true;
27553
enable: function(){
27554
this.disabled = false;
27558
Ext.tree.DefaultSelectionModel = function(config){
27559
this.selNode = null;
27569
Ext.apply(this, config);
27570
Ext.tree.DefaultSelectionModel.superclass.constructor.call(this);
27573
Ext.extend(Ext.tree.DefaultSelectionModel, Ext.util.Observable, {
27574
init : function(tree){
27576
tree.getTreeEl().on("keydown", this.onKeyDown, this);
27577
tree.on("click", this.onNodeClick, this);
27580
onNodeClick : function(node, e){
27585
select : function(node){
27586
var last = this.selNode;
27588
node.ui.onSelectedChange(true);
27589
}else if(this.fireEvent('beforeselect', this, node, last) !== false){
27591
last.ui.onSelectedChange(false);
27593
this.selNode = node;
27594
node.ui.onSelectedChange(true);
27595
this.fireEvent("selectionchange", this, node, last);
27601
unselect : function(node){
27602
if(this.selNode == node){
27603
this.clearSelections();
27608
clearSelections : function(){
27609
var n = this.selNode;
27611
n.ui.onSelectedChange(false);
27612
this.selNode = null;
27613
this.fireEvent("selectionchange", this, null);
27619
getSelectedNode : function(){
27620
return this.selNode;
27624
isSelected : function(node){
27625
return this.selNode == node;
27629
selectPrevious : function(){
27630
var s = this.selNode || this.lastSelNode;
27634
var ps = s.previousSibling;
27636
if(!ps.isExpanded() || ps.childNodes.length < 1){
27637
return this.select(ps);
27639
var lc = ps.lastChild;
27640
while(lc && lc.isExpanded() && lc.childNodes.length > 0){
27643
return this.select(lc);
27645
} else if(s.parentNode && (this.tree.rootVisible || !s.parentNode.isRoot)){
27646
return this.select(s.parentNode);
27652
selectNext : function(){
27653
var s = this.selNode || this.lastSelNode;
27657
if(s.firstChild && s.isExpanded()){
27658
return this.select(s.firstChild);
27659
}else if(s.nextSibling){
27660
return this.select(s.nextSibling);
27661
}else if(s.parentNode){
27663
s.parentNode.bubble(function(){
27664
if(this.nextSibling){
27665
newS = this.getOwnerTree().selModel.select(this.nextSibling);
27674
onKeyDown : function(e){
27675
var s = this.selNode || this.lastSelNode;
27676
// undesirable, but required
27681
var k = e.getKey();
27689
this.selectPrevious();
27692
e.preventDefault();
27693
if(s.hasChildNodes()){
27694
if(!s.isExpanded()){
27696
}else if(s.firstChild){
27697
this.select(s.firstChild, e);
27702
e.preventDefault();
27703
if(s.hasChildNodes() && s.isExpanded()){
27705
}else if(s.parentNode && (this.tree.rootVisible || s.parentNode != this.tree.getRootNode())){
27706
this.select(s.parentNode, e);
27714
Ext.tree.MultiSelectionModel = function(config){
27715
this.selNodes = [];
27721
Ext.apply(this, config);
27722
Ext.tree.MultiSelectionModel.superclass.constructor.call(this);
27725
Ext.extend(Ext.tree.MultiSelectionModel, Ext.util.Observable, {
27726
init : function(tree){
27728
tree.getTreeEl().on("keydown", this.onKeyDown, this);
27729
tree.on("click", this.onNodeClick, this);
27732
onNodeClick : function(node, e){
27733
if(e.ctrlKey && this.isSelected(node)){
27734
this.unselect(node);
27736
this.select(node, e, e.ctrlKey);
27741
select : function(node, e, keepExisting){
27742
if(keepExisting !== true){
27743
this.clearSelections(true);
27745
if(this.isSelected(node)){
27746
this.lastSelNode = node;
27749
this.selNodes.push(node);
27750
this.selMap[node.id] = node;
27751
this.lastSelNode = node;
27752
node.ui.onSelectedChange(true);
27753
this.fireEvent("selectionchange", this, this.selNodes);
27758
unselect : function(node){
27759
if(this.selMap[node.id]){
27760
node.ui.onSelectedChange(false);
27761
var sn = this.selNodes;
27762
var index = sn.indexOf(node);
27764
this.selNodes.splice(index, 1);
27766
delete this.selMap[node.id];
27767
this.fireEvent("selectionchange", this, this.selNodes);
27772
clearSelections : function(suppressEvent){
27773
var sn = this.selNodes;
27775
for(var i = 0, len = sn.length; i < len; i++){
27776
sn[i].ui.onSelectedChange(false);
27778
this.selNodes = [];
27780
if(suppressEvent !== true){
27781
this.fireEvent("selectionchange", this, this.selNodes);
27787
isSelected : function(node){
27788
return this.selMap[node.id] ? true : false;
27792
getSelectedNodes : function(){
27793
return this.selNodes;
27796
onKeyDown : Ext.tree.DefaultSelectionModel.prototype.onKeyDown,
27798
selectNext : Ext.tree.DefaultSelectionModel.prototype.selectNext,
27800
selectPrevious : Ext.tree.DefaultSelectionModel.prototype.selectPrevious
27803
Ext.tree.TreeNode = function(attributes){
27804
attributes = attributes || {};
27805
if(typeof attributes == "string"){
27806
attributes = {text: attributes};
27808
this.childrenRendered = false;
27809
this.rendered = false;
27810
Ext.tree.TreeNode.superclass.constructor.call(this, attributes);
27811
this.expanded = attributes.expanded === true;
27812
this.isTarget = attributes.isTarget !== false;
27813
this.draggable = attributes.draggable !== false && attributes.allowDrag !== false;
27814
this.allowChildren = attributes.allowChildren !== false && attributes.allowDrop !== false;
27817
this.text = attributes.text;
27819
this.disabled = attributes.disabled === true;
27821
this.hidden = attributes.hidden === true;
27847
"beforechildrenrendered"
27850
var uiClass = this.attributes.uiProvider || this.defaultUI || Ext.tree.TreeNodeUI;
27853
this.ui = new uiClass(this);
27855
Ext.extend(Ext.tree.TreeNode, Ext.data.Node, {
27856
preventHScroll: true,
27858
isExpanded : function(){
27859
return this.expanded;
27863
getUI : function(){
27867
getLoader : function(){
27869
return this.loader || ((owner = this.getOwnerTree()) && owner.loader ? owner.loader : new Ext.tree.TreeLoader());
27872
// private override
27873
setFirstChild : function(node){
27874
var of = this.firstChild;
27875
Ext.tree.TreeNode.superclass.setFirstChild.call(this, node);
27876
if(this.childrenRendered && of && node != of){
27877
of.renderIndent(true, true);
27880
this.renderIndent(true, true);
27884
// private override
27885
setLastChild : function(node){
27886
var ol = this.lastChild;
27887
Ext.tree.TreeNode.superclass.setLastChild.call(this, node);
27888
if(this.childrenRendered && ol && node != ol){
27889
ol.renderIndent(true, true);
27892
this.renderIndent(true, true);
27896
// these methods are overridden to provide lazy rendering support
27897
// private override
27898
appendChild : function(n){
27899
if(!n.render && !Ext.isArray(n)){
27900
n = this.getLoader().createNode(n);
27902
var node = Ext.tree.TreeNode.superclass.appendChild.call(this, n);
27903
if(node && this.childrenRendered){
27906
this.ui.updateExpandIcon();
27910
// private override
27911
removeChild : function(node){
27912
this.ownerTree.getSelectionModel().unselect(node);
27913
Ext.tree.TreeNode.superclass.removeChild.apply(this, arguments);
27914
// if it's been rendered remove dom node
27915
if(this.childrenRendered){
27918
if(this.childNodes.length < 1){
27919
this.collapse(false, false);
27921
this.ui.updateExpandIcon();
27923
if(!this.firstChild && !this.isHiddenRoot()) {
27924
this.childrenRendered = false;
27929
// private override
27930
insertBefore : function(node, refNode){
27932
node = this.getLoader().createNode(node);
27934
var newNode = Ext.tree.TreeNode.superclass.insertBefore.call(this, node, refNode);
27935
if(newNode && refNode && this.childrenRendered){
27938
this.ui.updateExpandIcon();
27943
setText : function(text){
27944
var oldText = this.text;
27946
this.attributes.text = text;
27947
if(this.rendered){ // event without subscribing
27948
this.ui.onTextChange(this, text, oldText);
27950
this.fireEvent("textchange", this, text, oldText);
27954
select : function(){
27955
this.getOwnerTree().getSelectionModel().select(this);
27959
unselect : function(){
27960
this.getOwnerTree().getSelectionModel().unselect(this);
27964
isSelected : function(){
27965
return this.getOwnerTree().getSelectionModel().isSelected(this);
27969
expand : function(deep, anim, callback, scope){
27970
if(!this.expanded){
27971
if(this.fireEvent("beforeexpand", this, deep, anim) === false){
27974
if(!this.childrenRendered){
27975
this.renderChildren();
27977
this.expanded = true;
27978
if(!this.isHiddenRoot() && (this.getOwnerTree().animate && anim !== false) || anim){
27979
this.ui.animExpand(function(){
27980
this.fireEvent("expand", this);
27981
this.runCallback(callback, scope || this, [this]);
27983
this.expandChildNodes(true);
27985
}.createDelegate(this));
27989
this.fireEvent("expand", this);
27990
this.runCallback(callback, scope || this, [this]);
27993
this.runCallback(callback, scope || this, [this]);
27996
this.expandChildNodes(true);
28000
runCallback: function(cb, scope, args){
28001
if(Ext.isFunction(cb)){
28002
cb.apply(scope, args);
28006
isHiddenRoot : function(){
28007
return this.isRoot && !this.getOwnerTree().rootVisible;
28011
collapse : function(deep, anim, callback, scope){
28012
if(this.expanded && !this.isHiddenRoot()){
28013
if(this.fireEvent("beforecollapse", this, deep, anim) === false){
28016
this.expanded = false;
28017
if((this.getOwnerTree().animate && anim !== false) || anim){
28018
this.ui.animCollapse(function(){
28019
this.fireEvent("collapse", this);
28020
this.runCallback(callback, scope || this, [this]);
28022
this.collapseChildNodes(true);
28024
}.createDelegate(this));
28027
this.ui.collapse();
28028
this.fireEvent("collapse", this);
28029
this.runCallback(callback, scope || this, [this]);
28031
}else if(!this.expanded){
28032
this.runCallback(callback, scope || this, [this]);
28035
var cs = this.childNodes;
28036
for(var i = 0, len = cs.length; i < len; i++) {
28037
cs[i].collapse(true, false);
28043
delayedExpand : function(delay){
28044
if(!this.expandProcId){
28045
this.expandProcId = this.expand.defer(delay, this);
28050
cancelExpand : function(){
28051
if(this.expandProcId){
28052
clearTimeout(this.expandProcId);
28054
this.expandProcId = false;
28058
toggle : function(){
28067
ensureVisible : function(callback, scope){
28068
var tree = this.getOwnerTree();
28069
tree.expandPath(this.parentNode ? this.parentNode.getPath() : this.getPath(), false, function(){
28070
var node = tree.getNodeById(this.id); // Somehow if we don't do this, we lose changes that happened to node in the meantime
28071
tree.getTreeEl().scrollChildIntoView(node.ui.anchor);
28072
this.runCallback(callback, scope || this, [this]);
28073
}.createDelegate(this));
28077
expandChildNodes : function(deep){
28078
var cs = this.childNodes;
28079
for(var i = 0, len = cs.length; i < len; i++) {
28080
cs[i].expand(deep);
28085
collapseChildNodes : function(deep){
28086
var cs = this.childNodes;
28087
for(var i = 0, len = cs.length; i < len; i++) {
28088
cs[i].collapse(deep);
28093
disable : function(){
28094
this.disabled = true;
28096
if(this.rendered && this.ui.onDisableChange){ // event without subscribing
28097
this.ui.onDisableChange(this, true);
28099
this.fireEvent("disabledchange", this, true);
28103
enable : function(){
28104
this.disabled = false;
28105
if(this.rendered && this.ui.onDisableChange){ // event without subscribing
28106
this.ui.onDisableChange(this, false);
28108
this.fireEvent("disabledchange", this, false);
28112
renderChildren : function(suppressEvent){
28113
if(suppressEvent !== false){
28114
this.fireEvent("beforechildrenrendered", this);
28116
var cs = this.childNodes;
28117
for(var i = 0, len = cs.length; i < len; i++){
28118
cs[i].render(true);
28120
this.childrenRendered = true;
28124
sort : function(fn, scope){
28125
Ext.tree.TreeNode.superclass.sort.apply(this, arguments);
28126
if(this.childrenRendered){
28127
var cs = this.childNodes;
28128
for(var i = 0, len = cs.length; i < len; i++){
28129
cs[i].render(true);
28135
render : function(bulkRender){
28136
this.ui.render(bulkRender);
28137
if(!this.rendered){
28138
// make sure it is registered
28139
this.getOwnerTree().registerNode(this);
28140
this.rendered = true;
28142
this.expanded = false;
28143
this.expand(false, false);
28149
renderIndent : function(deep, refresh){
28151
this.ui.childIndent = null;
28153
this.ui.renderIndent();
28154
if(deep === true && this.childrenRendered){
28155
var cs = this.childNodes;
28156
for(var i = 0, len = cs.length; i < len; i++){
28157
cs[i].renderIndent(true, refresh);
28162
beginUpdate : function(){
28163
this.childrenRendered = false;
28166
endUpdate : function(){
28167
if(this.expanded && this.rendered){
28168
this.renderChildren();
28172
destroy : function(){
28173
if(this.childNodes){
28174
for(var i = 0,l = this.childNodes.length; i < l; i++){
28175
this.childNodes[i].destroy();
28177
this.childNodes = null;
28179
if(this.ui.destroy){
28185
onIdChange: function(id){
28186
this.ui.onIdChange(id);
28190
Ext.tree.TreePanel.nodeTypes.node = Ext.tree.TreeNode;
28192
Ext.tree.AsyncTreeNode = function(config){
28193
this.loaded = config && config.loaded === true;
28194
this.loading = false;
28195
Ext.tree.AsyncTreeNode.superclass.constructor.apply(this, arguments);
28197
this.addEvents('beforeload', 'load');
28201
Ext.extend(Ext.tree.AsyncTreeNode, Ext.tree.TreeNode, {
28202
expand : function(deep, anim, callback, scope){
28203
if(this.loading){ // if an async load is already running, waiting til it's done
28205
var f = function(){
28206
if(!this.loading){ // done loading
28207
clearInterval(timer);
28208
this.expand(deep, anim, callback, scope);
28210
}.createDelegate(this);
28211
timer = setInterval(f, 200);
28215
if(this.fireEvent("beforeload", this) === false){
28218
this.loading = true;
28219
this.ui.beforeLoad(this);
28220
var loader = this.loader || this.attributes.loader || this.getOwnerTree().getLoader();
28222
loader.load(this, this.loadComplete.createDelegate(this, [deep, anim, callback, scope]), this);
28226
Ext.tree.AsyncTreeNode.superclass.expand.call(this, deep, anim, callback, scope);
28230
isLoading : function(){
28231
return this.loading;
28234
loadComplete : function(deep, anim, callback, scope){
28235
this.loading = false;
28236
this.loaded = true;
28237
this.ui.afterLoad(this);
28238
this.fireEvent("load", this);
28239
this.expand(deep, anim, callback, scope);
28243
isLoaded : function(){
28244
return this.loaded;
28247
hasChildNodes : function(){
28248
if(!this.isLeaf() && !this.loaded){
28251
return Ext.tree.AsyncTreeNode.superclass.hasChildNodes.call(this);
28256
reload : function(callback, scope){
28257
this.collapse(false, false);
28258
while(this.firstChild){
28259
this.removeChild(this.firstChild).destroy();
28261
this.childrenRendered = false;
28262
this.loaded = false;
28263
if(this.isHiddenRoot()){
28264
this.expanded = false;
28266
this.expand(false, false, callback, scope);
28270
Ext.tree.TreePanel.nodeTypes.async = Ext.tree.AsyncTreeNode;
28272
Ext.tree.TreeNodeUI = function(node){
28274
this.rendered = false;
28275
this.animating = false;
28276
this.wasLeaf = true;
28277
this.ecc = 'x-tree-ec-icon x-tree-elbow';
28278
this.emptyIcon = Ext.BLANK_IMAGE_URL;
28281
Ext.tree.TreeNodeUI.prototype = {
28283
removeChild : function(node){
28285
this.ctNode.removeChild(node.ui.getEl());
28290
beforeLoad : function(){
28291
this.addClass("x-tree-node-loading");
28295
afterLoad : function(){
28296
this.removeClass("x-tree-node-loading");
28300
onTextChange : function(node, text, oldText){
28302
this.textNode.innerHTML = text;
28307
onDisableChange : function(node, state){
28308
this.disabled = state;
28309
if (this.checkbox) {
28310
this.checkbox.disabled = state;
28313
this.addClass("x-tree-node-disabled");
28315
this.removeClass("x-tree-node-disabled");
28320
onSelectedChange : function(state){
28323
this.addClass("x-tree-selected");
28326
this.removeClass("x-tree-selected");
28331
onMove : function(tree, node, oldParent, newParent, index, refNode){
28332
this.childIndent = null;
28334
var targetNode = newParent.ui.getContainer();
28335
if(!targetNode){//target not rendered
28336
this.holder = document.createElement("div");
28337
this.holder.appendChild(this.wrap);
28340
var insertBefore = refNode ? refNode.ui.getEl() : null;
28342
targetNode.insertBefore(this.wrap, insertBefore);
28344
targetNode.appendChild(this.wrap);
28346
this.node.renderIndent(true);
28351
addClass : function(cls){
28353
Ext.fly(this.elNode).addClass(cls);
28358
removeClass : function(cls){
28360
Ext.fly(this.elNode).removeClass(cls);
28365
remove : function(){
28367
this.holder = document.createElement("div");
28368
this.holder.appendChild(this.wrap);
28373
fireEvent : function(){
28374
return this.node.fireEvent.apply(this.node, arguments);
28378
initEvents : function(){
28379
this.node.on("move", this.onMove, this);
28381
if(this.node.disabled){
28382
this.addClass("x-tree-node-disabled");
28383
if (this.checkbox) {
28384
this.checkbox.disabled = true;
28387
if(this.node.hidden){
28390
var ot = this.node.getOwnerTree();
28391
var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
28392
if(dd && (!this.node.isRoot || ot.rootVisible)){
28393
Ext.dd.Registry.register(this.elNode, {
28395
handles: this.getDDHandles(),
28402
getDDHandles : function(){
28403
return [this.iconNode, this.textNode, this.elNode];
28408
this.node.hidden = true;
28410
this.wrap.style.display = "none";
28416
this.node.hidden = false;
28418
this.wrap.style.display = "";
28423
onContextMenu : function(e){
28424
if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
28425
e.preventDefault();
28427
this.fireEvent("contextmenu", this.node, e);
28432
onClick : function(e){
28437
if(this.fireEvent("beforeclick", this.node, e) !== false){
28438
var a = e.getTarget('a');
28439
if(!this.disabled && this.node.attributes.href && a){
28440
this.fireEvent("click", this.node, e);
28442
}else if(a && e.ctrlKey){
28445
e.preventDefault();
28450
if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){
28451
this.node.toggle();
28454
this.fireEvent("click", this.node, e);
28461
onDblClick : function(e){
28462
e.preventDefault();
28467
this.toggleCheck();
28469
if(!this.animating && this.node.isExpandable()){
28470
this.node.toggle();
28472
this.fireEvent("dblclick", this.node, e);
28475
onOver : function(e){
28476
this.addClass('x-tree-node-over');
28479
onOut : function(e){
28480
this.removeClass('x-tree-node-over');
28484
onCheckChange : function(){
28485
var checked = this.checkbox.checked;
28487
this.checkbox.defaultChecked = checked;
28488
this.node.attributes.checked = checked;
28489
this.fireEvent('checkchange', this.node, checked);
28493
ecClick : function(e){
28494
if(!this.animating && this.node.isExpandable()){
28495
this.node.toggle();
28500
startDrop : function(){
28501
this.dropping = true;
28504
// delayed drop so the click event doesn't get fired on a drop
28505
endDrop : function(){
28506
setTimeout(function(){
28507
this.dropping = false;
28508
}.createDelegate(this), 50);
28512
expand : function(){
28513
this.updateExpandIcon();
28514
this.ctNode.style.display = "";
28518
focus : function(){
28519
if(!this.node.preventHScroll){
28520
try{this.anchor.focus();
28524
var noscroll = this.node.getOwnerTree().getTreeEl().dom;
28525
var l = noscroll.scrollLeft;
28526
this.anchor.focus();
28527
noscroll.scrollLeft = l;
28533
toggleCheck : function(value){
28534
var cb = this.checkbox;
28536
cb.checked = (value === undefined ? !cb.checked : value);
28537
this.onCheckChange();
28544
this.anchor.blur();
28549
animExpand : function(callback){
28550
var ct = Ext.get(this.ctNode);
28552
if(!this.node.isExpandable()){
28553
this.updateExpandIcon();
28554
this.ctNode.style.display = "";
28555
Ext.callback(callback);
28558
this.animating = true;
28559
this.updateExpandIcon();
28562
callback : function(){
28563
this.animating = false;
28564
Ext.callback(callback);
28567
duration: this.node.ownerTree.duration || .25
28572
highlight : function(){
28573
var tree = this.node.getOwnerTree();
28574
Ext.fly(this.wrap).highlight(
28575
tree.hlColor || "C3DAF9",
28576
{endColor: tree.hlBaseColor}
28581
collapse : function(){
28582
this.updateExpandIcon();
28583
this.ctNode.style.display = "none";
28587
animCollapse : function(callback){
28588
var ct = Ext.get(this.ctNode);
28589
ct.enableDisplayMode('block');
28592
this.animating = true;
28593
this.updateExpandIcon();
28596
callback : function(){
28597
this.animating = false;
28598
Ext.callback(callback);
28601
duration: this.node.ownerTree.duration || .25
28606
getContainer : function(){
28607
return this.ctNode;
28611
getEl : function(){
28616
appendDDGhost : function(ghostNode){
28617
ghostNode.appendChild(this.elNode.cloneNode(true));
28621
getDDRepairXY : function(){
28622
return Ext.lib.Dom.getXY(this.iconNode);
28626
onRender : function(){
28631
render : function(bulkRender){
28632
var n = this.node, a = n.attributes;
28633
var targetNode = n.parentNode ?
28634
n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
28636
if(!this.rendered){
28637
this.rendered = true;
28639
this.renderElements(n, a, targetNode, bulkRender);
28642
if(this.textNode.setAttributeNS){
28643
this.textNode.setAttributeNS("ext", "qtip", a.qtip);
28645
this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);
28648
this.textNode.setAttribute("ext:qtip", a.qtip);
28650
this.textNode.setAttribute("ext:qtitle", a.qtipTitle);
28653
}else if(a.qtipCfg){
28654
a.qtipCfg.target = Ext.id(this.textNode);
28655
Ext.QuickTips.register(a.qtipCfg);
28658
if(!this.node.expanded){
28659
this.updateExpandIcon(true);
28662
if(bulkRender === true) {
28663
targetNode.appendChild(this.wrap);
28669
renderElements : function(n, a, targetNode, bulkRender){
28670
// add some indent caching, this helps performance when rendering a large tree
28671
this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
28673
var cb = typeof a.checked == 'boolean';
28675
var href = a.href ? a.href : Ext.isGecko ? "" : "#";
28676
var buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
28677
'<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
28678
'<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
28679
'<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
28680
cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
28681
'<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
28682
a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
28683
'<ul class="x-tree-node-ct" style="display:none;"></ul>',
28687
if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
28688
this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
28690
this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
28693
this.elNode = this.wrap.childNodes[0];
28694
this.ctNode = this.wrap.childNodes[1];
28695
var cs = this.elNode.childNodes;
28696
this.indentNode = cs[0];
28697
this.ecNode = cs[1];
28698
this.iconNode = cs[2];
28701
this.checkbox = cs[3];
28703
this.checkbox.defaultChecked = this.checkbox.checked;
28706
this.anchor = cs[index];
28707
this.textNode = cs[index].firstChild;
28711
getAnchor : function(){
28712
return this.anchor;
28716
getTextEl : function(){
28717
return this.textNode;
28721
getIconEl : function(){
28722
return this.iconNode;
28726
isChecked : function(){
28727
return this.checkbox ? this.checkbox.checked : false;
28731
updateExpandIcon : function(){
28733
var n = this.node, c1, c2;
28734
var cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow";
28735
var hasChild = n.hasChildNodes();
28736
if(hasChild || n.attributes.expandable){
28739
c1 = "x-tree-node-collapsed";
28740
c2 = "x-tree-node-expanded";
28743
c1 = "x-tree-node-expanded";
28744
c2 = "x-tree-node-collapsed";
28747
this.removeClass("x-tree-node-leaf");
28748
this.wasLeaf = false;
28750
if(this.c1 != c1 || this.c2 != c2){
28751
Ext.fly(this.elNode).replaceClass(c1, c2);
28752
this.c1 = c1; this.c2 = c2;
28756
Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-leaf");
28759
this.wasLeaf = true;
28762
var ecc = "x-tree-ec-icon "+cls;
28763
if(this.ecc != ecc){
28764
this.ecNode.className = ecc;
28771
onIdChange: function(id){
28773
this.elNode.setAttribute('ext:tree-node-id', id);
28778
getChildIndent : function(){
28779
if(!this.childIndent){
28783
if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
28785
buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
28787
buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-icon" />');
28792
this.childIndent = buf.join("");
28794
return this.childIndent;
28798
renderIndent : function(){
28801
var p = this.node.parentNode;
28803
indent = p.ui.getChildIndent();
28805
if(this.indentMarkup != indent){ // don't rerender if not required
28806
this.indentNode.innerHTML = indent;
28807
this.indentMarkup = indent;
28809
this.updateExpandIcon();
28813
destroy : function(){
28815
Ext.dd.Registry.unregister(this.elNode.id);
28817
delete this.elNode;
28818
delete this.ctNode;
28819
delete this.indentNode;
28820
delete this.ecNode;
28821
delete this.iconNode;
28822
delete this.checkbox;
28823
delete this.anchor;
28824
delete this.textNode;
28828
Ext.removeNode(this.holder);
28829
delete this.holder;
28831
Ext.removeNode(this.wrap);
28838
Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
28840
render : function(){
28841
if(!this.rendered){
28842
var targetNode = this.node.ownerTree.innerCt.dom;
28843
this.node.expanded = true;
28844
targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
28845
this.wrap = this.ctNode = targetNode.firstChild;
28848
collapse : Ext.emptyFn,
28849
expand : Ext.emptyFn
28852
Ext.tree.TreeLoader = function(config){
28853
this.baseParams = {};
28854
Ext.apply(this, config);
28864
Ext.tree.TreeLoader.superclass.constructor.call(this);
28865
if(typeof this.paramOrder == 'string'){
28866
this.paramOrder = this.paramOrder.split(/[\s,|]/);
28870
Ext.extend(Ext.tree.TreeLoader, Ext.util.Observable, {
28881
clearOnLoad : true,
28884
paramOrder: undefined,
28887
paramsAsHash: false,
28890
directFn : undefined,
28893
load : function(node, callback, scope){
28894
if(this.clearOnLoad){
28895
while(node.firstChild){
28896
node.removeChild(node.firstChild);
28899
if(this.doPreload(node)){ // preloaded json children
28900
this.runCallback(callback, scope || node);
28901
}else if(this.directFn || this.dataUrl || this.url){
28902
this.requestData(node, callback, scope || node);
28906
doPreload : function(node){
28907
if(node.attributes.children){
28908
if(node.childNodes.length < 1){ // preloaded?
28909
var cs = node.attributes.children;
28910
node.beginUpdate();
28911
for(var i = 0, len = cs.length; i < len; i++){
28912
var cn = node.appendChild(this.createNode(cs[i]));
28913
if(this.preloadChildren){
28914
this.doPreload(cn);
28924
getParams: function(node){
28925
var buf = [], bp = this.baseParams;
28929
if(this.paramOrder){
28930
for(var i = 0, len = this.paramOrder.length; i < len; i++){
28931
buf.push(bp[this.paramOrder[i]]);
28933
}else if(this.paramsAsHash){
28939
for(var key in bp){
28940
if(!Ext.isFunction(bp[key])){
28941
buf.push(encodeURIComponent(key), "=", encodeURIComponent(bp[key]), "&");
28944
buf.push("node=", encodeURIComponent(node.id));
28945
return buf.join("");
28949
requestData : function(node, callback, scope){
28950
if(this.fireEvent("beforeload", this, node, callback) !== false){
28952
var args = this.getParams(node);
28953
args.push(this.processDirectResponse.createDelegate(this, [{callback: callback, node: node, scope: scope}], true));
28954
this.directFn.apply(window, args);
28956
this.transId = Ext.Ajax.request({
28957
method:this.requestMethod,
28958
url: this.dataUrl||this.url,
28959
success: this.handleResponse,
28960
failure: this.handleFailure,
28962
argument: {callback: callback, node: node, scope: scope},
28963
params: this.getParams(node)
28967
// if the load is cancelled, make sure we notify
28968
// the node that we are done
28969
this.runCallback(callback, scope || node);
28973
processDirectResponse: function(result, response, args){
28974
if(response.status){
28975
this.processResponse({
28976
responseData: Ext.isArray(result) ? result : null,
28977
responseText: result,
28979
}, args.node, args.callback, args.scope);
28981
this.handleFailure({
28988
runCallback: function(cb, scope, args){
28989
if(Ext.isFunction(cb)){
28990
cb.apply(scope, args);
28994
isLoading : function(){
28995
return !!this.transId;
28998
abort : function(){
28999
if(this.isLoading()){
29000
Ext.Ajax.abort(this.transId);
29005
createNode : function(attr){
29006
// apply baseAttrs, nice idea Corey!
29007
if(this.baseAttrs){
29008
Ext.applyIf(attr, this.baseAttrs);
29010
if(this.applyLoader !== false){
29011
attr.loader = this;
29013
if(typeof attr.uiProvider == 'string'){
29014
attr.uiProvider = this.uiProviders[attr.uiProvider] || eval(attr.uiProvider);
29017
return new Ext.tree.TreePanel.nodeTypes[attr.nodeType](attr);
29020
new Ext.tree.TreeNode(attr) :
29021
new Ext.tree.AsyncTreeNode(attr);
29025
processResponse : function(response, node, callback, scope){
29026
var json = response.responseText;
29028
var o = response.responseData || Ext.decode(json);
29029
node.beginUpdate();
29030
for(var i = 0, len = o.length; i < len; i++){
29031
var n = this.createNode(o[i]);
29033
node.appendChild(n);
29037
this.runCallback(callback, scope || node, [node]);
29039
this.handleFailure(response);
29043
handleResponse : function(response){
29044
this.transId = false;
29045
var a = response.argument;
29046
this.processResponse(response, a.node, a.callback, a.scope);
29047
this.fireEvent("load", this, a.node, response);
29050
handleFailure : function(response){
29051
this.transId = false;
29052
var a = response.argument;
29053
this.fireEvent("loadexception", this, a.node, response);
29054
this.runCallback(a.callback, a.scope || a.node, [a.node]);
29058
Ext.tree.TreeFilter = function(tree, config){
29060
this.filtered = {};
29061
Ext.apply(this, config);
29064
Ext.tree.TreeFilter.prototype = {
29071
filter : function(value, attr, startNode){
29072
attr = attr || "text";
29074
if(typeof value == "string"){
29075
var vlen = value.length;
29076
// auto clear empty filter
29077
if(vlen == 0 && this.clearBlank){
29081
value = value.toLowerCase();
29083
return n.attributes[attr].substr(0, vlen).toLowerCase() == value;
29085
}else if(value.exec){ // regex?
29087
return value.test(n.attributes[attr]);
29090
throw 'Illegal filter type, must be string or regex';
29092
this.filterBy(f, null, startNode);
29096
filterBy : function(fn, scope, startNode){
29097
startNode = startNode || this.tree.root;
29098
if(this.autoClear){
29101
var af = this.filtered, rv = this.reverse;
29102
var f = function(n){
29103
if(n == startNode){
29109
var m = fn.call(scope || n, n);
29117
startNode.cascade(f);
29120
if(typeof id != "function"){
29122
if(n && n.parentNode){
29123
n.parentNode.removeChild(n);
29131
clear : function(){
29133
var af = this.filtered;
29135
if(typeof id != "function"){
29142
this.filtered = {};
29147
Ext.tree.TreeSorter = function(tree, config){
29155
Ext.apply(this, config);
29156
tree.on("beforechildrenrendered", this.doSort, this);
29157
tree.on("append", this.updateSort, this);
29158
tree.on("insert", this.updateSort, this);
29159
tree.on("textchange", this.updateSortParent, this);
29161
var dsc = this.dir && this.dir.toLowerCase() == "desc";
29162
var p = this.property || "text";
29163
var sortType = this.sortType;
29164
var fs = this.folderSort;
29165
var cs = this.caseSensitive === true;
29166
var leafAttr = this.leafAttr || 'leaf';
29168
this.sortFn = function(n1, n2){
29170
if(n1.attributes[leafAttr] && !n2.attributes[leafAttr]){
29173
if(!n1.attributes[leafAttr] && n2.attributes[leafAttr]){
29177
var v1 = sortType ? sortType(n1) : (cs ? n1.attributes[p] : n1.attributes[p].toUpperCase());
29178
var v2 = sortType ? sortType(n2) : (cs ? n2.attributes[p] : n2.attributes[p].toUpperCase());
29180
return dsc ? +1 : -1;
29182
return dsc ? -1 : +1;
29189
Ext.tree.TreeSorter.prototype = {
29190
doSort : function(node){
29191
node.sort(this.sortFn);
29194
compareNodes : function(n1, n2){
29195
return (n1.text.toUpperCase() > n2.text.toUpperCase() ? 1 : -1);
29198
updateSort : function(tree, node){
29199
if(node.childrenRendered){
29200
this.doSort.defer(1, this, [node]);
29204
updateSortParent : function(node){
29205
var p = node.parentNode;
29206
if(p && p.childrenRendered){
29207
this.doSort.defer(1, this, [p]);
29212
if(Ext.dd.DropZone){
29214
Ext.tree.TreeDropZone = function(tree, config){
29216
this.allowParentInsert = config.allowParentInsert || false;
29218
this.allowContainerDrop = config.allowContainerDrop || false;
29220
this.appendOnly = config.appendOnly || false;
29222
Ext.tree.TreeDropZone.superclass.constructor.call(this, tree.getTreeEl(), config);
29226
this.dragOverData = {};
29228
this.lastInsertClass = "x-tree-no-status";
29231
Ext.extend(Ext.tree.TreeDropZone, Ext.dd.DropZone, {
29233
ddGroup : "TreeDD",
29236
expandDelay : 1000,
29239
expandNode : function(node){
29240
if(node.hasChildNodes() && !node.isExpanded()){
29241
node.expand(false, null, this.triggerCacheRefresh.createDelegate(this));
29246
queueExpand : function(node){
29247
this.expandProcId = this.expandNode.defer(this.expandDelay, this, [node]);
29251
cancelExpand : function(){
29252
if(this.expandProcId){
29253
clearTimeout(this.expandProcId);
29254
this.expandProcId = false;
29259
isValidDropPoint : function(n, pt, dd, e, data){
29260
if(!n || !data){ return false; }
29261
var targetNode = n.node;
29262
var dropNode = data.node;
29263
// default drop rules
29264
if(!(targetNode && targetNode.isTarget && pt)){
29267
if(pt == "append" && targetNode.allowChildren === false){
29270
if((pt == "above" || pt == "below") && (targetNode.parentNode && targetNode.parentNode.allowChildren === false)){
29273
if(dropNode && (targetNode == dropNode || dropNode.contains(targetNode))){
29276
// reuse the object
29277
var overEvent = this.dragOverData;
29278
overEvent.tree = this.tree;
29279
overEvent.target = targetNode;
29280
overEvent.data = data;
29281
overEvent.point = pt;
29282
overEvent.source = dd;
29283
overEvent.rawEvent = e;
29284
overEvent.dropNode = dropNode;
29285
overEvent.cancel = false;
29286
var result = this.tree.fireEvent("nodedragover", overEvent);
29287
return overEvent.cancel === false && result !== false;
29291
getDropPoint : function(e, n, dd){
29294
return tn.allowChildren !== false ? "append" : false; // always append for root
29296
var dragEl = n.ddel;
29297
var t = Ext.lib.Dom.getY(dragEl), b = t + dragEl.offsetHeight;
29298
var y = Ext.lib.Event.getPageY(e);
29299
var noAppend = tn.allowChildren === false || tn.isLeaf();
29300
if(this.appendOnly || tn.parentNode.allowChildren === false){
29301
return noAppend ? false : "append";
29303
var noBelow = false;
29304
if(!this.allowParentInsert){
29305
noBelow = tn.hasChildNodes() && tn.isExpanded();
29307
var q = (b - t) / (noAppend ? 2 : 3);
29308
if(y >= t && y < (t + q)){
29310
}else if(!noBelow && (noAppend || y >= b-q && y <= b)){
29318
onNodeEnter : function(n, dd, e, data){
29319
this.cancelExpand();
29322
onContainerOver : function(dd, e, data) {
29323
if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
29324
return this.dropAllowed;
29326
return this.dropNotAllowed;
29330
onNodeOver : function(n, dd, e, data){
29331
var pt = this.getDropPoint(e, n, dd);
29334
// auto node expand check
29335
if(!this.expandProcId && pt == "append" && node.hasChildNodes() && !n.node.isExpanded()){
29336
this.queueExpand(node);
29337
}else if(pt != "append"){
29338
this.cancelExpand();
29341
// set the insert point style on the target node
29342
var returnCls = this.dropNotAllowed;
29343
if(this.isValidDropPoint(n, pt, dd, e, data)){
29348
returnCls = n.node.isFirst() ? "x-tree-drop-ok-above" : "x-tree-drop-ok-between";
29349
cls = "x-tree-drag-insert-above";
29350
}else if(pt == "below"){
29351
returnCls = n.node.isLast() ? "x-tree-drop-ok-below" : "x-tree-drop-ok-between";
29352
cls = "x-tree-drag-insert-below";
29354
returnCls = "x-tree-drop-ok-append";
29355
cls = "x-tree-drag-append";
29357
if(this.lastInsertClass != cls){
29358
Ext.fly(el).replaceClass(this.lastInsertClass, cls);
29359
this.lastInsertClass = cls;
29367
onNodeOut : function(n, dd, e, data){
29368
this.cancelExpand();
29369
this.removeDropIndicators(n);
29373
onNodeDrop : function(n, dd, e, data){
29374
var point = this.getDropPoint(e, n, dd);
29375
var targetNode = n.node;
29376
targetNode.ui.startDrop();
29377
if(!this.isValidDropPoint(n, point, dd, e, data)){
29378
targetNode.ui.endDrop();
29381
// first try to find the drop node
29382
var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, point, e) : null);
29383
return this.processDrop(targetNode, data, point, dd, e, dropNode);
29386
onContainerDrop : function(dd, e, data){
29387
if (this.allowContainerDrop && this.isValidDropPoint({ ddel: this.tree.getRootNode().ui.elNode, node: this.tree.getRootNode() }, "append", dd, e, data)) {
29388
var targetNode = this.tree.getRootNode();
29389
targetNode.ui.startDrop();
29390
var dropNode = data.node || (dd.getTreeNode ? dd.getTreeNode(data, targetNode, 'append', e) : null);
29391
return this.processDrop(targetNode, data, 'append', dd, e, dropNode);
29397
processDrop: function(target, data, point, dd, e, dropNode){
29405
dropNode: dropNode,
29409
var retval = this.tree.fireEvent("beforenodedrop", dropEvent);
29410
if(retval === false || dropEvent.cancel === true || !dropEvent.dropNode){
29411
target.ui.endDrop();
29412
return dropEvent.dropStatus;
29415
target = dropEvent.target;
29416
if(point == 'append' && !target.isExpanded()){
29417
target.expand(false, null, function(){
29418
this.completeDrop(dropEvent);
29419
}.createDelegate(this));
29421
this.completeDrop(dropEvent);
29427
completeDrop : function(de){
29428
var ns = de.dropNode, p = de.point, t = de.target;
29429
if(!Ext.isArray(ns)){
29433
for(var i = 0, len = ns.length; i < len; i++){
29436
t.parentNode.insertBefore(n, t);
29437
}else if(p == "below"){
29438
t.parentNode.insertBefore(n, t.nextSibling);
29444
if(Ext.enableFx && this.tree.hlDrop){
29448
this.tree.fireEvent("nodedrop", de);
29452
afterNodeMoved : function(dd, data, e, targetNode, dropNode){
29453
if(Ext.enableFx && this.tree.hlDrop){
29454
dropNode.ui.focus();
29455
dropNode.ui.highlight();
29457
this.tree.fireEvent("nodedrop", this.tree, targetNode, data, dd, e);
29461
getTree : function(){
29466
removeDropIndicators : function(n){
29469
Ext.fly(el).removeClass([
29470
"x-tree-drag-insert-above",
29471
"x-tree-drag-insert-below",
29472
"x-tree-drag-append"]);
29473
this.lastInsertClass = "_noclass";
29478
beforeDragDrop : function(target, e, id){
29479
this.cancelExpand();
29484
afterRepair : function(data){
29485
if(data && Ext.enableFx){
29486
data.node.ui.highlight();
29494
if(Ext.dd.DragZone){
29495
Ext.tree.TreeDragZone = function(tree, config){
29496
Ext.tree.TreeDragZone.superclass.constructor.call(this, tree.innerCt, config);
29501
Ext.extend(Ext.tree.TreeDragZone, Ext.dd.DragZone, {
29503
ddGroup : "TreeDD",
29506
onBeforeDrag : function(data, e){
29508
return n && n.draggable && !n.disabled;
29512
onInitDrag : function(e){
29513
var data = this.dragData;
29514
this.tree.getSelectionModel().select(data.node);
29515
this.tree.eventModel.disable();
29516
this.proxy.update("");
29517
data.node.ui.appendDDGhost(this.proxy.ghost.dom);
29518
this.tree.fireEvent("startdrag", this.tree, data.node, e);
29522
getRepairXY : function(e, data){
29523
return data.node.ui.getDDRepairXY();
29527
onEndDrag : function(data, e){
29528
this.tree.eventModel.enable.defer(100, this.tree.eventModel);
29529
this.tree.fireEvent("enddrag", this.tree, data.node, e);
29533
onValidDrop : function(dd, e, id){
29534
this.tree.fireEvent("dragdrop", this.tree, this.dragData.node, dd, e);
29539
beforeInvalidDrop : function(e, id){
29540
// this scrolls the original position back into view
29541
var sm = this.tree.getSelectionModel();
29542
sm.clearSelections();
29543
sm.select(this.dragData.node);
29547
afterRepair : function(){
29548
if (Ext.enableFx && this.tree.hlDrop) {
29549
Ext.Element.fly(this.dragData.ddel).highlight(this.hlColor || "c3daf9");
29551
this.dragging = false;
29556
Ext.tree.TreeEditor = function(tree, fc, config){
29558
var field = fc.events ? fc : new Ext.form.TextField(fc);
29559
Ext.tree.TreeEditor.superclass.constructor.call(this, field, config);
29563
if(!tree.rendered){
29564
tree.on('render', this.initEditor, this);
29566
this.initEditor(tree);
29570
Ext.extend(Ext.tree.TreeEditor, Ext.Editor, {
29578
cls: "x-small-editor x-tree-editor",
29588
initEditor : function(tree){
29589
tree.on('beforeclick', this.beforeNodeClick, this);
29590
tree.on('dblclick', this.onNodeDblClick, this);
29591
this.on('complete', this.updateNode, this);
29592
this.on('beforestartedit', this.fitToTree, this);
29593
this.on('startedit', this.bindScroll, this, {delay:10});
29594
this.on('specialkey', this.onSpecialKey, this);
29598
fitToTree : function(ed, el){
29599
var td = this.tree.getTreeEl().dom, nd = el.dom;
29600
if(td.scrollLeft > nd.offsetLeft){ // ensure the node left point is visible
29601
td.scrollLeft = nd.offsetLeft;
29605
(td.clientWidth > 20 ? td.clientWidth : td.offsetWidth) - Math.max(0, nd.offsetLeft-td.scrollLeft) - 5);
29606
this.setSize(w, '');
29610
triggerEdit : function(node, defer){
29611
this.completeEdit();
29612
if(node.attributes.editable !== false){
29614
this.editNode = node;
29615
if(this.tree.autoScroll){
29616
Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body);
29618
var value = node.text || '';
29619
if (!Ext.isGecko && Ext.isEmpty(node.text)){
29620
node.setText(' ');
29622
this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]);
29628
bindScroll : function(){
29629
this.tree.getTreeEl().on('scroll', this.cancelEdit, this);
29633
beforeNodeClick : function(node, e){
29634
clearTimeout(this.autoEditTimer);
29635
if(this.tree.getSelectionModel().isSelected(node)){
29637
return this.triggerEdit(node);
29641
onNodeDblClick : function(node, e){
29642
clearTimeout(this.autoEditTimer);
29646
updateNode : function(ed, value){
29647
this.tree.getTreeEl().un('scroll', this.cancelEdit, this);
29648
this.editNode.setText(value);
29652
onHide : function(){
29653
Ext.tree.TreeEditor.superclass.onHide.call(this);
29655
this.editNode.ui.focus.defer(50, this.editNode.ui);
29660
onSpecialKey : function(field, e){
29661
var k = e.getKey();
29665
}else if(k == e.ENTER && !e.hasModifier()){
29667
this.completeEdit();
29672
Ext.layout.MenuLayout = Ext.extend(Ext.layout.ContainerLayout, {
29673
renderItem : function(c, position, target){
29674
if (!this.itemTpl) {
29675
this.itemTpl = Ext.layout.MenuLayout.prototype.itemTpl = new Ext.XTemplate(
29676
'<li id="{itemId}" class="{itemCls}">',
29677
'<tpl if="needsIcon">',
29678
'<img src="{icon}" class="{iconCls}">',
29684
if(c && !c.rendered){
29685
if(typeof position == 'number'){
29686
position = target.dom.childNodes[position];
29688
var a = this.getItemArgs(c);
29690
// The Component's positionEl is the <li> it is rendered into
29691
c.render(c.positionEl = position ?
29692
this.itemTpl.insertBefore(position, a, true) :
29693
this.itemTpl.append(target, a, true));
29695
// Link the containing <li> to the item.
29696
c.positionEl.menuItemId = c.itemId || c.id;
29698
// If rendering a regular Component, and it needs an icon,
29699
// move the Component rightwards.
29700
if (!a.isMenuItem && a.needsIcon) {
29701
c.positionEl.addClass('x-menu-list-item-indent');
29703
}else if(c && !this.isValidParent(c, target)){
29704
if(typeof position == 'number'){
29705
position = target.dom.childNodes[position];
29707
target.dom.insertBefore(c.getActionEl().dom, position || null);
29711
getItemArgs: function(c) {
29712
var isMenuItem = c instanceof Ext.menu.Item;
29714
isMenuItem: isMenuItem,
29715
needsIcon: !isMenuItem && (c.icon || c.iconCls),
29716
icon: c.icon || Ext.BLANK_IMAGE_URL,
29717
iconCls: 'x-menu-item-icon ' + (c.iconCls || ''),
29718
itemId: 'x-menu-el-' + c.id,
29719
itemCls: 'x-menu-list-item ' + (this.extraCls || '')
29723
// Valid if the Component is in a <li> which is part of our target <ul>
29724
isValidParent: function(c, target) {
29725
return c.el.up('li.x-menu-list-item', 5).dom.parentNode === (target.dom || target);
29728
onLayout : function(ct, target){
29729
this.renderAll(ct, target);
29733
doAutoSize : function(){
29734
var ct = this.container, w = ct.width;
29737
}else if(Ext.isIE){
29738
ct.setWidth(Ext.isStrict && (Ext.isIE7 || Ext.isIE8) ? 'auto' : ct.minWidth);
29739
var el = ct.getEl(), t = el.dom.offsetWidth; // force recalc
29740
ct.setWidth(ct.getLayoutTarget().getWidth() + el.getFrameWidth('lr'));
29744
Ext.Container.LAYOUTS['menu'] = Ext.layout.MenuLayout;
29747
Ext.menu.Menu = Ext.extend(Ext.Container, {
29755
subMenuAlign : "tl-tr?",
29757
defaultAlign : "tl-bl?",
29759
allowOtherMenus : false,
29761
ignoreParentClicks : false,
29763
enableScrolling: true,
29767
scrollIncrement: 24,
29769
showSeparator: true,
29772
floating: true, // Render as a Layer by default
29776
hideMode: 'offsets', // Important for laying out Components
29779
autoLayout: true, // Provided for backwards compat
29781
initComponent: function(){
29782
if(Ext.isArray(this.initialConfig)){
29783
Ext.apply(this, {items:this.initialConfig});
29803
Ext.menu.MenuMgr.register(this);
29804
Ext.menu.Menu.superclass.initComponent.call(this);
29805
if(this.autoLayout){
29807
add: this.doLayout,
29808
remove: this.doLayout,
29812
//Ext.EventManager.onWindowResize(this.hide, this);
29816
getLayoutTarget : function() {
29821
onRender : function(ct, position){
29823
ct = Ext.getBody();
29828
cls: 'x-menu ' + ((this.floating) ? 'x-layer ' : '') + (this.cls || '') + (this.plain ? ' x-menu-plain' : '') + (this.showSeparator ? '' : ' x-menu-nosep'),
29831
{tag: 'a', cls: 'x-menu-focus', href: '#', onclick: 'return false;', tabIndex: '-1'},
29832
{tag: 'ul', cls: 'x-menu-list'}
29836
this.el = new Ext.Layer({
29837
shadow: this.shadow,
29844
this.el = ct.createChild(dh);
29846
Ext.menu.Menu.superclass.onRender.call(this, ct, position);
29849
this.keyNav = new Ext.menu.MenuNav(this);
29851
// generic focus element
29852
this.focusEl = this.el.child('a.x-menu-focus');
29853
this.ul = this.el.child('ul.x-menu-list');
29854
this.mon(this.ul, 'click', this.onClick, this);
29855
this.mon(this.ul, 'mouseover', this.onMouseOver, this);
29856
this.mon(this.ul, 'mouseout', this.onMouseOut, this);
29857
if(this.enableScrolling){
29858
this.mon(this.el, 'click', this.onScroll, this, {delegate: '.x-menu-scroller'});
29859
this.mon(this.el, 'mouseover', this.deactivateActive, this, {delegate: '.x-menu-scroller'});
29864
findTargetItem : function(e){
29865
var t = e.getTarget(".x-menu-list-item", this.ul, true);
29866
if(t && t.menuItemId){
29867
return this.items.get(t.menuItemId);
29872
onClick : function(e){
29873
var t = this.findTargetItem(e);
29876
this.setActiveItem(t);
29878
if(t.menu && this.ignoreParentClicks){
29880
e.preventDefault();
29881
}else if(t.onClick){
29883
this.fireEvent("click", this, t, e);
29890
setActiveItem : function(item, autoExpand){
29891
if(item != this.activeItem){
29892
this.deactivateActive();
29893
if((this.activeItem = item).isFormField){
29896
item.activate(autoExpand);
29898
}else if(autoExpand){
29903
deactivateActive: function(){
29904
var a = this.activeItem;
29907
//Fields cannot deactivate, but Combos must collapse
29914
delete this.activeItem;
29919
tryActivate : function(start, step){
29920
var items = this.items;
29921
for(var i = start, len = items.length; i >= 0 && i < len; i+= step){
29922
var item = items.get(i);
29923
if(!item.disabled && (item.canActivate || item.isFormField)){
29924
this.setActiveItem(item, false);
29932
onMouseOver : function(e){
29933
var t = this.findTargetItem(e);
29935
if(t.canActivate && !t.disabled){
29936
this.setActiveItem(t, true);
29940
this.fireEvent("mouseover", this, e, t);
29944
onMouseOut : function(e){
29945
var t = this.findTargetItem(e);
29947
if(t == this.activeItem && t.shouldDeactivate && t.shouldDeactivate(e)){
29948
this.activeItem.deactivate();
29949
delete this.activeItem;
29953
this.fireEvent("mouseout", this, e, t);
29957
onScroll: function(e, t){
29961
var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
29962
ul.scrollTop += this.scrollIncrement * (top ? -1 : 1);
29963
if(top ? ul.scrollTop <= 0 : ul.scrollTop + this.activeMax >= ul.scrollHeight){
29964
this.onScrollerOut(null, t);
29969
onScrollerIn: function(e, t){
29970
var ul = this.ul.dom, top = Ext.fly(t).is('.x-menu-scroller-top');
29971
if(top ? ul.scrollTop > 0 : ul.scrollTop + this.activeMax < ul.scrollHeight){
29972
Ext.fly(t).addClass(['x-menu-item-active', 'x-menu-scroller-active']);
29977
onScrollerOut: function(e, t){
29978
Ext.fly(t).removeClass(['x-menu-item-active', 'x-menu-scroller-active']);
29982
show : function(el, pos, parentMenu){
29983
this.parentMenu = parentMenu;
29986
this.doLayout(false, true);
29988
this.fireEvent("beforeshow", this);
29989
this.showAt(this.el.getAlignToXY(el, pos || this.defaultAlign), parentMenu, false);
29993
showAt : function(xy, parentMenu, _e){
29994
this.parentMenu = parentMenu;
29999
this.fireEvent("beforeshow", this);
30000
xy = this.el.adjustForConstraints(xy);
30003
if(this.enableScrolling){
30004
this.constrainScroll(xy[1]);
30007
Ext.menu.Menu.superclass.onShow.call(this);
30009
this.layout.doAutoSize();
30011
this.hidden = false;
30013
this.fireEvent("show", this);
30016
constrainScroll: function(y){
30017
var max, full = this.ul.setHeight('auto').getHeight();
30018
if (this.maxHeight){
30019
max = this.maxHeight - (this.scrollerHeight * 3);
30021
var ct = Ext.get(this.el.dom.parentNode);
30022
max = Ext.fly(this.el.dom.parentNode).getViewSize().height - y - (this.scrollerHeight * 3);
30024
if (full > max && max > 0){
30025
this.activeMax = max;
30026
this.ul.setHeight(max);
30027
this.createScrollers();
30029
this.ul.setHeight(full);
30030
this.el.select('.x-menu-scroller').setDisplayed('none');
30032
this.ul.dom.scrollTop = 0;
30035
createScrollers: function(){
30036
if(!this.scroller){
30039
top: this.el.insertFirst({
30041
cls: 'x-menu-scroller x-menu-scroller-top',
30044
bottom: this.el.createChild({
30046
cls: 'x-menu-scroller x-menu-scroller-bottom',
30050
this.scroller.top.hover(this.onScrollerIn, this.onScrollerOut, this);
30051
this.scroller.topRepeater = new Ext.util.ClickRepeater(this.scroller.top, {
30053
click: this.onScroll.createDelegate(this, [null, this.scroller.top], false)
30056
this.scroller.bottom.hover(this.onScrollerIn, this.onScrollerOut, this);
30057
this.scroller.bottomRepeater = new Ext.util.ClickRepeater(this.scroller.bottom, {
30059
click: this.onScroll.createDelegate(this, [null, this.scroller.bottom], false)
30065
onLayout: function(){
30066
if(this.isVisible()){
30067
if(this.enableScrolling){
30068
this.constrainScroll(this.el.getTop());
30071
this.layout.doAutoSize();
30077
focus : function(){
30079
this.doFocus.defer(50, this);
30083
doFocus : function(){
30085
this.focusEl.focus();
30090
hide : function(deep){
30092
Ext.menu.Menu.superclass.hide.call(this);
30094
if(deep === true && this.parentMenu){
30095
this.parentMenu.hide(true);
30101
onHide: function(){
30102
Ext.menu.Menu.superclass.onHide.call(this);
30103
this.deactivateActive();
30107
lookupComponent: function(c){
30109
if(c.render){ // some kind of Component
30111
}else if(typeof c == "string"){ // string
30112
if(c == "separator" || c == "-"){
30113
item = new Ext.menu.Separator();
30115
item = new Ext.menu.TextItem(c);
30117
}else if(c.tagName || c.el){ // element. Wrap it.
30118
item = new Ext.BoxComponent({
30121
}else if(typeof c == "object"){ // must be menu item config?
30122
Ext.applyIf(c, this.defaults);
30123
item = this.getMenuItem(c);
30129
addSeparator : function(){
30130
return this.add(new Ext.menu.Separator());
30134
addElement : function(el){
30135
return this.add(new Ext.menu.BaseItem(el));
30139
addItem : function(item){
30140
return this.add(item);
30144
addMenuItem : function(config){
30145
return this.add(this.getMenuItem(config));
30149
getMenuItem: function(config){
30150
if(!(config.isXType && config.isXType(Ext.menu.Item))){
30152
return Ext.ComponentMgr.create(config, this.defaultType);
30153
}else if(typeof config.checked == "boolean"){ // must be check menu item config?
30154
return new Ext.menu.CheckItem(config);
30156
return new Ext.menu.Item(config);
30163
addText : function(text){
30164
return this.add(new Ext.menu.TextItem(text));
30168
onDestroy : function(){
30169
Ext.menu.Menu.superclass.onDestroy.call(this);
30170
Ext.menu.MenuMgr.unregister(this);
30171
Ext.EventManager.removeResizeListener(this.hide, this);
30173
this.keyNav.disable();
30175
var s = this.scroller;
30177
Ext.destroy(s.topRepeater, s.bottomRepeater, s.top, s.bottom);
30182
Ext.reg('menu', Ext.menu.Menu);
30184
// MenuNav is a private utility class used internally by the Menu
30185
Ext.menu.MenuNav = Ext.extend(Ext.KeyNav, function(){
30187
if(!m.tryActivate(m.items.indexOf(m.activeItem)-1, -1)){
30188
m.tryActivate(m.items.length-1, -1);
30191
function down(e, m){
30192
if(!m.tryActivate(m.items.indexOf(m.activeItem)+1, 1)){
30193
m.tryActivate(0, 1);
30197
constructor: function(menu){
30198
Ext.menu.MenuNav.superclass.constructor.call(this, menu.el);
30199
this.scope = this.menu = menu;
30202
doRelay : function(e, h){
30203
var k = e.getKey();
30204
// Keystrokes within a form Field (eg: down in a Combo) do not navigate. Allow only TAB
30205
if (this.menu.activeItem && this.menu.activeItem.isFormField && k != e.TAB) {
30208
if(!this.menu.activeItem && e.isNavKeyPress() && k != e.SPACE && k != e.RETURN){
30209
this.menu.tryActivate(0, 1);
30212
return h.call(this.scope || this, e, this.menu);
30215
tab: function(e, m) {
30228
right : function(e, m){
30230
m.activeItem.expandMenu(true);
30234
left : function(e, m){
30236
if(m.parentMenu && m.parentMenu.activeItem){
30237
m.parentMenu.activeItem.activate();
30241
enter : function(e, m){
30243
e.stopPropagation();
30244
m.activeItem.onClick(e);
30245
m.fireEvent("click", this, m.activeItem);
30252
Ext.menu.MenuMgr = function(){
30253
var menus, active, groups = {}, attached = false, lastShow = new Date();
30255
// private - called when first menu is created
30258
active = new Ext.util.MixedCollection();
30259
Ext.getDoc().addKeyListener(27, function(){
30260
if(active.length > 0){
30267
function hideAll(){
30268
if(active && active.length > 0){
30269
var c = active.clone();
30270
c.each(function(m){
30277
function onHide(m){
30279
if(active.length < 1){
30280
Ext.getDoc().un("mousedown", onMouseDown);
30286
function onShow(m){
30287
var last = active.last();
30288
lastShow = new Date();
30291
Ext.getDoc().on("mousedown", onMouseDown);
30295
m.getEl().setZIndex(parseInt(m.parentMenu.getEl().getStyle("z-index"), 10) + 3);
30296
m.parentMenu.activeChild = m;
30297
}else if(last && last.isVisible()){
30298
m.getEl().setZIndex(parseInt(last.getEl().getStyle("z-index"), 10) + 3);
30303
function onBeforeHide(m){
30305
m.activeChild.hide();
30307
if(m.autoHideTimer){
30308
clearTimeout(m.autoHideTimer);
30309
delete m.autoHideTimer;
30314
function onBeforeShow(m){
30315
var pm = m.parentMenu;
30316
if(!pm && !m.allowOtherMenus){
30318
}else if(pm && pm.activeChild){
30319
pm.activeChild.hide();
30324
function onMouseDown(e){
30325
if(lastShow.getElapsed() > 50 && active.length > 0 && !e.getTarget(".x-menu")){
30331
function onBeforeCheck(mi, state){
30333
var g = groups[mi.group];
30334
for(var i = 0, l = g.length; i < l; i++){
30336
g[i].setChecked(false);
30345
hideAll : function(){
30350
register : function(menu){
30354
menus[menu.id] = menu;
30355
menu.on("beforehide", onBeforeHide);
30356
menu.on("hide", onHide);
30357
menu.on("beforeshow", onBeforeShow);
30358
menu.on("show", onShow);
30359
var g = menu.group;
30360
if(g && menu.events["checkchange"]){
30364
groups[g].push(menu);
30365
menu.on("checkchange", onCheck);
30370
get : function(menu){
30371
if(typeof menu == "string"){ // menu id
30372
if(!menus){ // not initialized, no menus to return
30375
return menus[menu];
30376
}else if(menu.events){ // menu instance
30378
}else if(typeof menu.length == 'number'){ // array of menu items?
30379
return new Ext.menu.Menu({items:menu});
30380
}else{ // otherwise, must be a config
30381
return Ext.create(menu, 'menu');
30386
unregister : function(menu){
30387
delete menus[menu.id];
30388
menu.un("beforehide", onBeforeHide);
30389
menu.un("hide", onHide);
30390
menu.un("beforeshow", onBeforeShow);
30391
menu.un("show", onShow);
30392
var g = menu.group;
30393
if(g && menu.events["checkchange"]){
30394
groups[g].remove(menu);
30395
menu.un("checkchange", onCheck);
30400
registerCheckable : function(menuItem){
30401
var g = menuItem.group;
30406
groups[g].push(menuItem);
30407
menuItem.on("beforecheckchange", onBeforeCheck);
30412
unregisterCheckable : function(menuItem){
30413
var g = menuItem.group;
30415
groups[g].remove(menuItem);
30416
menuItem.un("beforecheckchange", onBeforeCheck);
30420
getCheckedItem : function(groupId){
30421
var g = groups[groupId];
30423
for(var i = 0, l = g.length; i < l; i++){
30432
setCheckedItem : function(groupId, itemId){
30433
var g = groups[groupId];
30435
for(var i = 0, l = g.length; i < l; i++){
30436
if(g[i].id == itemId){
30437
g[i].setChecked(true);
30447
Ext.menu.BaseItem = function(config){
30448
Ext.menu.BaseItem.superclass.constructor.call(this, config);
30460
this.on("click", this.handler, this.scope);
30464
Ext.extend(Ext.menu.BaseItem, Ext.Component, {
30469
canActivate : false,
30471
activeClass : "x-menu-item-active",
30473
hideOnClick : true,
30475
clickHideDelay : 1,
30478
ctype: "Ext.menu.BaseItem",
30481
actionMode : "container",
30484
onRender : function(container, position){
30485
Ext.menu.BaseItem.superclass.onRender.apply(this, arguments);
30486
if(this.ownerCt && this.ownerCt instanceof Ext.menu.Menu){
30487
this.parentMenu = this.ownerCt;
30489
this.container.addClass('x-menu-list-item');
30490
this.mon(this.el, 'click', this.onClick, this);
30491
this.mon(this.el, 'mouseenter', this.activate, this);
30492
this.mon(this.el, 'mouseleave', this.deactivate, this);
30497
setHandler : function(handler, scope){
30499
this.un("click", this.handler, this.scope);
30501
this.on("click", this.handler = handler, this.scope = scope);
30505
onClick : function(e){
30506
if(!this.disabled && this.fireEvent("click", this, e) !== false
30507
&& (this.parentMenu && this.parentMenu.fireEvent("itemclick", this, e) !== false)){
30508
this.handleClick(e);
30515
activate : function(){
30519
var li = this.container;
30520
li.addClass(this.activeClass);
30521
this.region = li.getRegion().adjust(2, 2, -2, -2);
30522
this.fireEvent("activate", this);
30527
deactivate : function(){
30528
this.container.removeClass(this.activeClass);
30529
this.fireEvent("deactivate", this);
30533
shouldDeactivate : function(e){
30534
return !this.region || !this.region.contains(e.getPoint());
30538
handleClick : function(e){
30539
if(this.hideOnClick){
30540
this.parentMenu.hide.defer(this.clickHideDelay, this.parentMenu, [true]);
30544
// private. Do nothing
30545
expandMenu : Ext.emptyFn,
30547
// private. Do nothing
30548
hideMenu : Ext.emptyFn
30550
Ext.reg('menubaseitem', Ext.menu.BaseItem);
30552
Ext.menu.TextItem = function(cfg){
30553
if(typeof cfg == 'string'){
30556
Ext.menu.TextItem.superclass.constructor.call(this, cfg);
30559
Ext.extend(Ext.menu.TextItem, Ext.menu.BaseItem, {
30562
hideOnClick : false,
30564
itemCls : "x-menu-text",
30567
onRender : function(){
30568
var s = document.createElement("span");
30569
s.className = this.itemCls;
30570
s.innerHTML = this.text;
30572
Ext.menu.TextItem.superclass.onRender.apply(this, arguments);
30575
Ext.reg('menutextitem', Ext.menu.TextItem);
30577
Ext.menu.Separator = function(config){
30578
Ext.menu.Separator.superclass.constructor.call(this, config);
30581
Ext.extend(Ext.menu.Separator, Ext.menu.BaseItem, {
30583
itemCls : "x-menu-sep",
30585
hideOnClick : false,
30591
onRender : function(li){
30592
var s = document.createElement("span");
30593
s.className = this.itemCls;
30594
s.innerHTML = " ";
30596
li.addClass("x-menu-sep-li");
30597
Ext.menu.Separator.superclass.onRender.apply(this, arguments);
30600
Ext.reg('menuseparator', Ext.menu.Separator);
30602
Ext.menu.Item = function(config){
30603
Ext.menu.Item.superclass.constructor.call(this, config);
30605
this.menu = Ext.menu.MenuMgr.get(this.menu);
30608
Ext.extend(Ext.menu.Item, Ext.menu.BaseItem, {
30617
itemCls : 'x-menu-item',
30619
canActivate : true,
30622
// doc'd in BaseItem
30626
ctype: 'Ext.menu.Item',
30629
onRender : function(container, position){
30630
if (!this.itemTpl) {
30631
this.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
30632
'<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}"',
30633
'<tpl if="hrefTarget">',
30634
' target="{hrefTarget}"',
30637
'<img src="{icon}" class="x-menu-item-icon {iconCls}">',
30638
'<span class="x-menu-item-text">{text}</span>',
30642
var a = this.getTemplateArgs();
30643
this.el = position ? this.itemTpl.insertBefore(position, a, true) : this.itemTpl.append(container, a, true);
30644
this.iconEl = this.el.child('img.x-menu-item-icon');
30645
this.textEl = this.el.child('.x-menu-item-text');
30646
Ext.menu.Item.superclass.onRender.call(this, container, position);
30649
getTemplateArgs: function() {
30652
cls: this.itemCls + (this.menu ? ' x-menu-item-arrow' : '') + (this.cls ? ' ' + this.cls : ''),
30653
href: this.href || '#',
30654
hrefTarget: this.hrefTarget,
30655
icon: this.icon || Ext.BLANK_IMAGE_URL,
30656
iconCls: this.iconCls || '',
30657
text: this.itemText||this.text||' '
30662
setText : function(text){
30663
this.text = text||' ';
30665
this.textEl.update(this.text);
30666
this.parentMenu.layout.doAutoSize();
30671
setIconClass : function(cls){
30672
var oldCls = this.iconCls;
30673
this.iconCls = cls;
30675
this.iconEl.replaceClass(oldCls, this.iconCls);
30680
beforeDestroy: function(){
30682
this.menu.destroy();
30684
Ext.menu.Item.superclass.beforeDestroy.call(this);
30688
handleClick : function(e){
30689
if(!this.href){ // if no link defined, stop the event automatically
30692
Ext.menu.Item.superclass.handleClick.apply(this, arguments);
30696
activate : function(autoExpand){
30697
if(Ext.menu.Item.superclass.activate.apply(this, arguments)){
30707
shouldDeactivate : function(e){
30708
if(Ext.menu.Item.superclass.shouldDeactivate.call(this, e)){
30709
if(this.menu && this.menu.isVisible()){
30710
return !this.menu.getEl().getRegion().contains(e.getPoint());
30718
deactivate : function(){
30719
Ext.menu.Item.superclass.deactivate.apply(this, arguments);
30724
expandMenu : function(autoActivate){
30725
if(!this.disabled && this.menu){
30726
clearTimeout(this.hideTimer);
30727
delete this.hideTimer;
30728
if(!this.menu.isVisible() && !this.showTimer){
30729
this.showTimer = this.deferExpand.defer(this.showDelay, this, [autoActivate]);
30730
}else if (this.menu.isVisible() && autoActivate){
30731
this.menu.tryActivate(0, 1);
30737
deferExpand : function(autoActivate){
30738
delete this.showTimer;
30739
this.menu.show(this.container, this.parentMenu.subMenuAlign || 'tl-tr?', this.parentMenu);
30741
this.menu.tryActivate(0, 1);
30746
hideMenu : function(){
30747
clearTimeout(this.showTimer);
30748
delete this.showTimer;
30749
if(!this.hideTimer && this.menu && this.menu.isVisible()){
30750
this.hideTimer = this.deferHide.defer(this.hideDelay, this);
30755
deferHide : function(){
30756
delete this.hideTimer;
30757
if(this.menu.over){
30758
this.parentMenu.setActiveItem(this, false);
30764
Ext.reg('menuitem', Ext.menu.Item);
30766
Ext.menu.CheckItem = function(config){
30767
Ext.menu.CheckItem.superclass.constructor.call(this, config);
30770
"beforecheckchange" ,
30775
if(this.checkHandler){
30776
this.on('checkchange', this.checkHandler, this.scope);
30778
Ext.menu.MenuMgr.registerCheckable(this);
30780
Ext.extend(Ext.menu.CheckItem, Ext.menu.Item, {
30783
itemCls : "x-menu-item x-menu-check-item",
30785
groupClass : "x-menu-group-item",
30791
ctype: "Ext.menu.CheckItem",
30794
onRender : function(c){
30795
Ext.menu.CheckItem.superclass.onRender.apply(this, arguments);
30797
this.el.addClass(this.groupClass);
30800
this.checked = false;
30801
this.setChecked(true, true);
30806
destroy : function(){
30807
Ext.menu.MenuMgr.unregisterCheckable(this);
30808
Ext.menu.CheckItem.superclass.destroy.apply(this, arguments);
30812
setChecked : function(state, suppressEvent){
30813
if(this.checked != state && this.fireEvent("beforecheckchange", this, state) !== false){
30814
if(this.container){
30815
this.container[state ? "addClass" : "removeClass"]("x-menu-item-checked");
30817
this.checked = state;
30818
if(suppressEvent !== true){
30819
this.fireEvent("checkchange", this, state);
30825
handleClick : function(e){
30826
if(!this.disabled && !(this.checked && this.group)){// disable unselect on radio item
30827
this.setChecked(!this.checked);
30829
Ext.menu.CheckItem.superclass.handleClick.apply(this, arguments);
30832
Ext.reg('menucheckitem', Ext.menu.CheckItem);
30834
Ext.menu.DateMenu = Ext.extend(Ext.menu.Menu, {
30836
enableScrolling: false,
30840
cls: 'x-date-menu',
30842
initComponent: function(){
30843
this.on('beforeshow', this.onBeforeShow, this);
30844
if(this.strict = (Ext.isIE7 && Ext.isStrict)){
30845
this.on('show', this.onShow, this, {single: true, delay: 20});
30849
showSeparator: false,
30850
items: this.picker = new Ext.DatePicker(Ext.apply({
30851
internalRender: this.strict || !Ext.isIE,
30852
ctCls: 'x-menu-date-item'
30853
}, this.initialConfig))
30855
this.picker.purgeListeners();
30856
Ext.menu.DateMenu.superclass.initComponent.call(this);
30857
this.relayEvents(this.picker, ["select"]);
30860
onClick: function() {
30861
if(this.hideOnClick){
30866
onBeforeShow: function(){
30868
this.picker.hideMonthPicker(true);
30872
onShow: function(){
30873
var el = this.picker.getEl();
30874
el.setWidth(el.getWidth()); //nasty hack for IE7 strict mode
30877
Ext.reg('datemenu', Ext.menu.DateMenu);
30879
Ext.menu.ColorMenu = Ext.extend(Ext.menu.Menu, {
30881
enableScrolling: false,
30885
initComponent: function(){
30888
showSeparator: false,
30889
items: this.palette = new Ext.ColorPalette(this.initialConfig)
30891
this.palette.purgeListeners();
30892
Ext.menu.ColorMenu.superclass.initComponent.call(this);
30893
this.relayEvents(this.palette, ['select']);
30896
onClick: function() {
30900
Ext.reg('colormenu', Ext.menu.ColorMenu);
30902
Ext.form.Field = Ext.extend(Ext.BoxComponent, {
30910
invalidClass : "x-form-invalid",
30912
invalidText : "The value in this field is invalid",
30914
focusClass : "x-form-focus",
30916
validationEvent : "keyup",
30918
validateOnBlur : true,
30920
validationDelay : 250,
30922
defaultAutoCreate : {tag: "input", type: "text", size: "20", autocomplete: "off"},
30924
fieldClass : "x-form-field",
30926
msgTarget : 'qtip',
30935
isFormField : true,
30941
initComponent : function(){
30942
Ext.form.Field.superclass.initComponent.call(this);
30960
getName: function(){
30961
return this.rendered && this.el.dom.name ? this.el.dom.name : this.name || this.id || '';
30965
onRender : function(ct, position){
30967
var cfg = this.getAutoCreate();
30970
cfg.name = this.name || this.id;
30972
if(this.inputType){
30973
cfg.type = this.inputType;
30977
Ext.form.Field.superclass.onRender.call(this, ct, position);
30979
var type = this.el.dom.type;
30981
if(type == 'password'){
30984
this.el.addClass('x-form-'+type);
30987
this.el.dom.readOnly = true;
30989
if(this.tabIndex !== undefined){
30990
this.el.dom.setAttribute('tabIndex', this.tabIndex);
30993
this.el.addClass([this.fieldClass, this.cls]);
30997
getItemCt : function(){
30998
return this.el.up('.x-form-item', 4);
31002
initValue : function(){
31003
if(this.value !== undefined){
31004
this.setValue(this.value);
31005
}else if(!Ext.isEmpty(this.el.dom.value) && this.el.dom.value != this.emptyText){
31006
this.setValue(this.el.dom.value);
31008
// reference to original value for reset
31009
this.originalValue = this.getValue();
31013
isDirty : function() {
31014
if(this.disabled || !this.rendered) {
31017
return String(this.getValue()) !== String(this.originalValue);
31021
afterRender : function(){
31022
Ext.form.Field.superclass.afterRender.call(this);
31028
fireKey : function(e){
31029
if(e.isSpecialKey()){
31030
this.fireEvent("specialkey", this, e);
31035
reset : function(){
31036
this.setValue(this.originalValue);
31037
this.clearInvalid();
31041
initEvents : function(){
31042
this.mon(this.el, Ext.isIE || Ext.isSafari3 || Ext.isChrome ? "keydown" : "keypress", this.fireKey, this);
31043
this.mon(this.el, 'focus', this.onFocus, this);
31045
// fix weird FF/Win editor issue when changing OS window focus
31046
var o = this.inEditor && Ext.isWindows && Ext.isGecko ? {buffer:10} : null;
31047
this.mon(this.el, 'blur', this.onBlur, this, o);
31051
onFocus : function(){
31052
if(this.focusClass){
31053
this.el.addClass(this.focusClass);
31055
if(!this.hasFocus){
31056
this.hasFocus = true;
31057
this.startValue = this.getValue();
31058
this.fireEvent("focus", this);
31063
beforeBlur : Ext.emptyFn,
31066
onBlur : function(){
31068
if(this.focusClass){
31069
this.el.removeClass(this.focusClass);
31071
this.hasFocus = false;
31072
if(this.validationEvent !== false && this.validateOnBlur && this.validationEvent != "blur"){
31075
var v = this.getValue();
31076
if(String(v) !== String(this.startValue)){
31077
this.fireEvent('change', this, v, this.startValue);
31079
this.fireEvent("blur", this);
31083
isValid : function(preventMark){
31087
var restore = this.preventMark;
31088
this.preventMark = preventMark === true;
31089
var v = this.validateValue(this.processValue(this.getRawValue()));
31090
this.preventMark = restore;
31095
validate : function(){
31096
if(this.disabled || this.validateValue(this.processValue(this.getRawValue()))){
31097
this.clearInvalid();
31103
// protected - should be overridden by subclasses if necessary to prepare raw values for validation
31104
processValue : function(value){
31109
// Subclasses should provide the validation implementation by overriding this
31110
validateValue : function(value){
31115
markInvalid : function(msg){
31116
if(!this.rendered || this.preventMark){ // not rendered
31119
msg = msg || this.invalidText;
31121
var mt = this.getMessageHandler();
31123
mt.mark(this, msg);
31124
}else if(this.msgTarget){
31125
this.el.addClass(this.invalidClass);
31126
var t = Ext.getDom(this.msgTarget);
31129
t.style.display = this.msgDisplay;
31132
this.fireEvent('invalid', this, msg);
31136
clearInvalid : function(){
31137
if(!this.rendered || this.preventMark){ // not rendered
31140
this.el.removeClass(this.invalidClass);
31141
var mt = this.getMessageHandler();
31144
}else if(this.msgTarget){
31145
this.el.removeClass(this.invalidClass);
31146
var t = Ext.getDom(this.msgTarget);
31149
t.style.display = 'none';
31152
this.fireEvent('valid', this);
31156
getMessageHandler : function(){
31157
return Ext.form.MessageTargets[this.msgTarget];
31161
getErrorCt : function(){
31162
return this.el.findParent('.x-form-element', 5, true) || // use form element wrap if available
31163
this.el.findParent('.x-form-field-wrap', 5, true); // else direct field wrap
31167
alignErrorIcon : function(){
31168
this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
31172
getRawValue : function(){
31173
var v = this.rendered ? this.el.getValue() : Ext.value(this.value, '');
31174
if(v === this.emptyText){
31181
getValue : function(){
31182
if(!this.rendered) {
31185
var v = this.el.getValue();
31186
if(v === this.emptyText || v === undefined){
31193
setRawValue : function(v){
31194
return this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
31198
setValue : function(v){
31201
this.el.dom.value = (Ext.isEmpty(v) ? '' : v);
31207
// private, does not work for all fields
31208
append :function(v){
31209
this.setValue([this.getValue(), v].join(''));
31213
adjustSize : function(w, h){
31214
var s = Ext.form.Field.superclass.adjustSize.call(this, w, h);
31215
s.width = this.adjustWidth(this.el.dom.tagName, s.width);
31217
var ct = this.getItemCt();
31218
s.width -= ct.getFrameWidth('lr');
31219
s.height -= ct.getFrameWidth('tb');
31225
adjustWidth : function(tag, w){
31226
if(typeof w == 'number' && (Ext.isIE && (Ext.isIE6 || !Ext.isStrict)) && /input|textarea/i.test(tag) && !this.inEditor){
31239
Ext.form.MessageTargets = {
31241
mark: function(field, msg){
31242
field.el.addClass(field.invalidClass);
31243
field.el.dom.qtip = msg;
31244
field.el.dom.qclass = 'x-form-invalid-tip';
31245
if(Ext.QuickTips){ // fix for floating editors interacting with DND
31246
Ext.QuickTips.enable();
31249
clear: function(field){
31250
field.el.removeClass(field.invalidClass);
31251
field.el.dom.qtip = '';
31255
mark: function(field, msg){
31256
field.el.addClass(field.invalidClass);
31257
field.el.dom.title = msg;
31259
clear: function(field){
31260
field.el.dom.title = '';
31264
mark: function(field, msg){
31265
field.el.addClass(field.invalidClass);
31266
if(!field.errorEl){
31267
var elp = field.getErrorCt();
31268
if(!elp){ // field has no container el
31269
field.el.dom.title = msg;
31272
field.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
31273
field.errorEl.setWidth(elp.getWidth(true)-20);
31275
field.errorEl.update(msg);
31276
Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field);
31278
clear: function(field){
31279
field.el.removeClass(field.invalidClass);
31281
Ext.form.Field.msgFx[field.msgFx].hide(field.errorEl, field);
31283
field.el.dom.title = '';
31288
mark: function(field, msg){
31289
field.el.addClass(field.invalidClass);
31290
if(!field.errorIcon){
31291
var elp = field.getErrorCt();
31292
if(!elp){ // field has no container el
31293
field.el.dom.title = msg;
31296
field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
31298
field.alignErrorIcon();
31299
field.errorIcon.dom.qtip = msg;
31300
field.errorIcon.dom.qclass = 'x-form-invalid-tip';
31301
field.errorIcon.show();
31302
field.on('resize', field.alignErrorIcon, field);
31304
clear: function(field){
31305
field.el.removeClass(field.invalidClass);
31306
if(field.errorIcon){
31307
field.errorIcon.dom.qtip = '';
31308
field.errorIcon.hide();
31309
field.un('resize', field.alignErrorIcon, field);
31311
field.el.dom.title = '';
31317
// anything other than normal should be considered experimental
31318
Ext.form.Field.msgFx = {
31320
show: function(msgEl, f){
31321
msgEl.setDisplayed('block');
31324
hide : function(msgEl, f){
31325
msgEl.setDisplayed(false).update('');
31330
show: function(msgEl, f){
31331
msgEl.slideIn('t', {stopFx:true});
31334
hide : function(msgEl, f){
31335
msgEl.slideOut('t', {stopFx:true,useDisplay:true});
31340
show: function(msgEl, f){
31341
msgEl.fixDisplay();
31342
msgEl.alignTo(f.el, 'tl-tr');
31343
msgEl.slideIn('l', {stopFx:true});
31346
hide : function(msgEl, f){
31347
msgEl.slideOut('l', {stopFx:true,useDisplay:true});
31351
Ext.reg('field', Ext.form.Field);
31354
Ext.form.TextField = Ext.extend(Ext.form.Field, {
31368
disableKeyFilter : false,
31374
maxLength : Number.MAX_VALUE,
31376
minLengthText : "The minimum length for this field is {0}",
31378
maxLengthText : "The maximum length for this field is {0}",
31380
selectOnFocus : false,
31382
blankText : "This field is required",
31392
emptyClass : 'x-form-empty-field',
31396
initComponent : function(){
31397
Ext.form.TextField.superclass.initComponent.call(this);
31412
initEvents : function(){
31413
Ext.form.TextField.superclass.initEvents.call(this);
31414
if(this.validationEvent == 'keyup'){
31415
this.validationTask = new Ext.util.DelayedTask(this.validate, this);
31416
this.mon(this.el, 'keyup', this.filterValidation, this);
31418
else if(this.validationEvent !== false){
31419
this.mon(this.el, this.validationEvent, this.validate, this, {buffer: this.validationDelay});
31421
if(this.selectOnFocus || this.emptyText){
31422
this.on("focus", this.preFocus, this);
31424
this.mon(this.el, 'mousedown', function(){
31425
if(!this.hasFocus){
31426
this.el.on('mouseup', function(e){
31427
e.preventDefault();
31428
}, this, {single:true});
31432
if(this.emptyText){
31433
this.on('blur', this.postBlur, this);
31434
this.applyEmptyText();
31437
if(this.maskRe || (this.vtype && this.disableKeyFilter !== true && (this.maskRe = Ext.form.VTypes[this.vtype+'Mask']))){
31438
this.mon(this.el, 'keypress', this.filterKeys, this);
31441
this.mon(this.el, 'keyup', this.onKeyUpBuffered, this, {buffer: 50});
31442
this.mon(this.el, 'click', this.autoSize, this);
31444
if(this.enableKeyEvents){
31445
this.mon(this.el, 'keyup', this.onKeyUp, this);
31446
this.mon(this.el, 'keydown', this.onKeyDown, this);
31447
this.mon(this.el, 'keypress', this.onKeyPress, this);
31451
processValue : function(value){
31452
if(this.stripCharsRe){
31453
var newValue = value.replace(this.stripCharsRe, '');
31454
if(newValue !== value){
31455
this.setRawValue(newValue);
31462
filterValidation : function(e){
31463
if(!e.isNavKeyPress()){
31464
this.validationTask.delay(this.validationDelay);
31469
onDisable: function(){
31470
Ext.form.TextField.superclass.onDisable.call(this);
31472
this.el.dom.unselectable = 'on';
31477
onEnable: function(){
31478
Ext.form.TextField.superclass.onEnable.call(this);
31480
this.el.dom.unselectable = '';
31485
onKeyUpBuffered : function(e){
31486
if(!e.isNavKeyPress()){
31492
onKeyUp : function(e){
31493
this.fireEvent('keyup', this, e);
31497
onKeyDown : function(e){
31498
this.fireEvent('keydown', this, e);
31502
onKeyPress : function(e){
31503
this.fireEvent('keypress', this, e);
31507
reset : function(){
31508
Ext.form.TextField.superclass.reset.call(this);
31509
this.applyEmptyText();
31512
applyEmptyText : function(){
31513
if(this.rendered && this.emptyText && this.getRawValue().length < 1 && !this.hasFocus){
31514
this.setRawValue(this.emptyText);
31515
this.el.addClass(this.emptyClass);
31520
preFocus : function(){
31522
if(this.emptyText){
31523
if(el.dom.value == this.emptyText){
31524
this.setRawValue('');
31526
el.removeClass(this.emptyClass);
31528
if(this.selectOnFocus){
31531
}).defer(this.inEditor && Ext.isIE ? 50 : 0);
31536
postBlur : function(){
31537
this.applyEmptyText();
31541
filterKeys : function(e){
31542
// special keys don't generate charCodes, so leave them alone
31543
if(e.ctrlKey || e.isSpecialKey()){
31547
if(!this.maskRe.test(String.fromCharCode(e.getCharCode()))){
31552
setValue : function(v){
31553
if(this.emptyText && this.el && Ext.isEmpty(v)){
31554
this.el.removeClass(this.emptyClass);
31556
Ext.form.TextField.superclass.setValue.apply(this, arguments);
31557
this.applyEmptyText();
31563
validateValue : function(value){
31564
if(Ext.isFunction(this.validator)){
31565
var msg = this.validator(value);
31567
this.markInvalid(msg);
31572
var vt = Ext.form.VTypes;
31573
if(!vt[this.vtype](value, this)){
31574
this.markInvalid(this.vtypeText || vt[this.vtype +'Text']);
31578
if(this.regex && !this.regex.test(value)){
31579
this.markInvalid(this.regexText);
31582
if(value.length < 1 || value === this.emptyText){ // if it's blank
31583
if(this.allowBlank){
31584
this.clearInvalid();
31587
this.markInvalid(this.blankText);
31591
if(value.length < this.minLength){
31592
this.markInvalid(String.format(this.minLengthText, this.minLength));
31595
if(value.length > this.maxLength){
31596
this.markInvalid(String.format(this.maxLengthText, this.maxLength));
31603
selectText : function(start, end){
31604
var v = this.getRawValue();
31605
var doFocus = false;
31607
start = start === undefined ? 0 : start;
31608
end = end === undefined ? v.length : end;
31609
var d = this.el.dom;
31610
if(d.setSelectionRange){
31611
d.setSelectionRange(start, end);
31612
}else if(d.createTextRange){
31613
var range = d.createTextRange();
31614
range.moveStart("character", start);
31615
range.moveEnd("character", end-v.length);
31618
doFocus = Ext.isGecko || Ext.isOpera;
31628
autoSize : function(){
31629
if(!this.grow || !this.rendered){
31633
this.metrics = Ext.util.TextMetrics.createInstance(this.el);
31636
var v = el.dom.value;
31637
var d = document.createElement('div');
31638
d.appendChild(document.createTextNode(v));
31643
var w = Math.min(this.growMax, Math.max(this.metrics.getWidth(v) + 10, this.growMin));
31644
this.el.setWidth(w);
31645
this.fireEvent("autosize", this, w);
31648
onDestroy: function(){
31649
if(this.validationTask){
31650
this.validationTask.cancel();
31651
this.validationTask = null;
31653
Ext.form.TextField.superclass.onDestroy.call(this);
31656
Ext.reg('textfield', Ext.form.TextField);
31659
Ext.form.TriggerField = Ext.extend(Ext.form.TextField, {
31663
defaultAutoCreate : {tag: "input", type: "text", size: "16", autocomplete: "off"},
31669
autoSize: Ext.emptyFn,
31673
deferHeight : true,
31678
onResize : function(w, h){
31679
Ext.form.TriggerField.superclass.onResize.call(this, w, h);
31680
if(typeof w == 'number'){
31681
this.el.setWidth(this.adjustWidth('input', w - this.trigger.getWidth()));
31683
this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
31687
adjustSize : Ext.BoxComponent.prototype.adjustSize,
31690
getResizeEl : function(){
31695
getPositionEl : function(){
31700
alignErrorIcon : function(){
31702
this.errorIcon.alignTo(this.wrap, 'tl-tr', [2, 0]);
31707
onRender : function(ct, position){
31708
Ext.form.TriggerField.superclass.onRender.call(this, ct, position);
31710
this.wrap = this.el.wrap({cls: 'x-form-field-wrap x-form-field-trigger-wrap'});
31711
this.trigger = this.wrap.createChild(this.triggerConfig ||
31712
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.triggerClass});
31713
if(this.hideTrigger){
31714
this.trigger.setDisplayed(false);
31716
this.initTrigger();
31718
this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
31720
if(!this.editable){
31721
this.editable = true;
31722
this.setEditable(false);
31726
afterRender : function(){
31727
Ext.form.TriggerField.superclass.afterRender.call(this);
31731
initTrigger : function(){
31732
this.mon(this.trigger, 'click', this.onTriggerClick, this, {preventDefault:true});
31733
this.trigger.addClassOnOver('x-form-trigger-over');
31734
this.trigger.addClassOnClick('x-form-trigger-click');
31738
onDestroy : function(){
31739
Ext.destroy(this.trigger, this.wrap);
31740
if (this.mimicing){
31741
Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur, this);
31743
Ext.form.TriggerField.superclass.onDestroy.call(this);
31747
onFocus : function(){
31748
Ext.form.TriggerField.superclass.onFocus.call(this);
31749
if(!this.mimicing){
31750
this.wrap.addClass('x-trigger-wrap-focus');
31751
this.mimicing = true;
31752
Ext.get(Ext.isIE ? document.body : document).on("mousedown", this.mimicBlur, this, {delay: 10});
31753
if(this.monitorTab){
31754
this.el.on('keydown', this.checkTab, this);
31760
checkTab : function(e){
31761
if(e.getKey() == e.TAB){
31762
this.triggerBlur();
31767
onBlur : function(){
31772
mimicBlur : function(e){
31773
if(!this.wrap.contains(e.target) && this.validateBlur(e)){
31774
this.triggerBlur();
31779
triggerBlur : function(){
31780
this.mimicing = false;
31781
Ext.get(Ext.isIE ? document.body : document).un("mousedown", this.mimicBlur, this);
31782
if(this.monitorTab && this.el){
31783
this.el.un("keydown", this.checkTab, this);
31787
this.wrap.removeClass('x-trigger-wrap-focus');
31789
Ext.form.TriggerField.superclass.onBlur.call(this);
31792
beforeBlur : Ext.emptyFn,
31795
setEditable : function(value){
31796
if(value == this.editable){
31799
this.editable = value;
31801
this.el.addClass('x-trigger-noedit').on('click', this.onTriggerClick, this).dom.setAttribute('readOnly', true);
31803
this.el.removeClass('x-trigger-noedit').un('click', this.onTriggerClick, this).dom.removeAttribute('readOnly');
31808
// This should be overriden by any subclass that needs to check whether or not the field can be blurred.
31809
validateBlur : function(e){
31814
onDisable : function(){
31815
Ext.form.TriggerField.superclass.onDisable.call(this);
31817
this.wrap.addClass(this.disabledClass);
31818
this.el.removeClass(this.disabledClass);
31823
onEnable : function(){
31824
Ext.form.TriggerField.superclass.onEnable.call(this);
31826
this.wrap.removeClass(this.disabledClass);
31831
onShow : function(){
31833
var s = this.wrap.dom.style;
31835
s.visibility = 'visible';
31840
onHide : function(){
31841
this.wrap.dom.style.display = 'none';
31845
onTriggerClick : Ext.emptyFn
31853
Ext.form.TwinTriggerField = Ext.extend(Ext.form.TriggerField, {
31858
initComponent : function(){
31859
Ext.form.TwinTriggerField.superclass.initComponent.call(this);
31861
this.triggerConfig = {
31862
tag:'span', cls:'x-form-twin-triggers', cn:[
31863
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger1Class},
31864
{tag: "img", src: Ext.BLANK_IMAGE_URL, cls: "x-form-trigger " + this.trigger2Class}
31868
getTrigger : function(index){
31869
return this.triggers[index];
31872
initTrigger : function(){
31873
var ts = this.trigger.select('.x-form-trigger', true);
31874
this.wrap.setStyle('overflow', 'hidden');
31875
var triggerField = this;
31876
ts.each(function(t, all, index){
31877
t.hide = function(){
31878
var w = triggerField.wrap.getWidth();
31879
this.dom.style.display = 'none';
31880
triggerField.el.setWidth(w-triggerField.trigger.getWidth());
31882
t.show = function(){
31883
var w = triggerField.wrap.getWidth();
31884
this.dom.style.display = '';
31885
triggerField.el.setWidth(w-triggerField.trigger.getWidth());
31887
var triggerIndex = 'Trigger'+(index+1);
31889
if(this['hide'+triggerIndex]){
31890
t.dom.style.display = 'none';
31892
this.mon(t, 'click', this['on'+triggerIndex+'Click'], this, {preventDefault:true});
31893
t.addClassOnOver('x-form-trigger-over');
31894
t.addClassOnClick('x-form-trigger-click');
31896
this.triggers = ts.elements;
31900
onTrigger1Click : Ext.emptyFn,
31902
onTrigger2Click : Ext.emptyFn
31904
Ext.reg('trigger', Ext.form.TriggerField);
31906
Ext.form.TextArea = Ext.extend(Ext.form.TextField, {
31911
growAppend : ' \n ',
31912
growPad : Ext.isWebKit ? -6 : 0,
31914
enterIsSpecial : false,
31917
preventScrollbars: false,
31921
onRender : function(ct, position){
31923
this.defaultAutoCreate = {
31925
style:"width:100px;height:60px;",
31926
autocomplete: "off"
31929
Ext.form.TextArea.superclass.onRender.call(this, ct, position);
31931
this.textSizeEl = Ext.DomHelper.append(document.body, {
31932
tag: "pre", cls: "x-form-grow-sizer"
31934
if(this.preventScrollbars){
31935
this.el.setStyle("overflow", "hidden");
31937
this.el.setHeight(this.growMin);
31941
onDestroy : function(){
31942
Ext.destroy(this.textSizeEl);
31943
Ext.form.TextArea.superclass.onDestroy.call(this);
31946
fireKey : function(e){
31947
if(e.isSpecialKey() && (this.enterIsSpecial || (e.getKey() != e.ENTER || e.hasModifier()))){
31948
this.fireEvent("specialkey", this, e);
31953
onKeyUp : function(e){
31954
if(!e.isNavKeyPress() || e.getKey() == e.ENTER){
31957
Ext.form.TextArea.superclass.onKeyUp.call(this, e);
31961
autoSize: function(){
31962
if(!this.grow || !this.textSizeEl){
31966
var v = el.dom.value;
31967
var ts = this.textSizeEl;
31969
ts.appendChild(document.createTextNode(v));
31971
Ext.fly(ts).setWidth(this.el.getWidth());
31973
v = "  ";
31975
v += this.growAppend;
31977
v = v.replace(/\n/g, '<br />');
31981
var h = Math.min(this.growMax, Math.max(ts.offsetHeight, this.growMin) + this.growPad);
31982
if(h != this.lastHeight){
31983
this.lastHeight = h;
31984
this.el.setHeight(h);
31985
this.fireEvent("autosize", this, h);
31989
Ext.reg('textarea', Ext.form.TextArea);
31991
Ext.form.NumberField = Ext.extend(Ext.form.TextField, {
31995
fieldClass: "x-form-field x-form-num-field",
31997
allowDecimals : true,
31999
decimalSeparator : ".",
32001
decimalPrecision : 2,
32003
allowNegative : true,
32005
minValue : Number.NEGATIVE_INFINITY,
32007
maxValue : Number.MAX_VALUE,
32009
minText : "The minimum value for this field is {0}",
32011
maxText : "The maximum value for this field is {0}",
32013
nanText : "{0} is not a valid number",
32015
baseChars : "0123456789",
32018
initEvents : function(){
32019
var allowed = this.baseChars + '';
32020
if (this.allowDecimals) {
32021
allowed += this.decimalSeparator;
32023
if (this.allowNegative) {
32026
this.maskRe = new RegExp('[' + Ext.escapeRe(allowed) + ']');
32027
Ext.form.NumberField.superclass.initEvents.call(this);
32031
validateValue : function(value){
32032
if(!Ext.form.NumberField.superclass.validateValue.call(this, value)){
32035
if(value.length < 1){ // if it's blank and textfield didn't flag it then it's valid
32038
value = String(value).replace(this.decimalSeparator, ".");
32040
this.markInvalid(String.format(this.nanText, value));
32043
var num = this.parseValue(value);
32044
if(num < this.minValue){
32045
this.markInvalid(String.format(this.minText, this.minValue));
32048
if(num > this.maxValue){
32049
this.markInvalid(String.format(this.maxText, this.maxValue));
32055
getValue : function(){
32056
return this.fixPrecision(this.parseValue(Ext.form.NumberField.superclass.getValue.call(this)));
32059
setValue : function(v){
32060
v = typeof v == 'number' ? v : parseFloat(String(v).replace(this.decimalSeparator, "."));
32061
v = isNaN(v) ? '' : String(v).replace(".", this.decimalSeparator);
32062
return Ext.form.NumberField.superclass.setValue.call(this, v);
32066
parseValue : function(value){
32067
value = parseFloat(String(value).replace(this.decimalSeparator, "."));
32068
return isNaN(value) ? '' : value;
32072
fixPrecision : function(value){
32073
var nan = isNaN(value);
32074
if(!this.allowDecimals || this.decimalPrecision == -1 || nan || !value){
32075
return nan ? '' : value;
32077
return parseFloat(parseFloat(value).toFixed(this.decimalPrecision));
32080
beforeBlur : function(){
32081
var v = this.parseValue(this.getRawValue());
32082
if(!Ext.isEmpty(v)){
32083
this.setValue(this.fixPrecision(v));
32087
Ext.reg('numberfield', Ext.form.NumberField);
32089
Ext.form.DateField = Ext.extend(Ext.form.TriggerField, {
32093
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",
32095
disabledDaysText : "Disabled",
32097
disabledDatesText : "Disabled",
32099
minText : "The date in this field must be equal to or after {0}",
32101
maxText : "The date in this field must be equal to or before {0}",
32103
invalidText : "{0} is not a valid date - it must be in the format {1}",
32105
triggerClass : 'x-form-date-trigger',
32115
defaultAutoCreate : {tag: "input", type: "text", size: "10", autocomplete: "off"},
32117
initComponent : function(){
32118
Ext.form.DateField.superclass.initComponent.call(this);
32125
if(typeof this.minValue == "string"){
32126
this.minValue = this.parseDate(this.minValue);
32128
if(typeof this.maxValue == "string"){
32129
this.maxValue = this.parseDate(this.maxValue);
32131
this.disabledDatesRE = null;
32132
this.initDisabledDays();
32136
initDisabledDays : function(){
32137
if(this.disabledDates){
32138
var dd = this.disabledDates;
32140
for(var i = 0; i < dd.length; i++){
32142
if(i != dd.length-1) re += "|";
32144
this.disabledDatesRE = new RegExp(re + ")");
32149
setDisabledDates : function(dd){
32150
this.disabledDates = dd;
32151
this.initDisabledDays();
32153
this.menu.picker.setDisabledDates(this.disabledDatesRE);
32158
setDisabledDays : function(dd){
32159
this.disabledDays = dd;
32161
this.menu.picker.setDisabledDays(dd);
32166
setMinValue : function(dt){
32167
this.minValue = (typeof dt == "string" ? this.parseDate(dt) : dt);
32169
this.menu.picker.setMinDate(this.minValue);
32174
setMaxValue : function(dt){
32175
this.maxValue = (typeof dt == "string" ? this.parseDate(dt) : dt);
32177
this.menu.picker.setMaxDate(this.maxValue);
32182
validateValue : function(value){
32183
value = this.formatDate(value);
32184
if(!Ext.form.DateField.superclass.validateValue.call(this, value)){
32187
if(value.length < 1){ // if it's blank and textfield didn't flag it then it's valid
32190
var svalue = value;
32191
value = this.parseDate(value);
32193
this.markInvalid(String.format(this.invalidText, svalue, this.format));
32196
var time = value.getTime();
32197
if(this.minValue && time < this.minValue.getTime()){
32198
this.markInvalid(String.format(this.minText, this.formatDate(this.minValue)));
32201
if(this.maxValue && time > this.maxValue.getTime()){
32202
this.markInvalid(String.format(this.maxText, this.formatDate(this.maxValue)));
32205
if(this.disabledDays){
32206
var day = value.getDay();
32207
for(var i = 0; i < this.disabledDays.length; i++) {
32208
if(day === this.disabledDays[i]){
32209
this.markInvalid(this.disabledDaysText);
32214
var fvalue = this.formatDate(value);
32215
if(this.disabledDatesRE && this.disabledDatesRE.test(fvalue)){
32216
this.markInvalid(String.format(this.disabledDatesText, fvalue));
32223
// Provides logic to override the default TriggerField.validateBlur which just returns true
32224
validateBlur : function(){
32225
return !this.menu || !this.menu.isVisible();
32229
getValue : function(){
32230
return this.parseDate(Ext.form.DateField.superclass.getValue.call(this)) || "";
32234
setValue : function(date){
32235
return Ext.form.DateField.superclass.setValue.call(this, this.formatDate(this.parseDate(date)));
32239
parseDate : function(value){
32240
if(!value || Ext.isDate(value)){
32243
var v = Date.parseDate(value, this.format);
32244
if(!v && this.altFormats){
32245
if(!this.altFormatsArray){
32246
this.altFormatsArray = this.altFormats.split("|");
32248
for(var i = 0, len = this.altFormatsArray.length; i < len && !v; i++){
32249
v = Date.parseDate(value, this.altFormatsArray[i]);
32256
onDestroy : function(){
32257
Ext.destroy(this.menu, this.wrap);
32258
Ext.form.DateField.superclass.onDestroy.call(this);
32262
formatDate : function(date){
32263
return Ext.isDate(date) ? date.dateFormat(this.format) : date;
32268
// Implements the default empty TriggerField.onTriggerClick function to display the DatePicker
32269
onTriggerClick : function(){
32273
if(this.menu == null){
32274
this.menu = new Ext.menu.DateMenu({
32279
Ext.apply(this.menu.picker, {
32280
minDate : this.minValue,
32281
maxDate : this.maxValue,
32282
disabledDatesRE : this.disabledDatesRE,
32283
disabledDatesText : this.disabledDatesText,
32284
disabledDays : this.disabledDays,
32285
disabledDaysText : this.disabledDaysText,
32286
format : this.format,
32287
showToday : this.showToday,
32288
minText : String.format(this.minText, this.formatDate(this.minValue)),
32289
maxText : String.format(this.maxText, this.formatDate(this.maxValue))
32291
this.menu.picker.setValue(this.getValue() || new Date());
32292
this.menu.show(this.el, "tl-bl?");
32293
this.menuEvents('on');
32297
menuEvents: function(method){
32298
this.menu[method]('select', this.onSelect, this);
32299
this.menu[method]('hide', this.onMenuHide, this);
32300
this.menu[method]('show', this.onFocus, this);
32303
onSelect: function(m, d){
32305
this.fireEvent('select', this, d);
32309
onMenuHide: function(){
32310
this.focus(false, 60);
32311
this.menuEvents('un');
32315
beforeBlur : function(){
32316
var v = this.parseDate(this.getRawValue());
32327
Ext.reg('datefield', Ext.form.DateField);
32329
Ext.form.DisplayField = Ext.extend(Ext.form.Field, {
32330
validationEvent : false,
32331
validateOnBlur : false,
32332
defaultAutoCreate : {tag: "div"},
32334
fieldClass : "x-form-display-field",
32339
initEvents : Ext.emptyFn,
32341
isValid : function(){
32345
validate : function(){
32349
getRawValue : function(){
32350
var v = this.rendered ? this.el.dom.innerHTML : Ext.value(this.value, '');
32351
if(v === this.emptyText){
32354
if(this.htmlEncode){
32355
v = Ext.util.Format.htmlDecode(v);
32360
getValue : function(){
32361
return this.getRawValue();
32364
getName: function() {
32368
setRawValue : function(v){
32369
if(this.htmlEncode){
32370
v = Ext.util.Format.htmlEncode(v);
32372
return this.rendered ? (this.el.dom.innerHTML = (Ext.isEmpty(v) ? '' : v)) : (this.value = v);
32375
setValue : function(v){
32376
this.setRawValue(v);
32387
Ext.reg('displayfield', Ext.form.DisplayField);
32390
Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
32398
defaultAutoCreate : {tag: "input", type: "text", size: "24", autocomplete: "off"},
32408
selectedClass : 'x-combo-selected',
32412
triggerClass : 'x-form-arrow-trigger',
32416
listAlign : 'tl-bl?',
32422
triggerAction : 'query',
32432
selectOnFocus : false,
32434
queryParam : 'query',
32436
loadingText : 'Loading...',
32448
forceSelection : false,
32450
typeAheadDelay : 250,
32459
initComponent : function(){
32460
Ext.form.ComboBox.superclass.initComponent.call(this);
32473
if(this.transform){
32474
var s = Ext.getDom(this.transform);
32475
if(!this.hiddenName){
32476
this.hiddenName = s.name;
32479
this.mode = 'local';
32480
var d = [], opts = s.options;
32481
for(var i = 0, len = opts.length;i < len; i++){
32483
var value = (o.hasAttribute ? o.hasAttribute('value') : o.getAttribute('value') !== null) ? o.value : o.text;
32484
if(o.selected && Ext.isEmpty(this.value, true)) {
32485
this.value = value;
32487
d.push([value, o.text]);
32489
this.store = new Ext.data.ArrayStore({
32491
fields: ['value', 'text'],
32495
this.valueField = 'value';
32496
this.displayField = 'text';
32498
s.name = Ext.id(); // wipe out the name in case somewhere else they have a reference
32499
if(!this.lazyRender){
32500
this.target = true;
32501
this.el = Ext.DomHelper.insertBefore(s, this.autoCreate || this.defaultAutoCreate);
32502
Ext.removeNode(s); // remove it
32503
this.render(this.el.parentNode);
32505
Ext.removeNode(s); // remove it
32508
//auto-configure store from local array data
32509
else if(this.store){
32510
this.store = Ext.StoreMgr.lookup(this.store);
32511
if(this.store.autoCreated){
32512
this.displayField = this.valueField = 'field1';
32513
if(!this.store.expandData){
32514
this.displayField = 'field2';
32516
this.mode = 'local';
32520
this.selectedIndex = -1;
32521
if(this.mode == 'local'){
32522
if(this.initialConfig.queryDelay === undefined){
32523
this.queryDelay = 10;
32525
if(this.initialConfig.minChars === undefined){
32532
onRender : function(ct, position){
32533
Ext.form.ComboBox.superclass.onRender.call(this, ct, position);
32534
if(this.hiddenName){
32535
this.hiddenField = this.el.insertSibling({tag:'input', type:'hidden', name: this.hiddenName,
32536
id: (this.hiddenId||this.hiddenName)}, 'before', true);
32538
// prevent input submission
32539
this.el.dom.removeAttribute('name');
32542
this.el.dom.setAttribute('autocomplete', 'off');
32545
if(!this.lazyInit){
32548
this.on('focus', this.initList, this, {single: true});
32553
initValue : function(){
32554
Ext.form.ComboBox.superclass.initValue.call(this);
32555
if(this.hiddenField){
32556
this.hiddenField.value =
32557
this.hiddenValue !== undefined ? this.hiddenValue :
32558
this.value !== undefined ? this.value : '';
32563
initList : function(){
32565
var cls = 'x-combo-list';
32567
this.list = new Ext.Layer({
32568
parentEl: this.getListParent(),
32569
shadow: this.shadow,
32570
cls: [cls, this.listClass].join(' '),
32574
var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
32575
this.list.setSize(lw, 0);
32576
this.list.swallowEvent('mousewheel');
32577
this.assetHeight = 0;
32578
if(this.syncFont !== false){
32579
this.list.setStyle('font-size', this.el.getStyle('font-size'));
32582
this.header = this.list.createChild({cls:cls+'-hd', html: this.title});
32583
this.assetHeight += this.header.getHeight();
32586
this.innerList = this.list.createChild({cls:cls+'-inner'});
32587
this.mon(this.innerList, 'mouseover', this.onViewOver, this);
32588
this.mon(this.innerList, 'mousemove', this.onViewMove, this);
32589
this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
32592
this.footer = this.list.createChild({cls:cls+'-ft'});
32593
this.pageTb = new Ext.PagingToolbar({
32595
pageSize: this.pageSize,
32596
renderTo:this.footer
32598
this.assetHeight += this.footer.getHeight();
32603
this.tpl = '<tpl for="."><div class="'+cls+'-item">{' + this.displayField + '}</div></tpl>';
32608
this.view = new Ext.DataView({
32609
applyTo: this.innerList,
32611
singleSelect: true,
32612
selectedClass: this.selectedClass,
32613
itemSelector: this.itemSelector || '.' + cls + '-item',
32614
emptyText: this.listEmptyText
32617
this.mon(this.view, 'click', this.onViewClick, this);
32619
this.bindStore(this.store, true);
32621
if(this.resizable){
32622
this.resizer = new Ext.Resizable(this.list, {
32623
pinned:true, handles:'se'
32625
this.mon(this.resizer, 'resize', function(r, w, h){
32626
this.maxHeight = h-this.handleHeight-this.list.getFrameWidth('tb')-this.assetHeight;
32627
this.listWidth = w;
32628
this.innerList.setWidth(w - this.list.getFrameWidth('lr'));
32629
this.restrictHeight();
32632
this[this.pageSize?'footer':'innerList'].setStyle('margin-bottom', this.handleHeight+'px');
32638
getListParent : function() {
32639
return document.body;
32643
getStore : function(){
32648
bindStore : function(store, initial){
32649
if(this.store && !initial){
32650
this.store.un('beforeload', this.onBeforeLoad, this);
32651
this.store.un('load', this.onLoad, this);
32652
this.store.un('loadexception', this.collapse, this);
32653
this.store.un('exception', this.collapse, this);
32654
if(this.store !== store && this.store.autoDestroy){
32655
this.store.destroy();
32660
this.view.bindStore(null);
32666
this.lastQuery = null;
32668
this.pageTb.bindStore(store);
32672
this.store = Ext.StoreMgr.lookup(store);
32675
beforeload: this.onBeforeLoad,
32677
loadexception: this.collapse,
32678
exception: this.collapse
32682
this.view.bindStore(store);
32688
initEvents : function(){
32689
Ext.form.ComboBox.superclass.initEvents.call(this);
32691
this.keyNav = new Ext.KeyNav(this.el, {
32692
"up" : function(e){
32693
this.inKeyMode = true;
32697
"down" : function(e){
32698
if(!this.isExpanded()){
32699
this.onTriggerClick();
32701
this.inKeyMode = true;
32706
"enter" : function(e){
32707
this.onViewClick();
32708
this.delayedCheck = true;
32709
this.unsetDelayCheck.defer(10, this);
32712
"esc" : function(e){
32716
"tab" : function(e){
32717
this.onViewClick(false);
32723
doRelay : function(foo, bar, hname){
32724
if(hname == 'down' || this.scope.isExpanded()){
32725
return Ext.KeyNav.prototype.doRelay.apply(this, arguments);
32730
forceKeyDown : true
32732
this.queryDelay = Math.max(this.queryDelay || 10,
32733
this.mode == 'local' ? 10 : 250);
32734
this.dqTask = new Ext.util.DelayedTask(this.initQuery, this);
32735
if(this.typeAhead){
32736
this.taTask = new Ext.util.DelayedTask(this.onTypeAhead, this);
32738
if(this.editable !== false){
32739
this.mon(this.el, 'keyup', this.onKeyUp, this);
32744
onDestroy : function(){
32746
this.dqTask.cancel();
32747
this.dqTask = null;
32749
this.bindStore(null);
32751
this.resizer.destroy(true);
32758
Ext.form.ComboBox.superclass.onDestroy.call(this);
32762
unsetDelayCheck : function(){
32763
delete this.delayedCheck;
32767
fireKey : function(e){
32768
var fn = function(ev){
32769
if (ev.isNavKeyPress() && !this.isExpanded() && !this.delayedCheck) {
32770
this.fireEvent("specialkey", this, ev);
32773
//For some reason I can't track down, the events fire in a different order in webkit.
32774
//Need a slight delay here
32775
if(this.inEditor && Ext.isWebKit && e.getKey() == e.TAB){
32776
fn.defer(10, this, [new Ext.EventObjectImpl(e)]);
32783
onResize : function(w, h){
32784
Ext.form.ComboBox.superclass.onResize.apply(this, arguments);
32785
if(this.list && this.listWidth === undefined){
32786
var lw = Math.max(w, this.minListWidth);
32787
this.list.setWidth(lw);
32788
this.innerList.setWidth(lw - this.list.getFrameWidth('lr'));
32793
onEnable : function(){
32794
Ext.form.ComboBox.superclass.onEnable.apply(this, arguments);
32795
if(this.hiddenField){
32796
this.hiddenField.disabled = false;
32801
onDisable : function(){
32802
Ext.form.ComboBox.superclass.onDisable.apply(this, arguments);
32803
if(this.hiddenField){
32804
this.hiddenField.disabled = true;
32809
onBeforeLoad : function(){
32810
if(!this.hasFocus){
32813
this.innerList.update(this.loadingText ?
32814
'<div class="loading-indicator">'+this.loadingText+'</div>' : '');
32815
this.restrictHeight();
32816
this.selectedIndex = -1;
32820
onLoad : function(){
32821
if(!this.hasFocus){
32824
if(this.store.getCount() > 0){
32826
this.restrictHeight();
32827
if(this.lastQuery == this.allQuery){
32829
this.el.dom.select();
32831
if(!this.selectByValue(this.value, true)){
32832
this.select(0, true);
32836
if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
32837
this.taTask.delay(this.typeAheadDelay);
32841
this.onEmptyResults();
32847
onTypeAhead : function(){
32848
if(this.store.getCount() > 0){
32849
var r = this.store.getAt(0);
32850
var newValue = r.data[this.displayField];
32851
var len = newValue.length;
32852
var selStart = this.getRawValue().length;
32853
if(selStart != len){
32854
this.setRawValue(newValue);
32855
this.selectText(selStart, newValue.length);
32861
onSelect : function(record, index){
32862
if(this.fireEvent('beforeselect', this, record, index) !== false){
32863
this.setValue(record.data[this.valueField || this.displayField]);
32865
this.fireEvent('select', this, record, index);
32870
getName: function(){
32871
var hf = this.hiddenField;
32872
return hf && hf.name ? hf.name : this.hiddenName || Ext.form.ComboBox.superclass.getName.call(this);
32876
getValue : function(){
32877
if(this.valueField){
32878
return typeof this.value != 'undefined' ? this.value : '';
32880
return Ext.form.ComboBox.superclass.getValue.call(this);
32885
clearValue : function(){
32886
if(this.hiddenField){
32887
this.hiddenField.value = '';
32889
this.setRawValue('');
32890
this.lastSelectionText = '';
32891
this.applyEmptyText();
32896
setValue : function(v){
32898
if(this.valueField){
32899
var r = this.findRecord(this.valueField, v);
32901
text = r.data[this.displayField];
32902
}else if(this.valueNotFoundText !== undefined){
32903
text = this.valueNotFoundText;
32906
this.lastSelectionText = text;
32907
if(this.hiddenField){
32908
this.hiddenField.value = v;
32910
Ext.form.ComboBox.superclass.setValue.call(this, text);
32916
findRecord : function(prop, value){
32918
if(this.store.getCount() > 0){
32919
this.store.each(function(r){
32920
if(r.data[prop] == value){
32930
onViewMove : function(e, t){
32931
this.inKeyMode = false;
32935
onViewOver : function(e, t){
32936
if(this.inKeyMode){ // prevent key nav and mouse over conflicts
32939
var item = this.view.findItemFromChild(t);
32941
var index = this.view.indexOf(item);
32942
this.select(index, false);
32947
onViewClick : function(doFocus){
32948
var index = this.view.getSelectedIndexes()[0];
32949
var r = this.store.getAt(index);
32951
this.onSelect(r, index);
32953
if(doFocus !== false){
32959
restrictHeight : function(){
32960
this.innerList.dom.style.height = '';
32961
var inner = this.innerList.dom;
32962
var pad = this.list.getFrameWidth('tb')+(this.resizable?this.handleHeight:0)+this.assetHeight;
32963
var h = Math.max(inner.clientHeight, inner.offsetHeight, inner.scrollHeight);
32964
var ha = this.getPosition()[1]-Ext.getBody().getScroll().top;
32965
var hb = Ext.lib.Dom.getViewHeight()-ha-this.getSize().height;
32966
var space = Math.max(ha, hb, this.minHeight || 0)-this.list.shadowOffset-pad-5;
32967
h = Math.min(h, space, this.maxHeight);
32969
this.innerList.setHeight(h);
32970
this.list.beginUpdate();
32971
this.list.setHeight(h+pad);
32972
this.list.alignTo(this.wrap, this.listAlign);
32973
this.list.endUpdate();
32977
onEmptyResults : function(){
32982
isExpanded : function(){
32983
return this.list && this.list.isVisible();
32987
selectByValue : function(v, scrollIntoView){
32988
if(v !== undefined && v !== null){
32989
var r = this.findRecord(this.valueField || this.displayField, v);
32991
this.select(this.store.indexOf(r), scrollIntoView);
32999
select : function(index, scrollIntoView){
33000
this.selectedIndex = index;
33001
this.view.select(index);
33002
if(scrollIntoView !== false){
33003
var el = this.view.getNode(index);
33005
this.innerList.scrollChildIntoView(el, false);
33011
selectNext : function(){
33012
var ct = this.store.getCount();
33014
if(this.selectedIndex == -1){
33016
}else if(this.selectedIndex < ct-1){
33017
this.select(this.selectedIndex+1);
33023
selectPrev : function(){
33024
var ct = this.store.getCount();
33026
if(this.selectedIndex == -1){
33028
}else if(this.selectedIndex != 0){
33029
this.select(this.selectedIndex-1);
33035
onKeyUp : function(e){
33036
if(this.editable !== false && !e.isSpecialKey()){
33037
this.lastKey = e.getKey();
33038
this.dqTask.delay(this.queryDelay);
33043
validateBlur : function(){
33044
return !this.list || !this.list.isVisible();
33048
initQuery : function(){
33049
this.doQuery(this.getRawValue());
33053
beforeBlur : function(){
33054
var val = this.getRawValue();
33055
if(this.forceSelection){
33056
if(val.length > 0 && val != this.emptyText){
33057
this.el.dom.value = this.lastSelectionText === undefined ? '' : this.lastSelectionText;
33058
this.applyEmptyText();
33063
var rec = this.findRecord(this.displayField, val);
33065
val = rec.get(this.valueField);
33067
this.setValue(val);
33072
doQuery : function(q, forceAll){
33073
q = Ext.isEmpty(q) ? '' : q;
33076
forceAll: forceAll,
33080
if(this.fireEvent('beforequery', qe)===false || qe.cancel){
33084
forceAll = qe.forceAll;
33085
if(forceAll === true || (q.length >= this.minChars)){
33086
if(this.lastQuery !== q){
33087
this.lastQuery = q;
33088
if(this.mode == 'local'){
33089
this.selectedIndex = -1;
33091
this.store.clearFilter();
33093
this.store.filter(this.displayField, q);
33097
this.store.baseParams[this.queryParam] = q;
33099
params: this.getParams(q)
33104
this.selectedIndex = -1;
33111
getParams : function(q){
33113
//p[this.queryParam] = q;
33116
p.limit = this.pageSize;
33122
collapse : function(){
33123
if(!this.isExpanded()){
33127
Ext.getDoc().un('mousewheel', this.collapseIf, this);
33128
Ext.getDoc().un('mousedown', this.collapseIf, this);
33129
this.fireEvent('collapse', this);
33133
collapseIf : function(e){
33134
if(!e.within(this.wrap) && !e.within(this.list)){
33140
expand : function(){
33141
if(this.isExpanded() || !this.hasFocus){
33144
this.list.alignTo(this.wrap, this.listAlign);
33146
this.innerList.setOverflow('auto'); // necessary for FF 2.0/Mac
33147
Ext.getDoc().on('mousewheel', this.collapseIf, this);
33148
Ext.getDoc().on('mousedown', this.collapseIf, this);
33149
this.fireEvent('expand', this);
33154
// Implements the default empty TriggerField.onTriggerClick function
33155
onTriggerClick : function(){
33159
if(this.isExpanded()){
33164
if(this.triggerAction == 'all') {
33165
this.doQuery(this.allQuery, true);
33167
this.doQuery(this.getRawValue());
33179
Ext.reg('combo', Ext.form.ComboBox);
33181
Ext.form.Checkbox = Ext.extend(Ext.form.Field, {
33183
focusClass : undefined,
33185
fieldClass: "x-form-field",
33189
defaultAutoCreate : { tag: "input", type: 'checkbox', autocomplete: "off"},
33196
initComponent : function(){
33197
Ext.form.Checkbox.superclass.initComponent.call(this);
33205
onResize : function(){
33206
Ext.form.Checkbox.superclass.onResize.apply(this, arguments);
33207
if(!this.boxLabel){
33208
this.el.alignTo(this.wrap, 'c-c');
33213
initEvents : function(){
33214
Ext.form.Checkbox.superclass.initEvents.call(this);
33215
this.mon(this.el, 'click', this.onClick, this);
33216
this.mon(this.el, 'change', this.onClick, this);
33220
getResizeEl : function(){
33225
getPositionEl : function(){
33230
markInvalid : Ext.emptyFn,
33232
clearInvalid : Ext.emptyFn,
33235
onRender : function(ct, position){
33236
Ext.form.Checkbox.superclass.onRender.call(this, ct, position);
33237
if(this.inputValue !== undefined){
33238
this.el.dom.value = this.inputValue;
33240
this.wrap = this.el.wrap({cls: "x-form-check-wrap"});
33242
this.wrap.createChild({tag: 'label', htmlFor: this.el.id, cls: 'x-form-cb-label', html: this.boxLabel});
33245
this.setValue(true);
33247
this.checked = this.el.dom.checked;
33252
onDestroy : function(){
33253
Ext.destroy(this.wrap);
33254
Ext.form.Checkbox.superclass.onDestroy.call(this);
33258
initValue : Ext.emptyFn,
33261
getValue : function(){
33263
return this.el.dom.checked;
33269
onClick : function(){
33270
if(this.el.dom.checked != this.checked){
33271
this.setValue(this.el.dom.checked);
33276
setValue : function(v){
33277
var checked = this.checked = (v === true || v === 'true' || v == '1' || String(v).toLowerCase() == 'on');
33278
if(this.el && this.el.dom){
33279
this.el.dom.checked = checked;
33280
this.el.dom.defaultChecked = checked;
33282
this.fireEvent("check", this, checked);
33284
this.handler.call(this.scope || this, this, checked);
33289
Ext.reg('checkbox', Ext.form.Checkbox);
33291
Ext.form.CheckboxGroup = Ext.extend(Ext.form.Field, {
33300
blankText : "You must select at least one item in this group",
33303
defaultType : 'checkbox',
33306
groupCls: 'x-form-check-group',
33309
onRender : function(ct, position){
33312
cls: this.groupCls,
33318
defaultType: this.defaultType,
33327
if(this.items[0].items){
33329
// The container has standard ColumnLayout configs, so pass them in directly
33331
Ext.apply(panelCfg, {
33332
layoutConfig: {columns: this.items.length},
33333
defaults: this.defaults,
33336
for(var i=0, len=this.items.length; i<len; i++){
33337
Ext.applyIf(this.items[i], colCfg);
33342
// The container has field item configs, so we have to generate the column
33343
// panels first then move the items into the columns as needed.
33345
var numCols, cols = [];
33347
if(typeof this.columns == 'string'){ // 'auto' so create a col per item
33348
this.columns = this.items.length;
33350
if(!Ext.isArray(this.columns)){
33352
for(var i=0; i<this.columns; i++){
33353
cs.push((100/this.columns)*.01); // distribute by even %
33358
numCols = this.columns.length;
33360
// Generate the column configs with the correct width setting
33361
for(var i=0; i<numCols; i++){
33362
var cc = Ext.apply({items:[]}, colCfg);
33363
cc[this.columns[i] <= 1 ? 'columnWidth' : 'width'] = this.columns[i];
33365
cc.defaults = Ext.apply(cc.defaults || {}, this.defaults)
33370
// Distribute the original items into the columns
33372
var rows = Math.ceil(this.items.length / numCols), ri = 0;
33373
for(var i=0, len=this.items.length; i<len; i++){
33374
if(i>0 && i%rows==0){
33377
if(this.items[i].fieldLabel){
33378
this.items[i].hideLabel = false;
33380
cols[ri].items.push(this.items[i]);
33383
for(var i=0, len=this.items.length; i<len; i++){
33384
var ci = i % numCols;
33385
if(this.items[i].fieldLabel){
33386
this.items[i].hideLabel = false;
33388
cols[ci].items.push(this.items[i]);
33392
Ext.apply(panelCfg, {
33393
layoutConfig: {columns: numCols},
33398
this.panel = new Ext.Panel(panelCfg);
33399
this.el = this.panel.getEl();
33401
if(this.forId && this.itemCls){
33402
var l = this.el.up(this.itemCls).child('label', true);
33404
l.setAttribute('htmlFor', this.forId);
33408
var fields = this.panel.findBy(function(c){
33409
return c.isFormField;
33412
this.items = new Ext.util.MixedCollection();
33413
this.items.addAll(fields);
33415
Ext.form.CheckboxGroup.superclass.onRender.call(this, ct, position);
33418
afterRender: function(){
33419
Ext.form.CheckboxGroup.superclass.afterRender.call(this);
33421
this.setValue.apply(this, this.values);
33422
delete this.values;
33427
validateValue : function(value){
33428
if(!this.allowBlank){
33430
this.items.each(function(f){
33432
return blank = false;
33436
this.markInvalid(this.blankText);
33444
onDisable : function(){
33445
this.items.each(function(item){
33451
onEnable : function(){
33452
this.items.each(function(item){
33458
onResize : function(w, h){
33459
this.panel.setSize(w, h);
33460
this.panel.doLayout();
33463
// inherit docs from Field
33464
reset : function(){
33465
Ext.form.CheckboxGroup.superclass.reset.call(this);
33466
this.items.each(function(c){
33474
setValue : function(id, value){
33476
if(arguments.length == 1){
33477
if(Ext.isArray(id)){
33478
//an array of boolean values
33479
Ext.each(id, function(val, idx){
33480
var item = this.items.itemAt(idx);
33482
item.setValue(val);
33485
}else if(Ext.isObject(id)){
33486
//set of name/value pairs
33488
var f = this.getBox(i);
33495
var f = this.getBox(id);
33501
this.values = arguments;
33506
getBox: function(id){
33508
this.items.each(function(f){
33509
if(id == f || f.dataIndex == id || f.id == id || f.getName() == id){
33518
getValue: function(){
33521
this.items.each(function(item){
33532
initValue : Ext.emptyFn,
33534
getValue : Ext.emptyFn,
33536
getRawValue : Ext.emptyFn,
33539
setRawValue : Ext.emptyFn
33543
Ext.reg('checkboxgroup', Ext.form.CheckboxGroup);
33546
Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
33547
inputType: 'radio',
33550
markInvalid : Ext.emptyFn,
33552
clearInvalid : Ext.emptyFn,
33555
getGroupValue : function(){
33556
var p = this.el.up('form') || Ext.getBody();
33557
var c = p.child('input[name='+this.el.dom.name+']:checked', true);
33558
return c ? c.value : null;
33562
onClick : function(){
33563
if(this.el.dom.checked != this.checked){
33564
var p = this.el.up('form') || Ext.getBody();
33565
var els = p.select('input[name='+this.el.dom.name+']');
33566
els.each(function(el){
33567
if(el.dom.id == this.id){
33568
this.setValue(true);
33570
Ext.getCmp(el.dom.id).setValue(false);
33577
setValue : function(v){
33578
if (typeof v == 'boolean') {
33579
Ext.form.Radio.superclass.setValue.call(this, v);
33581
var r = this.el.up('form').child('input[name='+this.el.dom.name+'][value='+v+']', true);
33589
Ext.reg('radio', Ext.form.Radio);
33592
Ext.form.RadioGroup = Ext.extend(Ext.form.CheckboxGroup, {
33596
blankText : "You must select one item in this group",
33599
defaultType : 'radio',
33602
groupCls: 'x-form-radio-group',
33605
getValue: function(){
33608
this.items.each(function(item){
33619
setValue: function(id, value){
33621
var f = this.getBox(id);
33625
this.items.each(function(item){
33627
item.setValue(false);
33633
this.values = [id, value];
33640
Ext.reg('radiogroup', Ext.form.RadioGroup);
33643
Ext.form.Hidden = Ext.extend(Ext.form.Field, {
33645
inputType : 'hidden',
33648
onRender : function(){
33649
Ext.form.Hidden.superclass.onRender.apply(this, arguments);
33653
initEvents : function(){
33654
this.originalValue = this.getValue();
33657
// These are all private overrides
33658
setSize : Ext.emptyFn,
33659
setWidth : Ext.emptyFn,
33660
setHeight : Ext.emptyFn,
33661
setPosition : Ext.emptyFn,
33662
setPagePosition : Ext.emptyFn,
33663
markInvalid : Ext.emptyFn,
33664
clearInvalid : Ext.emptyFn
33666
Ext.reg('hidden', Ext.form.Hidden);
33668
Ext.form.BasicForm = function(el, config){
33669
Ext.apply(this, config);
33670
if(typeof this.paramOrder == 'string'){
33671
this.paramOrder = this.paramOrder.split(/[\s,|]/);
33674
this.items = new Ext.util.MixedCollection(false, function(o){
33675
return o.itemId || o.id || (o.id = Ext.id());
33689
Ext.form.BasicForm.superclass.constructor.call(this);
33692
Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
33705
paramOrder: undefined,
33708
paramsAsHash: false,
33712
activeAction : null,
33715
trackResetOnLoad : false,
33721
initEl : function(el){
33722
this.el = Ext.get(el);
33723
this.id = this.el.id || Ext.id();
33724
if(!this.standardSubmit){
33725
this.el.on('submit', this.onSubmit, this);
33727
this.el.addClass('x-form');
33736
onSubmit : function(e){
33741
destroy: function() {
33742
this.items.each(function(f){
33746
this.el.removeAllListeners();
33749
this.purgeListeners();
33753
isValid : function(){
33755
this.items.each(function(f){
33764
isDirty : function(){
33766
this.items.each(function(f){
33776
doAction : function(action, options){
33777
if(typeof action == 'string'){
33778
action = new Ext.form.Action.ACTION_TYPES[action](this, options);
33780
if(this.fireEvent('beforeaction', this, action) !== false){
33781
this.beforeAction(action);
33782
action.run.defer(100, action);
33788
submit : function(options){
33789
if(this.standardSubmit){
33790
var v = this.isValid();
33792
this.el.dom.submit();
33796
var submitAction = String.format('{0}submit', this.api ? 'direct' : '');
33797
this.doAction(submitAction, options);
33802
load : function(options){
33803
var loadAction = String.format('{0}load', this.api ? 'direct' : '');
33804
this.doAction(loadAction, options);
33809
updateRecord : function(record){
33810
record.beginEdit();
33811
var fs = record.fields;
33812
fs.each(function(f){
33813
var field = this.findField(f.name);
33815
record.set(f.name, field.getValue());
33823
loadRecord : function(record){
33824
this.setValues(record.data);
33829
beforeAction : function(action){
33830
var o = action.options;
33832
if(this.waitMsgTarget === true){
33833
this.el.mask(o.waitMsg, 'x-mask-loading');
33834
}else if(this.waitMsgTarget){
33835
this.waitMsgTarget = Ext.get(this.waitMsgTarget);
33836
this.waitMsgTarget.mask(o.waitMsg, 'x-mask-loading');
33838
Ext.MessageBox.wait(o.waitMsg, o.waitTitle || this.waitTitle || 'Please Wait...');
33844
afterAction : function(action, success){
33845
this.activeAction = null;
33846
var o = action.options;
33848
if(this.waitMsgTarget === true){
33850
}else if(this.waitMsgTarget){
33851
this.waitMsgTarget.unmask();
33853
Ext.MessageBox.updateProgress(1);
33854
Ext.MessageBox.hide();
33861
Ext.callback(o.success, o.scope, [this, action]);
33862
this.fireEvent('actioncomplete', this, action);
33864
Ext.callback(o.failure, o.scope, [this, action]);
33865
this.fireEvent('actionfailed', this, action);
33870
findField : function(id){
33871
var field = this.items.get(id);
33872
if(!Ext.isObject(field)){
33873
this.items.each(function(f){
33874
if(f.isFormField && (f.dataIndex == id || f.id == id || f.getName() == id)){
33880
return field || null;
33885
markInvalid : function(errors){
33886
if(Ext.isArray(errors)){
33887
for(var i = 0, len = errors.length; i < len; i++){
33888
var fieldError = errors[i];
33889
var f = this.findField(fieldError.id);
33891
f.markInvalid(fieldError.msg);
33897
if(!Ext.isFunction(errors[id]) && (field = this.findField(id))){
33898
field.markInvalid(errors[id]);
33906
setValues : function(values){
33907
if(Ext.isArray(values)){ // array of objects
33908
for(var i = 0, len = values.length; i < len; i++){
33910
var f = this.findField(v.id);
33912
f.setValue(v.value);
33913
if(this.trackResetOnLoad){
33914
f.originalValue = f.getValue();
33918
}else{ // object hash
33921
if(!Ext.isFunction(values[id]) && (field = this.findField(id))){
33922
field.setValue(values[id]);
33923
if(this.trackResetOnLoad){
33924
field.originalValue = field.getValue();
33933
getValues : function(asString){
33934
var fs = Ext.lib.Ajax.serializeForm(this.el.dom);
33935
if(asString === true){
33938
return Ext.urlDecode(fs);
33941
getFieldValues : function(){
33943
this.items.each(function(f){
33944
o[f.getName()] = f.getValue();
33950
clearInvalid : function(){
33951
this.items.each(function(f){
33958
reset : function(){
33959
this.items.each(function(f){
33967
this.items.addAll(Array.prototype.slice.call(arguments, 0));
33973
remove : function(field){
33974
this.items.remove(field);
33979
render : function(){
33980
this.items.each(function(f){
33981
if(f.isFormField && !f.rendered && document.getElementById(f.id)){ // if the element exists
33982
f.applyToMarkup(f.id);
33989
applyToFields : function(o){
33990
this.items.each(function(f){
33997
applyIfToFields : function(o){
33998
this.items.each(function(f){
34004
callFieldMethod : function(fnName, args){
34006
this.items.each(function(f){
34007
if(Ext.isFunction(f[fnName])){
34008
f[fnName].apply(f, args);
34016
Ext.BasicForm = Ext.form.BasicForm;
34018
Ext.FormPanel = Ext.extend(Ext.Panel, {
34027
buttonAlign : 'center',
34030
minButtonWidth : 75,
34033
labelAlign : 'left',
34036
monitorValid : false,
34045
initComponent : function(){
34046
this.form = this.createForm();
34047
Ext.FormPanel.superclass.initComponent.call(this);
34051
cls: this.baseCls + '-body',
34052
method : this.method || 'POST',
34053
id : this.formId || Ext.id()
34055
if(this.fileUpload) {
34056
this.bodyCfg.enctype = 'multipart/form-data';
34065
this.relayEvents(this.form, ['beforeaction', 'actionfailed', 'actioncomplete']);
34069
createForm : function(){
34070
delete this.initialConfig.listeners;
34071
return new Ext.form.BasicForm(null, this.initialConfig);
34075
initFields : function(){
34077
var formPanel = this;
34078
var fn = function(c){
34079
if(formPanel.isField(c)){
34081
}if(c.isFieldWrap){
34083
labelAlign: c.ownerCt.labelAlign,
34084
labelWidth: c.ownerCt.labelWidth,
34085
itemCls: c.ownerCt.itemCls
34088
}else if(c.doLayout && c != formPanel){
34090
labelAlign: c.ownerCt.labelAlign,
34091
labelWidth: c.ownerCt.labelWidth,
34092
itemCls: c.ownerCt.itemCls
34095
c.items.each(fn, this);
34099
this.items.each(fn, this);
34103
getLayoutTarget : function(){
34104
return this.form.el;
34108
getForm : function(){
34113
onRender : function(ct, position){
34115
Ext.FormPanel.superclass.onRender.call(this, ct, position);
34116
this.form.initEl(this.body);
34120
beforeDestroy : function(){
34121
Ext.FormPanel.superclass.beforeDestroy.call(this);
34122
this.stopMonitoring();
34123
Ext.destroy(this.form);
34126
// Determine if a Component is usable as a form Field.
34127
isField : function(c) {
34128
return !!c.setValue && !!c.getValue && !!c.markInvalid && !!c.clearInvalid;
34132
initEvents : function(){
34133
Ext.FormPanel.superclass.initEvents.call(this);
34134
this.on('remove', this.onRemove, this);
34135
this.on('add', this.onAdd, this);
34136
if(this.monitorValid){ // initialize after render
34137
this.startMonitoring();
34142
onAdd : function(ct, c) {
34143
// If a single form Field, add it
34144
if (this.isField(c)) {
34146
// If a Container, add any Fields it might contain
34147
} else if (c.findBy) {
34149
labelAlign: c.ownerCt.labelAlign,
34150
labelWidth: c.ownerCt.labelWidth,
34151
itemCls: c.ownerCt.itemCls
34153
this.form.add.apply(this.form, c.findBy(this.isField));
34158
onRemove : function(ct, c) {
34159
// If a single form Field, remove it
34160
if (this.isField(c)) {
34161
Ext.destroy(c.container.up('.x-form-item'));
34162
this.form.remove(c);
34163
// If a Container, remove any Fields it might contain
34164
} else if (c.findByType) {
34165
Ext.each(c.findBy(this.isField), this.form.remove, this.form);
34170
startMonitoring : function(){
34171
if(!this.validTask){
34172
this.validTask = new Ext.util.TaskRunner();
34173
this.validTask.start({
34174
run : this.bindHandler,
34175
interval : this.monitorPoll || 200,
34182
stopMonitoring : function(){
34183
if(this.validTask){
34184
this.validTask.stopAll();
34185
this.validTask = null;
34191
this.form.load.apply(this.form, arguments);
34195
onDisable : function(){
34196
Ext.FormPanel.superclass.onDisable.call(this);
34198
this.form.items.each(function(){
34205
onEnable : function(){
34206
Ext.FormPanel.superclass.onEnable.call(this);
34208
this.form.items.each(function(){
34215
bindHandler : function(){
34217
this.form.items.each(function(f){
34218
if(!f.isValid(true)){
34224
var fitems = this.fbar.items.items;
34225
for(var i = 0, len = fitems.length; i < len; i++){
34226
var btn = fitems[i];
34227
if(btn.formBind === true && btn.disabled === valid){
34228
btn.setDisabled(!valid);
34232
this.fireEvent('clientvalidation', this, valid);
34235
Ext.reg('form', Ext.FormPanel);
34237
Ext.form.FormPanel = Ext.FormPanel;
34241
Ext.form.FieldSet = Ext.extend(Ext.Panel, {
34248
baseCls:'x-fieldset',
34252
animCollapse: false,
34255
onRender : function(ct, position){
34257
this.el = document.createElement('fieldset');
34258
this.el.id = this.id;
34259
if (this.title || this.header || this.checkboxToggle) {
34260
this.el.appendChild(document.createElement('legend')).className = 'x-fieldset-header';
34264
Ext.form.FieldSet.superclass.onRender.call(this, ct, position);
34266
if(this.checkboxToggle){
34267
var o = typeof this.checkboxToggle == 'object' ?
34268
this.checkboxToggle :
34269
{tag: 'input', type: 'checkbox', name: this.checkboxName || this.id+'-checkbox'};
34270
this.checkbox = this.header.insertFirst(o);
34271
this.checkbox.dom.checked = !this.collapsed;
34272
this.mon(this.checkbox, 'click', this.onCheckClick, this);
34277
onCollapse : function(doAnim, animArg){
34279
this.checkbox.dom.checked = false;
34281
Ext.form.FieldSet.superclass.onCollapse.call(this, doAnim, animArg);
34286
onExpand : function(doAnim, animArg){
34288
this.checkbox.dom.checked = true;
34290
Ext.form.FieldSet.superclass.onExpand.call(this, doAnim, animArg);
34294
onCheckClick : function(){
34295
this[this.checkbox.dom.checked ? 'expand' : 'collapse']();
34338
Ext.reg('fieldset', Ext.form.FieldSet);
34343
Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
34345
enableFormat : true,
34347
enableFontSize : true,
34349
enableColors : true,
34351
enableAlignments : true,
34353
enableLists : true,
34355
enableSourceEdit : true,
34357
enableLinks : true,
34361
createLinkText : 'Please enter the URL for the link:',
34363
defaultLinkValue : 'http:/'+'/',
34372
defaultFont: 'tahoma',
34374
defaultValue: Ext.isOpera ? ' ' : '​',
34376
// private properties
34377
validationEvent : false,
34379
initialized : false,
34381
sourceEditMode : false,
34382
onFocus : Ext.emptyFn,
34384
hideMode:'offsets',
34385
defaultAutoCreate : {
34387
style:"width:500px;height:300px;",
34388
autocomplete: "off"
34392
initComponent : function(){
34412
createFontOptions : function(){
34413
var buf = [], fs = this.fontFamilies, ff, lc;
34414
for(var i = 0, len = fs.length; i< len; i++){
34416
lc = ff.toLowerCase();
34418
'<option value="',lc,'" style="font-family:',ff,';"',
34419
(this.defaultFont == lc ? ' selected="true">' : '>'),
34424
return buf.join('');
34428
createToolbar : function(editor){
34430
var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
34432
function btn(id, toggle, handler){
34435
cls : 'x-btn-icon',
34436
iconCls: 'x-edit-'+id,
34437
enableToggle:toggle !== false,
34439
handler:handler||editor.relayBtnCmd,
34440
clickEvent:'mousedown',
34441
tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
34446
// build the toolbar
34447
var tb = new Ext.Toolbar({
34448
renderTo:this.wrap.dom.firstChild
34451
// stop form submits
34452
this.mon(tb.el, 'click', function(e){
34453
e.preventDefault();
34456
if(this.enableFont && !Ext.isSafari2){
34457
this.fontSelect = tb.el.createChild({
34459
cls:'x-font-select',
34460
html: this.createFontOptions()
34462
this.mon(this.fontSelect, 'change', function(){
34463
var font = this.fontSelect.dom.value;
34464
this.relayCmd('fontname', font);
34469
this.fontSelect.dom,
34474
if(this.enableFormat){
34482
if(this.enableFontSize){
34485
btn('increasefontsize', false, this.adjustFont),
34486
btn('decreasefontsize', false, this.adjustFont)
34490
if(this.enableColors){
34493
itemId:'forecolor',
34495
iconCls: 'x-edit-forecolor',
34496
clickEvent:'mousedown',
34497
tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
34499
menu : new Ext.menu.ColorMenu({
34500
allowReselect: true,
34501
focus: Ext.emptyFn,
34506
select: function(cp, color){
34507
this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
34511
clickEvent:'mousedown'
34514
itemId:'backcolor',
34516
iconCls: 'x-edit-backcolor',
34517
clickEvent:'mousedown',
34518
tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
34520
menu : new Ext.menu.ColorMenu({
34521
focus: Ext.emptyFn,
34524
allowReselect: true,
34527
select: function(cp, color){
34529
this.execCmd('useCSS', false);
34530
this.execCmd('hilitecolor', color);
34531
this.execCmd('useCSS', true);
34534
this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
34539
clickEvent:'mousedown'
34545
if(this.enableAlignments){
34548
btn('justifyleft'),
34549
btn('justifycenter'),
34550
btn('justifyright')
34554
if(!Ext.isSafari2){
34555
if(this.enableLinks){
34558
btn('createlink', false, this.createLink)
34562
if(this.enableLists){
34565
btn('insertorderedlist'),
34566
btn('insertunorderedlist')
34569
if(this.enableSourceEdit){
34572
btn('sourceedit', true, function(btn){
34573
this.toggleSourceEdit(!this.sourceEditMode);
34583
getDocMarkup : function(){
34584
return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
34588
getEditorBody : function(){
34589
return this.doc.body || this.doc.documentElement;
34593
getDoc : function(){
34594
return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
34598
getWin : function(){
34599
return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
34603
onRender : function(ct, position){
34604
Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
34605
this.el.dom.style.border = '0 none';
34606
this.el.dom.setAttribute('tabIndex', -1);
34607
this.el.addClass('x-hidden');
34608
if(Ext.isIE){ // fix IE 1px bogus margin
34609
this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
34611
this.wrap = this.el.wrap({
34612
cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
34615
this.createToolbar(this);
34617
this.disableItems(true);
34619
// this.tb.doLayout();
34621
this.createIFrame();
34624
var sz = this.el.getSize();
34625
this.setSize(sz.width, this.height || sz.height);
34629
createIFrame: function(){
34630
var iframe = document.createElement('iframe');
34631
iframe.name = Ext.id();
34632
iframe.frameBorder = '0';
34633
iframe.src = Ext.isIE ? Ext.SSL_SECURE_URL : "javascript:;";
34634
this.wrap.dom.appendChild(iframe);
34636
this.iframe = iframe;
34638
this.monitorTask = Ext.TaskMgr.start({
34639
run: this.checkDesignMode,
34645
initFrame : function(){
34646
Ext.TaskMgr.stop(this.monitorTask);
34647
this.doc = this.getDoc();
34648
this.win = this.getWin();
34651
this.doc.write(this.getDocMarkup());
34654
var task = { // must defer to wait for browser to be ready
34656
if(this.doc.body || this.doc.readyState == 'complete'){
34657
Ext.TaskMgr.stop(task);
34658
this.doc.designMode="on";
34659
this.initEditor.defer(10, this);
34666
Ext.TaskMgr.start(task);
34670
checkDesignMode : function(){
34671
if(this.wrap && this.wrap.dom.offsetWidth){
34672
var doc = this.getDoc();
34676
if(!doc.editorInitialized || String(doc.designMode).toLowerCase() != 'on'){
34682
disableItems: function(disabled){
34683
if(this.fontSelect){
34684
this.fontSelect.dom.disabled = disabled;
34686
this.tb.items.each(function(item){
34687
if(item.itemId != 'sourceedit'){
34688
item.setDisabled(disabled);
34694
onResize : function(w, h){
34695
Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
34696
if(this.el && this.iframe){
34697
if(typeof w == 'number'){
34698
var aw = w - this.wrap.getFrameWidth('lr');
34699
this.el.setWidth(this.adjustWidth('textarea', aw));
34700
this.tb.setWidth(aw);
34701
this.iframe.style.width = Math.max(aw, 0) + 'px';
34703
if(typeof h == 'number'){
34704
var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
34705
this.el.setHeight(this.adjustWidth('textarea', ah));
34706
this.iframe.style.height = Math.max(ah, 0) + 'px';
34708
this.getEditorBody().style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
34715
toggleSourceEdit : function(sourceEditMode){
34716
if(sourceEditMode === undefined){
34717
sourceEditMode = !this.sourceEditMode;
34719
this.sourceEditMode = sourceEditMode === true;
34720
var btn = this.tb.items.get('sourceedit');
34721
if(btn.pressed !== this.sourceEditMode){
34722
btn.toggle(this.sourceEditMode);
34723
if(!btn.xtbHidden){
34727
if(this.sourceEditMode){
34728
this.disableItems(true);
34730
this.iframe.className = 'x-hidden';
34731
this.el.removeClass('x-hidden');
34732
this.el.dom.removeAttribute('tabIndex');
34735
if(this.initialized){
34736
this.disableItems(false);
34739
this.iframe.className = '';
34740
this.el.addClass('x-hidden');
34741
this.el.dom.setAttribute('tabIndex', -1);
34744
var lastSize = this.lastSize;
34746
delete this.lastSize;
34747
this.setSize(lastSize);
34749
this.fireEvent('editmodechange', this, this.sourceEditMode);
34752
// private used internally
34753
createLink : function(){
34754
var url = prompt(this.createLinkText, this.defaultLinkValue);
34755
if(url && url != 'http:/'+'/'){
34756
this.relayCmd('createlink', url);
34760
// private (for BoxComponent)
34761
adjustSize : Ext.BoxComponent.prototype.adjustSize,
34763
// private (for BoxComponent)
34764
getResizeEl : function(){
34768
// private (for BoxComponent)
34769
getPositionEl : function(){
34774
initEvents : function(){
34775
this.originalValue = this.getValue();
34779
markInvalid : Ext.emptyFn,
34782
clearInvalid : Ext.emptyFn,
34784
// docs inherit from Field
34785
setValue : function(v){
34786
Ext.form.HtmlEditor.superclass.setValue.call(this, v);
34792
cleanHtml : function(html){
34793
html = String(html);
34794
if(html.length > 5){
34795
if(Ext.isWebKit){ // strip safari nonsense
34796
html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
34799
if(html == this.defaultValue){
34806
syncValue : function(){
34807
if(this.initialized){
34808
var bd = this.getEditorBody();
34809
var html = bd.innerHTML;
34811
var bs = bd.getAttribute('style'); // Safari puts text-align styles on the body element!
34812
var m = bs.match(/text-align:(.*?);/i);
34814
html = '<div style="'+m[0]+'">' + html + '</div>';
34817
html = this.cleanHtml(html);
34818
if(this.fireEvent('beforesync', this, html) !== false){
34819
this.el.dom.value = html;
34820
this.fireEvent('sync', this, html);
34825
//docs inherit from Field
34826
getValue : function() {
34827
this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
34828
return Ext.form.HtmlEditor.superclass.getValue.call(this);
34832
pushValue : function(){
34833
if(this.initialized){
34834
var v = this.el.dom.value;
34835
if(!this.activated && v.length < 1){
34836
v = this.defaultValue;
34838
if(this.fireEvent('beforepush', this, v) !== false){
34839
this.getEditorBody().innerHTML = v;
34840
this.fireEvent('push', this, v);
34846
deferFocus : function(){
34847
this.focus.defer(10, this);
34850
// docs inherit from Field
34851
focus : function(){
34852
if(this.win && !this.sourceEditMode){
34860
initEditor : function(){
34861
//Destroying the component during/before initEditor can cause issues.
34863
var dbody = this.getEditorBody();
34864
var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
34865
ss['background-attachment'] = 'fixed'; // w3c
34866
dbody.bgProperties = 'fixed'; // ie
34868
Ext.DomHelper.applyStyles(dbody, ss);
34872
Ext.EventManager.removeAll(this.doc);
34876
this.doc = this.getDoc();
34878
Ext.EventManager.on(this.doc, {
34879
'mousedown': this.onEditorEvent,
34880
'dblclick': this.onEditorEvent,
34881
'click': this.onEditorEvent,
34882
'keyup': this.onEditorEvent,
34888
Ext.EventManager.on(this.doc, 'keypress', this.applyCommand, this);
34890
if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
34891
Ext.EventManager.on(this.doc, 'keydown', this.fixKeys, this);
34893
this.initialized = true;
34894
this.fireEvent('initialize', this);
34895
this.doc.editorInitialized = true;
34901
onDestroy : function(){
34902
if(this.monitorTask){
34903
Ext.TaskMgr.stop(this.monitorTask);
34906
Ext.destroy(this.tb);
34908
this.wrap.dom.innerHTML = '';
34909
this.wrap.remove();
34913
this.el.removeAllListeners();
34919
Ext.EventManager.removeAll(this.doc);
34920
for (var prop in this.doc){
34921
delete this.doc[prop];
34925
this.purgeListeners();
34929
onFirstFocus : function(){
34930
this.activated = true;
34931
this.disableItems(false);
34932
if(Ext.isGecko){ // prevent silly gecko errors
34934
var s = this.win.getSelection();
34935
if(!s.focusNode || s.focusNode.nodeType != 3){
34936
var r = s.getRangeAt(0);
34937
r.selectNodeContents(this.getEditorBody());
34942
this.execCmd('useCSS', true);
34943
this.execCmd('styleWithCSS', false);
34946
this.fireEvent('activate', this);
34950
adjustFont: function(btn){
34951
var adjust = btn.itemId == 'increasefontsize' ? 1 : -1;
34953
var v = parseInt(this.doc.queryCommandValue('FontSize') || 2, 10);
34954
if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){
34956
// 1 = 10px, 2 = 13px, 3 = 16px, 4 = 18px, 5 = 24px, 6 = 32px
34970
v = v.constrain(1, 6);
34972
if(Ext.isSafari){ // safari
34975
v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
34977
this.execCmd('FontSize', v);
34981
onEditorEvent : function(e){
34982
this.updateToolbar();
34987
updateToolbar: function(){
34989
if(!this.activated){
34990
this.onFirstFocus();
34994
var btns = this.tb.items.map, doc = this.doc;
34996
if(this.enableFont && !Ext.isSafari2){
34997
var name = (this.doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
34998
if(name != this.fontSelect.dom.value){
34999
this.fontSelect.dom.value = name;
35002
if(this.enableFormat){
35003
btns.bold.toggle(doc.queryCommandState('bold'));
35004
btns.italic.toggle(doc.queryCommandState('italic'));
35005
btns.underline.toggle(doc.queryCommandState('underline'));
35007
if(this.enableAlignments){
35008
btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
35009
btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
35010
btns.justifyright.toggle(doc.queryCommandState('justifyright'));
35012
if(!Ext.isSafari2 && this.enableLists){
35013
btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
35014
btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
35017
Ext.menu.MenuMgr.hideAll();
35023
relayBtnCmd : function(btn){
35024
this.relayCmd(btn.itemId);
35028
relayCmd : function(cmd, value){
35031
this.execCmd(cmd, value);
35032
this.updateToolbar();
35033
}).defer(10, this);
35037
execCmd : function(cmd, value){
35038
this.doc.execCommand(cmd, false, value === undefined ? null : value);
35043
applyCommand : function(e){
35045
var c = e.getCharCode(), cmd;
35047
c = String.fromCharCode(c);
35063
e.preventDefault();
35070
insertAtCursor : function(text){
35071
if(!this.activated){
35076
var r = this.doc.selection.createRange();
35083
}else if(Ext.isGecko || Ext.isOpera){
35085
this.execCmd('InsertHTML', text);
35087
}else if(Ext.isWebKit){
35088
this.execCmd('InsertText', text);
35094
fixKeys : function(){ // load time branching for fastest keydown performance
35096
return function(e){
35097
var k = e.getKey(), r;
35100
r = this.doc.selection.createRange();
35103
r.pasteHTML(' ');
35106
}else if(k == e.ENTER){
35107
r = this.doc.selection.createRange();
35109
var target = r.parentElement();
35110
if(!target || target.tagName.toLowerCase() != 'li'){
35112
r.pasteHTML('<br />');
35119
}else if(Ext.isOpera){
35120
return function(e){
35121
var k = e.getKey();
35125
this.execCmd('InsertHTML',' ');
35129
}else if(Ext.isWebKit){
35130
return function(e){
35131
var k = e.getKey();
35134
this.execCmd('InsertText','\t');
35142
getToolbar : function(){
35149
title: 'Bold (Ctrl+B)',
35150
text: 'Make the selected text bold.',
35151
cls: 'x-html-editor-tip'
35154
title: 'Italic (Ctrl+I)',
35155
text: 'Make the selected text italic.',
35156
cls: 'x-html-editor-tip'
35159
title: 'Underline (Ctrl+U)',
35160
text: 'Underline the selected text.',
35161
cls: 'x-html-editor-tip'
35163
increasefontsize : {
35164
title: 'Grow Text',
35165
text: 'Increase the font size.',
35166
cls: 'x-html-editor-tip'
35168
decreasefontsize : {
35169
title: 'Shrink Text',
35170
text: 'Decrease the font size.',
35171
cls: 'x-html-editor-tip'
35174
title: 'Text Highlight Color',
35175
text: 'Change the background color of the selected text.',
35176
cls: 'x-html-editor-tip'
35179
title: 'Font Color',
35180
text: 'Change the color of the selected text.',
35181
cls: 'x-html-editor-tip'
35184
title: 'Align Text Left',
35185
text: 'Align text to the left.',
35186
cls: 'x-html-editor-tip'
35189
title: 'Center Text',
35190
text: 'Center text in the editor.',
35191
cls: 'x-html-editor-tip'
35194
title: 'Align Text Right',
35195
text: 'Align text to the right.',
35196
cls: 'x-html-editor-tip'
35198
insertunorderedlist : {
35199
title: 'Bullet List',
35200
text: 'Start a bulleted list.',
35201
cls: 'x-html-editor-tip'
35203
insertorderedlist : {
35204
title: 'Numbered List',
35205
text: 'Start a numbered list.',
35206
cls: 'x-html-editor-tip'
35209
title: 'Hyperlink',
35210
text: 'Make the selected text a hyperlink.',
35211
cls: 'x-html-editor-tip'
35214
title: 'Source Edit',
35215
text: 'Switch to source editing mode.',
35216
cls: 'x-html-editor-tip'
35220
// hide stuff that is not compatible
35255
Ext.reg('htmleditor', Ext.form.HtmlEditor);
35257
Ext.form.TimeField = Ext.extend(Ext.form.ComboBox, {
35263
minText : "The time in this field must be equal to or after {0}",
35265
maxText : "The time in this field must be equal to or before {0}",
35267
invalidText : "{0} is not a valid time",
35271
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",
35275
// private override
35277
// private override
35278
triggerAction: 'all',
35279
// private override
35282
// private - This is the date to use when generating time values in the absence of either minValue
35283
// or maxValue. Using the current date causes DST issues on DST boundary dates, so this is an
35284
// arbitrary "safe" date that can be any date aside from DST boundary dates.
35285
initDate: '1/1/2008',
35288
initComponent : function(){
35289
Ext.form.TimeField.superclass.initComponent.call(this);
35291
if(typeof this.minValue == "string"){
35292
this.minValue = this.parseDate(this.minValue);
35294
if(typeof this.maxValue == "string"){
35295
this.maxValue = this.parseDate(this.maxValue);
35299
var min = this.parseDate(this.minValue);
35301
min = new Date(this.initDate).clearTime();
35303
var max = this.parseDate(this.maxValue);
35305
max = new Date(this.initDate).clearTime().add('mi', (24 * 60) - 1);
35309
times.push([min.dateFormat(this.format)]);
35310
min = min.add('mi', this.increment);
35312
this.store = new Ext.data.ArrayStore({
35316
this.displayField = 'text';
35321
getValue : function(){
35322
var v = Ext.form.TimeField.superclass.getValue.call(this);
35323
return this.formatDate(this.parseDate(v)) || '';
35327
setValue : function(value){
35328
return Ext.form.TimeField.superclass.setValue.call(this, this.formatDate(this.parseDate(value)));
35331
// private overrides
35332
validateValue : Ext.form.DateField.prototype.validateValue,
35333
parseDate : Ext.form.DateField.prototype.parseDate,
35334
formatDate : Ext.form.DateField.prototype.formatDate,
35337
beforeBlur : function(){
35338
var v = this.parseDate(this.getRawValue());
35340
this.setValue(v.dateFormat(this.format));
35342
Ext.form.TimeField.superclass.beforeBlur.call(this);
35350
Ext.reg('timefield', Ext.form.TimeField);
35352
Ext.form.Label = Ext.extend(Ext.BoxComponent, {
35358
onRender : function(ct, position){
35360
this.el = document.createElement('label');
35361
this.el.id = this.getId();
35362
this.el.innerHTML = this.text ? Ext.util.Format.htmlEncode(this.text) : (this.html || '');
35364
this.el.setAttribute('for', this.forId);
35367
Ext.form.Label.superclass.onRender.call(this, ct, position);
35371
setText: function(t, encode){
35374
this.el.dom.innerHTML = encode !== false ? Ext.util.Format.htmlEncode(t) : t;
35380
Ext.reg('label', Ext.form.Label);
35382
Ext.form.Action = function(form, options){
35384
this.options = options || {};
35388
Ext.form.Action.CLIENT_INVALID = 'client';
35390
Ext.form.Action.SERVER_INVALID = 'server';
35392
Ext.form.Action.CONNECT_FAILURE = 'connect';
35394
Ext.form.Action.LOAD_FAILURE = 'load';
35396
Ext.form.Action.prototype = {
35414
// interface method
35415
run : function(options){
35419
// interface method
35420
success : function(response){
35424
// interface method
35425
handleResponse : function(response){
35429
// default connection failure
35430
failure : function(response){
35431
this.response = response;
35432
this.failureType = Ext.form.Action.CONNECT_FAILURE;
35433
this.form.afterAction(this, false);
35437
// shared code among all Actions to validate that there was a response
35438
// with either responseText or responseXml
35439
processResponse : function(response){
35440
this.response = response;
35441
if(!response.responseText && !response.responseXML){
35444
this.result = this.handleResponse(response);
35445
return this.result;
35448
// utility functions used internally
35449
getUrl : function(appendParams){
35450
var url = this.options.url || this.form.url || this.form.el.dom.action;
35452
var p = this.getParams();
35454
url += (url.indexOf('?') != -1 ? '&' : '?') + p;
35461
getMethod : function(){
35462
return (this.options.method || this.form.method || this.form.el.dom.method || 'POST').toUpperCase();
35466
getParams : function(){
35467
var bp = this.form.baseParams;
35468
var p = this.options.params;
35470
if(typeof p == "object"){
35471
p = Ext.urlEncode(Ext.applyIf(p, bp));
35472
}else if(typeof p == 'string' && bp){
35473
p += '&' + Ext.urlEncode(bp);
35476
p = Ext.urlEncode(bp);
35482
createCallback : function(opts){
35483
var opts = opts || {};
35485
success: this.success,
35486
failure: this.failure,
35488
timeout: (opts.timeout*1000) || (this.form.timeout*1000),
35489
upload: this.form.fileUpload ? this.success : undefined
35495
Ext.form.Action.Submit = function(form, options){
35496
Ext.form.Action.Submit.superclass.constructor.call(this, form, options);
35499
Ext.extend(Ext.form.Action.Submit, Ext.form.Action, {
35506
var o = this.options;
35507
var method = this.getMethod();
35508
var isGet = method == 'GET';
35509
if(o.clientValidation === false || this.form.isValid()){
35510
Ext.Ajax.request(Ext.apply(this.createCallback(o), {
35511
form:this.form.el.dom,
35512
url:this.getUrl(isGet),
35514
headers: o.headers,
35515
params:!isGet ? this.getParams() : null,
35516
isUpload: this.form.fileUpload
35518
}else if (o.clientValidation !== false){ // client validation failed
35519
this.failureType = Ext.form.Action.CLIENT_INVALID;
35520
this.form.afterAction(this, false);
35525
success : function(response){
35526
var result = this.processResponse(response);
35527
if(result === true || result.success){
35528
this.form.afterAction(this, true);
35532
this.form.markInvalid(result.errors);
35533
this.failureType = Ext.form.Action.SERVER_INVALID;
35535
this.form.afterAction(this, false);
35539
handleResponse : function(response){
35540
if(this.form.errorReader){
35541
var rs = this.form.errorReader.read(response);
35544
for(var i = 0, len = rs.records.length; i < len; i++) {
35545
var r = rs.records[i];
35546
errors[i] = r.data;
35549
if(errors.length < 1){
35553
success : rs.success,
35557
return Ext.decode(response.responseText);
35563
Ext.form.Action.Load = function(form, options){
35564
Ext.form.Action.Load.superclass.constructor.call(this, form, options);
35565
this.reader = this.form.reader;
35568
Ext.extend(Ext.form.Action.Load, Ext.form.Action, {
35574
Ext.Ajax.request(Ext.apply(
35575
this.createCallback(this.options), {
35576
method:this.getMethod(),
35577
url:this.getUrl(false),
35578
headers: this.options.headers,
35579
params:this.getParams()
35584
success : function(response){
35585
var result = this.processResponse(response);
35586
if(result === true || !result.success || !result.data){
35587
this.failureType = Ext.form.Action.LOAD_FAILURE;
35588
this.form.afterAction(this, false);
35591
this.form.clearInvalid();
35592
this.form.setValues(result.data);
35593
this.form.afterAction(this, true);
35597
handleResponse : function(response){
35598
if(this.form.reader){
35599
var rs = this.form.reader.read(response);
35600
var data = rs.records && rs.records[0] ? rs.records[0].data : null;
35602
success : rs.success,
35606
return Ext.decode(response.responseText);
35613
Ext.form.Action.DirectLoad = Ext.extend(Ext.form.Action.Load, {
35614
constructor: function(form, opts) {
35615
Ext.form.Action.DirectLoad.superclass.constructor.call(this, form, opts);
35617
type: 'directload',
35620
var args = this.getParams();
35621
args.push(this.success, this);
35622
this.form.api.load.apply(window, args);
35625
getParams: function() {
35626
var buf = [], o = {};
35627
var bp = this.form.baseParams;
35628
var p = this.options.params;
35629
Ext.apply(o, p, bp);
35630
var paramOrder = this.form.paramOrder;
35632
for(var i = 0, len = paramOrder.length; i < len; i++){
35633
buf.push(o[paramOrder[i]]);
35635
}else if(this.form.paramsAsHash){
35640
// Direct actions have already been processed and therefore
35641
// we can directly set the result; Direct Actions do not have
35642
// a this.response property.
35643
processResponse: function(result) {
35644
this.result = result;
35650
Ext.form.Action.DirectSubmit = Ext.extend(Ext.form.Action.Submit, {
35651
constructor: function(form, opts) {
35652
Ext.form.Action.DirectSubmit.superclass.constructor.call(this, form, opts);
35654
type: 'directsubmit',
35655
// override of Submit
35657
var o = this.options;
35658
if(o.clientValidation === false || this.form.isValid()){
35659
// tag on any additional params to be posted in the
35661
this.success.params = this.getParams();
35662
this.form.api.submit(this.form.el.dom, this.success, this);
35663
}else if (o.clientValidation !== false){ // client validation failed
35664
this.failureType = Ext.form.Action.CLIENT_INVALID;
35665
this.form.afterAction(this, false);
35669
getParams: function() {
35671
var bp = this.form.baseParams;
35672
var p = this.options.params;
35673
Ext.apply(o, p, bp);
35676
// Direct actions have already been processed and therefore
35677
// we can directly set the result; Direct Actions do not have
35678
// a this.response property.
35679
processResponse: function(result) {
35680
this.result = result;
35686
Ext.form.Action.ACTION_TYPES = {
35687
'load' : Ext.form.Action.Load,
35688
'submit' : Ext.form.Action.Submit,
35689
'directload': Ext.form.Action.DirectLoad,
35690
'directsubmit': Ext.form.Action.DirectSubmit
35694
Ext.form.VTypes = function(){
35695
// closure these in so they are only created once.
35696
var alpha = /^[a-zA-Z_]+$/;
35697
var alphanum = /^[a-zA-Z0-9_]+$/;
35698
var email = /^([\w]+)(\.[\w]+)*@([\w\-]+\.){1,5}([A-Za-z]){2,4}$/;
35699
var url = /(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
35701
// All these messages and functions are configurable
35704
'email' : function(v){
35705
return email.test(v);
35708
'emailText' : 'This field should be an e-mail address in the format "user@domain.com"',
35710
'emailMask' : /[a-z0-9_\.\-@]/i,
35713
'url' : function(v){
35714
return url.test(v);
35717
'urlText' : 'This field should be a URL in the format "http:/'+'/www.domain.com"',
35720
'alpha' : function(v){
35721
return alpha.test(v);
35724
'alphaText' : 'This field should only contain letters and _',
35726
'alphaMask' : /[a-z_]/i,
35729
'alphanum' : function(v){
35730
return alphanum.test(v);
35733
'alphanumText' : 'This field should only contain letters, numbers and _',
35735
'alphanumMask' : /[a-z0-9_]/i
35739
Ext.grid.GridPanel = Ext.extend(Ext.Panel, {
35741
autoExpandColumn : false,
35743
autoExpandMax : 1000,
35745
autoExpandMin : 50,
35747
columnLines : false,
35752
ddText : "{0} selected row{1}",
35754
deferRowRender : true,
35758
enableColumnHide : true,
35760
enableColumnMove : true,
35762
enableDragDrop : false,
35764
enableHdMenu : true,
35770
minColumnWidth : 25,
35775
stripeRows : false,
35777
trackMouseOver : true,
35779
stateEvents : ["columnmove", "columnresize", "sortchange"],
35790
initComponent : function(){
35791
Ext.grid.GridPanel.superclass.initComponent.call(this);
35793
if(this.columnLines){
35794
this.cls = (this.cls || '') + ' x-grid-with-col-lines';
35796
// override any provided value since it isn't valid
35797
// and is causing too many bug reports ;)
35798
this.autoScroll = false;
35799
this.autoWidth = false;
35801
if(Ext.isArray(this.columns)){
35802
this.colModel = new Ext.grid.ColumnModel(this.columns);
35803
delete this.columns;
35806
// check and correct shorthanded configs
35808
this.store = this.ds;
35812
this.colModel = this.cm;
35816
this.selModel = this.sm;
35819
this.store = Ext.StoreMgr.lookup(this.store);
35867
"headercontextmenu",
35880
onRender : function(ct, position){
35881
Ext.grid.GridPanel.superclass.onRender.apply(this, arguments);
35885
this.el.addClass('x-grid-panel');
35887
var view = this.getView();
35891
mousedown: this.onMouseDown,
35892
click: this.onClick,
35893
dblclick: this.onDblClick,
35894
contextmenu: this.onContextMenu,
35895
keydown: this.onKeyDown,
35899
this.relayEvents(c, ["mousedown","mouseup","mouseover","mouseout","keypress"]);
35901
this.getSelectionModel().init(this);
35902
this.view.render();
35906
initEvents : function(){
35907
Ext.grid.GridPanel.superclass.initEvents.call(this);
35910
this.loadMask = new Ext.LoadMask(this.bwrap,
35911
Ext.apply({store:this.store}, this.loadMask));
35915
initStateEvents : function(){
35916
Ext.grid.GridPanel.superclass.initStateEvents.call(this);
35917
this.mon(this.colModel, 'hiddenchange', this.saveState, this, {delay: 100});
35920
applyState : function(state){
35921
var cm = this.colModel;
35922
var cs = state.columns;
35924
for(var i = 0, len = cs.length; i < len; i++){
35926
var c = cm.getColumnById(s.id);
35928
c.hidden = s.hidden;
35930
var oldIndex = cm.getIndexById(s.id);
35932
cm.moveColumn(oldIndex, i);
35937
if(state.sort && this.store){
35938
this.store[this.store.remoteSort ? 'setDefaultSort' : 'sort'](state.sort.field, state.sort.direction);
35940
delete state.columns;
35942
Ext.grid.GridPanel.superclass.applyState.call(this, state);
35945
getState : function(){
35946
var o = {columns: []};
35947
for(var i = 0, c; c = this.colModel.config[i]; i++){
35953
o.columns[i].hidden = true;
35957
var ss = this.store.getSortState();
35966
afterRender : function(){
35967
Ext.grid.GridPanel.superclass.afterRender.call(this);
35968
this.view.layout();
35969
if(this.deferRowRender){
35970
this.view.afterRender.defer(10, this.view);
35972
this.view.afterRender();
35974
this.viewReady = true;
35978
reconfigure : function(store, colModel){
35980
this.loadMask.destroy();
35981
this.loadMask = new Ext.LoadMask(this.bwrap,
35982
Ext.apply({}, {store:store}, this.initialConfig.loadMask));
35984
this.view.initData(store, colModel);
35985
this.store = store;
35986
this.colModel = colModel;
35988
this.view.refresh(true);
35993
onKeyDown : function(e){
35994
this.fireEvent("keydown", e);
35998
onDestroy : function(){
36001
c.removeAllListeners();
36003
Ext.destroy(this.view, this.loadMask);
36004
}else if(this.store && this.store.autoDestroy){
36005
this.store.destroy();
36007
Ext.destroy(this.colModel);
36008
this.store = this.colModel = this.view = this.loadMask = null;
36009
Ext.grid.GridPanel.superclass.onDestroy.call(this);
36013
processEvent : function(name, e){
36014
this.fireEvent(name, e);
36015
var t = e.getTarget();
36017
var header = v.findHeaderIndex(t);
36018
if(header !== false){
36019
this.fireEvent("header" + name, this, header, e);
36021
var row = v.findRowIndex(t);
36022
var cell = v.findCellIndex(t);
36024
this.fireEvent("row" + name, this, row, e);
36025
if(cell !== false){
36026
this.fireEvent("cell" + name, this, row, cell, e);
36033
onClick : function(e){
36034
this.processEvent("click", e);
36038
onMouseDown : function(e){
36039
this.processEvent("mousedown", e);
36043
onContextMenu : function(e, t){
36044
this.processEvent("contextmenu", e);
36048
onDblClick : function(e){
36049
this.processEvent("dblclick", e);
36053
walkCells : function(row, col, step, fn, scope){
36054
var cm = this.colModel, clen = cm.getColumnCount();
36055
var ds = this.store, rlen = ds.getCount(), first = true;
36067
if(fn.call(scope || this, row, col, cm) === true){
36085
if(fn.call(scope || this, row, col, cm) === true){
36097
onResize : function(){
36098
Ext.grid.GridPanel.superclass.onResize.apply(this, arguments);
36099
if(this.viewReady){
36100
this.view.layout();
36105
getGridEl : function(){
36109
// private for compatibility, overridden by editor grid
36110
stopEditing : Ext.emptyFn,
36113
getSelectionModel : function(){
36114
if(!this.selModel){
36115
this.selModel = new Ext.grid.RowSelectionModel(
36116
this.disableSelection ? {selectRow: Ext.emptyFn} : null);
36118
return this.selModel;
36122
getStore : function(){
36127
getColumnModel : function(){
36128
return this.colModel;
36132
getView : function(){
36134
this.view = new Ext.grid.GridView(this.viewConfig);
36139
getDragDropText : function(){
36140
var count = this.selModel.getCount();
36141
return String.format(this.ddText, count, count == 1 ? '' : 's');
36194
Ext.reg('grid', Ext.grid.GridPanel);
36196
Ext.grid.GridView = function(config){
36197
Ext.apply(this, config);
36198
// These events are only used internally by the grid components
36201
"beforerowremoved",
36203
"beforerowsinserted",
36215
Ext.grid.GridView.superclass.constructor.call(this);
36218
Ext.extend(Ext.grid.GridView, Ext.util.Observable, {
36225
deferEmptyText : true,
36233
sortClasses : ["sort-asc", "sort-desc"],
36235
sortAscText : "Sort Ascending",
36237
sortDescText : "Sort Descending",
36239
columnsText : "Columns",
36242
selectedRowClass : "x-grid3-row-selected",
36246
tdClass : 'x-grid3-cell',
36247
hdCls : 'x-grid3-hd',
36251
cellSelectorDepth : 4,
36253
rowSelectorDepth : 10,
36256
cellSelector : 'td.x-grid3-cell',
36258
rowSelector : 'div.x-grid3-row',
36263
initTemplates : function(){
36264
var ts = this.templates || {};
36266
ts.master = new Ext.Template(
36267
'<div class="x-grid3" hidefocus="true">',
36268
'<div class="x-grid3-viewport">',
36269
'<div class="x-grid3-header"><div class="x-grid3-header-inner"><div class="x-grid3-header-offset" style="{ostyle}">{header}</div></div><div class="x-clear"></div></div>',
36270
'<div class="x-grid3-scroller"><div class="x-grid3-body" style="{bstyle}">{body}</div><a href="#" class="x-grid3-focus" tabIndex="-1"></a></div>',
36272
'<div class="x-grid3-resize-marker"> </div>',
36273
'<div class="x-grid3-resize-proxy"> </div>',
36279
ts.header = new Ext.Template(
36280
'<table border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
36281
'<thead><tr class="x-grid3-hd-row">{cells}</tr></thead>',
36287
ts.hcell = new Ext.Template(
36288
'<td class="x-grid3-hd x-grid3-cell x-grid3-td-{id} {css}" style="{style}"><div {tooltip} {attr} class="x-grid3-hd-inner x-grid3-hd-{id}" unselectable="on" style="{istyle}">', this.grid.enableHdMenu ? '<a class="x-grid3-hd-btn" href="#"></a>' : '',
36289
'{value}<img class="x-grid3-sort-icon" src="', Ext.BLANK_IMAGE_URL, '" />',
36295
ts.body = new Ext.Template('{rows}');
36299
ts.row = new Ext.Template(
36300
'<div class="x-grid3-row {alt}" style="{tstyle}"><table class="x-grid3-row-table" border="0" cellspacing="0" cellpadding="0" style="{tstyle}">',
36301
'<tbody><tr>{cells}</tr>',
36302
(this.enableRowBody ? '<tr class="x-grid3-row-body-tr" style="{bodyStyle}"><td colspan="{cols}" class="x-grid3-body-cell" tabIndex="0" hidefocus="on"><div class="x-grid3-row-body">{body}</div></td></tr>' : ''),
36303
'</tbody></table></div>'
36308
ts.cell = new Ext.Template(
36309
'<td class="x-grid3-col x-grid3-cell x-grid3-td-{id} {css}" style="{style}" tabIndex="0" {cellAttr}>',
36310
'<div class="x-grid3-cell-inner x-grid3-col-{id}" unselectable="on" {attr}>{value}</div>',
36317
if(t && typeof t.compile == 'function' && !t.compiled){
36318
t.disableFormats = true;
36323
this.templates = ts;
36324
this.colRe = new RegExp("x-grid3-td-([^\\s]+)", "");
36328
fly : function(el){
36329
if(!this._flyweight){
36330
this._flyweight = new Ext.Element.Flyweight(document.body);
36332
this._flyweight.dom = el;
36333
return this._flyweight;
36337
getEditorParent : function(ed){
36338
return this.scroller.dom;
36342
initElements : function(){
36343
var E = Ext.Element;
36345
var el = this.grid.getGridEl().dom.firstChild;
36346
var cs = el.childNodes;
36348
this.el = new E(el);
36350
this.mainWrap = new E(cs[0]);
36351
this.mainHd = new E(this.mainWrap.dom.firstChild);
36353
if(this.grid.hideHeaders){
36354
this.mainHd.setDisplayed(false);
36357
this.innerHd = this.mainHd.dom.firstChild;
36358
this.scroller = new E(this.mainWrap.dom.childNodes[1]);
36360
this.scroller.setStyle('overflow-x', 'hidden');
36363
this.mainBody = new E(this.scroller.dom.firstChild);
36365
this.focusEl = new E(this.scroller.dom.childNodes[1]);
36366
this.focusEl.swallowEvent("click", true);
36368
this.resizeMarker = new E(cs[1]);
36369
this.resizeProxy = new E(cs[2]);
36373
getRows : function(){
36374
return this.hasRows() ? this.mainBody.dom.childNodes : [];
36377
// finder methods, used with delegation
36380
findCell : function(el){
36384
return this.fly(el).findParent(this.cellSelector, this.cellSelectorDepth);
36388
findCellIndex : function(el, requiredCls){
36389
var cell = this.findCell(el);
36390
if(cell && (!requiredCls || this.fly(cell).hasClass(requiredCls))){
36391
return this.getCellIndex(cell);
36397
getCellIndex : function(el){
36399
var m = el.className.match(this.colRe);
36401
return this.cm.getIndexById(m[1]);
36408
findHeaderCell : function(el){
36409
var cell = this.findCell(el);
36410
return cell && this.fly(cell).hasClass(this.hdCls) ? cell : null;
36414
findHeaderIndex : function(el){
36415
return this.findCellIndex(el, this.hdCls);
36419
findRow : function(el){
36423
return this.fly(el).findParent(this.rowSelector, this.rowSelectorDepth);
36427
findRowIndex : function(el){
36428
var r = this.findRow(el);
36429
return r ? r.rowIndex : false;
36432
// getter methods for fetching elements dynamically in the grid
36435
getRow : function(row){
36436
return this.getRows()[row];
36440
getCell : function(row, col){
36441
return this.getRow(row).getElementsByTagName('td')[col];
36445
getHeaderCell : function(index){
36446
return this.mainHd.dom.getElementsByTagName('td')[index];
36449
// manipulating elements
36451
// private - use getRowClass to apply custom row classes
36452
addRowClass : function(row, cls){
36453
var r = this.getRow(row);
36455
this.fly(r).addClass(cls);
36460
removeRowClass : function(row, cls){
36461
var r = this.getRow(row);
36463
this.fly(r).removeClass(cls);
36468
removeRow : function(row){
36469
Ext.removeNode(this.getRow(row));
36470
this.syncFocusEl(row);
36474
removeRows : function(firstRow, lastRow){
36475
var bd = this.mainBody.dom;
36476
for(var rowIndex = firstRow; rowIndex <= lastRow; rowIndex++){
36477
Ext.removeNode(bd.childNodes[firstRow]);
36479
this.syncFocusEl(firstRow);
36485
getScrollState : function(){
36486
var sb = this.scroller.dom;
36487
return {left: sb.scrollLeft, top: sb.scrollTop};
36491
restoreScroll : function(state){
36492
var sb = this.scroller.dom;
36493
sb.scrollLeft = state.left;
36494
sb.scrollTop = state.top;
36498
scrollToTop : function(){
36499
this.scroller.dom.scrollTop = 0;
36500
this.scroller.dom.scrollLeft = 0;
36504
syncScroll : function(){
36505
this.syncHeaderScroll();
36506
var mb = this.scroller.dom;
36507
this.grid.fireEvent("bodyscroll", mb.scrollLeft, mb.scrollTop);
36511
syncHeaderScroll : function(){
36512
var mb = this.scroller.dom;
36513
this.innerHd.scrollLeft = mb.scrollLeft;
36514
this.innerHd.scrollLeft = mb.scrollLeft; // second time for IE (1/2 time first fails, other browsers ignore)
36518
updateSortIcon : function(col, dir){
36519
var sc = this.sortClasses;
36520
var hds = this.mainHd.select('td').removeClass(sc);
36521
hds.item(col).addClass(sc[dir == "DESC" ? 1 : 0]);
36525
updateAllColumnWidths : function(){
36526
var tw = this.getTotalWidth();
36527
var clen = this.cm.getColumnCount();
36529
for(var i = 0; i < clen; i++){
36530
ws[i] = this.getColumnWidth(i);
36532
this.innerHd.firstChild.style.width = this.getOffsetWidth();
36533
this.innerHd.firstChild.firstChild.style.width = tw;
36534
this.mainBody.dom.style.width = tw;
36535
for(var i = 0; i < clen; i++){
36536
var hd = this.getHeaderCell(i);
36537
hd.style.width = ws[i];
36540
var ns = this.getRows(), row, trow;
36541
for(var i = 0, len = ns.length; i < len; i++){
36543
row.style.width = tw;
36544
if(row.firstChild){
36545
row.firstChild.style.width = tw;
36546
trow = row.firstChild.rows[0];
36547
for (var j = 0; j < clen; j++) {
36548
trow.childNodes[j].style.width = ws[j];
36553
this.onAllColumnWidthsUpdated(ws, tw);
36557
updateColumnWidth : function(col, width){
36558
var w = this.getColumnWidth(col);
36559
var tw = this.getTotalWidth();
36560
this.innerHd.firstChild.style.width = this.getOffsetWidth();
36561
this.innerHd.firstChild.firstChild.style.width = tw;
36562
this.mainBody.dom.style.width = tw;
36563
var hd = this.getHeaderCell(col);
36564
hd.style.width = w;
36566
var ns = this.getRows(), row;
36567
for(var i = 0, len = ns.length; i < len; i++){
36569
row.style.width = tw;
36570
if(row.firstChild){
36571
row.firstChild.style.width = tw;
36572
row.firstChild.rows[0].childNodes[col].style.width = w;
36576
this.onColumnWidthUpdated(col, w, tw);
36580
updateColumnHidden : function(col, hidden){
36581
var tw = this.getTotalWidth();
36582
this.innerHd.firstChild.style.width = this.getOffsetWidth();
36583
this.innerHd.firstChild.firstChild.style.width = tw;
36584
this.mainBody.dom.style.width = tw;
36585
var display = hidden ? 'none' : '';
36587
var hd = this.getHeaderCell(col);
36588
hd.style.display = display;
36590
var ns = this.getRows(), row;
36591
for(var i = 0, len = ns.length; i < len; i++){
36593
row.style.width = tw;
36594
if(row.firstChild){
36595
row.firstChild.style.width = tw;
36596
row.firstChild.rows[0].childNodes[col].style.display = display;
36600
this.onColumnHiddenUpdated(col, hidden, tw);
36601
delete this.lastViewWidth; // force recalc
36606
doRender : function(cs, rs, ds, startRow, colCount, stripe){
36607
var ts = this.templates, ct = ts.cell, rt = ts.row, last = colCount-1;
36608
var tstyle = 'width:'+this.getTotalWidth()+';';
36610
var buf = [], cb, c, p = {}, rp = {tstyle: tstyle}, r;
36611
for(var j = 0, len = rs.length; j < len; j++){
36612
r = rs[j]; cb = [];
36613
var rowIndex = (j+startRow);
36614
for(var i = 0; i < colCount; i++){
36617
p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
36618
p.attr = p.cellAttr = "";
36619
p.value = c.renderer(r.data[c.name], p, r, rowIndex, i, ds);
36621
if(p.value == undefined || p.value === "") p.value = " ";
36622
if(this.markDirty && r.dirty && typeof r.modified[c.name] !== 'undefined'){
36623
p.css += ' x-grid3-dirty-cell';
36625
cb[cb.length] = ct.apply(p);
36628
if(stripe && ((rowIndex+1) % 2 == 0)){
36629
alt[0] = "x-grid3-row-alt";
36632
alt[1] = " x-grid3-dirty-row";
36634
rp.cols = colCount;
36635
if(this.getRowClass){
36636
alt[2] = this.getRowClass(r, rowIndex, rp, ds);
36638
rp.alt = alt.join(" ");
36639
rp.cells = cb.join("");
36640
buf[buf.length] = rt.apply(rp);
36642
return buf.join("");
36646
processRows : function(startRow, skipStripe){
36647
if(!this.ds || this.ds.getCount() < 1){
36650
skipStripe = skipStripe || !this.grid.stripeRows;
36651
startRow = startRow || 0;
36652
var rows = this.getRows();
36653
var cls = ' x-grid3-row-alt ';
36654
rows[0].className += ' x-grid3-row-first';
36655
rows[rows.length - 1].className += ' x-grid3-row-last';
36656
for(var i = startRow, len = rows.length; i < len; i++){
36660
var isAlt = ((i+1) % 2 == 0);
36661
var hasAlt = (' '+row.className + ' ').indexOf(cls) != -1;
36662
if(isAlt == hasAlt){
36666
row.className += " x-grid3-row-alt";
36668
row.className = row.className.replace("x-grid3-row-alt", "");
36674
afterRender : function(){
36675
if(!this.ds || !this.cm){
36678
this.mainBody.dom.innerHTML = this.renderRows() || ' ';
36679
this.processRows(0, true);
36681
if(this.deferEmptyText !== true){
36682
this.applyEmptyText();
36687
renderUI : function(){
36689
var header = this.renderHeaders();
36690
var body = this.templates.body.apply({rows:' '});
36693
var html = this.templates.master.apply({
36696
ostyle: 'width:'+this.getOffsetWidth()+';',
36697
bstyle: 'width:'+this.getTotalWidth()+';'
36702
g.getGridEl().dom.innerHTML = html;
36704
this.initElements();
36706
// get mousedowns early
36707
Ext.fly(this.innerHd).on("click", this.handleHdDown, this);
36710
mouseover: this.handleHdOver,
36711
mouseout: this.handleHdOut,
36712
mousemove: this.handleHdMove
36715
this.scroller.on('scroll', this.syncScroll, this);
36716
if(g.enableColumnResize !== false){
36717
this.splitZone = new Ext.grid.GridView.SplitDragZone(g, this.mainHd.dom);
36720
if(g.enableColumnMove){
36721
this.columnDrag = new Ext.grid.GridView.ColumnDragZone(g, this.innerHd);
36722
this.columnDrop = new Ext.grid.HeaderDropZone(g, this.mainHd.dom);
36725
if(g.enableHdMenu !== false){
36726
this.hmenu = new Ext.menu.Menu({id: g.id + "-hctx"});
36728
{itemId:"asc", text: this.sortAscText, cls: "xg-hmenu-sort-asc"},
36729
{itemId:"desc", text: this.sortDescText, cls: "xg-hmenu-sort-desc"}
36731
if(g.enableColumnHide !== false){
36732
this.colMenu = new Ext.menu.Menu({id:g.id + "-hcols-menu"});
36735
beforeshow: this.beforeColMenuShow,
36736
itemclick: this.handleHdMenuClick
36738
this.hmenu.add('-', {
36740
hideOnClick: false,
36741
text: this.columnsText,
36742
menu: this.colMenu,
36743
iconCls: 'x-cols-icon'
36746
this.hmenu.on("itemclick", this.handleHdMenuClick, this);
36749
if(g.trackMouseOver){
36752
mouseover: this.onRowOver,
36753
mouseout: this.onRowOut
36757
if(g.enableDragDrop || g.enableDrag){
36758
this.dragZone = new Ext.grid.GridDragZone(g, {
36759
ddGroup : g.ddGroup || 'GridDD'
36763
this.updateHeaderSortState();
36768
layout : function(){
36769
if(!this.mainBody){
36770
return; // not rendered
36773
var c = g.getGridEl();
36774
var csize = c.getSize(true);
36775
var vw = csize.width;
36777
if(vw < 20 || csize.height < 20){ // display: none?
36782
this.scroller.dom.style.overflow = 'visible';
36784
this.scroller.dom.style.position = 'static';
36787
this.el.setSize(csize.width, csize.height);
36789
var hdHeight = this.mainHd.getHeight();
36790
var vh = csize.height - (hdHeight);
36792
this.scroller.setSize(vw, vh);
36794
this.innerHd.style.width = (vw)+'px';
36798
if(this.lastViewWidth != vw){
36799
this.fitColumns(false, false);
36800
this.lastViewWidth = vw;
36804
this.syncHeaderScroll();
36806
this.onLayout(vw, vh);
36809
// template functions for subclasses and plugins
36810
// these functions include precalculated values
36811
onLayout : function(vw, vh){
36815
onColumnWidthUpdated : function(col, w, tw){
36819
onAllColumnWidthsUpdated : function(ws, tw){
36823
onColumnHiddenUpdated : function(col, hidden, tw){
36827
updateColumnText : function(col, text){
36831
afterMove : function(colIndex){
36837
init : function(grid){
36840
this.initTemplates();
36841
this.initData(grid.store, grid.colModel);
36846
getColumnId : function(index){
36847
return this.cm.getColumnId(index);
36851
getOffsetWidth : function() {
36852
return (this.cm.getTotalWidth() + this.scrollOffset) + 'px';
36856
renderHeaders : function(){
36857
var cm = this.cm, ts = this.templates;
36860
var cb = [], p = {};
36861
var len = cm.getColumnCount();
36862
var last = len - 1;
36863
for(var i = 0; i < len; i++){
36864
p.id = cm.getColumnId(i);
36865
p.value = cm.getColumnHeader(i) || "";
36866
p.style = this.getColumnStyle(i, true);
36867
p.tooltip = this.getColumnTooltip(i);
36868
p.css = i == 0 ? 'x-grid3-cell-first ' : (i == last ? 'x-grid3-cell-last ' : '');
36869
if(cm.config[i].align == 'right'){
36870
p.istyle = 'padding-right:16px';
36874
cb[cb.length] = ct.apply(p);
36876
return ts.header.apply({cells: cb.join(""), tstyle:'width:'+this.getTotalWidth()+';'});
36880
getColumnTooltip : function(i){
36881
var tt = this.cm.getColumnTooltip(i);
36883
if(Ext.QuickTips.isEnabled()){
36884
return 'ext:qtip="'+tt+'"';
36886
return 'title="'+tt+'"';
36893
beforeUpdate : function(){
36894
this.grid.stopEditing(true);
36898
updateHeaders : function(){
36899
this.innerHd.firstChild.innerHTML = this.renderHeaders();
36900
this.innerHd.firstChild.style.width = this.getOffsetWidth();
36901
this.innerHd.firstChild.firstChild.style.width = this.getTotalWidth();
36905
focusRow : function(row){
36906
this.focusCell(row, 0, false);
36910
focusCell : function(row, col, hscroll){
36911
this.syncFocusEl(this.ensureVisible(row, col, hscroll));
36913
this.focusEl.focus();
36915
this.focusEl.focus.defer(1, this.focusEl);
36919
resolveCell : function(row, col, hscroll){
36920
if(typeof row != "number"){
36921
row = row.rowIndex;
36926
if(row < 0 || row >= this.ds.getCount()){
36929
col = (col !== undefined ? col : 0);
36931
var rowEl = this.getRow(row), cellEl;
36932
if(!(hscroll === false && col === 0)){
36933
while(this.cm.isHidden(col)){
36936
cellEl = this.getCell(row, col);
36939
return {row: rowEl, cell: cellEl};
36942
getResolvedXY : function(resolved){
36946
var s = this.scroller.dom, c = resolved.cell, r = resolved.row;
36947
return c ? Ext.fly(c).getXY() : [this.el.getX(), Ext.fly(r).getY()];
36950
syncFocusEl : function(row, col, hscroll){
36952
if(!Ext.isArray(xy)){
36953
row = Math.min(row, Math.max(0, this.getRows().length-1));
36954
xy = this.getResolvedXY(this.resolveCell(row, col, hscroll));
36956
this.focusEl.setXY(xy||this.scroller.getXY());
36959
ensureVisible : function(row, col, hscroll){
36960
var resolved = this.resolveCell(row, col, hscroll);
36961
if(!resolved || !resolved.row){
36965
var rowEl = resolved.row, cellEl = resolved.cell;
36967
var c = this.scroller.dom;
36970
var p = rowEl, stop = this.el.dom;
36971
while(p && p != stop){
36972
ctop += p.offsetTop;
36973
p = p.offsetParent;
36975
ctop -= this.mainHd.dom.offsetHeight;
36977
var cbot = ctop + rowEl.offsetHeight;
36979
var ch = c.clientHeight;
36980
var stop = parseInt(c.scrollTop, 10);
36981
var sbot = stop + ch;
36984
c.scrollTop = ctop;
36985
}else if(cbot > sbot){
36986
c.scrollTop = cbot-ch;
36989
if(hscroll !== false){
36990
var cleft = parseInt(cellEl.offsetLeft, 10);
36991
var cright = cleft + cellEl.offsetWidth;
36993
var sleft = parseInt(c.scrollLeft, 10);
36994
var sright = sleft + c.clientWidth;
36996
c.scrollLeft = cleft;
36997
}else if(cright > sright){
36998
c.scrollLeft = cright-c.clientWidth;
37001
return this.getResolvedXY(resolved);
37005
insertRows : function(dm, firstRow, lastRow, isUpdate){
37006
if(!isUpdate && firstRow === 0 && lastRow >= dm.getCount()-1){
37010
this.fireEvent("beforerowsinserted", this, firstRow, lastRow);
37012
var html = this.renderRows(firstRow, lastRow);
37013
var before = this.getRow(firstRow);
37015
Ext.DomHelper.insertHtml('beforeBegin', before, html);
37017
Ext.DomHelper.insertHtml('beforeEnd', this.mainBody.dom, html);
37020
this.fireEvent("rowsinserted", this, firstRow, lastRow);
37021
this.processRows(firstRow);
37024
this.syncFocusEl(firstRow);
37028
deleteRows : function(dm, firstRow, lastRow){
37029
if(dm.getRowCount()<1){
37032
this.fireEvent("beforerowsdeleted", this, firstRow, lastRow);
37034
this.removeRows(firstRow, lastRow);
37036
this.processRows(firstRow);
37037
this.fireEvent("rowsdeleted", this, firstRow, lastRow);
37042
getColumnStyle : function(col, isHeader){
37043
var style = !isHeader ? (this.cm.config[col].css || '') : '';
37044
style += 'width:'+this.getColumnWidth(col)+';';
37045
if(this.cm.isHidden(col)){
37046
style += 'display:none;';
37048
var align = this.cm.config[col].align;
37050
style += 'text-align:'+align+';';
37056
getColumnWidth : function(col){
37057
var w = this.cm.getColumnWidth(col);
37058
if(typeof w == 'number'){
37059
return (Ext.isBorderBox ? w : (w-this.borderWidth > 0 ? w-this.borderWidth:0)) + 'px';
37065
getTotalWidth : function(){
37066
return this.cm.getTotalWidth()+'px';
37070
fitColumns : function(preventRefresh, onlyExpand, omitColumn){
37071
var cm = this.cm, i;
37072
var tw = cm.getTotalWidth(false);
37073
var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
37075
if(aw < 20){ // not initialized, so don't screw up the default widths
37078
var extra = aw - tw;
37084
var vc = cm.getColumnCount(true);
37085
var ac = vc-(typeof omitColumn == 'number' ? 1 : 0);
37088
omitColumn = undefined;
37090
var colCount = cm.getColumnCount();
37095
for (i = 0; i < colCount; i++){
37096
if(!cm.isHidden(i) && !cm.isFixed(i) && i !== omitColumn){
37097
w = cm.getColumnWidth(i);
37104
var frac = (aw - cm.getTotalWidth())/width;
37105
while (cols.length){
37108
cm.setColumnWidth(i, Math.max(this.grid.minColumnWidth, Math.floor(w + w*frac)), true);
37111
if((tw = cm.getTotalWidth(false)) > aw){
37112
var adjustCol = ac != vc ? omitColumn : extraCol;
37113
cm.setColumnWidth(adjustCol, Math.max(1,
37114
cm.getColumnWidth(adjustCol)- (tw-aw)), true);
37117
if(preventRefresh !== true){
37118
this.updateAllColumnWidths();
37126
autoExpand : function(preventUpdate){
37127
var g = this.grid, cm = this.cm;
37128
if(!this.userResized && g.autoExpandColumn){
37129
var tw = cm.getTotalWidth(false);
37130
var aw = this.grid.getGridEl().getWidth(true)-this.scrollOffset;
37132
var ci = cm.getIndexById(g.autoExpandColumn);
37133
var currentWidth = cm.getColumnWidth(ci);
37134
var cw = Math.min(Math.max(((aw-tw)+currentWidth), g.autoExpandMin), g.autoExpandMax);
37135
if(cw != currentWidth){
37136
cm.setColumnWidth(ci, cw, true);
37137
if(preventUpdate !== true){
37138
this.updateColumnWidth(ci, cw);
37146
getColumnData : function(){
37147
// build a map for all the columns
37148
var cs = [], cm = this.cm, colCount = cm.getColumnCount();
37149
for(var i = 0; i < colCount; i++){
37150
var name = cm.getDataIndex(i);
37152
name : (typeof name == 'undefined' ? this.ds.fields.get(i).name : name),
37153
renderer : cm.getRenderer(i),
37154
id : cm.getColumnId(i),
37155
style : this.getColumnStyle(i)
37162
renderRows : function(startRow, endRow){
37163
// pull in all the crap needed to render rows
37164
var g = this.grid, cm = g.colModel, ds = g.store, stripe = g.stripeRows;
37165
var colCount = cm.getColumnCount();
37167
if(ds.getCount() < 1){
37171
var cs = this.getColumnData();
37173
startRow = startRow || 0;
37174
endRow = typeof endRow == "undefined"? ds.getCount()-1 : endRow;
37176
// records to render
37177
var rs = ds.getRange(startRow, endRow);
37179
return this.doRender(cs, rs, ds, startRow, colCount, stripe);
37183
renderBody : function(){
37184
var markup = this.renderRows() || ' ';
37185
return this.templates.body.apply({rows: markup});
37189
refreshRow : function(record){
37190
var ds = this.ds, index;
37191
if(typeof record == 'number'){
37193
record = ds.getAt(index);
37198
index = ds.indexOf(record);
37203
this.insertRows(ds, index, index, true);
37204
this.getRow(index).rowIndex = index;
37205
this.onRemove(ds, record, index+1, true);
37206
this.fireEvent("rowupdated", this, index, record);
37210
refresh : function(headersToo){
37211
this.fireEvent("beforerefresh", this);
37212
this.grid.stopEditing(true);
37214
var result = this.renderBody();
37215
this.mainBody.update(result);
37217
if(headersToo === true){
37218
this.updateHeaders();
37219
this.updateHeaderSortState();
37221
this.processRows(0, true);
37223
this.applyEmptyText();
37224
this.fireEvent("refresh", this);
37228
applyEmptyText : function(){
37229
if(this.emptyText && !this.hasRows()){
37230
this.mainBody.update('<div class="x-grid-empty">' + this.emptyText + '</div>');
37235
updateHeaderSortState : function(){
37236
var state = this.ds.getSortState();
37240
if(!this.sortState || (this.sortState.field != state.field || this.sortState.direction != state.direction)){
37241
this.grid.fireEvent('sortchange', this.grid, state);
37243
this.sortState = state;
37244
var sortColumn = this.cm.findColumnIndex(state.field);
37245
if(sortColumn != -1){
37246
var sortDir = state.direction;
37247
this.updateSortIcon(sortColumn, sortDir);
37252
destroy : function(){
37254
Ext.menu.MenuMgr.unregister(this.colMenu);
37255
this.colMenu.destroy();
37256
delete this.colMenu;
37259
Ext.menu.MenuMgr.unregister(this.hmenu);
37260
this.hmenu.destroy();
37263
if(this.grid.enableColumnMove){
37264
var dds = Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
37266
for(var dd in dds){
37267
if(!dds[dd].config.isTarget && dds[dd].dragElId){
37268
var elid = dds[dd].dragElId;
37270
Ext.get(elid).remove();
37271
} else if(dds[dd].config.isTarget){
37272
dds[dd].proxyTop.remove();
37273
dds[dd].proxyBottom.remove();
37276
if(Ext.dd.DDM.locationCache[dd]){
37277
delete Ext.dd.DDM.locationCache[dd];
37280
delete Ext.dd.DDM.ids['gridHeader' + this.grid.getGridEl().id];
37285
this.dragZone.unreg();
37288
Ext.fly(this.innerHd).removeAllListeners();
37289
Ext.removeNode(this.innerHd);
37291
Ext.destroy(this.resizeMarker, this.resizeProxy, this.focusEl, this.mainBody,
37292
this.scroller, this.mainHd, this.mainWrap, this.dragZone,
37293
this.splitZone, this.columnDrag, this.columnDrop);
37295
this.initData(null, null);
37296
Ext.EventManager.removeResizeListener(this.onWindowResize, this);
37297
this.purgeListeners();
37301
onDenyColumnHide : function(){
37306
render : function(){
37308
var ct = this.grid.ownerCt;
37309
if (ct && ct.getLayout()){
37310
ct.on('afterlayout', function(){
37311
this.fitColumns(true, true);
37312
this.updateHeaders();
37313
}, this, {single: true});
37315
this.fitColumns(true, true);
37317
}else if(this.forceFit){
37318
this.fitColumns(true, false);
37319
}else if(this.grid.autoExpandColumn){
37320
this.autoExpand(true);
37328
initData : function(ds, cm){
37330
this.ds.un("load", this.onLoad, this);
37331
this.ds.un("datachanged", this.onDataChange, this);
37332
this.ds.un("add", this.onAdd, this);
37333
this.ds.un("remove", this.onRemove, this);
37334
this.ds.un("update", this.onUpdate, this);
37335
this.ds.un("clear", this.onClear, this);
37336
if(this.ds !== ds && this.ds.autoDestroy){
37344
datachanged: this.onDataChange,
37346
remove: this.onRemove,
37347
update: this.onUpdate,
37348
clear: this.onClear
37354
this.cm.un("configchange", this.onColConfigChange, this);
37355
this.cm.un("widthchange", this.onColWidthChange, this);
37356
this.cm.un("headerchange", this.onHeaderChange, this);
37357
this.cm.un("hiddenchange", this.onHiddenChange, this);
37358
this.cm.un("columnmoved", this.onColumnMove, this);
37361
delete this.lastViewWidth;
37364
configchange: this.onColConfigChange,
37365
widthchange: this.onColWidthChange,
37366
headerchange: this.onHeaderChange,
37367
hiddenchange: this.onHiddenChange,
37368
columnmoved: this.onColumnMove
37375
onDataChange : function(){
37377
this.updateHeaderSortState();
37378
this.syncFocusEl(0);
37382
onClear : function(){
37384
this.syncFocusEl(0);
37388
onUpdate : function(ds, record){
37389
this.refreshRow(record);
37393
onAdd : function(ds, records, index){
37394
this.insertRows(ds, index, index + (records.length-1));
37398
onRemove : function(ds, record, index, isUpdate){
37399
if(isUpdate !== true){
37400
this.fireEvent("beforerowremoved", this, index, record);
37402
this.removeRow(index);
37403
if(isUpdate !== true){
37404
this.processRows(index);
37405
this.applyEmptyText();
37406
this.fireEvent("rowremoved", this, index, record);
37411
onLoad : function(){
37412
this.scrollToTop();
37416
onColWidthChange : function(cm, col, width){
37417
this.updateColumnWidth(col, width);
37421
onHeaderChange : function(cm, col, text){
37422
this.updateHeaders();
37426
onHiddenChange : function(cm, col, hidden){
37427
this.updateColumnHidden(col, hidden);
37431
onColumnMove : function(cm, oldIndex, newIndex){
37432
this.indexMap = null;
37433
var s = this.getScrollState();
37434
this.refresh(true);
37435
this.restoreScroll(s);
37436
this.afterMove(newIndex);
37440
onColConfigChange : function(){
37441
delete this.lastViewWidth;
37442
this.indexMap = null;
37443
this.refresh(true);
37448
initUI : function(grid){
37449
grid.on("headerclick", this.onHeaderClick, this);
37453
initEvents : function(){
37457
onHeaderClick : function(g, index){
37458
if(this.headersDisabled || !this.cm.isSortable(index)){
37461
g.stopEditing(true);
37462
g.store.sort(this.cm.getDataIndex(index));
37466
onRowOver : function(e, t){
37468
if((row = this.findRowIndex(t)) !== false){
37469
this.addRowClass(row, "x-grid3-row-over");
37474
onRowOut : function(e, t){
37476
if((row = this.findRowIndex(t)) !== false && !e.within(this.getRow(row), true)){
37477
this.removeRowClass(row, "x-grid3-row-over");
37482
handleWheel : function(e){
37483
e.stopPropagation();
37487
onRowSelect : function(row){
37488
this.addRowClass(row, this.selectedRowClass);
37492
onRowDeselect : function(row){
37493
this.removeRowClass(row, this.selectedRowClass);
37497
onCellSelect : function(row, col){
37498
var cell = this.getCell(row, col);
37500
this.fly(cell).addClass("x-grid3-cell-selected");
37505
onCellDeselect : function(row, col){
37506
var cell = this.getCell(row, col);
37508
this.fly(cell).removeClass("x-grid3-cell-selected");
37513
onColumnSplitterMoved : function(i, w){
37514
this.userResized = true;
37515
var cm = this.grid.colModel;
37516
cm.setColumnWidth(i, w, true);
37519
this.fitColumns(true, false, i);
37520
this.updateAllColumnWidths();
37522
this.updateColumnWidth(i, w);
37523
this.syncHeaderScroll();
37526
this.grid.fireEvent("columnresize", i, w);
37530
handleHdMenuClick : function(item){
37531
var index = this.hdCtxIndex;
37532
var cm = this.cm, ds = this.ds;
37533
switch(item.itemId){
37535
ds.sort(cm.getDataIndex(index), "ASC");
37538
ds.sort(cm.getDataIndex(index), "DESC");
37541
index = cm.getIndexById(item.itemId.substr(4));
37543
if(item.checked && cm.getColumnsBy(this.isHideableColumn, this).length <= 1){
37544
this.onDenyColumnHide();
37547
cm.setHidden(index, item.checked);
37554
isHideableColumn : function(c){
37555
return !c.hidden && !c.fixed;
37559
beforeColMenuShow : function(){
37560
var cm = this.cm, colCount = cm.getColumnCount();
37561
this.colMenu.removeAll();
37562
for(var i = 0; i < colCount; i++){
37563
if(cm.config[i].fixed !== true && cm.config[i].hideable !== false){
37564
this.colMenu.add(new Ext.menu.CheckItem({
37565
itemId: "col-"+cm.getColumnId(i),
37566
text: cm.getColumnHeader(i),
37567
checked: !cm.isHidden(i),
37569
disabled: cm.config[i].hideable === false
37576
handleHdDown : function(e, t){
37577
if(Ext.fly(t).hasClass('x-grid3-hd-btn')){
37579
var hd = this.findHeaderCell(t);
37580
Ext.fly(hd).addClass('x-grid3-hd-menu-open');
37581
var index = this.getCellIndex(hd);
37582
this.hdCtxIndex = index;
37583
var ms = this.hmenu.items, cm = this.cm;
37584
ms.get("asc").setDisabled(!cm.isSortable(index));
37585
ms.get("desc").setDisabled(!cm.isSortable(index));
37586
this.hmenu.on("hide", function(){
37587
Ext.fly(hd).removeClass('x-grid3-hd-menu-open');
37588
}, this, {single:true});
37589
this.hmenu.show(t, "tl-bl?");
37594
handleHdOver : function(e, t){
37595
var hd = this.findHeaderCell(t);
37596
if(hd && !this.headersDisabled){
37597
this.activeHd = hd;
37598
this.activeHdIndex = this.getCellIndex(hd);
37599
var fly = this.fly(hd);
37600
this.activeHdRegion = fly.getRegion();
37601
if(!this.cm.isMenuDisabled(this.activeHdIndex)){
37602
fly.addClass("x-grid3-hd-over");
37603
this.activeHdBtn = fly.child('.x-grid3-hd-btn');
37604
if(this.activeHdBtn){
37605
this.activeHdBtn.dom.style.height = (hd.firstChild.offsetHeight-1)+'px';
37612
handleHdMove : function(e, t){
37613
if(this.activeHd && !this.headersDisabled){
37614
var hw = this.splitHandleWidth || 5;
37615
var r = this.activeHdRegion;
37616
var x = e.getPageX();
37617
var ss = this.activeHd.style;
37618
if(x - r.left <= hw && this.cm.isResizable(this.activeHdIndex-1)){
37619
ss.cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'e-resize' : 'col-resize'; // col-resize not always supported
37620
}else if(r.right - x <= (!this.activeHdBtn ? hw : 2) && this.cm.isResizable(this.activeHdIndex)){
37621
ss.cursor = Ext.isAir ? 'move' : Ext.isWebKit ? 'w-resize' : 'col-resize';
37629
handleHdOut : function(e, t){
37630
var hd = this.findHeaderCell(t);
37631
if(hd && (!Ext.isIE || !e.within(hd, true))){
37632
this.activeHd = null;
37633
this.fly(hd).removeClass("x-grid3-hd-over");
37634
hd.style.cursor = '';
37639
hasRows : function(){
37640
var fc = this.mainBody.dom.firstChild;
37641
return fc && fc.nodeType == 1 && fc.className != 'x-grid-empty';
37645
bind : function(d, c){
37646
this.initData(d, c);
37652
// This is a support class used internally by the Grid components
37653
Ext.grid.GridView.SplitDragZone = function(grid, hd){
37655
this.view = grid.getView();
37656
this.marker = this.view.resizeMarker;
37657
this.proxy = this.view.resizeProxy;
37658
Ext.grid.GridView.SplitDragZone.superclass.constructor.call(this, hd,
37659
"gridSplitters" + this.grid.getGridEl().id, {
37660
dragElId : Ext.id(this.proxy.dom), resizeFrame:false
37662
this.scroll = false;
37663
this.hw = this.view.splitHandleWidth || 5;
37665
Ext.extend(Ext.grid.GridView.SplitDragZone, Ext.dd.DDProxy, {
37667
b4StartDrag : function(x, y){
37668
this.view.headersDisabled = true;
37669
var h = this.view.mainWrap.getHeight();
37670
this.marker.setHeight(h);
37671
this.marker.show();
37672
this.marker.alignTo(this.view.getHeaderCell(this.cellIndex), 'tl-tl', [-2, 0]);
37673
this.proxy.setHeight(h);
37674
var w = this.cm.getColumnWidth(this.cellIndex);
37675
var minw = Math.max(w-this.grid.minColumnWidth, 0);
37676
this.resetConstraints();
37677
this.setXConstraint(minw, 1000);
37678
this.setYConstraint(0, 0);
37679
this.minX = x - minw;
37680
this.maxX = x + 1000;
37682
Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
37686
handleMouseDown : function(e){
37687
var t = this.view.findHeaderCell(e.getTarget());
37689
var xy = this.view.fly(t).getXY(), x = xy[0], y = xy[1];
37690
var exy = e.getXY(), ex = exy[0];
37691
var w = t.offsetWidth, adjust = false;
37692
if((ex - x) <= this.hw){
37694
}else if((x+w) - ex <= this.hw){
37697
if(adjust !== false){
37698
this.cm = this.grid.colModel;
37699
var ci = this.view.getCellIndex(t);
37701
if (ci + adjust < 0) {
37704
while(this.cm.isHidden(ci+adjust)){
37711
this.cellIndex = ci+adjust;
37712
this.split = t.dom;
37713
if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
37714
Ext.grid.GridView.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
37716
}else if(this.view.columnDrag){
37717
this.view.columnDrag.callHandleMouseDown(e);
37722
endDrag : function(e){
37723
this.marker.hide();
37725
var endX = Math.max(this.minX, e.getPageX());
37726
var diff = endX - this.startPos;
37727
v.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
37728
setTimeout(function(){
37729
v.headersDisabled = false;
37733
autoOffset : function(){
37734
this.setDelta(0,0);
37739
Ext.grid.GroupingView = Ext.extend(Ext.grid.GridView, {
37741
hideGroupedColumn:false,
37743
showGroupName:true,
37745
startCollapsed:false,
37747
enableGrouping:true,
37749
enableGroupingMenu:true,
37751
enableNoGroups:true,
37753
emptyGroupText : '(None)',
37757
groupTextTpl : '{text}',
37764
initTemplates : function(){
37765
Ext.grid.GroupingView.superclass.initTemplates.call(this);
37768
var sm = this.grid.getSelectionModel();
37769
sm.on(sm.selectRow ? 'beforerowselect' : 'beforecellselect',
37770
this.onBeforeRowSelect, this);
37772
if(!this.startGroup){
37773
this.startGroup = new Ext.XTemplate(
37774
'<div id="{groupId}" class="x-grid-group {cls}">',
37775
'<div id="{groupId}-hd" class="x-grid-group-hd" style="{style}"><div>', this.groupTextTpl ,'</div></div>',
37776
'<div id="{groupId}-bd" class="x-grid-group-body">'
37779
this.startGroup.compile();
37780
this.endGroup = '</div></div>';
37784
findGroup : function(el){
37785
return Ext.fly(el).up('.x-grid-group', this.mainBody.dom);
37789
getGroups : function(){
37790
return this.hasRows() ? this.mainBody.dom.childNodes : [];
37794
onAdd : function(){
37795
if(this.enableGrouping && !this.ignoreAdd){
37796
var ss = this.getScrollState();
37798
this.restoreScroll(ss);
37799
}else if(!this.enableGrouping){
37800
Ext.grid.GroupingView.superclass.onAdd.apply(this, arguments);
37805
onRemove : function(ds, record, index, isUpdate){
37806
Ext.grid.GroupingView.superclass.onRemove.apply(this, arguments);
37807
var g = document.getElementById(record._groupId);
37808
if(g && g.childNodes[1].childNodes.length < 1){
37811
this.applyEmptyText();
37815
refreshRow : function(record){
37816
if(this.ds.getCount()==1){
37819
this.isUpdating = true;
37820
Ext.grid.GroupingView.superclass.refreshRow.apply(this, arguments);
37821
this.isUpdating = false;
37826
beforeMenuShow : function(){
37827
var item, items = this.hmenu.items, disabled = this.cm.config[this.hdCtxIndex].groupable === false;
37828
if((item = items.get('groupBy'))){
37829
item.setDisabled(disabled);
37831
if((item = items.get('showGroups'))){
37832
item.setDisabled(disabled);
37833
item.setChecked(!!this.getGroupField(), true);
37838
renderUI : function(){
37839
Ext.grid.GroupingView.superclass.renderUI.call(this);
37840
this.mainBody.on('mousedown', this.interceptMouse, this);
37842
if(this.enableGroupingMenu && this.hmenu){
37843
this.hmenu.add('-',{
37845
text: this.groupByText,
37846
handler: this.onGroupByClick,
37848
iconCls:'x-group-by-icon'
37850
if(this.enableNoGroups){
37852
itemId:'showGroups',
37853
text: this.showGroupsText,
37855
checkHandler: this.onShowGroupsClick,
37859
this.hmenu.on('beforeshow', this.beforeMenuShow, this);
37864
onGroupByClick : function(){
37865
this.grid.store.groupBy(this.cm.getDataIndex(this.hdCtxIndex));
37866
this.beforeMenuShow(); // Make sure the checkboxes get properly set when changing groups
37870
onShowGroupsClick : function(mi, checked){
37872
this.onGroupByClick();
37874
this.grid.store.clearGrouping();
37879
toggleGroup : function(group, expanded){
37880
this.grid.stopEditing(true);
37881
group = Ext.getDom(group);
37882
var gel = Ext.fly(group);
37883
expanded = expanded !== undefined ?
37884
expanded : gel.hasClass('x-grid-group-collapsed');
37886
this.state[gel.dom.id] = expanded;
37887
gel[expanded ? 'removeClass' : 'addClass']('x-grid-group-collapsed');
37891
toggleAllGroups : function(expanded){
37892
var groups = this.getGroups();
37893
for(var i = 0, len = groups.length; i < len; i++){
37894
this.toggleGroup(groups[i], expanded);
37899
expandAllGroups : function(){
37900
this.toggleAllGroups(true);
37904
collapseAllGroups : function(){
37905
this.toggleAllGroups(false);
37909
interceptMouse : function(e){
37910
var hd = e.getTarget('.x-grid-group-hd', this.mainBody);
37913
this.toggleGroup(hd.parentNode);
37918
getGroup : function(v, r, groupRenderer, rowIndex, colIndex, ds){
37919
var g = groupRenderer ? groupRenderer(v, {}, r, rowIndex, colIndex, ds) : String(v);
37921
g = this.cm.config[colIndex].emptyGroupText || this.emptyGroupText;
37927
getGroupField : function(){
37928
return this.grid.store.getGroupState();
37932
afterRender: function(){
37933
Ext.grid.GroupingView.superclass.afterRender.call(this);
37934
if(this.grid.deferRowRender){
37935
this.updateGroupWidths();
37940
renderRows : function(){
37941
var groupField = this.getGroupField();
37942
var eg = !!groupField;
37943
// if they turned off grouping and the last grouped field is hidden
37944
if(this.hideGroupedColumn) {
37945
var colIndex = this.cm.findColumnIndex(groupField);
37946
if(!eg && this.lastGroupField !== undefined) {
37947
this.mainBody.update('');
37948
this.cm.setHidden(this.cm.findColumnIndex(this.lastGroupField), false);
37949
delete this.lastGroupField;
37950
}else if (eg && this.lastGroupField === undefined) {
37951
this.lastGroupField = groupField;
37952
this.cm.setHidden(colIndex, true);
37953
}else if (eg && this.lastGroupField !== undefined && groupField !== this.lastGroupField) {
37954
this.mainBody.update('');
37955
var oldIndex = this.cm.findColumnIndex(this.lastGroupField);
37956
this.cm.setHidden(oldIndex, false);
37957
this.lastGroupField = groupField;
37958
this.cm.setHidden(colIndex, true);
37961
return Ext.grid.GroupingView.superclass.renderRows.apply(
37966
doRender : function(cs, rs, ds, startRow, colCount, stripe){
37970
var groupField = this.getGroupField();
37971
var colIndex = this.cm.findColumnIndex(groupField);
37973
this.enableGrouping = !!groupField;
37975
if(!this.enableGrouping || this.isUpdating){
37976
return Ext.grid.GroupingView.superclass.doRender.apply(
37979
var gstyle = 'width:'+this.getTotalWidth()+';';
37981
var gidPrefix = this.grid.getGridEl().id;
37982
var cfg = this.cm.config[colIndex];
37983
var groupRenderer = cfg.groupRenderer || cfg.renderer;
37984
var prefix = this.showGroupName ?
37985
(cfg.groupName || cfg.header)+': ' : '';
37987
var groups = [], curGroup, i, len, gid;
37988
for(i = 0, len = rs.length; i < len; i++){
37989
var rowIndex = startRow + i;
37991
gvalue = r.data[groupField],
37992
g = this.getGroup(gvalue, r, groupRenderer, rowIndex, colIndex, ds);
37993
if(!curGroup || curGroup.group != g){
37994
gid = gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(g);
37995
// if state is defined use it, however state is in terms of expanded
37996
// so negate it, otherwise use the default.
37997
var isCollapsed = typeof this.state[gid] !== 'undefined' ? !this.state[gid] : this.startCollapsed;
37998
var gcls = isCollapsed ? 'x-grid-group-collapsed' : '';
38004
startRow: rowIndex,
38009
groups.push(curGroup);
38011
curGroup.rs.push(r);
38017
for(i = 0, len = groups.length; i < len; i++){
38019
this.doGroupStart(buf, g, cs, ds, colCount);
38020
buf[buf.length] = Ext.grid.GroupingView.superclass.doRender.call(
38021
this, cs, g.rs, ds, g.startRow, colCount, stripe);
38023
this.doGroupEnd(buf, g, cs, ds, colCount);
38025
return buf.join('');
38029
getGroupId : function(value){
38030
var gidPrefix = this.grid.getGridEl().id;
38031
var groupField = this.getGroupField();
38032
var colIndex = this.cm.findColumnIndex(groupField);
38033
var cfg = this.cm.config[colIndex];
38034
var groupRenderer = cfg.groupRenderer || cfg.renderer;
38035
var gtext = this.getGroup(value, {data:{}}, groupRenderer, 0, colIndex, this.ds);
38036
return gidPrefix + '-gp-' + groupField + '-' + Ext.util.Format.htmlEncode(value);
38040
doGroupStart : function(buf, g, cs, ds, colCount){
38041
buf[buf.length] = this.startGroup.apply(g);
38045
doGroupEnd : function(buf, g, cs, ds, colCount){
38046
buf[buf.length] = this.endGroup;
38050
getRows : function(){
38051
if(!this.enableGrouping){
38052
return Ext.grid.GroupingView.superclass.getRows.call(this);
38055
var g, gs = this.getGroups();
38056
for(var i = 0, len = gs.length; i < len; i++){
38057
g = gs[i].childNodes[1].childNodes;
38058
for(var j = 0, jlen = g.length; j < jlen; j++){
38059
r[r.length] = g[j];
38066
updateGroupWidths : function(){
38067
if(!this.enableGrouping || !this.hasRows()){
38070
var tw = Math.max(this.cm.getTotalWidth(), this.el.dom.offsetWidth-this.scrollOffset) +'px';
38071
var gs = this.getGroups();
38072
for(var i = 0, len = gs.length; i < len; i++){
38073
gs[i].firstChild.style.width = tw;
38078
onColumnWidthUpdated : function(col, w, tw){
38079
Ext.grid.GroupingView.superclass.onColumnWidthUpdated.call(this, col, w, tw);
38080
this.updateGroupWidths();
38084
onAllColumnWidthsUpdated : function(ws, tw){
38085
Ext.grid.GroupingView.superclass.onAllColumnWidthsUpdated.call(this, ws, tw);
38086
this.updateGroupWidths();
38090
onColumnHiddenUpdated : function(col, hidden, tw){
38091
Ext.grid.GroupingView.superclass.onColumnHiddenUpdated.call(this, col, hidden, tw);
38092
this.updateGroupWidths();
38096
onLayout : function(){
38097
this.updateGroupWidths();
38101
onBeforeRowSelect : function(sm, rowIndex){
38102
if(!this.enableGrouping){
38105
var row = this.getRow(rowIndex);
38106
if(row && !row.offsetParent){
38107
var g = this.findGroup(row);
38108
this.toggleGroup(g, true);
38113
groupByText: 'Group By This Field',
38115
showGroupsText: 'Show in Groups'
38118
Ext.grid.GroupingView.GROUP_ID = 1000;
38120
// This is a support class used internally by the Grid components
38121
Ext.grid.HeaderDragZone = function(grid, hd, hd2){
38123
this.view = grid.getView();
38124
this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
38125
Ext.grid.HeaderDragZone.superclass.constructor.call(this, hd);
38127
this.setHandleElId(Ext.id(hd));
38128
this.setOuterHandleElId(Ext.id(hd2));
38130
this.scroll = false;
38132
Ext.extend(Ext.grid.HeaderDragZone, Ext.dd.DragZone, {
38134
getDragData : function(e){
38135
var t = Ext.lib.Event.getTarget(e);
38136
var h = this.view.findHeaderCell(t);
38138
return {ddel: h.firstChild, header:h};
38143
onInitDrag : function(e){
38144
this.view.headersDisabled = true;
38145
var clone = this.dragData.ddel.cloneNode(true);
38146
clone.id = Ext.id();
38147
clone.style.width = Math.min(this.dragData.header.offsetWidth,this.maxDragWidth) + "px";
38148
this.proxy.update(clone);
38152
afterValidDrop : function(){
38154
setTimeout(function(){
38155
v.headersDisabled = false;
38159
afterInvalidDrop : function(){
38161
setTimeout(function(){
38162
v.headersDisabled = false;
38168
// This is a support class used internally by the Grid components
38169
Ext.grid.HeaderDropZone = function(grid, hd, hd2){
38171
this.view = grid.getView();
38172
// split the proxies so they don't interfere with mouse events
38173
this.proxyTop = Ext.DomHelper.append(document.body, {
38174
cls:"col-move-top", html:" "
38176
this.proxyBottom = Ext.DomHelper.append(document.body, {
38177
cls:"col-move-bottom", html:" "
38179
this.proxyTop.hide = this.proxyBottom.hide = function(){
38180
this.setLeftTop(-100,-100);
38181
this.setStyle("visibility", "hidden");
38183
this.ddGroup = "gridHeader" + this.grid.getGridEl().id;
38184
// temporarily disabled
38185
//Ext.dd.ScrollManager.register(this.view.scroller.dom);
38186
Ext.grid.HeaderDropZone.superclass.constructor.call(this, grid.getGridEl().dom);
38188
Ext.extend(Ext.grid.HeaderDropZone, Ext.dd.DropZone, {
38189
proxyOffsets : [-4, -9],
38190
fly: Ext.Element.fly,
38192
getTargetFromEvent : function(e){
38193
var t = Ext.lib.Event.getTarget(e);
38194
var cindex = this.view.findCellIndex(t);
38195
if(cindex !== false){
38196
return this.view.getHeaderCell(cindex);
38200
nextVisible : function(h){
38201
var v = this.view, cm = this.grid.colModel;
38204
if(!cm.isHidden(v.getCellIndex(h))){
38212
prevVisible : function(h){
38213
var v = this.view, cm = this.grid.colModel;
38216
if(!cm.isHidden(v.getCellIndex(h))){
38224
positionIndicator : function(h, n, e){
38225
var x = Ext.lib.Event.getPageX(e);
38226
var r = Ext.lib.Dom.getRegion(n.firstChild);
38227
var px, pt, py = r.top + this.proxyOffsets[1];
38228
if((r.right - x) <= (r.right-r.left)/2){
38229
px = r.right+this.view.borderWidth;
38236
if(this.grid.colModel.isFixed(this.view.getCellIndex(n))){
38240
px += this.proxyOffsets[0];
38241
this.proxyTop.setLeftTop(px, py);
38242
this.proxyTop.show();
38243
if(!this.bottomOffset){
38244
this.bottomOffset = this.view.mainHd.getHeight();
38246
this.proxyBottom.setLeftTop(px, py+this.proxyTop.dom.offsetHeight+this.bottomOffset);
38247
this.proxyBottom.show();
38251
onNodeEnter : function(n, dd, e, data){
38252
if(data.header != n){
38253
this.positionIndicator(data.header, n, e);
38257
onNodeOver : function(n, dd, e, data){
38258
var result = false;
38259
if(data.header != n){
38260
result = this.positionIndicator(data.header, n, e);
38263
this.proxyTop.hide();
38264
this.proxyBottom.hide();
38266
return result ? this.dropAllowed : this.dropNotAllowed;
38269
onNodeOut : function(n, dd, e, data){
38270
this.proxyTop.hide();
38271
this.proxyBottom.hide();
38274
onNodeDrop : function(n, dd, e, data){
38275
var h = data.header;
38277
var cm = this.grid.colModel;
38278
var x = Ext.lib.Event.getPageX(e);
38279
var r = Ext.lib.Dom.getRegion(n.firstChild);
38280
var pt = (r.right - x) <= ((r.right-r.left)/2) ? "after" : "before";
38281
var oldIndex = this.view.getCellIndex(h);
38282
var newIndex = this.view.getCellIndex(n);
38286
if(oldIndex < newIndex){
38289
cm.moveColumn(oldIndex, newIndex);
38290
this.grid.fireEvent("columnmove", oldIndex, newIndex);
38298
Ext.grid.GridView.ColumnDragZone = function(grid, hd){
38299
Ext.grid.GridView.ColumnDragZone.superclass.constructor.call(this, grid, hd, null);
38300
this.proxy.el.addClass('x-grid3-col-dd');
38303
Ext.extend(Ext.grid.GridView.ColumnDragZone, Ext.grid.HeaderDragZone, {
38304
handleMouseDown : function(e){
38308
callHandleMouseDown : function(e){
38309
Ext.grid.GridView.ColumnDragZone.superclass.handleMouseDown.call(this, e);
38313
// This is a support class used internally by the Grid components
38314
Ext.grid.SplitDragZone = function(grid, hd, hd2){
38316
this.view = grid.getView();
38317
this.proxy = this.view.resizeProxy;
38318
Ext.grid.SplitDragZone.superclass.constructor.call(this, hd,
38319
"gridSplitters" + this.grid.getGridEl().id, {
38320
dragElId : Ext.id(this.proxy.dom), resizeFrame:false
38322
this.setHandleElId(Ext.id(hd));
38323
this.setOuterHandleElId(Ext.id(hd2));
38324
this.scroll = false;
38326
Ext.extend(Ext.grid.SplitDragZone, Ext.dd.DDProxy, {
38327
fly: Ext.Element.fly,
38329
b4StartDrag : function(x, y){
38330
this.view.headersDisabled = true;
38331
this.proxy.setHeight(this.view.mainWrap.getHeight());
38332
var w = this.cm.getColumnWidth(this.cellIndex);
38333
var minw = Math.max(w-this.grid.minColumnWidth, 0);
38334
this.resetConstraints();
38335
this.setXConstraint(minw, 1000);
38336
this.setYConstraint(0, 0);
38337
this.minX = x - minw;
38338
this.maxX = x + 1000;
38340
Ext.dd.DDProxy.prototype.b4StartDrag.call(this, x, y);
38344
handleMouseDown : function(e){
38345
var ev = Ext.EventObject.setEvent(e);
38346
var t = this.fly(ev.getTarget());
38347
if(t.hasClass("x-grid-split")){
38348
this.cellIndex = this.view.getCellIndex(t.dom);
38349
this.split = t.dom;
38350
this.cm = this.grid.colModel;
38351
if(this.cm.isResizable(this.cellIndex) && !this.cm.isFixed(this.cellIndex)){
38352
Ext.grid.SplitDragZone.superclass.handleMouseDown.apply(this, arguments);
38357
endDrag : function(e){
38358
this.view.headersDisabled = false;
38359
var endX = Math.max(this.minX, Ext.lib.Event.getPageX(e));
38360
var diff = endX - this.startPos;
38361
this.view.onColumnSplitterMoved(this.cellIndex, this.cm.getColumnWidth(this.cellIndex)+diff);
38364
autoOffset : function(){
38365
this.setDelta(0,0);
38369
Ext.grid.GridDragZone = function(grid, config){
38370
this.view = grid.getView();
38371
Ext.grid.GridDragZone.superclass.constructor.call(this, this.view.mainBody.dom, config);
38372
this.scroll = false;
38374
this.ddel = document.createElement('div');
38375
this.ddel.className = 'x-grid-dd-wrap';
38378
Ext.extend(Ext.grid.GridDragZone, Ext.dd.DragZone, {
38379
ddGroup : "GridDD",
38382
getDragData : function(e){
38383
var t = Ext.lib.Event.getTarget(e);
38384
var rowIndex = this.view.findRowIndex(t);
38385
if(rowIndex !== false){
38386
var sm = this.grid.selModel;
38387
if(!sm.isSelected(rowIndex) || e.hasModifier()){
38388
sm.handleMouseDown(this.grid, rowIndex, e);
38390
return {grid: this.grid, ddel: this.ddel, rowIndex: rowIndex, selections:sm.getSelections()};
38396
onInitDrag : function(e){
38397
var data = this.dragData;
38398
this.ddel.innerHTML = this.grid.getDragDropText();
38399
this.proxy.update(this.ddel);
38400
// fire start drag?
38404
afterRepair : function(){
38405
this.dragging = false;
38409
getRepairXY : function(e, data){
38413
onEndDrag : function(data, e){
38417
onValidDrop : function(dd, e, id){
38422
beforeInvalidDrop : function(e, id){
38428
Ext.grid.ColumnModel = function(config){
38430
if(config.columns){
38431
Ext.apply(this, config);
38432
this.setConfig(config.columns, true);
38434
this.setConfig(config, true);
38448
Ext.grid.ColumnModel.superclass.constructor.call(this);
38450
Ext.extend(Ext.grid.ColumnModel, Ext.util.Observable, {
38454
defaultSortable: false,
38459
getColumnId : function(index){
38460
return this.config[index].id;
38463
getColumnAt : function(index){
38464
return this.config[index];
38468
setConfig : function(config, initial){
38469
if(!initial){ // cleanup
38470
delete this.totalWidth;
38471
for(var i = 0, len = this.config.length; i < len; i++){
38472
var c = this.config[i];
38474
c.editor.destroy();
38479
// backward compatibility
38480
this.defaults = Ext.apply({
38481
width: this.defaultWidth,
38482
sortable: this.defaultSortable
38485
this.config = config;
38487
// if no id, create one
38488
for(var i = 0, len = config.length; i < len; i++){
38489
var c = Ext.applyIf(config[i], this.defaults);
38491
var cls = Ext.grid.Column.types[c.xtype || 'gridcolumn'];
38495
this.lookup[c.id] = c;
38498
this.fireEvent('configchange', this);
38503
getColumnById : function(id){
38504
return this.lookup[id];
38508
getIndexById : function(id){
38509
for(var i = 0, len = this.config.length; i < len; i++){
38510
if(this.config[i].id == id){
38518
moveColumn : function(oldIndex, newIndex){
38519
var c = this.config[oldIndex];
38520
this.config.splice(oldIndex, 1);
38521
this.config.splice(newIndex, 0, c);
38522
this.dataMap = null;
38523
this.fireEvent("columnmoved", this, oldIndex, newIndex);
38527
getColumnCount : function(visibleOnly){
38528
if(visibleOnly === true){
38530
for(var i = 0, len = this.config.length; i < len; i++){
38531
if(!this.isHidden(i)){
38537
return this.config.length;
38541
getColumnsBy : function(fn, scope){
38543
for(var i = 0, len = this.config.length; i < len; i++){
38544
var c = this.config[i];
38545
if(fn.call(scope||this, c, i) === true){
38553
isSortable : function(col){
38554
return this.config[col].sortable;
38558
isMenuDisabled : function(col){
38559
return !!this.config[col].menuDisabled;
38563
getRenderer : function(col){
38564
if(!this.config[col].renderer){
38565
return Ext.grid.ColumnModel.defaultRenderer;
38567
return this.config[col].renderer;
38571
setRenderer : function(col, fn){
38572
this.config[col].renderer = fn;
38576
getColumnWidth : function(col){
38577
return this.config[col].width;
38581
setColumnWidth : function(col, width, suppressEvent){
38582
this.config[col].width = width;
38583
this.totalWidth = null;
38584
if(!suppressEvent){
38585
this.fireEvent("widthchange", this, col, width);
38590
getTotalWidth : function(includeHidden){
38591
if(!this.totalWidth){
38592
this.totalWidth = 0;
38593
for(var i = 0, len = this.config.length; i < len; i++){
38594
if(includeHidden || !this.isHidden(i)){
38595
this.totalWidth += this.getColumnWidth(i);
38599
return this.totalWidth;
38603
getColumnHeader : function(col){
38604
return this.config[col].header;
38608
setColumnHeader : function(col, header){
38609
this.config[col].header = header;
38610
this.fireEvent("headerchange", this, col, header);
38614
getColumnTooltip : function(col){
38615
return this.config[col].tooltip;
38618
setColumnTooltip : function(col, tooltip){
38619
this.config[col].tooltip = tooltip;
38623
getDataIndex : function(col){
38624
return this.config[col].dataIndex;
38628
setDataIndex : function(col, dataIndex){
38629
this.config[col].dataIndex = dataIndex;
38633
findColumnIndex : function(dataIndex){
38634
var c = this.config;
38635
for(var i = 0, len = c.length; i < len; i++){
38636
if(c[i].dataIndex == dataIndex){
38644
isCellEditable : function(colIndex, rowIndex){
38645
return (this.config[colIndex].editable || (typeof this.config[colIndex].editable == "undefined" && this.config[colIndex].editor)) ? true : false;
38649
getCellEditor : function(colIndex, rowIndex){
38650
return this.config[colIndex].getCellEditor(rowIndex);
38654
setEditable : function(col, editable){
38655
this.config[col].editable = editable;
38660
isHidden : function(colIndex){
38661
return this.config[colIndex].hidden;
38666
isFixed : function(colIndex){
38667
return this.config[colIndex].fixed;
38671
isResizable : function(colIndex){
38672
return colIndex >= 0 && this.config[colIndex].resizable !== false && this.config[colIndex].fixed !== true;
38675
setHidden : function(colIndex, hidden){
38676
var c = this.config[colIndex];
38677
if(c.hidden !== hidden){
38679
this.totalWidth = null;
38680
this.fireEvent("hiddenchange", this, colIndex, hidden);
38685
setEditor : function(col, editor){
38686
Ext.destroy(this.config[col].editor);
38687
this.config[col].editor = editor;
38691
destroy : function(){
38692
var c = this.config;
38693
for(var i = 0, c = this.config, len = c.length; i < len; i++){
38694
Ext.destroy(c[i].editor);
38696
this.purgeListeners();
38701
Ext.grid.ColumnModel.defaultRenderer = function(value){
38702
if(typeof value == "string" && value.length < 1){
38708
Ext.grid.AbstractSelectionModel = function(){
38709
this.locked = false;
38710
Ext.grid.AbstractSelectionModel.superclass.constructor.call(this);
38713
Ext.extend(Ext.grid.AbstractSelectionModel, Ext.util.Observable, {
38715
init : function(grid){
38722
this.locked = true;
38726
unlock : function(){
38727
this.locked = false;
38731
isLocked : function(){
38732
return this.locked;
38736
Ext.grid.RowSelectionModel = function(config){
38737
Ext.apply(this, config);
38738
this.selections = new Ext.util.MixedCollection(false, function(o){
38743
this.lastActive = false;
38756
Ext.grid.RowSelectionModel.superclass.constructor.call(this);
38759
Ext.extend(Ext.grid.RowSelectionModel, Ext.grid.AbstractSelectionModel, {
38761
singleSelect : false,
38765
initEvents : function(){
38767
if(!this.grid.enableDragDrop && !this.grid.enableDrag){
38768
this.grid.on("rowmousedown", this.handleMouseDown, this);
38769
}else{ // allow click to work like normal
38770
this.grid.on("rowclick", function(grid, rowIndex, e) {
38771
if(e.button === 0 && !e.shiftKey && !e.ctrlKey) {
38772
this.selectRow(rowIndex, false);
38773
grid.view.focusRow(rowIndex);
38778
this.rowNav = new Ext.KeyNav(this.grid.getGridEl(), {
38779
"up" : function(e){
38780
if(!e.shiftKey || this.singleSelect){
38781
this.selectPrevious(false);
38782
}else if(this.last !== false && this.lastActive !== false){
38783
var last = this.last;
38784
this.selectRange(this.last, this.lastActive-1);
38785
this.grid.getView().focusRow(this.lastActive);
38786
if(last !== false){
38790
this.selectFirstRow();
38793
"down" : function(e){
38794
if(!e.shiftKey || this.singleSelect){
38795
this.selectNext(false);
38796
}else if(this.last !== false && this.lastActive !== false){
38797
var last = this.last;
38798
this.selectRange(this.last, this.lastActive+1);
38799
this.grid.getView().focusRow(this.lastActive);
38800
if(last !== false){
38804
this.selectFirstRow();
38810
var view = this.grid.view;
38811
view.on("refresh", this.onRefresh, this);
38812
view.on("rowupdated", this.onRowUpdated, this);
38813
view.on("rowremoved", this.onRemove, this);
38817
onRefresh : function(){
38818
var ds = this.grid.store, index;
38819
var s = this.getSelections();
38820
this.clearSelections(true);
38821
for(var i = 0, len = s.length; i < len; i++){
38823
if((index = ds.indexOfId(r.id)) != -1){
38824
this.selectRow(index, true);
38827
if(s.length != this.selections.getCount()){
38828
this.fireEvent("selectionchange", this);
38833
onRemove : function(v, index, r){
38834
if(this.selections.remove(r) !== false){
38835
this.fireEvent('selectionchange', this);
38840
onRowUpdated : function(v, index, r){
38841
if(this.isSelected(r)){
38842
v.onRowSelect(index);
38847
selectRecords : function(records, keepExisting){
38849
this.clearSelections();
38851
var ds = this.grid.store;
38852
for(var i = 0, len = records.length; i < len; i++){
38853
this.selectRow(ds.indexOf(records[i]), true);
38858
getCount : function(){
38859
return this.selections.length;
38863
selectFirstRow : function(){
38868
selectLastRow : function(keepExisting){
38869
this.selectRow(this.grid.store.getCount() - 1, keepExisting);
38873
selectNext : function(keepExisting){
38874
if(this.hasNext()){
38875
this.selectRow(this.last+1, keepExisting);
38876
this.grid.getView().focusRow(this.last);
38883
selectPrevious : function(keepExisting){
38884
if(this.hasPrevious()){
38885
this.selectRow(this.last-1, keepExisting);
38886
this.grid.getView().focusRow(this.last);
38893
hasNext : function(){
38894
return this.last !== false && (this.last+1) < this.grid.store.getCount();
38898
hasPrevious : function(){
38899
return !!this.last;
38904
getSelections : function(){
38905
return [].concat(this.selections.items);
38909
getSelected : function(){
38910
return this.selections.itemAt(0);
38914
each : function(fn, scope){
38915
var s = this.getSelections();
38916
for(var i = 0, len = s.length; i < len; i++){
38917
if(fn.call(scope || this, s[i], i) === false){
38925
clearSelections : function(fast){
38926
if(this.isLocked()) return;
38928
var ds = this.grid.store;
38929
var s = this.selections;
38930
s.each(function(r){
38931
this.deselectRow(ds.indexOfId(r.id));
38935
this.selections.clear();
38942
selectAll : function(){
38943
if(this.isLocked()) return;
38944
this.selections.clear();
38945
for(var i = 0, len = this.grid.store.getCount(); i < len; i++){
38946
this.selectRow(i, true);
38951
hasSelection : function(){
38952
return this.selections.length > 0;
38956
isSelected : function(index){
38957
var r = typeof index == "number" ? this.grid.store.getAt(index) : index;
38958
return (r && this.selections.key(r.id) ? true : false);
38962
isIdSelected : function(id){
38963
return (this.selections.key(id) ? true : false);
38967
handleMouseDown : function(g, rowIndex, e){
38968
if(e.button !== 0 || this.isLocked()){
38971
var view = this.grid.getView();
38972
if(e.shiftKey && !this.singleSelect && this.last !== false){
38973
var last = this.last;
38974
this.selectRange(last, rowIndex, e.ctrlKey);
38975
this.last = last; // reset the last
38976
view.focusRow(rowIndex);
38978
var isSelected = this.isSelected(rowIndex);
38979
if(e.ctrlKey && isSelected){
38980
this.deselectRow(rowIndex);
38981
}else if(!isSelected || this.getCount() > 1){
38982
this.selectRow(rowIndex, e.ctrlKey || e.shiftKey);
38983
view.focusRow(rowIndex);
38989
selectRows : function(rows, keepExisting){
38991
this.clearSelections();
38993
for(var i = 0, len = rows.length; i < len; i++){
38994
this.selectRow(rows[i], true);
38999
selectRange : function(startRow, endRow, keepExisting){
39000
if(this.isLocked()) return;
39002
this.clearSelections();
39004
if(startRow <= endRow){
39005
for(var i = startRow; i <= endRow; i++){
39006
this.selectRow(i, true);
39009
for(var i = startRow; i >= endRow; i--){
39010
this.selectRow(i, true);
39016
deselectRange : function(startRow, endRow, preventViewNotify){
39017
if(this.isLocked()) return;
39018
for(var i = startRow; i <= endRow; i++){
39019
this.deselectRow(i, preventViewNotify);
39024
selectRow : function(index, keepExisting, preventViewNotify){
39025
if(this.isLocked() || (index < 0 || index >= this.grid.store.getCount()) || (keepExisting && this.isSelected(index))){
39028
var r = this.grid.store.getAt(index);
39029
if(r && this.fireEvent("beforerowselect", this, index, keepExisting, r) !== false){
39030
if(!keepExisting || this.singleSelect){
39031
this.clearSelections();
39033
this.selections.add(r);
39034
this.last = this.lastActive = index;
39035
if(!preventViewNotify){
39036
this.grid.getView().onRowSelect(index);
39038
this.fireEvent("rowselect", this, index, r);
39039
this.fireEvent("selectionchange", this);
39044
deselectRow : function(index, preventViewNotify){
39045
if(this.isLocked()) return;
39046
if(this.last == index){
39049
if(this.lastActive == index){
39050
this.lastActive = false;
39052
var r = this.grid.store.getAt(index);
39054
this.selections.remove(r);
39055
if(!preventViewNotify){
39056
this.grid.getView().onRowDeselect(index);
39058
this.fireEvent("rowdeselect", this, index, r);
39059
this.fireEvent("selectionchange", this);
39064
restoreLast : function(){
39066
this.last = this._last;
39071
acceptsNav : function(row, col, cm){
39072
return !cm.isHidden(col) && cm.isCellEditable(col, row);
39076
onEditorKey : function(field, e){
39077
var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
39078
var shift = e.shiftKey;
39083
newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
39085
newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
39087
}else if(k == e.ENTER){
39090
if(this.moveEditorOnEnter !== false){
39092
newCell = g.walkCells(ed.row - 1, ed.col, -1, this.acceptsNav, this);
39094
newCell = g.walkCells(ed.row + 1, ed.col, 1, this.acceptsNav, this);
39097
}else if(k == e.ESC){
39101
g.startEditing(newCell[0], newCell[1]);
39106
Ext.grid.CellSelectionModel = function(config){
39107
Ext.apply(this, config);
39109
this.selection = null;
39113
"beforecellselect",
39120
Ext.grid.CellSelectionModel.superclass.constructor.call(this);
39123
Ext.extend(Ext.grid.CellSelectionModel, Ext.grid.AbstractSelectionModel, {
39126
initEvents : function(){
39127
this.grid.on("cellmousedown", this.handleMouseDown, this);
39128
this.grid.getGridEl().on(Ext.isIE || Ext.isSafari3 || Ext.isChrome ? "keydown" : "keypress", this.handleKeyDown, this);
39129
var view = this.grid.view;
39130
view.on("refresh", this.onViewChange, this);
39131
view.on("rowupdated", this.onRowUpdated, this);
39132
view.on("beforerowremoved", this.clearSelections, this);
39133
view.on("beforerowsinserted", this.clearSelections, this);
39134
if(this.grid.isEditor){
39135
this.grid.on("beforeedit", this.beforeEdit, this);
39140
beforeEdit : function(e){
39141
this.select(e.row, e.column, false, true, e.record);
39145
onRowUpdated : function(v, index, r){
39146
if(this.selection && this.selection.record == r){
39147
v.onCellSelect(index, this.selection.cell[1]);
39152
onViewChange : function(){
39153
this.clearSelections(true);
39157
getSelectedCell : function(){
39158
return this.selection ? this.selection.cell : null;
39162
clearSelections : function(preventNotify){
39163
var s = this.selection;
39165
if(preventNotify !== true){
39166
this.grid.view.onCellDeselect(s.cell[0], s.cell[1]);
39168
this.selection = null;
39169
this.fireEvent("selectionchange", this, null);
39174
hasSelection : function(){
39175
return this.selection ? true : false;
39179
handleMouseDown : function(g, row, cell, e){
39180
if(e.button !== 0 || this.isLocked()){
39183
this.select(row, cell);
39187
select : function(rowIndex, colIndex, preventViewNotify, preventFocus, r){
39188
if(this.fireEvent("beforecellselect", this, rowIndex, colIndex) !== false){
39189
this.clearSelections();
39190
r = r || this.grid.store.getAt(rowIndex);
39193
cell : [rowIndex, colIndex]
39195
if(!preventViewNotify){
39196
var v = this.grid.getView();
39197
v.onCellSelect(rowIndex, colIndex);
39198
if(preventFocus !== true){
39199
v.focusCell(rowIndex, colIndex);
39202
this.fireEvent("cellselect", this, rowIndex, colIndex);
39203
this.fireEvent("selectionchange", this, this.selection);
39208
isSelectable : function(rowIndex, colIndex, cm){
39209
return !cm.isHidden(colIndex);
39213
handleKeyDown : function(e){
39214
if(!e.isNavKeyPress()){
39217
var g = this.grid, s = this.selection;
39220
var cell = g.walkCells(0, 0, 1, this.isSelectable, this);
39222
this.select(cell[0], cell[1]);
39227
var walk = function(row, col, step){
39228
return g.walkCells(row, col, step, sm.isSelectable, sm);
39230
var k = e.getKey(), r = s.cell[0], c = s.cell[1];
39236
newCell = walk(r, c-1, -1);
39238
newCell = walk(r, c+1, 1);
39242
newCell = walk(r+1, c, 1);
39245
newCell = walk(r-1, c, -1);
39248
newCell = walk(r, c+1, 1);
39251
newCell = walk(r, c-1, -1);
39254
if(g.isEditor && !g.editing){
39255
g.startEditing(r, c);
39262
this.select(newCell[0], newCell[1]);
39267
acceptsNav : function(row, col, cm){
39268
return !cm.isHidden(col) && cm.isCellEditable(col, row);
39271
onEditorKey : function(field, e){
39272
var k = e.getKey(), newCell, g = this.grid, ed = g.activeEditor;
39275
newCell = g.walkCells(ed.row, ed.col-1, -1, this.acceptsNav, this);
39277
newCell = g.walkCells(ed.row, ed.col+1, 1, this.acceptsNav, this);
39280
}else if(k == e.ENTER){
39283
}else if(k == e.ESC){
39288
g.startEditing(newCell[0], newCell[1]);
39293
Ext.grid.EditorGridPanel = Ext.extend(Ext.grid.GridPanel, {
39298
forceValidation: false,
39306
autoEncode : false,
39310
trackMouseOver: false, // causes very odd FF errors
39313
initComponent : function(){
39314
Ext.grid.EditorGridPanel.superclass.initComponent.call(this);
39316
if(!this.selModel){
39318
this.selModel = new Ext.grid.CellSelectionModel();
39321
this.activeEditor = null;
39334
initEvents : function(){
39335
Ext.grid.EditorGridPanel.superclass.initEvents.call(this);
39337
this.on("bodyscroll", this.stopEditing, this, [true]);
39338
this.on("columnresize", this.stopEditing, this, [true]);
39340
if(this.clicksToEdit == 1){
39341
this.on("cellclick", this.onCellDblClick, this);
39343
if(this.clicksToEdit == 'auto' && this.view.mainBody){
39344
this.view.mainBody.on("mousedown", this.onAutoEditClick, this);
39346
this.on("celldblclick", this.onCellDblClick, this);
39351
onCellDblClick : function(g, row, col){
39352
this.startEditing(row, col);
39356
onAutoEditClick : function(e, t){
39357
if(e.button !== 0){
39360
var row = this.view.findRowIndex(t);
39361
var col = this.view.findCellIndex(t);
39362
if(row !== false && col !== false){
39363
this.stopEditing();
39364
if(this.selModel.getSelectedCell){ // cell sm
39365
var sc = this.selModel.getSelectedCell();
39366
if(sc && sc.cell[0] === row && sc.cell[1] === col){
39367
this.startEditing(row, col);
39370
if(this.selModel.isSelected(row)){
39371
this.startEditing(row, col);
39378
onEditComplete : function(ed, value, startValue){
39379
this.editing = false;
39380
this.activeEditor = null;
39381
ed.un("specialkey", this.selModel.onEditorKey, this.selModel);
39383
var field = this.colModel.getDataIndex(ed.col);
39384
value = this.postEditValue(value, startValue, r, field);
39385
if(this.forceValidation === true || String(value) !== String(startValue)){
39390
originalValue: startValue,
39396
if(this.fireEvent("validateedit", e) !== false && !e.cancel && String(value) !== String(startValue)){
39397
r.set(field, e.value);
39399
this.fireEvent("afteredit", e);
39402
this.view.focusCell(ed.row, ed.col);
39406
startEditing : function(row, col){
39407
this.stopEditing();
39408
if(this.colModel.isCellEditable(col, row)){
39409
this.view.ensureVisible(row, col, true);
39410
var r = this.store.getAt(row);
39411
var field = this.colModel.getDataIndex(col);
39416
value: r.data[field],
39421
if(this.fireEvent("beforeedit", e) !== false && !e.cancel){
39422
this.editing = true;
39423
var ed = this.colModel.getCellEditor(col, row);
39428
ed.render(this.view.getEditorParent(ed));
39430
(function(){ // complex but required for focus issues in safari, ie and opera
39434
ed.on("complete", this.onEditComplete, this, {single: true});
39435
ed.on("specialkey", this.selModel.onEditorKey, this.selModel);
39437
this.activeEditor = ed;
39438
var v = this.preEditValue(r, field);
39439
ed.startEdit(this.view.getCell(row, col).firstChild, v === undefined ? '' : v);
39440
}).defer(50, this);
39446
preEditValue : function(r, field){
39447
var value = r.data[field];
39448
return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlDecode(value) : value;
39452
postEditValue : function(value, originalValue, r, field){
39453
return this.autoEncode && typeof value == 'string' ? Ext.util.Format.htmlEncode(value) : value;
39457
stopEditing : function(cancel){
39458
if(this.activeEditor){
39459
this.activeEditor[cancel === true ? 'cancelEdit' : 'completeEdit']();
39461
this.activeEditor = null;
39464
Ext.reg('editorgrid', Ext.grid.EditorGridPanel);
39466
// This is a support class used internally by the Grid components
39467
Ext.grid.GridEditor = function(field, config){
39468
Ext.grid.GridEditor.superclass.constructor.call(this, field, config);
39469
field.monitorTab = false;
39472
Ext.extend(Ext.grid.GridEditor, Ext.Editor, {
39473
alignment: "tl-tl",
39476
cls: "x-small-editor x-grid-editor",
39481
Ext.grid.PropertyRecord = Ext.data.Record.create([
39482
{name:'name',type:'string'}, 'value'
39486
Ext.grid.PropertyStore = function(grid, source){
39488
this.store = new Ext.data.Store({
39489
recordType : Ext.grid.PropertyRecord
39491
this.store.on('update', this.onUpdate, this);
39493
this.setSource(source);
39495
Ext.grid.PropertyStore.superclass.constructor.call(this);
39497
Ext.extend(Ext.grid.PropertyStore, Ext.util.Observable, {
39498
// protected - should only be called by the grid. Use grid.setSource instead.
39499
setSource : function(o){
39501
this.store.removeAll();
39504
if(this.isEditableValue(o[k])){
39505
data.push(new Ext.grid.PropertyRecord({name: k, value: o[k]}, k));
39508
this.store.loadRecords({records: data}, {}, true);
39512
onUpdate : function(ds, record, type){
39513
if(type == Ext.data.Record.EDIT){
39514
var v = record.data['value'];
39515
var oldValue = record.modified['value'];
39516
if(this.grid.fireEvent('beforepropertychange', this.source, record.id, v, oldValue) !== false){
39517
this.source[record.id] = v;
39519
this.grid.fireEvent('propertychange', this.source, record.id, v, oldValue);
39527
getProperty : function(row){
39528
return this.store.getAt(row);
39532
isEditableValue: function(val){
39533
if(Ext.isDate(val)){
39535
}else if(typeof val == 'object' || typeof val == 'function'){
39542
setValue : function(prop, value){
39543
this.source[prop] = value;
39544
this.store.getById(prop).set('value', value);
39547
// protected - should only be called by the grid. Use grid.getSource instead.
39548
getSource : function(){
39549
return this.source;
39554
Ext.grid.PropertyColumnModel = function(grid, store){
39557
g.PropertyColumnModel.superclass.constructor.call(this, [
39558
{header: this.nameText, width:50, sortable: true, dataIndex:'name', id: 'name', menuDisabled:true},
39559
{header: this.valueText, width:50, resizable:false, dataIndex: 'value', id: 'value', menuDisabled:true}
39561
this.store = store;
39562
this.bselect = Ext.DomHelper.append(document.body, {
39563
tag: 'select', cls: 'x-grid-editor x-hide-display', children: [
39564
{tag: 'option', value: 'true', html: 'true'},
39565
{tag: 'option', value: 'false', html: 'false'}
39570
var bfield = new f.Field({
39572
bselect : this.bselect,
39574
getValue : function(){
39575
return this.bselect.value == 'true';
39579
'date' : new g.GridEditor(new f.DateField({selectOnFocus:true})),
39580
'string' : new g.GridEditor(new f.TextField({selectOnFocus:true})),
39581
'number' : new g.GridEditor(new f.NumberField({selectOnFocus:true, style:'text-align:left;'})),
39582
'boolean' : new g.GridEditor(bfield)
39584
this.renderCellDelegate = this.renderCell.createDelegate(this);
39585
this.renderPropDelegate = this.renderProp.createDelegate(this);
39588
Ext.extend(Ext.grid.PropertyColumnModel, Ext.grid.ColumnModel, {
39589
// private - strings used for locale support
39591
valueText : 'Value',
39592
dateFormat : 'm/j/Y',
39595
renderDate : function(dateVal){
39596
return dateVal.dateFormat(this.dateFormat);
39600
renderBool : function(bVal){
39601
return bVal ? 'true' : 'false';
39605
isCellEditable : function(colIndex, rowIndex){
39606
return colIndex == 1;
39610
getRenderer : function(col){
39612
this.renderCellDelegate : this.renderPropDelegate;
39616
renderProp : function(v){
39617
return this.getPropertyName(v);
39621
renderCell : function(val){
39623
if(Ext.isDate(val)){
39624
rv = this.renderDate(val);
39625
}else if(typeof val == 'boolean'){
39626
rv = this.renderBool(val);
39628
return Ext.util.Format.htmlEncode(rv);
39632
getPropertyName : function(name){
39633
var pn = this.grid.propertyNames;
39634
return pn && pn[name] ? pn[name] : name;
39638
getCellEditor : function(colIndex, rowIndex){
39639
var p = this.store.getProperty(rowIndex);
39640
var n = p.data['name'], val = p.data['value'];
39641
if(this.grid.customEditors[n]){
39642
return this.grid.customEditors[n];
39644
if(Ext.isDate(val)){
39645
return this.editors['date'];
39646
}else if(typeof val == 'number'){
39647
return this.editors['number'];
39648
}else if(typeof val == 'boolean'){
39649
return this.editors['boolean'];
39651
return this.editors['string'];
39656
destroy : function(){
39657
Ext.grid.PropertyColumnModel.superclass.destroy.call(this);
39658
for(var ed in this.editors){
39665
Ext.grid.PropertyGrid = Ext.extend(Ext.grid.EditorGridPanel, {
39670
// private config overrides
39671
enableColumnMove:false,
39673
trackMouseOver: false,
39675
enableHdMenu : false,
39681
initComponent : function(){
39682
this.customEditors = this.customEditors || {};
39683
this.lastEditRow = null;
39684
var store = new Ext.grid.PropertyStore(this);
39685
this.propStore = store;
39686
var cm = new Ext.grid.PropertyColumnModel(this, store);
39687
store.store.sort('name', 'ASC');
39690
'beforepropertychange',
39695
this.ds = store.store;
39696
Ext.grid.PropertyGrid.superclass.initComponent.call(this);
39698
this.mon(this.selModel, 'beforecellselect', function(sm, rowIndex, colIndex){
39699
if(colIndex === 0){
39700
this.startEditing.defer(200, this, [rowIndex, 1]);
39707
onRender : function(){
39708
Ext.grid.PropertyGrid.superclass.onRender.apply(this, arguments);
39710
this.getGridEl().addClass('x-props-grid');
39714
afterRender: function(){
39715
Ext.grid.PropertyGrid.superclass.afterRender.apply(this, arguments);
39717
this.setSource(this.source);
39722
setSource : function(source){
39723
this.propStore.setSource(source);
39727
getSource : function(){
39728
return this.propStore.getSource();
39731
Ext.reg("propertygrid", Ext.grid.PropertyGrid);
39734
Ext.grid.Column = function(config){
39735
Ext.apply(this, config);
39737
if(typeof this.renderer == "string"){
39738
this.renderer = Ext.util.Format[this.renderer];
39739
} else if(typeof this.renderer == 'object'){
39740
this.scope = this.renderer.scope;
39741
this.renderer = this.renderer.fn;
39743
this.renderer = this.renderer.createDelegate(this.scope || config);
39745
if(typeof this.id == "undefined"){
39746
this.id = ++Ext.grid.Column.AUTO_ID;
39749
if(this.editor.xtype && !this.editor.events){
39750
this.editor = Ext.create(this.editor, 'textfield');
39755
Ext.grid.Column.AUTO_ID = 0;
39757
Ext.grid.Column.prototype = {
39780
// private. Used by ColumnModel to avoid reprocessing
39783
renderer : function(value){
39784
if(typeof value == "string" && value.length < 1){
39791
getEditor: function(rowIndex){
39792
return this.editable !== false ? this.editor : null;
39796
getCellEditor: function(rowIndex){
39797
var editor = this.getEditor(rowIndex);
39799
if(!editor.startEdit){
39800
if(!editor.gridEditor){
39801
editor.gridEditor = new Ext.grid.GridEditor(editor);
39803
return editor.gridEditor;
39804
}else if(editor.startEdit){
39813
Ext.grid.BooleanColumn = Ext.extend(Ext.grid.Column, {
39817
falseText: 'false',
39819
undefinedText: ' ',
39821
constructor: function(cfg){
39822
this.supr().constructor.apply(this, arguments);
39823
var t = this.trueText, f = this.falseText, u = this.undefinedText;
39824
this.renderer = function(v){
39825
if(v === undefined){
39828
if(!v || v === 'false'){
39837
Ext.grid.NumberColumn = Ext.extend(Ext.grid.Column, {
39839
format : '0,000.00',
39840
constructor: function(cfg){
39841
this.supr().constructor.apply(this, arguments);
39842
this.renderer = Ext.util.Format.numberRenderer(this.format);
39847
Ext.grid.DateColumn = Ext.extend(Ext.grid.Column, {
39850
constructor: function(cfg){
39851
this.supr().constructor.apply(this, arguments);
39852
this.renderer = Ext.util.Format.dateRenderer(this.format);
39857
Ext.grid.TemplateColumn = Ext.extend(Ext.grid.Column, {
39859
constructor: function(cfg){
39860
this.supr().constructor.apply(this, arguments);
39861
var tpl = typeof this.tpl == 'object' ? this.tpl : new Ext.XTemplate(this.tpl);
39862
this.renderer = function(value, p, r){
39863
return tpl.apply(r.data);
39870
Ext.grid.Column.types = {
39871
gridcolumn : Ext.grid.Column,
39872
booleancolumn: Ext.grid.BooleanColumn,
39873
numbercolumn: Ext.grid.NumberColumn,
39874
datecolumn: Ext.grid.DateColumn,
39875
templatecolumn: Ext.grid.TemplateColumn
39878
Ext.grid.RowNumberer = function(config){
39879
Ext.apply(this, config);
39881
this.renderer = this.renderer.createDelegate(this);
39885
Ext.grid.RowNumberer.prototype = {
39898
rowspan: undefined,
39901
renderer : function(v, p, record, rowIndex){
39903
p.cellAttr = 'rowspan="'+this.rowspan+'"';
39909
Ext.grid.CheckboxSelectionModel = Ext.extend(Ext.grid.RowSelectionModel, {
39913
header: '<div class="x-grid3-hd-checker"> </div>',
39925
constructor: function(){
39926
Ext.grid.CheckboxSelectionModel.superclass.constructor.apply(this, arguments);
39928
if(this.checkOnly){
39929
this.handleMouseDown = Ext.emptyFn;
39934
initEvents : function(){
39935
Ext.grid.CheckboxSelectionModel.superclass.initEvents.call(this);
39936
this.grid.on('render', function(){
39937
var view = this.grid.getView();
39938
view.mainBody.on('mousedown', this.onMouseDown, this);
39939
Ext.fly(view.innerHd).on('mousedown', this.onHdMouseDown, this);
39945
onMouseDown : function(e, t){
39946
if(e.button === 0 && t.className == 'x-grid3-row-checker'){ // Only fire if left-click
39948
var row = e.getTarget('.x-grid3-row');
39950
var index = row.rowIndex;
39951
if(this.isSelected(index)){
39952
this.deselectRow(index);
39954
this.selectRow(index, true);
39961
onHdMouseDown : function(e, t){
39962
if(t.className == 'x-grid3-hd-checker'){
39964
var hd = Ext.fly(t.parentNode);
39965
var isChecked = hd.hasClass('x-grid3-hd-checker-on');
39967
hd.removeClass('x-grid3-hd-checker-on');
39968
this.clearSelections();
39970
hd.addClass('x-grid3-hd-checker-on');
39977
renderer : function(v, p, record){
39978
return '<div class="x-grid3-row-checker"> </div>';
39982
Ext.LoadMask = function(el, config){
39983
this.el = Ext.get(el);
39984
Ext.apply(this, config);
39986
this.store.on('beforeload', this.onBeforeLoad, this);
39987
this.store.on('load', this.onLoad, this);
39988
this.store.on('loadexception', this.onLoad, this);
39989
this.store.on('exception', this.onLoad, this);
39990
this.removeMask = Ext.value(this.removeMask, false);
39992
var um = this.el.getUpdater();
39993
um.showLoadIndicator = false; // disable the default indicator
39994
um.on('beforeupdate', this.onBeforeLoad, this);
39995
um.on('update', this.onLoad, this);
39996
um.on('failure', this.onLoad, this);
39997
this.removeMask = Ext.value(this.removeMask, true);
40001
Ext.LoadMask.prototype = {
40005
msg : 'Loading...',
40007
msgCls : 'x-mask-loading',
40013
disable : function(){
40014
this.disabled = true;
40018
enable : function(){
40019
this.disabled = false;
40023
onLoad : function(){
40024
this.el.unmask(this.removeMask);
40028
onBeforeLoad : function(){
40029
if(!this.disabled){
40030
this.el.mask(this.msg, this.msgCls);
40036
this.onBeforeLoad();
40045
destroy : function(){
40047
this.store.un('beforeload', this.onBeforeLoad, this);
40048
this.store.un('load', this.onLoad, this);
40049
this.store.un('loadexception', this.onLoad, this);
40050
this.store.un('exception', this.onLoad, this);
40052
var um = this.el.getUpdater();
40053
um.un('beforeupdate', this.onBeforeLoad, this);
40054
um.un('update', this.onLoad, this);
40055
um.un('failure', this.onLoad, this);
40060
Ext.ProgressBar = Ext.extend(Ext.BoxComponent, {
40062
baseCls : 'x-progress',
40071
initComponent : function(){
40072
Ext.ProgressBar.superclass.initComponent.call(this);
40080
onRender : function(ct, position){
40081
var tpl = new Ext.Template(
40082
'<div class="{cls}-wrap">',
40083
'<div class="{cls}-inner">',
40084
'<div class="{cls}-bar">',
40085
'<div class="{cls}-text">',
40086
'<div> </div>',
40089
'<div class="{cls}-text {cls}-text-back">',
40090
'<div> </div>',
40097
? tpl.insertBefore(position, {cls: this.baseCls}, true)
40098
: tpl.append(ct, {cls: this.baseCls}, true);
40101
this.el.dom.id = this.id;
40103
var inner = this.el.dom.firstChild;
40104
this.progressBar = Ext.get(inner.firstChild);
40107
//use an external text el
40108
this.textEl = Ext.get(this.textEl);
40109
delete this.textTopEl;
40111
//setup our internal layered text els
40112
this.textTopEl = Ext.get(this.progressBar.dom.firstChild);
40113
var textBackEl = Ext.get(inner.childNodes[1]);
40114
this.textTopEl.setStyle("z-index", 99).addClass('x-hidden');
40115
this.textEl = new Ext.CompositeElement([this.textTopEl.dom.firstChild, textBackEl.dom.firstChild]);
40116
this.textEl.setWidth(inner.offsetWidth);
40118
this.progressBar.setHeight(inner.offsetHeight);
40122
afterRender : function(){
40123
Ext.ProgressBar.superclass.afterRender.call(this);
40125
this.updateProgress(this.value, this.text);
40127
this.updateText(this.text);
40132
updateProgress : function(value, text, animate){
40133
this.value = value || 0;
40135
this.updateText(text);
40138
var w = Math.floor(value*this.el.dom.firstChild.offsetWidth);
40139
this.progressBar.setWidth(w, animate === true || (animate !== false && this.animate));
40140
if(this.textTopEl){
40141
//textTopEl should be the same width as the bar so overflow will clip as the bar moves
40142
this.textTopEl.removeClass('x-hidden').setWidth(w);
40145
this.fireEvent('update', this, value, text);
40150
wait : function(o){
40151
if(!this.waitTimer){
40154
this.updateText(o.text);
40155
this.waitTimer = Ext.TaskMgr.start({
40157
var inc = o.increment || 10;
40158
this.updateProgress(((((i+inc)%inc)+1)*(100/inc))*.01, null, o.animate);
40160
interval: o.interval || 1000,
40161
duration: o.duration,
40162
onStop: function(){
40164
o.fn.apply(o.scope || this);
40175
isWaiting : function(){
40176
return this.waitTimer != null;
40180
updateText : function(text){
40181
this.text = text || ' ';
40183
this.textEl.update(this.text);
40189
syncProgressBar : function(){
40191
this.updateProgress(this.value, this.text);
40197
setSize : function(w, h){
40198
Ext.ProgressBar.superclass.setSize.call(this, w, h);
40199
if(this.textTopEl){
40200
var inner = this.el.dom.firstChild;
40201
this.textEl.setSize(inner.offsetWidth, inner.offsetHeight);
40203
this.syncProgressBar();
40208
reset : function(hide){
40209
this.updateProgress(0);
40210
if(this.textTopEl){
40211
this.textTopEl.addClass('x-hidden');
40213
if(this.waitTimer){
40214
this.waitTimer.onStop = null; //prevent recursion
40215
Ext.TaskMgr.stop(this.waitTimer);
40216
this.waitTimer = null;
40224
Ext.reg('progress', Ext.ProgressBar);
40231
function createConsole(){
40233
var scriptPanel = new Ext.debug.ScriptsPanel();
40234
var logView = new Ext.debug.LogPanel();
40235
var tree = new Ext.debug.DomTree();
40236
var compInspector = new Ext.debug.ComponentInspector();
40237
var compInfoPanel = new Ext.debug.ComponentInfoPanel();
40238
var storeInspector = new Ext.debug.StoreInspector();
40239
var objInspector = new Ext.debug.ObjectInspector();
40241
var tabs = new Ext.TabPanel({
40244
tabPosition: 'bottom',
40246
title: 'Debug Console',
40248
items: [logView, scriptPanel]
40250
title: 'HTML Inspector',
40254
title: 'Component Inspector',
40256
items: [compInspector,compInfoPanel]
40258
title: 'Object Inspector',
40260
items: [objInspector]
40262
title: 'Data Stores',
40264
items: [storeInspector]
40268
cp = new Ext.Panel({
40269
id: 'x-debug-browser',
40272
animCollapse: false,
40273
style: 'position:absolute;left:0;bottom:0;z-index:101',
40280
handler: function(){
40283
Ext.EventManager.removeResizeListener(handleResize);
40290
cp.render(Ext.getBody());
40292
cp.resizer = new Ext.Resizable(cp.el, {
40297
resizeElement : function(){
40298
var box = this.proxy.getBox();
40300
cp.setHeight(box.height);
40305
// function handleResize(){
40306
// cp.setWidth(Ext.getBody().getViewSize().width);
40308
// Ext.EventManager.onWindowResize(handleResize);
40312
function handleResize(){
40313
var b = Ext.getBody()
40314
var size = b.getViewSize();
40315
if(size.height < b.dom.scrollHeight) {
40318
cp.setWidth(size.width);
40320
Ext.EventManager.onWindowResize(handleResize);
40330
cp.logView.log.apply(cp.logView, arguments);
40333
logf : function(format, arg1, arg2, etc){
40334
Ext.log(String.format.apply(String, arguments));
40337
dump : function(o){
40338
if(typeof o == 'string' || typeof o == 'number' || typeof o == 'undefined' || Ext.isDate(o)){
40342
}else if(typeof o != "object"){
40343
Ext.log('Unknown return type');
40344
}else if(Ext.isArray(o)){
40345
Ext.log('['+o.join(',')+']');
40349
var to = typeof o[key];
40350
if(to != "function" && to != "object"){
40351
b.push(String.format(" {0}: {1},\n", key, o[key]));
40354
var s = b.join("");
40356
s = s.substr(0, s.length-2);
40358
Ext.log(s + "\n}");
40364
time : function(name){
40365
name = name || "def";
40366
Ext._timers[name] = new Date().getTime();
40369
timeEnd : function(name, printResults){
40370
var t = new Date().getTime();
40371
name = name || "def";
40372
var v = String.format("{0} ms", t-Ext._timers[name]);
40373
Ext._timers[name] = new Date().getTime();
40374
if(printResults !== false){
40375
Ext.log('Timer ' + (name == "def" ? v : name + ": " + v));
40384
Ext.debug.ScriptsPanel = Ext.extend(Ext.Panel, {
40385
id:'x-debug-scripts',
40392
style:'border-width:0 0 0 1px;',
40394
initComponent : function(){
40396
this.scriptField = new Ext.form.TextArea({
40397
anchor: '100% -26',
40398
style:'border-width:0;'
40401
this.trapBox = new Ext.form.Checkbox({
40402
id: 'console-trap',
40403
boxLabel: 'Trap Errors',
40407
this.toolbar = new Ext.Toolbar([{
40410
handler: this.evalScript
40414
handler: this.clear
40421
this.items = [this.toolbar, this.scriptField];
40423
Ext.debug.ScriptsPanel.superclass.initComponent.call(this);
40426
evalScript : function(){
40427
var s = this.scriptField.getValue();
40428
if(this.trapBox.getValue()){
40431
Ext.dump(rt === undefined? '(no return)' : rt);
40433
Ext.log(e.message || e.descript);
40437
Ext.dump(rt === undefined? '(no return)' : rt);
40441
clear : function(){
40442
this.scriptField.setValue('');
40443
this.scriptField.focus();
40448
Ext.debug.LogPanel = Ext.extend(Ext.Panel, {
40452
style:'border-width:0 1px 0 0',
40455
var markup = [ '<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
40456
Ext.util.Format.htmlEncode(Array.prototype.join.call(arguments, ', ')).replace(/\n/g, '<br />').replace(/\s/g, ' '),
40457
'</div>'].join('');
40459
this.body.insertHtml('beforeend', markup);
40460
this.body.scrollTo('top', 100000);
40463
clear : function(){
40464
this.body.update('');
40465
this.body.dom.scrollTop = 0;
40469
Ext.debug.DomTree = Ext.extend(Ext.tree.TreePanel, {
40479
initComponent : function(){
40482
Ext.debug.DomTree.superclass.initComponent.call(this);
40484
// tree related stuff
40485
var styles = false, hnode;
40486
var nonSpace = /^\s*$/;
40487
var html = Ext.util.Format.htmlEncode;
40488
var ellipsis = Ext.util.Format.ellipsis;
40489
var styleRe = /\s?([a-z\-]*)\:([^;]*)(?:[;\s\n\r]*)/gi;
40491
function findNode(n){
40492
if(!n || n.nodeType != 1 || n == document.body || n == document){
40495
var pn = [n], p = n;
40496
while((p = p.parentNode) && p.nodeType == 1 && p.tagName.toUpperCase() != 'HTML'){
40500
for(var i = 0, len = pn.length; i < len; i++){
40502
cn = cn.findChild('htmlNode', pn[i]);
40503
if(!cn){ // in this dialog?
40508
var a = cn.ui.anchor;
40509
treeEl.dom.scrollTop = Math.max(0 ,a.offsetTop-10);
40510
//treeEl.dom.scrollLeft = Math.max(0 ,a.offsetLeft-10); no likey
40515
function nodeTitle(n){
40519
}else if(n.className){
40520
s += '.'+n.className;
40527
this.loader = new Ext.tree.TreeLoader();
40528
this.loader.load = function(n, cb){
40529
var isBody = n.htmlNode == document.body;
40530
var cn = n.htmlNode.childNodes;
40531
for(var i = 0, c; c = cn[i]; i++){
40532
if(isBody && c.id == 'x-debug-browser'){
40535
if(c.nodeType == 1){
40536
n.appendChild(new Ext.debug.HtmlNode(c));
40537
}else if(c.nodeType == 3 && !nonSpace.test(c.nodeValue)){
40538
n.appendChild(new Ext.tree.TreeNode({
40539
text:'<em>' + ellipsis(html(String(c.nodeValue)), 35) + '</em>',
40540
cls: 'x-tree-noicon'
40547
//tree.getSelectionModel().on('selectionchange', onNodeSelect, null, {buffer:250});
40549
this.root = this.setRootNode(new Ext.tree.TreeNode('Ext'));
40551
hnode = this.root.appendChild(new Ext.debug.HtmlNode(
40552
document.getElementsByTagName('html')[0]
40558
Ext.debug.ComponentNodeUI = Ext.extend(Ext.tree.TreeNodeUI,{
40559
onOver : function(e){
40560
Ext.debug.ComponentNodeUI.superclass.onOver.call(this);
40561
var cmp = this.node.attributes.component;
40562
if (cmp.el && cmp.el.mask && cmp.id !='x-debug-browser') {
40563
try { // Oddly bombs on some elements in IE, gets any we care about though
40569
onOut : function(e){
40570
Ext.debug.ComponentNodeUI.superclass.onOut.call(this);
40571
var cmp = this.node.attributes.component;
40572
if (cmp.el && cmp.el.unmask && cmp.id !='x-debug-browser') {
40580
Ext.debug.ComponentInspector = Ext.extend(Ext.tree.TreePanel, {
40590
initComponent : function(){
40591
this.loader = new Ext.tree.TreeLoader();
40592
this.bbar = new Ext.Toolbar([{
40594
handler: this.refresh,
40597
Ext.debug.ComponentInspector.superclass.initComponent.call(this);
40599
this.root = this.setRootNode(new Ext.tree.TreeNode({
40600
text: 'Ext Components',
40601
component: Ext.ComponentMgr.all,
40604
this.parseRootNode();
40606
this.on('click', this.onClick, this);
40609
createNode: function(n,c) {
40610
var leaf = (c.items && c.items.length > 0);
40611
return n.appendChild(new Ext.tree.TreeNode({
40612
text: c.id + (c.getXType() ? ' [ ' + c.getXType() + ' ]': '' ),
40614
uiProvider:Ext.debug.ComponentNodeUI,
40619
parseChildItems: function(n) {
40620
var cn = n.attributes.component.items;
40622
for (var i = 0;i < cn.length; i++) {
40624
if (c.id != this.id && c.id != this.bottomToolbar.id) {
40625
var newNode = this.createNode(n,c);
40626
if (!newNode.leaf) {
40627
this.parseChildItems(newNode)
40634
parseRootNode: function() {
40636
var cn = n.attributes.component.items;
40637
for (var i = 0,c;c = cn[i];i++) {
40638
if (c.id != this.id && c.id != this.bottomToolbar.id) {
40640
var newNode = this.createNode(n,c);
40641
if (!newNode.leaf) {
40642
this.parseChildItems(newNode);
40649
onClick: function(node, e) {
40650
var oi = Ext.getCmp('x-debug-objinspector');
40651
oi.refreshNodes(node.attributes.component);
40655
refresh: function() {
40656
while (this.root.firstChild) {
40657
this.root.removeChild(this.root.firstChild);
40659
this.parseRootNode();
40660
var ci = Ext.getCmp('x-debug-compinfo');
40662
ci.message('refreshed component tree - '+Ext.ComponentMgr.all.length)
40667
Ext.debug.ComponentInfoPanel = Ext.extend(Ext.Panel,{
40668
id:'x-debug-compinfo',
40676
style:'border-width:0 0 0 1px;',
40678
initComponent: function() {
40679
this.watchBox = new Ext.form.Checkbox({
40680
id: 'x-debug-watchcomp',
40681
boxLabel: 'Watch ComponentMgr',
40683
check: function(cb, val) {
40685
Ext.ComponentMgr.all.on('add', this.onAdd, this);
40686
Ext.ComponentMgr.all.on('remove', this.onRemove, this);
40688
Ext.ComponentMgr.all.un('add', this.onAdd, this);
40689
Ext.ComponentMgr.all.un('remove', this.onRemove, this);
40696
this.tbar = new Ext.Toolbar([{
40698
handler: this.clear,
40700
},'->',this.watchBox
40702
Ext.debug.ComponentInfoPanel.superclass.initComponent.call(this);
40705
onAdd: function(i, o, key) {
40706
var markup = ['<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
40708
'</div>'].join('');
40709
this.insertMarkup(markup);
40712
onRemove: function(o, key) {
40713
var markup = ['<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
40715
'</div>'].join('');
40716
this.insertMarkup(markup);
40719
message: function(msg) {
40720
var markup = ['<div style="padding:5px !important;border-bottom:1px solid #ccc;">',
40722
'</div>'].join('');
40723
this.insertMarkup(markup);
40725
insertMarkup: function(markup) {
40726
this.body.insertHtml('beforeend', markup);
40727
this.body.scrollTo('top', 100000);
40729
clear : function(){
40730
this.body.update('');
40731
this.body.dom.scrollTop = 0;
40735
Ext.debug.ColumnNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
40736
focus: Ext.emptyFn, // prevent odd scrolling behavior
40738
renderElements : function(n, a, targetNode, bulkRender){
40739
this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
40741
var t = n.getOwnerTree();
40742
var cols = t.columns;
40743
var bw = t.borderWidth;
40747
'<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf ', a.cls,'">',
40748
'<div class="x-tree-col" style="width:',c.width-bw,'px;">',
40749
'<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
40750
'<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow">',
40751
'<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on">',
40752
'<a hidefocus="on" class="x-tree-node-anchor" href="',a.href ? a.href : "#",'" tabIndex="1" ',
40753
a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '>',
40754
'<span unselectable="on">', n.text || (c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]),"</span></a>",
40756
for(var i = 1, len = cols.length; i < len; i++){
40759
buf.push('<div class="x-tree-col ',(c.cls?c.cls:''),'" style="width:',c.width-bw,'px;">',
40760
'<div class="x-tree-col-text">',(c.renderer ? c.renderer(a[c.dataIndex], n, a) : a[c.dataIndex]),"</div>",
40764
'<div class="x-clear"></div></div>',
40765
'<ul class="x-tree-node-ct" style="display:none;"></ul>',
40768
if(bulkRender !== true && n.nextSibling && n.nextSibling.ui.getEl()){
40769
this.wrap = Ext.DomHelper.insertHtml("beforeBegin",
40770
n.nextSibling.ui.getEl(), buf.join(""));
40772
this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf.join(""));
40775
this.elNode = this.wrap.childNodes[0];
40776
this.ctNode = this.wrap.childNodes[1];
40777
var cs = this.elNode.firstChild.childNodes;
40778
this.indentNode = cs[0];
40779
this.ecNode = cs[1];
40780
this.iconNode = cs[2];
40781
this.anchor = cs[3];
40782
this.textNode = cs[3].firstChild;
40786
Ext.debug.ObjectInspector = Ext.extend(Ext.tree.TreePanel, {
40787
id: 'x-debug-objinspector',
40797
borderWidth: Ext.isBorderBox ? 0 : 2, // the combined left/right border for each cell
40798
cls:'x-column-tree',
40800
initComponent : function(){
40801
this.showFunc = false;
40802
this.toggleFunc = function() {
40803
this.showFunc = !this.showFunc;
40804
this.refreshNodes(this.currentObject);
40806
this.bbar = new Ext.Toolbar([{
40807
text: 'Show Functions',
40808
enableToggle: true,
40810
handler: this.toggleFunc,
40816
loader: new Ext.tree.TreeLoader(),
40828
Ext.debug.ObjectInspector.superclass.initComponent.call(this);
40830
this.root = this.setRootNode(new Ext.tree.TreeNode({
40831
text: 'Dummy Node',
40835
if (this.currentObject) {
40840
refreshNodes: function(newObj) {
40841
this.currentObject = newObj;
40842
var node = this.root;
40843
while(node.firstChild){
40844
node.removeChild(node.firstChild);
40849
parseNodes: function() {
40850
for (var o in this.currentObject) {
40851
if (!this.showFunc) {
40852
if (Ext.isFunction(this.currentObject[o])) {
40856
this.createNode(o);
40860
createNode: function(o) {
40861
return this.root.appendChild(new Ext.tree.TreeNode({
40863
value: this.currentObject[o],
40864
uiProvider:Ext.debug.ColumnNodeUI,
40865
iconCls: 'x-debug-node',
40870
onRender : function(){
40871
Ext.debug.ObjectInspector.superclass.onRender.apply(this, arguments);
40872
this.headers = this.header.createChild({cls:'x-tree-headers'});
40874
var cols = this.columns, c;
40875
var totalWidth = 0;
40877
for(var i = 0, len = cols.length; i < len; i++){
40879
totalWidth += c.width;
40880
this.headers.createChild({
40881
cls:'x-tree-hd ' + (c.cls?c.cls+'-hd':''),
40883
cls:'x-tree-hd-text',
40886
style:'width:'+(c.width-this.borderWidth)+'px;'
40889
this.headers.createChild({cls:'x-clear'});
40890
// prevent floats from wrapping when clipped
40891
this.headers.setWidth(totalWidth);
40892
this.innerCt.setWidth(totalWidth);
40897
Ext.debug.StoreInspector = Ext.extend(Ext.tree.TreePanel, {
40907
initComponent: function() {
40908
this.bbar = new Ext.Toolbar([{
40910
handler: this.refresh,
40913
Ext.debug.StoreInspector.superclass.initComponent.call(this);
40915
this.root = this.setRootNode(new Ext.tree.TreeNode({
40916
text: 'Data Stores',
40919
this.on('click', this.onClick, this);
40921
this.parseStores();
40924
parseStores: function() {
40925
var cn = Ext.StoreMgr.items;
40926
for (var i = 0,c;c = cn[i];i++) {
40927
this.root.appendChild({
40928
text: c.storeId + ' - ' + c.totalLength + ' records',
40935
onClick: function(node, e) {
40936
var oi = Ext.getCmp('x-debug-objinspector');
40937
oi.refreshNodes(node.attributes.component);
40941
refresh: function() {
40942
while (this.root.firstChild) {
40943
this.root.removeChild(this.root.firstChild);
40945
this.parseStores();
40949
// highly unusual class declaration
40950
Ext.debug.HtmlNode = function(){
40951
var html = Ext.util.Format.htmlEncode;
40952
var ellipsis = Ext.util.Format.ellipsis;
40953
var nonSpace = /^\s*$/;
40956
{n: 'id', v: 'id'},
40957
{n: 'className', v: 'class'},
40958
{n: 'name', v: 'name'},
40959
{n: 'type', v: 'type'},
40960
{n: 'src', v: 'src'},
40961
{n: 'href', v: 'href'}
40964
function hasChild(n){
40965
for(var i = 0, c; c = n.childNodes[i]; i++){
40966
if(c.nodeType == 1){
40973
function renderNode(n, leaf){
40974
var tag = n.tagName.toLowerCase();
40975
var s = '<' + tag;
40976
for(var i = 0, len = attrs.length; i < len; i++){
40979
if(v && !nonSpace.test(v)){
40980
s += ' ' + a.v + '="<i>' + html(v) +'</i>"';
40983
var style = n.style ? n.style.cssText : '';
40985
s += ' style="<i>' + html(style.toLowerCase()) +'</i>"';
40987
if(leaf && n.childNodes.length > 0){
40988
s+='><em>' + ellipsis(html(String(n.innerHTML)), 35) + '</em></'+tag+'>';
40997
var HtmlNode = function(n){
40998
var leaf = !hasChild(n);
41000
this.tagName = n.tagName.toLowerCase();
41002
text : renderNode(n, leaf),
41004
cls: 'x-tree-noicon'
41006
HtmlNode.superclass.constructor.call(this, attr);
41007
this.attributes.htmlNode = n; // for searching
41009
this.on('expand', this.onExpand, this);
41010
this.on('collapse', this.onCollapse, this);
41015
Ext.extend(HtmlNode, Ext.tree.AsyncTreeNode, {
41016
cls: 'x-tree-noicon',
41017
preventHScroll: true,
41018
refresh : function(highlight){
41019
var leaf = !hasChild(this.htmlNode);
41020
this.setText(renderNode(this.htmlNode, leaf));
41022
Ext.fly(this.ui.textNode).highlight();
41026
onExpand : function(){
41027
if(!this.closeNode && this.parentNode){
41028
this.closeNode = this.parentNode.insertBefore(new Ext.tree.TreeNode({
41029
text:'</' + this.tagName + '>',
41030
cls: 'x-tree-noicon'
41031
}), this.nextSibling);
41032
}else if(this.closeNode){
41033
this.closeNode.ui.show();
41037
onCollapse : function(){
41038
if(this.closeNode){
41039
this.closeNode.ui.hide();
41043
render : function(bulkRender){
41044
HtmlNode.superclass.render.call(this, bulkRender);
41047
highlightNode : function(){
41048
//Ext.fly(this.htmlNode).highlight();
41051
highlight : function(){
41052
//Ext.fly(this.ui.textNode).highlight();
41055
frame : function(){
41056
this.htmlNode.style.border = '1px solid #0000ff';
41057
//this.highlightNode();
41060
unframe : function(){
41061
//Ext.fly(this.htmlNode).removeClass('x-debug-frame');
41062
this.htmlNode.style.border = '';
41069
var deconcept = deconcept || {};
41071
if(typeof deconcept.util == "undefined" || !deconcept.util){
41072
deconcept.util = {};
41075
if(typeof deconcept.SWFObjectUtil == "undefined" || !deconcept.SWFObjectUtil){
41076
deconcept.SWFObjectUtil = {};
41079
deconcept.SWFObject = function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey){
41080
if(!document.getElementById){
41083
this.DETECT_KEY = detectKey ? detectKey : 'detectflash';
41084
this.skipDetect = deconcept.util.getRequestParameter(this.DETECT_KEY);
41086
this.variables = {};
41087
this.attributes = [];
41089
this.setAttribute('swf', swf);
41092
this.setAttribute('id', id);
41095
this.setAttribute('width', w);
41098
this.setAttribute('height', h);
41101
this.setAttribute('version', new deconcept.PlayerVersion(ver.toString().split(".")));
41103
this.installedVer = deconcept.SWFObjectUtil.getPlayerVersion();
41104
if(!window.opera && document.all && this.installedVer.major > 7){
41105
// only add the onunload cleanup if the Flash Player version supports External Interface and we are in IE
41106
deconcept.SWFObject.doPrepUnload = true;
41109
this.addParam('bgcolor', c);
41111
var q = quality ? quality : 'high';
41112
this.addParam('quality', q);
41113
this.setAttribute('useExpressInstall', false);
41114
this.setAttribute('doExpressInstall', false);
41115
var xir = (xiRedirectUrl) ? xiRedirectUrl : window.location;
41116
this.setAttribute('xiRedirectUrl', xir);
41117
this.setAttribute('redirectUrl', '');
41119
this.setAttribute('redirectUrl', redirectUrl);
41123
deconcept.SWFObject.prototype = {
41124
useExpressInstall: function(path){
41125
this.xiSWFPath = !path ? "expressinstall.swf" : path;
41126
this.setAttribute('useExpressInstall', true);
41128
setAttribute: function(name, value){
41129
this.attributes[name] = value;
41131
getAttribute: function(name){
41132
return this.attributes[name];
41134
addParam: function(name, value){
41135
this.params[name] = value;
41137
getParams: function(){
41138
return this.params;
41140
addVariable: function(name, value){
41141
this.variables[name] = value;
41143
getVariable: function(name){
41144
return this.variables[name];
41146
getVariables: function(){
41147
return this.variables;
41149
getVariablePairs: function(){
41150
var variablePairs = [];
41152
var variables = this.getVariables();
41153
for(key in variables){
41154
variablePairs[variablePairs.length] = key + "=" + variables[key];
41156
return variablePairs;
41158
getSWFHTML: function(){
41163
if(navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length){ // netscape plugin architecture
41164
if(this.getAttribute("doExpressInstall")){
41165
this.addVariable("MMplayerType", "PlugIn");
41166
this.setAttribute('swf', this.xiSWFPath);
41168
swfNode = '<embed type="application/x-shockwave-flash" src="' + this.getAttribute('swf') + '" width="' + this.getAttribute('width') + '" height="' + this.getAttribute('height') + '" style="' + this.getAttribute('style') + '"';
41169
swfNode += ' id="' + this.getAttribute('id') + '" name="' + this.getAttribute('id') + '" ';
41170
params = this.getParams();
41171
for(key in params){
41172
swfNode += [key] + '="' + params[key] + '" ';
41174
pairs = this.getVariablePairs().join("&");
41175
if(pairs.length > 0){
41176
swfNode += 'flashvars="' + pairs + '"';
41180
if(this.getAttribute("doExpressInstall")){
41181
this.addVariable("MMplayerType", "ActiveX");
41182
this.setAttribute('swf', this.xiSWFPath);
41184
swfNode = '<object id="' + this.getAttribute('id') + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="' + this.getAttribute('width') + '" height="' + this.getAttribute('height') + '" style="' + this.getAttribute('style') + '">';
41185
swfNode += '<param name="movie" value="' + this.getAttribute('swf') + '" />';
41186
params = this.getParams();
41187
for(key in params){
41188
swfNode += '<param name="' + key + '" value="' + params[key] + '" />';
41190
pairs = this.getVariablePairs().join("&");
41191
if(pairs.length > 0){
41192
swfNode += '<param name="flashvars" value="' + pairs + '" />';
41194
swfNode += "</object>";
41198
write: function(elementId){
41199
if(this.getAttribute('useExpressInstall')){
41200
// check to see if we need to do an express install
41201
var expressInstallReqVer = new deconcept.PlayerVersion([6,0,65]);
41202
if(this.installedVer.versionIsValid(expressInstallReqVer) && !this.installedVer.versionIsValid(this.getAttribute('version'))){
41203
this.setAttribute('doExpressInstall', true);
41204
this.addVariable("MMredirectURL", escape(this.getAttribute('xiRedirectUrl')));
41205
document.title = document.title.slice(0, 47) + " - Flash Player Installation";
41206
this.addVariable("MMdoctitle", document.title);
41209
if(this.skipDetect || this.getAttribute('doExpressInstall') || this.installedVer.versionIsValid(this.getAttribute('version'))){
41210
var n = (typeof elementId == 'string') ? document.getElementById(elementId) : elementId;
41211
n.innerHTML = this.getSWFHTML();
41214
if(this.getAttribute('redirectUrl') !== ""){
41215
document.location.replace(this.getAttribute('redirectUrl'));
41223
deconcept.SWFObjectUtil.getPlayerVersion = function(){
41225
var PlayerVersion = new deconcept.PlayerVersion([0,0,0]);
41226
if(navigator.plugins && navigator.mimeTypes.length){
41227
var x = navigator.plugins["Shockwave Flash"];
41228
if(x && x.description){
41229
PlayerVersion = new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split("."));
41231
} else if(navigator.userAgent && navigator.userAgent.indexOf("Windows CE") >= 0){ // if Windows CE
41236
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash." + counter);
41237
// document.write("player v: "+ counter);
41238
PlayerVersion = new deconcept.PlayerVersion([counter,0,0]);
41243
} else{ // Win IE (non mobile)
41244
// do minor version lookup in IE, but avoid fp6 crashing issues
41245
// see http://blog.deconcept.com/2006/01/11/getvariable-setvariable-crash-internet-explorer-flash-6/
41247
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
41250
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
41251
PlayerVersion = new deconcept.PlayerVersion([6,0,21]);
41252
axo.AllowScriptAccess = "always"; // error if player version < 6.0.47 (thanks to Michael Williams @ Adobe for this code)
41254
if(PlayerVersion.major == 6){
41255
return PlayerVersion;
41259
axo = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
41265
PlayerVersion = new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));
41268
return PlayerVersion;
41271
deconcept.PlayerVersion = function(arrVersion){
41272
this.major = arrVersion[0] !== null ? parseInt(arrVersion[0], 0) : 0;
41273
this.minor = arrVersion[1] !== null ? parseInt(arrVersion[1], 0) : 0;
41274
this.rev = arrVersion[2] !== null ? parseInt(arrVersion[2], 0) : 0;
41277
deconcept.PlayerVersion.prototype.versionIsValid = function(fv){
41278
if(this.major < fv.major){
41281
if(this.major > fv.major){
41284
if(this.minor < fv.minor){
41287
if(this.minor > fv.minor){
41290
if(this.rev < fv.rev){
41298
getRequestParameter: function(param){
41299
var q = document.location.search || document.location.hash;
41300
if(param === null){
41304
var pairs = q.substring(1).split("&");
41305
for(var i = 0; i < pairs.length; i++){
41306
if(pairs[i].substring(0, pairs[i].indexOf("=")) == param){
41307
return pairs[i].substring((pairs[i].indexOf("=") + 1));
41316
deconcept.SWFObjectUtil.cleanupSWFs = function(){
41317
var objects = document.getElementsByTagName("OBJECT");
41318
for(var i = objects.length - 1; i >= 0; i--){
41319
objects[i].style.display = 'none';
41320
for(var x in objects[i]){
41321
if(typeof objects[i][x] == 'function'){
41322
objects[i][x] = function(){
41329
// fixes bug in some fp9 versions see http://blog.deconcept.com/2006/07/28/swfobject-143-released/
41330
if(deconcept.SWFObject.doPrepUnload){
41331
if(!deconcept.unloadSet){
41332
deconcept.SWFObjectUtil.prepUnload = function(){
41333
__flash_unloadHandler = function(){
41335
__flash_savedUnloadHandler = function(){
41337
window.attachEvent("onunload", deconcept.SWFObjectUtil.cleanupSWFs);
41339
window.attachEvent("onbeforeunload", deconcept.SWFObjectUtil.prepUnload);
41340
deconcept.unloadSet = true;
41344
Ext.FlashComponent = Ext.extend(Ext.BoxComponent, {
41345
flashVersion : '9.0.45',
41346
backgroundColor: '#ffffff',
41352
expressInstall: false,
41354
initComponent : function(){
41355
Ext.FlashComponent.superclass.initComponent.call(this);
41357
this.addEvents('initialize');
41360
onRender : function(){
41361
Ext.FlashComponent.superclass.onRender.apply(this, arguments);
41363
var swfId = this.getSwfId();
41364
var swf = new deconcept.SWFObject(this.url, swfId, this.swfWidth, this.swfHeight, this.flashVersion, this.backgroundColor);
41365
if(this.expressInstall){
41366
swf.useExpressInstall(this.expressInstall);
41370
swf.addParam("allowScriptAccess", "always");
41371
if(this.wmode !== undefined){
41372
swf.addParam("wmode", this.wmode);
41375
swf.addVariable("allowedDomain", document.location.hostname);
41376
swf.addVariable("elementID", this.getId());
41378
// set the name of the function to call when the swf has an event
41379
swf.addVariable("eventHandler", "Ext.FlashEventProxy.onEvent");
41381
var r = swf.write(this.el.dom);
41383
this.swf = Ext.getDom(swfId);
41387
getSwfId : function(){
41388
return this.swfId || (this.swfId = "extswf" + (++Ext.Component.AUTO_ID));
41391
getId : function(){
41392
return this.id || (this.id = "extflashcmp" + (++Ext.Component.AUTO_ID));
41395
onFlashEvent : function(e){
41403
e.component = this;
41404
this.fireEvent(e.type.toLowerCase().replace(/event$/, ''), e);
41407
initSwf : function(){
41408
this.onSwfReady(!!this.isInitialized);
41409
this.isInitialized = true;
41410
this.fireEvent('initialize', this);
41413
beforeDestroy: function(){
41414
if(Ext.isIE && this.rendered){
41415
var el = this.el.child('object');
41418
for (var prop in el){
41419
if(Ext.isFunction(el[prop])){
41420
el[prop] = Ext.emptyFn;
41425
Ext.FlashComponent.superclass.beforeDestroy.call(this);
41428
onSwfReady : Ext.emptyFn
41431
Ext.reg('flash', Ext.FlashComponent);
41433
Ext.FlashEventProxy = {
41434
onEvent : function(id, e){
41435
var fp = Ext.getCmp(id);
41437
fp.onFlashEvent(e);
41439
arguments.callee.defer(10, this, [id, e]);
41444
Ext.Slider = Ext.extend(Ext.BoxComponent, {
41453
decimalPrecision: 0,
41459
clickRange: [5,15],
41461
clickToChange : true,
41468
// private override
41469
initComponent : function(){
41470
if(this.value === undefined){
41471
this.value = this.minValue;
41473
Ext.Slider.superclass.initComponent.call(this);
41474
this.keyIncrement = Math.max(this.increment, this.keyIncrement);
41491
Ext.apply(this, Ext.Slider.Vertical);
41495
// private override
41496
onRender : function(){
41498
cls: 'x-slider ' + (this.vertical ? 'x-slider-vert' : 'x-slider-horz'),
41499
cn:{cls:'x-slider-end',cn:{cls:'x-slider-inner',cn:[{cls:'x-slider-thumb'},{tag:'a', cls:'x-slider-focus', href:"#", tabIndex: '-1', hidefocus:'on'}]}}
41501
Ext.Slider.superclass.onRender.apply(this, arguments);
41502
this.endEl = this.el.first();
41503
this.innerEl = this.endEl.first();
41504
this.thumb = this.innerEl.first();
41505
this.halfThumb = (this.vertical ? this.thumb.getHeight() : this.thumb.getWidth())/2;
41506
this.focusEl = this.thumb.next();
41510
// private override
41511
initEvents : function(){
41512
this.thumb.addClassOnOver('x-slider-thumb-over');
41513
this.mon(this.el, {
41515
mousedown: this.onMouseDown,
41516
keydown: this.onKeyDown
41519
this.focusEl.swallowEvent("click", true);
41521
this.tracker = new Ext.dd.DragTracker({
41522
onBeforeStart: this.onBeforeDragStart.createDelegate(this),
41523
onStart: this.onDragStart.createDelegate(this),
41524
onDrag: this.onDrag.createDelegate(this),
41525
onEnd: this.onDragEnd.createDelegate(this),
41529
this.tracker.initEl(this.thumb);
41530
this.on('beforedestroy', this.tracker.destroy, this.tracker);
41533
// private override
41534
onMouseDown : function(e){
41535
if(this.disabled) {return;}
41536
if(this.clickToChange && e.target != this.thumb.dom){
41537
var local = this.innerEl.translatePoints(e.getXY());
41538
this.onClickChange(local);
41544
onClickChange : function(local){
41545
if(local.top > this.clickRange[0] && local.top < this.clickRange[1]){
41546
this.setValue(Ext.util.Format.round(this.reverseValue(local.left), this.decimalPrecision), undefined, true);
41551
onKeyDown : function(e){
41552
if(this.disabled){e.preventDefault();return;}
41553
var k = e.getKey();
41559
this.setValue(this.maxValue, undefined, true);
41561
this.setValue(this.value+this.keyIncrement, undefined, true);
41568
this.setValue(this.minValue, undefined, true);
41570
this.setValue(this.value-this.keyIncrement, undefined, true);
41574
e.preventDefault();
41579
doSnap : function(value){
41580
if(!this.increment || this.increment == 1 || !value) {
41583
var newValue = value, inc = this.increment;
41584
var m = value % inc;
41589
}else if(m * 2 < -inc){
41593
return newValue.constrain(this.minValue, this.maxValue);
41597
afterRender : function(){
41598
Ext.Slider.superclass.afterRender.apply(this, arguments);
41599
if(this.value !== undefined){
41600
var v = this.normalizeValue(this.value);
41601
if(v !== this.value){
41603
this.setValue(v, false);
41605
this.moveThumb(this.translateValue(v), false);
41611
getRatio : function(){
41612
var w = this.innerEl.getWidth();
41613
var v = this.maxValue - this.minValue;
41614
return v == 0 ? w : (w/v);
41618
normalizeValue : function(v){
41619
v = this.doSnap(v);
41620
v = Ext.util.Format.round(v, this.decimalPrecision);
41621
v = v.constrain(this.minValue, this.maxValue);
41626
setValue : function(v, animate, changeComplete){
41627
v = this.normalizeValue(v);
41628
if(v !== this.value && this.fireEvent('beforechange', this, v, this.value) !== false){
41630
this.moveThumb(this.translateValue(v), animate !== false);
41631
this.fireEvent('change', this, v);
41632
if(changeComplete){
41633
this.fireEvent('changecomplete', this, v);
41639
translateValue : function(v){
41640
var ratio = this.getRatio();
41641
return (v * ratio)-(this.minValue * ratio)-this.halfThumb;
41644
reverseValue : function(pos){
41645
var ratio = this.getRatio();
41646
return (pos+this.halfThumb+(this.minValue * ratio))/ratio;
41650
moveThumb: function(v, animate){
41651
if(!animate || this.animate === false){
41652
this.thumb.setLeft(v);
41654
this.thumb.shift({left: v, stopFx: true, duration:.35});
41659
focus : function(){
41660
this.focusEl.focus(10);
41664
onBeforeDragStart : function(e){
41665
return !this.disabled;
41669
onDragStart: function(e){
41670
this.thumb.addClass('x-slider-thumb-drag');
41671
this.dragging = true;
41672
this.dragStartValue = this.value;
41673
this.fireEvent('dragstart', this, e);
41677
onDrag: function(e){
41678
var pos = this.innerEl.translatePoints(this.tracker.getXY());
41679
this.setValue(Ext.util.Format.round(this.reverseValue(pos.left), this.decimalPrecision), false);
41680
this.fireEvent('drag', this, e);
41684
onDragEnd: function(e){
41685
this.thumb.removeClass('x-slider-thumb-drag');
41686
this.dragging = false;
41687
this.fireEvent('dragend', this, e);
41688
if(this.dragStartValue != this.value){
41689
this.fireEvent('changecomplete', this, this.value);
41694
onResize : function(w, h){
41695
this.innerEl.setWidth(w - (this.el.getPadding('l') + this.endEl.getPadding('r')));
41700
onDisable: function(){
41701
Ext.Slider.superclass.onDisable.call(this);
41702
this.thumb.addClass(this.disabledClass);
41704
//IE breaks when using overflow visible and opacity other than 1.
41705
//Create a place holder for the thumb and display it.
41706
var xy = this.thumb.getXY();
41708
this.innerEl.addClass(this.disabledClass).dom.disabled = true;
41709
if (!this.thumbHolder){
41710
this.thumbHolder = this.endEl.createChild({cls: 'x-slider-thumb ' + this.disabledClass});
41712
this.thumbHolder.show().setXY(xy);
41717
onEnable: function(){
41718
Ext.Slider.superclass.onEnable.call(this);
41719
this.thumb.removeClass(this.disabledClass);
41721
this.innerEl.removeClass(this.disabledClass).dom.disabled = false;
41722
if (this.thumbHolder){
41723
this.thumbHolder.hide();
41731
syncThumb : function(){
41733
this.moveThumb(this.translateValue(this.value));
41738
getValue : function(){
41742
Ext.reg('slider', Ext.Slider);
41744
// private class to support vertical sliders
41745
Ext.Slider.Vertical = {
41746
onResize : function(w, h){
41747
this.innerEl.setHeight(h - (this.el.getPadding('t') + this.endEl.getPadding('b')));
41751
getRatio : function(){
41752
var h = this.innerEl.getHeight();
41753
var v = this.maxValue - this.minValue;
41757
moveThumb: function(v, animate){
41758
if(!animate || this.animate === false){
41759
this.thumb.setBottom(v);
41761
this.thumb.shift({bottom: v, stopFx: true, duration:.35});
41765
onDrag: function(e){
41766
var pos = this.innerEl.translatePoints(this.tracker.getXY());
41767
var bottom = this.innerEl.getHeight()-pos.top;
41768
this.setValue(this.minValue + Ext.util.Format.round(bottom/this.getRatio(), this.decimalPrecision), false);
41769
this.fireEvent('drag', this, e);
41772
onClickChange : function(local){
41773
if(local.left > this.clickRange[0] && local.left < this.clickRange[1]){
41774
var bottom = this.innerEl.getHeight()-local.top;
41775
this.setValue(this.minValue + Ext.util.Format.round(bottom/this.getRatio(), this.decimalPrecision), undefined, true);
41779
Ext.util.Cookies = {
41780
set : function(name, value){
41781
var argv = arguments;
41782
var argc = arguments.length;
41783
var expires = (argc > 2) ? argv[2] : null;
41784
var path = (argc > 3) ? argv[3] : '/';
41785
var domain = (argc > 4) ? argv[4] : null;
41786
var secure = (argc > 5) ? argv[5] : false;
41787
document.cookie = name + "=" + escape(value) + ((expires == null) ? "" : ("; expires=" + expires.toGMTString())) + ((path == null) ? "" : ("; path=" + path)) + ((domain == null) ? "" : ("; domain=" + domain)) + ((secure == true) ? "; secure" : "");
41790
get : function(name){
41791
var arg = name + "=";
41792
var alen = arg.length;
41793
var clen = document.cookie.length;
41798
if(document.cookie.substring(i, j) == arg)
41799
return Ext.util.Cookies.getCookieVal(j);
41800
i = document.cookie.indexOf(" ", i) + 1;
41807
clear : function(name){
41808
if(Ext.util.Cookies.get(name)){
41809
document.cookie = name + "=" + "; expires=Thu, 01-Jan-70 00:00:01 GMT";
41813
getCookieVal : function(offset){
41814
var endstr = document.cookie.indexOf(";", offset);
41816
endstr = document.cookie.length;
41818
return unescape(document.cookie.substring(offset, endstr));
41822
Ext.chart.Chart = Ext.extend(Ext.FlashComponent, {
41823
url: "http:/"+"/yui.yahooapis.com/2.5.1/build/charts/assets/charts.swf",
41824
refreshBuffer: 100,
41828
animationEnabled: true,
41853
initComponent : function(){
41854
Ext.chart.Chart.superclass.initComponent.call(this);
41868
setStyle: function(name, value){
41869
value = Ext.encode(value);
41870
this.swf.setStyle(name, value);
41874
setStyles: function(styles){
41875
styles = Ext.encode(styles);
41876
this.swf.setStyles(styles);
41880
setSeriesStyles: function(styles){
41881
for(var i = 0; i < styles.length; i++){
41882
styles[i] = Ext.encode(styles[i]);
41884
this.swf.setSeriesStyles(styles);
41887
setCategoryNames : function(names){
41888
this.swf.setCategoryNames(names);
41891
setTipRenderer : function(fn){
41893
this.tipFnName = this.createFnProxy(function(item, index, series){
41894
var record = chart.store.getAt(index);
41895
return fn(chart, record, index, series);
41896
}, this.tipFnName);
41897
this.swf.setDataTipFunction(this.tipFnName);
41900
setSeries : function(series){
41901
this.series = series;
41906
bindStore : function(store, initial){
41907
if(!initial && this.store){
41908
this.store.un("datachanged", this.refresh, this);
41909
this.store.un("add", this.delayRefresh, this);
41910
this.store.un("remove", this.delayRefresh, this);
41911
this.store.un("update", this.delayRefresh, this);
41912
this.store.un("clear", this.refresh, this);
41913
if(store !== this.store && this.store.autoDestroy){
41914
this.store.destroy();
41918
store = Ext.StoreMgr.lookup(store);
41921
datachanged: this.refresh,
41922
add: this.delayRefresh,
41923
remove: this.delayRefresh,
41924
update: this.delayRefresh,
41925
clear: this.refresh
41928
this.store = store;
41929
if(store && !initial){
41934
onSwfReady : function(isReset){
41935
Ext.chart.Chart.superclass.onSwfReady.call(this, isReset);
41937
this.swf.setType(this.type);
41939
if(this.chartStyle){
41940
this.setStyles(this.chartStyle);
41943
if(this.categoryNames){
41944
this.setCategoryNames(this.categoryNames);
41947
if(this.tipRenderer){
41948
this.setTipRenderer(this.tipRenderer);
41951
this.bindStore(this.store, true);
41953
this.refresh.defer(10, this);
41956
delayRefresh : function(){
41957
if(!this.refreshTask){
41958
this.refreshTask = new Ext.util.DelayedTask(this.refresh, this);
41960
this.refreshTask.delay(this.refreshBuffer);
41963
refresh : function(){
41964
var styleChanged = false;
41965
// convert the store data into something YUI charts can understand
41966
var data = [], rs = this.store.data.items;
41967
for(var j = 0, len = rs.length; j < len; j++){
41968
data[j] = rs[j].data;
41970
//make a copy of the series definitions so that we aren't
41971
//editing them directly.
41972
var dataProvider = [];
41973
var seriesCount = 0;
41974
var currentSeries = null;
41977
seriesCount = this.series.length;
41978
for(i = 0; i < seriesCount; i++){
41979
currentSeries = this.series[i];
41980
var clonedSeries = {};
41981
for(var prop in currentSeries){
41982
if(prop == "style" && currentSeries.style !== null){
41983
clonedSeries.style = Ext.encode(currentSeries.style);
41984
styleChanged = true;
41985
//we don't want to modify the styles again next time
41986
//so null out the style property.
41987
// this causes issues
41988
// currentSeries.style = null;
41990
clonedSeries[prop] = currentSeries[prop];
41993
dataProvider.push(clonedSeries);
41997
if(seriesCount > 0){
41998
for(i = 0; i < seriesCount; i++){
41999
currentSeries = dataProvider[i];
42000
if(!currentSeries.type){
42001
currentSeries.type = this.type;
42003
currentSeries.dataProvider = data;
42006
dataProvider.push({type: this.type, dataProvider: data});
42008
this.swf.setDataProvider(dataProvider, (this.isFirst = (this.isFirst === undefined)));
42011
createFnProxy : function(fn, old){
42013
delete window[old];
42015
var fnName = "extFnProxy" + (++Ext.chart.Chart.PROXY_FN_ID);
42016
window[fnName] = fn;
42020
Ext.reg('chart', Ext.chart.Chart);
42021
Ext.chart.Chart.PROXY_FN_ID = 0;
42024
Ext.chart.PieChart = Ext.extend(Ext.chart.Chart, {
42027
onSwfReady : function(isReset){
42028
Ext.chart.PieChart.superclass.onSwfReady.call(this, isReset);
42030
this.setDataField(this.dataField);
42031
this.setCategoryField(this.categoryField);
42034
setDataField : function(field){
42035
this.dataField = field;
42036
this.swf.setDataField(field);
42039
setCategoryField : function(field){
42040
this.categoryField = field;
42041
this.swf.setCategoryField(field);
42044
Ext.reg('piechart', Ext.chart.PieChart);
42047
Ext.chart.CartesianChart = Ext.extend(Ext.chart.Chart, {
42048
onSwfReady : function(isReset){
42049
Ext.chart.CartesianChart.superclass.onSwfReady.call(this, isReset);
42052
this.setXField(this.xField);
42055
this.setYField(this.yField);
42058
this.setXAxis(this.xAxis);
42061
this.setYAxis(this.yAxis);
42065
setXField : function(value){
42066
this.xField = value;
42067
this.swf.setHorizontalField(value);
42070
setYField : function(value){
42071
this.yField = value;
42072
this.swf.setVerticalField(value);
42075
setXAxis : function(value){
42076
this.xAxis = this.createAxis('xAxis', value);
42077
this.swf.setHorizontalAxis(this.xAxis);
42080
setYAxis : function(value){
42081
this.yAxis = this.createAxis('yAxis', value);
42082
this.swf.setVerticalAxis(this.yAxis);
42085
createAxis : function(axis, value){
42086
var o = Ext.apply({}, value), oldFn = null;
42088
oldFn = this[axis].labelFunction;
42090
if(o.labelRenderer){
42091
var fn = o.labelRenderer;
42092
o.labelFunction = this.createFnProxy(function(v){
42095
delete o.labelRenderer;
42100
Ext.reg('cartesianchart', Ext.chart.CartesianChart);
42103
Ext.chart.LineChart = Ext.extend(Ext.chart.CartesianChart, {
42106
Ext.reg('linechart', Ext.chart.LineChart);
42109
Ext.chart.ColumnChart = Ext.extend(Ext.chart.CartesianChart, {
42112
Ext.reg('columnchart', Ext.chart.ColumnChart);
42115
Ext.chart.BarChart = Ext.extend(Ext.chart.CartesianChart, {
42118
Ext.reg('barchart', Ext.chart.BarChart);
42123
Ext.chart.Axis = function(config){
42124
Ext.apply(this, config);
42127
Ext.chart.Axis.prototype =
42133
orientation: "horizontal",
42139
labelFunction: null,
42142
hideOverlappingLabels: true
42146
Ext.chart.NumericAxis = Ext.extend(Ext.chart.Axis, {
42165
alwaysShowZero: true,
42172
Ext.chart.TimeAxis = Ext.extend(Ext.chart.Axis, {
42185
majorTimeUnit: null,
42191
minorTimeUnit: null,
42198
Ext.chart.CategoryAxis = Ext.extend(Ext.chart.Axis, {
42202
categoryNames: null
42206
Ext.chart.Series = function(config) { Ext.apply(this, config); };
42208
Ext.chart.Series.prototype =
42218
Ext.chart.CartesianSeries = Ext.extend(Ext.chart.Series, {
42227
Ext.chart.ColumnSeries = Ext.extend(Ext.chart.CartesianSeries, {
42232
Ext.chart.LineSeries = Ext.extend(Ext.chart.CartesianSeries, {
42237
Ext.chart.BarSeries = Ext.extend(Ext.chart.CartesianSeries, {
42243
Ext.chart.PieSeries = Ext.extend(Ext.chart.Series, {
42246
categoryField: null
42249
Ext.History = (function () {
42250
var iframe, hiddenField;
42254
function getHash() {
42255
var href = top.location.href, i = href.indexOf("#");
42256
return i >= 0 ? href.substr(i + 1) : null;
42259
function doSave() {
42260
hiddenField.value = currentToken;
42263
function handleStateChange(token) {
42264
currentToken = token;
42265
Ext.History.fireEvent('change', token);
42268
function updateIFrame (token) {
42269
var html = ['<html><body><div id="state">',token,'</div></body></html>'].join('');
42271
var doc = iframe.contentWindow.document;
42281
function checkIFrame() {
42282
if (!iframe.contentWindow || !iframe.contentWindow.document) {
42283
setTimeout(checkIFrame, 10);
42287
var doc = iframe.contentWindow.document;
42288
var elem = doc.getElementById("state");
42289
var token = elem ? elem.innerText : null;
42291
var hash = getHash();
42293
setInterval(function () {
42295
doc = iframe.contentWindow.document;
42296
elem = doc.getElementById("state");
42298
var newtoken = elem ? elem.innerText : null;
42300
var newHash = getHash();
42302
if (newtoken !== token) {
42304
handleStateChange(token);
42305
top.location.hash = token;
42308
} else if (newHash !== hash) {
42310
updateIFrame(newHash);
42317
Ext.History.fireEvent('ready', Ext.History);
42320
function startUp() {
42321
currentToken = hiddenField.value ? hiddenField.value : getHash();
42326
var hash = getHash();
42327
setInterval(function () {
42328
var newHash = getHash();
42329
if (newHash !== hash) {
42331
handleStateChange(hash);
42336
Ext.History.fireEvent('ready', Ext.History);
42342
fieldId: 'x-history-field',
42344
iframeId: 'x-history-frame',
42349
init: function (onReady, scope) {
42351
Ext.callback(onReady, scope, [this]);
42355
Ext.onReady(function(){
42356
Ext.History.init(onReady, scope);
42360
hiddenField = Ext.getDom(Ext.History.fieldId);
42362
iframe = Ext.getDom(Ext.History.iframeId);
42364
this.addEvents('ready', 'change');
42366
this.on('ready', onReady, scope, {single:true});
42372
add: function (token, preventDup) {
42373
if(preventDup !== false){
42374
if(this.getToken() == token){
42379
return updateIFrame(token);
42381
top.location.hash = token;
42392
forward: function(){
42397
getToken: function() {
42398
return ready ? currentToken : getHash();
42402
Ext.apply(Ext.History, new Ext.util.Observable());