ExtJS 3.4.0 - Use checkchange event to check/uncheck all tree nodes in Ext.tree.TreePanel

今天主要探到的是,改寫ExtJS 3.4.0 example內的tree範例來達到基本的操作,即點擊父節點

使得所有的子節點能夠被checked or unchecked。

ExtJS的TreePanel定義如下:

var tree = new Ext.tree.TreePanel({
        renderTo:'tree-div',
        title: '我擅長的技能',
        height: 300,
        width: 400,
        enableDD:false,
        containerScroll: true,
        rootVisible: false,
        checkModel: 'multiple',
        root: {
            nodeType: 'async'
        },
        
        // auto create TreeLoader
        dataUrl: 'js/check-nodes.json'
});

關於TreePanel的基本屬性定義,在此就不多加說明,可參閱官方API

PS. renderTo定義的tree-div,即掛載於html code內的div => id = "tree-div"之下囉!

至於要讀取的資料格式為JSON Format,來源為檔案資料內容,可以改寫為讀取Server端。

JSON Data如下:

[{
    text: '電腦資訊', 
    cls: 'folder',
    children: [{
        text: '程式設計',
        cls: 'folder',
        checked: false,
        children: [{
         id: 123,
         text: 'Java',
         cls: 'file',
         leaf: true,
         checked: false
     },{
      id: 124,
         text: 'C',
         leaf: true,
         cls: 'file',
         checked: false
        }]
    },{
        text: '網頁設計',
        cls: 'folder',
        checked: false,
        children: [{
         text: 'PHP',
         leaf: true,
         cls: 'file',
         checked: false
     },{
         text: 'JavaScript',
         leaf: true,
         cls: 'file',
         checked: false
        }]
    },{
        text: '資料庫',
        cls: 'folder',
        checked: false,
        children: [{
         text: 'MySQL',
         leaf: true,
         cls: 'file',
         checked: false
     },{
         text: 'MSSQL',
         leaf: true,
         cls: 'file',
         checked: false
        }]
    }]
}]

需注意的是,若該節點沒有子節點,則leaf屬性需設為true,而cls屬性的定義可區分哪些

節點為parent or children。

初始化當下,若要展開所有的節點,需以root reference來call expand method

tree.getRootNode().expand(true);

再來定義checkchange事件,並透過呼叫自行定義的execToggleCheck method來改變子節點

的check/uncheck。

tree.on({
    'checkchange': {
        fn: function(node) {
            var n = node.attributes;
            if(n.cls == 'folder'){
                execToggleCheck(node);
            } 
        },
        scope: this
    }
});

function execToggleCheck(node, isCheck){
  if(node) {
   //node.expand();
   node.cascade(function(){
     if (this.attributes.cls=="file") {
       this.ui.toggleCheck(isCheck);
       this.attributes.checked=isCheck;
     }
   });
  }
 }

請注意,要改變UI的現狀,即呈現出子節點變換為check/uncheck需呼叫

this.ui.toggleCheck(isCheck);,但是API裡面有提到,一旦呼叫這個method會連帶地觸發

checkchange事件。因此在定義此事件時,需過濾出只有folder屬性的節點才會去呼叫

execToggleCheck method,否則會一直停留在第一個子節點進入無窮迴圈導致瀏覽器炸掉囉!

結果畫面如下:


透過點擊程式設計,會連帶的勾選起Java、C的部分;反之亦然!

留言