~mortenoh/+junk/dhis2-detailed-import-export

« back to all changes in this revision

Viewing changes to gis/dhis-gis-geostat/mfbase/ext/source/widgets/tree/TreeNodeUI.js

  • Committer: larshelge at gmail
  • Date: 2009-03-03 16:46:36 UTC
  • Revision ID: larshelge@gmail.com-20090303164636-2sjlrquo7ib1gf7r
Initial check-in

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Ext JS Library 2.2
 
3
 * Copyright(c) 2006-2008, Ext JS, LLC.
 
4
 * licensing@extjs.com
 
5
 * 
 
6
 * http://extjs.com/license
 
7
 */
 
8
 
 
9
/**
 
10
 * @class Ext.tree.TreeNodeUI
 
11
 * This class provides the default UI implementation for Ext TreeNodes.
 
12
 * The TreeNode UI implementation is separate from the
 
13
 * tree implementation, and allows customizing of the appearance of
 
14
 * tree nodes.<br>
 
15
 * <p>
 
16
 * If you are customizing the Tree's user interface, you
 
17
 * may need to extend this class, but you should never need to instantiate this class.<br>
 
18
 * <p>
 
19
 * This class provides access to the user interface components of an Ext TreeNode, through
 
20
 * {@link Ext.tree.TreeNode#getUI}
 
21
 */
 
22
Ext.tree.TreeNodeUI = function(node){
 
23
    this.node = node;
 
24
    this.rendered = false;
 
25
    this.animating = false;
 
26
    this.wasLeaf = true;
 
27
    this.ecc = 'x-tree-ec-icon x-tree-elbow';
 
28
    this.emptyIcon = Ext.BLANK_IMAGE_URL;
 
29
};
 
30
 
 
31
Ext.tree.TreeNodeUI.prototype = {
 
32
    // private
 
33
    removeChild : function(node){
 
34
        if(this.rendered){
 
35
            this.ctNode.removeChild(node.ui.getEl());
 
36
        } 
 
37
    },
 
38
 
 
39
    // private
 
40
    beforeLoad : function(){
 
41
         this.addClass("x-tree-node-loading");
 
42
    },
 
43
 
 
44
    // private
 
45
    afterLoad : function(){
 
46
         this.removeClass("x-tree-node-loading");
 
47
    },
 
48
 
 
49
    // private
 
50
    onTextChange : function(node, text, oldText){
 
51
        if(this.rendered){
 
52
            this.textNode.innerHTML = text;
 
53
        }
 
54
    },
 
55
 
 
56
    // private
 
57
    onDisableChange : function(node, state){
 
58
        this.disabled = state;
 
59
                if (this.checkbox) {
 
60
                        this.checkbox.disabled = state;
 
61
                }        
 
62
        if(state){
 
63
            this.addClass("x-tree-node-disabled");
 
64
        }else{
 
65
            this.removeClass("x-tree-node-disabled");
 
66
        } 
 
67
    },
 
68
 
 
69
    // private
 
70
    onSelectedChange : function(state){
 
71
        if(state){
 
72
            this.focus();
 
73
            this.addClass("x-tree-selected");
 
74
        }else{
 
75
            //this.blur();
 
76
            this.removeClass("x-tree-selected");
 
77
        }
 
78
    },
 
79
 
 
80
    // private
 
81
    onMove : function(tree, node, oldParent, newParent, index, refNode){
 
82
        this.childIndent = null;
 
83
        if(this.rendered){
 
84
            var targetNode = newParent.ui.getContainer();
 
85
            if(!targetNode){//target not rendered
 
86
                this.holder = document.createElement("div");
 
87
                this.holder.appendChild(this.wrap);
 
88
                return;
 
89
            }
 
90
            var insertBefore = refNode ? refNode.ui.getEl() : null;
 
91
            if(insertBefore){
 
92
                targetNode.insertBefore(this.wrap, insertBefore);
 
93
            }else{
 
94
                targetNode.appendChild(this.wrap);
 
95
            }
 
96
            this.node.renderIndent(true);
 
97
        }
 
98
    },
 
99
 
 
100
/**
 
101
 * Adds one or more CSS classes to the node's UI element.
 
102
 * Duplicate classes are automatically filtered out.
 
103
 * @param {String/Array} className The CSS class to add, or an array of classes
 
104
 */
 
105
    addClass : function(cls){
 
106
        if(this.elNode){
 
107
            Ext.fly(this.elNode).addClass(cls);
 
108
        }
 
109
    },
 
110
 
 
111
/**
 
112
 * Removes one or more CSS classes from the node's UI element.
 
113
 * @param {String/Array} className The CSS class to remove, or an array of classes
 
114
 */
 
115
    removeClass : function(cls){
 
116
        if(this.elNode){
 
117
            Ext.fly(this.elNode).removeClass(cls);  
 
118
        }
 
119
    },
 
120
 
 
121
    // private
 
122
    remove : function(){
 
123
        if(this.rendered){
 
124
            this.holder = document.createElement("div");
 
125
            this.holder.appendChild(this.wrap);
 
126
        }  
 
127
    },
 
128
 
 
129
    // private
 
130
    fireEvent : function(){
 
131
        return this.node.fireEvent.apply(this.node, arguments);  
 
132
    },
 
133
 
 
134
    // private
 
135
    initEvents : function(){
 
136
        this.node.on("move", this.onMove, this);
 
137
 
 
138
        if(this.node.disabled){
 
139
            this.addClass("x-tree-node-disabled");
 
140
                        if (this.checkbox) {
 
141
                                this.checkbox.disabled = true;
 
142
                        }            
 
143
        }
 
144
        if(this.node.hidden){
 
145
            this.hide();
 
146
        }
 
147
        var ot = this.node.getOwnerTree();
 
148
        var dd = ot.enableDD || ot.enableDrag || ot.enableDrop;
 
149
        if(dd && (!this.node.isRoot || ot.rootVisible)){
 
150
            Ext.dd.Registry.register(this.elNode, {
 
151
                node: this.node,
 
152
                handles: this.getDDHandles(),
 
153
                isHandle: false
 
154
            });
 
155
        }
 
156
    },
 
157
 
 
158
    // private
 
159
    getDDHandles : function(){
 
160
        return [this.iconNode, this.textNode, this.elNode];
 
161
    },
 
162
 
 
163
/**
 
164
 * Hides this node.
 
165
 */
 
166
    hide : function(){
 
167
        this.node.hidden = true;
 
168
        if(this.wrap){
 
169
            this.wrap.style.display = "none";
 
170
        }
 
171
    },
 
172
 
 
173
/**
 
174
 * Shows this node.
 
175
 */
 
176
    show : function(){
 
177
        this.node.hidden = false;
 
178
        if(this.wrap){
 
179
            this.wrap.style.display = "";
 
180
        } 
 
181
    },
 
182
 
 
183
    // private
 
184
    onContextMenu : function(e){
 
185
        if (this.node.hasListener("contextmenu") || this.node.getOwnerTree().hasListener("contextmenu")) {
 
186
            e.preventDefault();
 
187
            this.focus();
 
188
            this.fireEvent("contextmenu", this.node, e);
 
189
        }
 
190
    },
 
191
 
 
192
    // private
 
193
    onClick : function(e){
 
194
        if(this.dropping){
 
195
            e.stopEvent();
 
196
            return;
 
197
        }
 
198
        if(this.fireEvent("beforeclick", this.node, e) !== false){
 
199
            var a = e.getTarget('a');
 
200
            if(!this.disabled && this.node.attributes.href && a){
 
201
                this.fireEvent("click", this.node, e);
 
202
                return;
 
203
            }else if(a && e.ctrlKey){
 
204
                e.stopEvent();
 
205
            }
 
206
            e.preventDefault();
 
207
            if(this.disabled){
 
208
                return;
 
209
            }
 
210
 
 
211
            if(this.node.attributes.singleClickExpand && !this.animating && this.node.isExpandable()){
 
212
                this.node.toggle();
 
213
            }
 
214
 
 
215
            this.fireEvent("click", this.node, e);
 
216
        }else{
 
217
            e.stopEvent();
 
218
        }
 
219
    },
 
220
 
 
221
    // private
 
222
    onDblClick : function(e){
 
223
        e.preventDefault();
 
224
        if(this.disabled){
 
225
            return;
 
226
        }
 
227
        if(this.checkbox){
 
228
            this.toggleCheck();
 
229
        }
 
230
        if(!this.animating && this.node.isExpandable()){
 
231
            this.node.toggle();
 
232
        }
 
233
        this.fireEvent("dblclick", this.node, e);
 
234
    },
 
235
 
 
236
    onOver : function(e){
 
237
        this.addClass('x-tree-node-over');
 
238
    },
 
239
 
 
240
    onOut : function(e){
 
241
        this.removeClass('x-tree-node-over');
 
242
    },
 
243
 
 
244
    // private
 
245
    onCheckChange : function(){
 
246
        var checked = this.checkbox.checked;
 
247
                // fix for IE6
 
248
                this.checkbox.defaultChecked = checked;
 
249
        this.node.attributes.checked = checked;
 
250
        this.fireEvent('checkchange', this.node, checked);
 
251
    },
 
252
 
 
253
    // private
 
254
    ecClick : function(e){
 
255
        if(!this.animating && this.node.isExpandable()){
 
256
            this.node.toggle();
 
257
        }
 
258
    },
 
259
 
 
260
    // private
 
261
    startDrop : function(){
 
262
        this.dropping = true;
 
263
    },
 
264
    
 
265
    // delayed drop so the click event doesn't get fired on a drop
 
266
    endDrop : function(){ 
 
267
       setTimeout(function(){
 
268
           this.dropping = false;
 
269
       }.createDelegate(this), 50); 
 
270
    },
 
271
 
 
272
    // private
 
273
    expand : function(){
 
274
        this.updateExpandIcon();
 
275
        this.ctNode.style.display = "";
 
276
    },
 
277
 
 
278
    // private
 
279
    focus : function(){
 
280
        if(!this.node.preventHScroll){
 
281
            try{this.anchor.focus();
 
282
            }catch(e){}
 
283
        }else if(!Ext.isIE){
 
284
            try{
 
285
                var noscroll = this.node.getOwnerTree().getTreeEl().dom;
 
286
                var l = noscroll.scrollLeft;
 
287
                this.anchor.focus();
 
288
                noscroll.scrollLeft = l;
 
289
            }catch(e){}
 
290
        }
 
291
    },
 
292
 
 
293
/**
 
294
 * Sets the checked status of the tree node to the passed value, or, if no value was passed,
 
295
 * toggles the checked status. If the node was rendered with no checkbox, this has no effect.
 
296
 * @param {Boolean} (optional) The new checked status.
 
297
 */
 
298
    toggleCheck : function(value){
 
299
        var cb = this.checkbox;
 
300
        if(cb){
 
301
            cb.checked = (value === undefined ? !cb.checked : value);
 
302
            this.onCheckChange();
 
303
        }
 
304
    },
 
305
 
 
306
    // private
 
307
    blur : function(){
 
308
        try{
 
309
            this.anchor.blur();
 
310
        }catch(e){} 
 
311
    },
 
312
 
 
313
    // private
 
314
    animExpand : function(callback){
 
315
        var ct = Ext.get(this.ctNode);
 
316
        ct.stopFx();
 
317
        if(!this.node.isExpandable()){
 
318
            this.updateExpandIcon();
 
319
            this.ctNode.style.display = "";
 
320
            Ext.callback(callback);
 
321
            return;
 
322
        }
 
323
        this.animating = true;
 
324
        this.updateExpandIcon();
 
325
        
 
326
        ct.slideIn('t', {
 
327
           callback : function(){
 
328
               this.animating = false;
 
329
               Ext.callback(callback);
 
330
            },
 
331
            scope: this,
 
332
            duration: this.node.ownerTree.duration || .25
 
333
        });
 
334
    },
 
335
 
 
336
    // private
 
337
    highlight : function(){
 
338
        var tree = this.node.getOwnerTree();
 
339
        Ext.fly(this.wrap).highlight(
 
340
            tree.hlColor || "C3DAF9",
 
341
            {endColor: tree.hlBaseColor}
 
342
        );
 
343
    },
 
344
 
 
345
    // private
 
346
    collapse : function(){
 
347
        this.updateExpandIcon();
 
348
        this.ctNode.style.display = "none";
 
349
    },
 
350
 
 
351
    // private
 
352
    animCollapse : function(callback){
 
353
        var ct = Ext.get(this.ctNode);
 
354
        ct.enableDisplayMode('block');
 
355
        ct.stopFx();
 
356
 
 
357
        this.animating = true;
 
358
        this.updateExpandIcon();
 
359
 
 
360
        ct.slideOut('t', {
 
361
            callback : function(){
 
362
               this.animating = false;
 
363
               Ext.callback(callback);
 
364
            },
 
365
            scope: this,
 
366
            duration: this.node.ownerTree.duration || .25
 
367
        });
 
368
    },
 
369
 
 
370
    // private
 
371
    getContainer : function(){
 
372
        return this.ctNode;  
 
373
    },
 
374
 
 
375
    // private
 
376
    getEl : function(){
 
377
        return this.wrap;  
 
378
    },
 
379
 
 
380
    // private
 
381
    appendDDGhost : function(ghostNode){
 
382
        ghostNode.appendChild(this.elNode.cloneNode(true));
 
383
    },
 
384
 
 
385
    // private
 
386
    getDDRepairXY : function(){
 
387
        return Ext.lib.Dom.getXY(this.iconNode);
 
388
    },
 
389
 
 
390
    // private
 
391
    onRender : function(){
 
392
        this.render();    
 
393
    },
 
394
 
 
395
    // private
 
396
    render : function(bulkRender){
 
397
        var n = this.node, a = n.attributes;
 
398
        var targetNode = n.parentNode ? 
 
399
              n.parentNode.ui.getContainer() : n.ownerTree.innerCt.dom;
 
400
        
 
401
        if(!this.rendered){
 
402
            this.rendered = true;
 
403
 
 
404
            this.renderElements(n, a, targetNode, bulkRender);
 
405
 
 
406
            if(a.qtip){
 
407
               if(this.textNode.setAttributeNS){
 
408
                   this.textNode.setAttributeNS("ext", "qtip", a.qtip);
 
409
                   if(a.qtipTitle){
 
410
                       this.textNode.setAttributeNS("ext", "qtitle", a.qtipTitle);
 
411
                   }
 
412
               }else{
 
413
                   this.textNode.setAttribute("ext:qtip", a.qtip);
 
414
                   if(a.qtipTitle){
 
415
                       this.textNode.setAttribute("ext:qtitle", a.qtipTitle);
 
416
                   }
 
417
               } 
 
418
            }else if(a.qtipCfg){
 
419
                a.qtipCfg.target = Ext.id(this.textNode);
 
420
                Ext.QuickTips.register(a.qtipCfg);
 
421
            }
 
422
            this.initEvents();
 
423
            if(!this.node.expanded){
 
424
                this.updateExpandIcon(true);
 
425
            }
 
426
        }else{
 
427
            if(bulkRender === true) {
 
428
                targetNode.appendChild(this.wrap);
 
429
            }
 
430
        }
 
431
    },
 
432
 
 
433
    // private
 
434
    renderElements : function(n, a, targetNode, bulkRender){
 
435
        // add some indent caching, this helps performance when rendering a large tree
 
436
        this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
 
437
 
 
438
        var cb = typeof a.checked == 'boolean';
 
439
 
 
440
        var href = a.href ? a.href : Ext.isGecko ? "" : "#";
 
441
        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">',
 
442
            '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
 
443
            '<img src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
 
444
            '<img src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
 
445
            cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
 
446
            '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
 
447
             a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
 
448
            '<ul class="x-tree-node-ct" style="display:none;"></ul>',
 
449
            "</li>"].join('');
 
450
 
 
451
        var nel;
 
452
        if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
 
453
            this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
 
454
        }else{
 
455
            this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
 
456
        }
 
457
        
 
458
        this.elNode = this.wrap.childNodes[0];
 
459
        this.ctNode = this.wrap.childNodes[1];
 
460
        var cs = this.elNode.childNodes;
 
461
        this.indentNode = cs[0];
 
462
        this.ecNode = cs[1];
 
463
        this.iconNode = cs[2];
 
464
        var index = 3;
 
465
        if(cb){
 
466
            this.checkbox = cs[3];
 
467
                        // fix for IE6
 
468
                        this.checkbox.defaultChecked = this.checkbox.checked;                   
 
469
            index++;
 
470
        }
 
471
        this.anchor = cs[index];
 
472
        this.textNode = cs[index].firstChild;
 
473
    },
 
474
 
 
475
/**
 
476
 * Returns the &lt;a> element that provides focus for the node's UI.
 
477
 * @return {HtmlElement} The DOM anchor element.
 
478
 */
 
479
    getAnchor : function(){
 
480
        return this.anchor;
 
481
    },
 
482
    
 
483
/**
 
484
 * Returns the text node.
 
485
 * @return {HtmlNode} The DOM text node.
 
486
 */
 
487
    getTextEl : function(){
 
488
        return this.textNode;
 
489
    },
 
490
    
 
491
/**
 
492
 * Returns the icon &lt;img> element.
 
493
 * @return {HtmlElement} The DOM image element.
 
494
 */
 
495
    getIconEl : function(){
 
496
        return this.iconNode;
 
497
    },
 
498
 
 
499
/**
 
500
 * Returns the checked status of the node. If the node was rendered with no
 
501
 * checkbox, it returns false.
 
502
 * @return {Boolean} The checked flag.
 
503
 */
 
504
    isChecked : function(){
 
505
        return this.checkbox ? this.checkbox.checked : false; 
 
506
    },
 
507
 
 
508
    // private
 
509
    updateExpandIcon : function(){
 
510
        if(this.rendered){
 
511
            var n = this.node, c1, c2;
 
512
            var cls = n.isLast() ? "x-tree-elbow-end" : "x-tree-elbow";
 
513
            if(n.isExpandable()){
 
514
                if(n.expanded){
 
515
                    cls += "-minus";
 
516
                    c1 = "x-tree-node-collapsed";
 
517
                    c2 = "x-tree-node-expanded";
 
518
                }else{
 
519
                    cls += "-plus";
 
520
                    c1 = "x-tree-node-expanded";
 
521
                    c2 = "x-tree-node-collapsed";
 
522
                }
 
523
                if(this.wasLeaf){
 
524
                    this.removeClass("x-tree-node-leaf");
 
525
                    this.wasLeaf = false;
 
526
                }
 
527
                if(this.c1 != c1 || this.c2 != c2){
 
528
                    Ext.fly(this.elNode).replaceClass(c1, c2);
 
529
                    this.c1 = c1; this.c2 = c2;
 
530
                }
 
531
            }else{
 
532
                if(!this.wasLeaf){
 
533
                    Ext.fly(this.elNode).replaceClass("x-tree-node-expanded", "x-tree-node-leaf");
 
534
                    delete this.c1;
 
535
                    delete this.c2;
 
536
                    this.wasLeaf = true;
 
537
                }
 
538
            }
 
539
            var ecc = "x-tree-ec-icon "+cls;
 
540
            if(this.ecc != ecc){
 
541
                this.ecNode.className = ecc;
 
542
                this.ecc = ecc;
 
543
            }
 
544
        }
 
545
    },
 
546
 
 
547
    // private
 
548
    getChildIndent : function(){
 
549
        if(!this.childIndent){
 
550
            var buf = [];
 
551
            var p = this.node;
 
552
            while(p){
 
553
                if(!p.isRoot || (p.isRoot && p.ownerTree.rootVisible)){
 
554
                    if(!p.isLast()) {
 
555
                        buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-elbow-line" />');
 
556
                    } else {
 
557
                        buf.unshift('<img src="'+this.emptyIcon+'" class="x-tree-icon" />');
 
558
                    }
 
559
                }
 
560
                p = p.parentNode;
 
561
            }
 
562
            this.childIndent = buf.join("");
 
563
        }
 
564
        return this.childIndent;
 
565
    },
 
566
 
 
567
    // private
 
568
    renderIndent : function(){
 
569
        if(this.rendered){
 
570
            var indent = "";
 
571
            var p = this.node.parentNode;
 
572
            if(p){
 
573
                indent = p.ui.getChildIndent();
 
574
            }
 
575
            if(this.indentMarkup != indent){ // don't rerender if not required
 
576
                this.indentNode.innerHTML = indent;
 
577
                this.indentMarkup = indent;
 
578
            }
 
579
            this.updateExpandIcon();
 
580
        }
 
581
    },
 
582
 
 
583
    destroy : function(){
 
584
        if(this.elNode){
 
585
            Ext.dd.Registry.unregister(this.elNode.id);
 
586
        }
 
587
        delete this.elNode;
 
588
        delete this.ctNode;
 
589
        delete this.indentNode;
 
590
        delete this.ecNode;
 
591
        delete this.iconNode;
 
592
        delete this.checkbox;
 
593
        delete this.anchor;
 
594
        delete this.textNode;
 
595
        Ext.removeNode(this.ctNode);
 
596
    }
 
597
};
 
598
 
 
599
/**
 
600
 * @class Ext.tree.RootTreeNodeUI
 
601
 * This class provides the default UI implementation for <b>root</b> Ext TreeNodes.
 
602
 * The RootTreeNode UI implementation allows customizing the appearance of the root tree node.<br>
 
603
 * <p>
 
604
 * If you are customizing the Tree's user interface, you
 
605
 * may need to extend this class, but you should never need to instantiate this class.<br>
 
606
 */
 
607
Ext.tree.RootTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
 
608
    // private
 
609
    render : function(){
 
610
        if(!this.rendered){
 
611
            var targetNode = this.node.ownerTree.innerCt.dom;
 
612
            this.node.expanded = true;
 
613
            targetNode.innerHTML = '<div class="x-tree-root-node"></div>';
 
614
            this.wrap = this.ctNode = targetNode.firstChild;
 
615
        }
 
616
    },
 
617
    collapse : Ext.emptyFn,
 
618
    expand : Ext.emptyFn
 
619
});
 
 
b'\\ No newline at end of file'