zoukankan      html  css  js  c++  java
  • 扩展TreeView控件(1) 联动复选框(复选框的全选和取消全选)

    TreeView既强大又好用。为了让它更强大、更好用,我们来写一个继承自TreeView的控件。
    [源码下载]


    扩展TreeView控件(1) - 联动复选框(复选框的全选和取消全选)


    作者:webabcd


    介绍
    扩展TreeView控件:
    联动复选框(复选框的全选和取消全选)。选中指定的父复选框,则设置其所有子复选框为选中状态;取消选中指定的父复选框,则设置其所有子复选框为取消选中状态。如果某父复选框的所有子复选框为均选中状态,则设置该父复选框为选中状态;如果某复选框的所有子复选框至少有一个为取消选中状态,则设置该父复选框为取消选中状态

    使用方法(设置属性):
    AllowCascadeCheckbox - 是否启用联动复选框功能


    关键代码
    相关的js
    //----------------------------
    //
     http://webabcd.cnblogs.com/
    //
    ----------------------------

    /*Helper 开始*/
    String.prototype.yy_stv_startsWith 
    = function(s)
    {   
    /// <summary>StartsWith()</summary>

        
    var reg = new RegExp("^" + s);   
        
    return reg.test(this);
    }


    function yy_stv_addEvent(obj, evtType, fn) 
    {
    /// <summary>绑定事件</summary>

        
    // FF
        if (obj.addEventListener)
        
    {
            obj.addEventListener(evtType, fn, 
    true);
            
    return true;
        }

        
    // IE
        else if (obj.attachEvent)
        
    {
            
    var r = obj.attachEvent("on" + evtType, fn);
            
    return r;
        }

        
    else
        
    {
            
    return false;
        }
        
    }

    /*Helper 结束*/


    /*联动复选框 开始*/
    var yy_stv_ccTreeView_pre = new Array(); // cs中动态向其灌数据(TreeView内控件ID的前缀数组)

    function yy_stv_ccClickCheckbox(e) 
    {
    /// <summary>单击复选框时</summary>

        
    var evt = e || window.event; // FF || IE
        var obj = evt.target || evt.srcElement  // FF || IE
        
        yy_stv_foreachChildCheckbox(obj);
        yy_stv_foreachParentCheckbox(obj);
    }



    function yy_stv_checkParentCheckbox(table, checked)
    {
    /// <summary>设置父复选框的状态</summary>

        
    var nodes = table.parentNode.parentNode.childNodes;
            
        
    for (var i=1; i<nodes.length; i++)
        
    {
            
    if (nodes[i] == table.parentNode)
            
    {
                
    if (typeof(nodes[i-1]) == 'undefined' || typeof(nodes[i-1].rows) == 'undefined') return;

                
    for (var x=0; x < nodes[i-1].rows.length; x++)
                
    {
                    
    for (var j=0; j < nodes[i-1].rows[x].cells.length; j++)
                    
    {
                        
    // debugger;
                        var chk = nodes[i-1].rows[x].cells[j].childNodes[0];
                        
    if (typeof(chk) != 'undefined' && chk.tagName == "INPUT" && chk.type == "checkbox"
                        
    {
                            chk.checked 
    = checked;
                            yy_stv_foreachParentCheckbox(nodes[i
    -1]);
                            
    return;
                        }

                    }

                }

            }

        }

    }


    function yy_stv_foreachChildCheckbox(obj)
    {   
    /// <summary>单击父复选框时,设置其子复选框的选中状态</summary>

        
    var checked;
        
        
    if (obj.tagName == "INPUT" && obj.type == "checkbox"
        
    {
            checked 
    = obj.checked;
            
    do
            
    {
                obj 
    = obj.parentNode;
            }
     
            
    while (obj.tagName != "TABLE")
        }

        
        
    var nodes = obj.parentNode.childNodes;
            
        
    for (var i=0; i<nodes.length - 1; i++)
        
    {
            
    if (nodes[i] == obj && nodes[i + 1].tagName == "DIV")
            
    {
                
    var elements = nodes[i+1].getElementsByTagName("INPUT");
                
                
    for (j=0; j< elements.length; j++
                
    {       
                    
    if (elements[j].type == 'checkbox') 
                    
    {
                        elements[j].checked 
    = checked;
                    }

                }
        
            }

        }

    }


    function yy_stv_foreachParentCheckbox(obj)
    {    
    /// <summary>单击某一复选框时,设置其父复选框的选中状态</summary>

        
    var checkedNum = 0;
        
    var uncheckedNum = 0;
        
        
    if (obj.tagName == "INPUT" && obj.type == "checkbox"
        
    {
            
    do
            
    {
                obj 
    = obj.parentNode;
            }
     
            
    while (obj.tagName != "TABLE")
        }

                    
        
    var tables = obj.parentNode.getElementsByTagName("TABLE");
         
        
    if (typeof(tables) == 'undefined') return;
           
        
    for (var i=0; i < tables.length; i++)
        
    {        
            
    for (var x=0; x < tables[i].rows.length; x++)
            
    {
                
    for (var j=0; j < tables[i].rows[x].cells.length; j++)
                
    {
                    
    var chk = tables[i].rows[x].cells[j].childNodes[0];
                    
    if (typeof(chk) != 'undefined' && chk.tagName == "INPUT" && chk.type == "checkbox"
                    
    {
                        
    if (chk.checked)
                            checkedNum 
    ++;
                        
    else
                            uncheckedNum 
    ++;
                    }

                }

            }

        }

        
        
    if (uncheckedNum == 0)
        
    {
            yy_stv_checkParentCheckbox(obj, 
    true);
        }

        
    else
        
    {
            yy_stv_checkParentCheckbox(obj, 
    false);
        }

    }



    function yy_stv_attachCheckboxClickListener()
    {
    /// <summary>监听所有联动复选框的单击事件</summary>

        
    var elements =  document.getElementsByTagName("INPUT");
        
        
    for (i=0; i< elements.length; i++
        
    {       
            
    if (elements[i].type == 'checkbox') 
            
    {
                
    for (j=0; j<yy_stv_ccTreeView_pre.length; j++)
                
    {
                    
    if (elements[i].id.yy_stv_startsWith(yy_stv_ccTreeView_pre[j]))
                    
    {
                        yy_stv_addEvent(elements[i], 'click', yy_stv_ccClickCheckbox); 
                        
    break;
                    }

                }

            }

        }
        
    }


    if (document.all)
    {
        window.attachEvent('onload', yy_stv_attachCheckboxClickListener);
    }

    else
    {
        window.addEventListener('load', yy_stv_attachCheckboxClickListener, 
    false);
    }

    /*联动复选框 结束*/

    说明:
    1、页面加载时为指定的TreeView的所有复选框绑定单击事件(根据复选框的前缀判断其是否属于指定的复选框)
    2、单击某复选框,则遍历其所有子复选框,并进行相应的操作。同时,遍历同级复选框,并对它们的父复选框进行操作,然后再遍历它们的父复选框的同级的复选框,以此类推往上走。

    相关的属性
    using System;
    using System.Collections.Generic;
    using System.Text;

    using System.ComponentModel;
    using System.Web.UI;

    namespace YYControls
    {
        
    /// <summary>
        
    /// SmartTreeView类的属性部分
        
    /// </summary>

        public partial class SmartTreeView
        
    {
            
    private bool _allowCascadeCheckbox;
            
    /// <summary>
            
    /// 是否启用联动复选框功能
            
    /// </summary>

            [
            Browsable(
    true),
            Description(
    "是否启用联动复选框功能"),
            Category(
    "扩展"),
            DefaultValue(
    false)
            ]
            
    public virtual bool AllowCascadeCheckbox
            
    {
                
    get return _allowCascadeCheckbox; }
                
    set { _allowCascadeCheckbox = value; }
            }


        }

    }


    相关的cs
    using System;
    using System.Collections.Generic;
    using System.Text;

    using System.Web.UI.WebControls;
    using System.Web.UI;

    namespace YYControls.SmartTreeViewFunction
    {
        
    /// <summary>
        
    /// 扩展功能:联动复选框
        
    /// </summary>

        public class CascadeCheckboxFunction : ExtendFunction
        
    {
            
    /// <summary>
            
    /// 构造函数
            
    /// </summary>

            public CascadeCheckboxFunction()
                : 
    base()
            
    {

            }


            
    /// <summary>
            
    /// 构造函数
            
    /// </summary>
            
    /// <param name="stv">SmartTreeView对象</param>

            public CascadeCheckboxFunction(SmartTreeView stv)
                : 
    base(stv)
            
    {

            }


            
    /// <summary>
            
    /// 扩展功能的实现
            
    /// </summary>

            protected override void Execute()
            
    {
                
    this._stv.PreRender += new EventHandler(_stv_PreRender);
            }


            
    /// <summary>
            
    /// SmartTreeView的PreRender事件
            
    /// </summary>
            
    /// <param name="sender"></param>
            
    /// <param name="e"></param>

            void _stv_PreRender(object sender, EventArgs e)
            
    {
                
    // 注册向数组中添加成员的脚本
                if (!this._stv.Page.ClientScript.IsClientScriptBlockRegistered(String.Format("yy_stv_cascadeCheckbox_{0}"this._stv.ID)))
                
    {
                    
    this._stv.Page.ClientScript.RegisterClientScriptBlock
                    (
                        
    this.GetType(),
                        String.Format(
    "yy_stv_cascadeCheckbox_{0}"this._stv.ID),
                        String.Format(
    "yy_stv_ccTreeView_pre.push('{0}');", Helper.Common.GetChildControlPrefix(this._stv)),
                        
    true
                    );
                }

            }

        }

    }



    OK
    [源码下载]
  • 相关阅读:
    jmeter压测-05-xpath表达式
    测试那些事-测试资源篇
    测试那些事-沟通篇
    测试那些事-前端
    测试那些事儿-后端
    记一次大数据量不同处理方式下服务器负载
    jmeter压测dubbo接口,参数为dto时如何写传参及有错误时的分析思路
    pyton3 字典排序
    python测试dubbo接口
    记录一下telnet测试dubbo接口,参数为dto时怎么测试,枚举类型传参
  • 原文地址:https://www.cnblogs.com/webabcd/p/862173.html
Copyright © 2011-2022 走看看