擴展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(' yy_stv_attachCheckboxClickListener);
}
else
{
        window.addEventListener('load', yy_stv_attachCheckboxClickListener, false);
}
/*聯動複選框 結束*/
 
說明:
一、頁面加載時爲指定的TreeView的全部複選框綁定單擊事件(根據複選框的前綴判斷其是否屬於指定的複選框)
二、單擊某複選框,則遍歷其全部子複選框,並進行相應的操做。同時,遍歷同級複選框,並對它們的父複選框進行操做,而後再遍歷它們的父複選框的同級的複選框,以此類推往上走。

相關的屬性
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
                                );
                        }
                }
        }
}
 
相關文章
相關標籤/搜索