2012年7月20日 星期五

Javascript TreeView CheckBox Select All / Cancel Select All

參考了此篇文章:http://geekswithblogs.net/ranganh/archive/2006/03/25/73300.aspx

可以成功的勾選父節點時,子節點也全部勾起

但是遇到一個需求就是子節點(Child Node)取消勾選後(Cancel Checked),父節點(Parent Node)、祖父節點(GrandParent Node)....等等也要跟著取消勾選(Cancel Checked),
於是將此篇的Javascript做了些改良。

1.首先先隨便建立一個TreeView



  

 protected void Page_Load(object sender, EventArgs e)
    {

        if (!IsPostBack)
        {
            //Level 1 :Root Node
            TreeNode tnRoot = new TreeNode();
            tnRoot.Value = "Root";
            tnRoot.Text = "Root";
            this.tvNode.Nodes.Add(tnRoot);

            //Level 2
            TreeNode tnNode1 = new TreeNode();
            tnNode1.Value = "Node1";
            tnNode1.Value = "Node1";
            this.tvNode.Nodes[0].ChildNodes.Add(tnNode1);
            TreeNode tnNode2 = new TreeNode();
            tnNode2.Value = "Node2";
            tnNode2.Value = "Node2";
            this.tvNode.Nodes[0].ChildNodes.Add(tnNode2);
            TreeNode tnNode7 = new TreeNode();
            tnNode7.Value = "Node7";
            tnNode7.Value = "Node7";
            this.tvNode.Nodes[0].ChildNodes.Add(tnNode7);
            TreeNode tnNode8 = new TreeNode();
            tnNode8.Value = "tnNode8";
            tnNode8.Value = "tnNode8";
            this.tvNode.Nodes[0].ChildNodes.Add(tnNode8);
            TreeNode tnNode9 = new TreeNode();
            tnNode9.Value = "tnNode9";
            tnNode9.Value = "tnNode9";
            this.tvNode.Nodes[0].ChildNodes.Add(tnNode9);
            TreeNode tnNode10 = new TreeNode();
            tnNode10.Value = "tnNode10";
            tnNode10.Value = "tnNode10";
            this.tvNode.Nodes[0].ChildNodes.Add(tnNode10);

            //Level 3
            TreeNode tnNode3 = new TreeNode();
            tnNode3.Value = "Node1-1";
            tnNode3.Value = "Node1-1";
            this.tvNode.Nodes[0].ChildNodes[0].ChildNodes.Add(tnNode3);
            TreeNode tnNode4 = new TreeNode();
            tnNode4.Value = "Node1-2";
            tnNode4.Value = "Node1-2";
            this.tvNode.Nodes[0].ChildNodes[0].ChildNodes.Add(tnNode4);
            TreeNode tnNode5 = new TreeNode();
            tnNode5.Value = "Node2-1";
            tnNode5.Value = "Node2-1";
            this.tvNode.Nodes[0].ChildNodes[1].ChildNodes.Add(tnNode5);

            //Level 4
            TreeNode tnNode6 = new TreeNode();
            tnNode6.Value = "Node1-1-1";
            tnNode6.Value = "Node1-1-1";
            this.tvNode.Nodes[0].ChildNodes[0].ChildNodes[0].ChildNodes.Add(tnNode6);

        }

    }
2. Treeview的部分
    Treeview的部分增加Javascript event "OnTreeNodeChecked"
  

3. Javascript event "OnTreeNodeChecked" 
可以先利用Web Developer(Chrome, IE, Firefox firebug)了解Treeview html呈現的方式
 
function OnTreeNodeChecked() {

    //註1:treeView的每個Node其實都是一個Html Talbe,子節點再用div包住。

    //node1..

    //node1 child1

    //node1 child1 Chilld...

    //node1 child2

    //取得目前作用的對象,例如:Node1的checkbox

    var obj = window.event.srcElement;

    var treeNodeFound = false;

    var checkedState;

    //若目前是Event對象是CheckBox

    if (obj.tagName == "INPUT" & amp; & amp; obj.type == "checkbox") {

         
        var treeNode = obj;

        //設定checkState為目前選取的狀態

        checkedState = treeNode.checked;

        do {

            //參考註1,每個Node都是一個Table

            obj = obj.parentElement;

        } while (obj.tagName != "TABLE")

        //td的數量代表level,Child愈深所以rows[0].cells.length(換句話說td數量越多)

        var parentTreeLevel = obj.rows[0].cells.length;

        var parentTreeNode = obj.rows[0].cells[0];

        //找出父親下所有的table(也代表所有的node)

        var tables = obj.parentElement.getElementsByTagName("TABLE");

        //node數量

        var numTables = tables.length

        if (numTables & gt; = 1) {

             
            for (i = 0; i & lt; numTables; i++) {

                //如果找到自己,則found

                if (tables[i] == obj) {

                    treeNodeFound = true;

                    //新增加的部分

                    //處理子節點取消,上層節點也跟著取消

                    //Child UnChecked, Parent also Unckecked 

                    if (treeNodeFound & amp; & amp; !checkedState) {

                         
                        var objparent = obj;

                        do {

                              //取得parent再取得parent上一個sibling(Tree sturcture)

                            //參考註一會較了解                               

                            objparent = objparent.parentElement;

                            var objTree = objparent.previousSibling;

                            if (objTree.tagName == "TABLE") {

                                var level = objTree.rows[0].cells.length - 1;

                                objTree.rows[0].cells[level].firstChild.checked = false;

                            }

                        } while (objparent.id != "tvNode")

                    }

                    i++;

                    if (i == numTables) {

                        return;

                    }

                }

                //找到自己後,若level大於自己的level則代表是自己的子節點(參考註一)                    

                if (treeNodeFound == true) {

                    var childTreeLevel = tables[i].rows[0].cells.length;

                    if (childTreeLevel & gt; parentTreeLevel) {

                        var cell = tables[i].rows[0].cells[childTreeLevel - 1];

                        var inputs = cell.getElementsByTagName("INPUT");

                        inputs[0].checked = checkedState;

                    } else {

                        return;

                    }

                }

            }

        }

    }

}

沒有留言:

張貼留言