GridView CheckBox Selection With a Twist
http://www.codeproject.com/cs/miscctrl/GridViewCheckBox.asp
不過它的範例在GridView具有二個以上的「全選/取消全選」欄位時會發生問題,勾選了其中一個欄位時,會造成GridView中所有的欄位都被勾選,如下圖所示。
針對以上的問題,以它的程式碼做部分修正。
首先在頁面上放置一個GridView控制項,要做「全選/取消全選」功能的欄位要以TemplateField來實作。
在TemplateField的HeaderTemplate中加入一個CheckBox做為「全選/取消全選」的操作,CheckBox的onclick執行JavaScript Check()函式。
1
<
HeaderTemplate
>
2 < input type ="checkbox" id ="chkAll" name ="chkAll" onclick ="Check(this,'chkSelect1')" /> CategoryName
3 </ HeaderTemplate >
2 < input type ="checkbox" id ="chkAll" name ="chkAll" onclick ="Check(this,'chkSelect1')" /> CategoryName
3 </ HeaderTemplate >
在ItemTemplate加入CheckBox及Label,其中CheckBox的ID設為chkSelect1,即為HeaderTemplate的Check()函式的第二個引數。
1
<
ItemTemplate
>
2 < asp:CheckBox ID ="chkSelect1" runat ="server" />
3 < asp:Label ID ="Label1" runat ="server" Text ='<%# Bind("CategoryName") % > '> </ asp:Label >
4 </ ItemTemplate >
2 < asp:CheckBox ID ="chkSelect1" runat ="server" />
3 < asp:Label ID ="Label1" runat ="server" Text ='<%# Bind("CategoryName") % > '> </ asp:Label >
4 </ ItemTemplate >
因為要做二個欄位的「全選/取消全選」,故將TemplateField複製一份,並將第二個TemplateField的 ItemTemplate中CheckBox的ID設為chkSelect2,其HeaderTemplate的Check()函式第二個引數即為 chkSelect2。
GridView完整的aspx程式碼如下
1
<
asp:GridView
ID
="GridView1"
runat
="server"
AutoGenerateColumns
="False"
DataKeyNames
="CategoryID"
2 DataSourceID ="SqlDataSource2" EmptyDataText ="沒有資料錄可顯示。" >
3 < Columns >
4 < asp:TemplateField HeaderText ="CategoryID" SortExpression ="CategoryName" >
5 < HeaderTemplate >
6 < input type ="checkbox" id ="chkAll" name ="chkAll" onclick ="Check(this,'chkSelect')" /> CategoryName
7 </ HeaderTemplate >
8 < ItemTemplate >
9 < asp:CheckBox ID ="chkSelect" runat ="server" />
10 < asp:Label ID ="Label1" runat ="server" Text ='<%# Bind("CategoryName") % > '> </ asp:Label >
11 </ ItemTemplate >
12 </ asp:TemplateField >
13 < asp:TemplateField HeaderText ="CategoryID" SortExpression ="CategoryName" >
14 < HeaderTemplate >
15 < input type ="checkbox" id ="chkAll" name ="chkAll" onclick ="Check(this,'chkSelect2')" /> CategoryName
16 </ HeaderTemplate >
17 < ItemTemplate >
18 < asp:CheckBox ID ="chkSelect2" runat ="server" />
19 < asp:Label ID ="Label1" runat ="server" Text ='<%# Bind("CategoryName") % > '> </ asp:Label >
20 </ ItemTemplate >
21 </ asp:TemplateField >
22 < asp:BoundField DataField ="Description" HeaderText ="Description" SortExpression ="Description" />
23 </ Columns >
24 </ asp:GridView >
25
2 DataSourceID ="SqlDataSource2" EmptyDataText ="沒有資料錄可顯示。" >
3 < Columns >
4 < asp:TemplateField HeaderText ="CategoryID" SortExpression ="CategoryName" >
5 < HeaderTemplate >
6 < input type ="checkbox" id ="chkAll" name ="chkAll" onclick ="Check(this,'chkSelect')" /> CategoryName
7 </ HeaderTemplate >
8 < ItemTemplate >
9 < asp:CheckBox ID ="chkSelect" runat ="server" />
10 < asp:Label ID ="Label1" runat ="server" Text ='<%# Bind("CategoryName") % > '> </ asp:Label >
11 </ ItemTemplate >
12 </ asp:TemplateField >
13 < asp:TemplateField HeaderText ="CategoryID" SortExpression ="CategoryName" >
14 < HeaderTemplate >
15 < input type ="checkbox" id ="chkAll" name ="chkAll" onclick ="Check(this,'chkSelect2')" /> CategoryName
16 </ HeaderTemplate >
17 < ItemTemplate >
18 < asp:CheckBox ID ="chkSelect2" runat ="server" />
19 < asp:Label ID ="Label1" runat ="server" Text ='<%# Bind("CategoryName") % > '> </ asp:Label >
20 </ ItemTemplate >
21 </ asp:TemplateField >
22 < asp:BoundField DataField ="Description" HeaderText ="Description" SortExpression ="Description" />
23 </ Columns >
24 </ asp:GridView >
25
在頁面加入下列的JavaScript程式碼,其中Check()即為GridView表頭CheckBox的呼叫的函式。
1
<
script type
=
"
text/javascript
"
>
2 function Check(parentChk,ChildId)
3 {
4 var oElements = document.getElementsByTagName( " INPUT " );
5 var bIsChecked = parentChk.checked;
6
7 for (i = 0 ; i < oElements.length;i ++ )
8 {
9 if ( IsCheckBox(oElements[i]) &&
10 IsMatch(oElements[i].id, ChildId))
11 {
12 oElements[i].checked = bIsChecked;
13 }
14 }
15 }
16
17 function IsMatch(id, ChildId)
18 {
19 var sPattern = ' ^ GridView1. * ' + ChildId + '$';
20 var oRegExp = new RegExp(sPattern);
21 if (oRegExp.exec(id))
22 return true ;
23 else
24 return false ;
25 }
26
27 function IsCheckBox(chk)
28 {
29 if (chk.type == 'checkbox') return true ;
30 else return false ;
31 }
32 </ script >
33
2 function Check(parentChk,ChildId)
3 {
4 var oElements = document.getElementsByTagName( " INPUT " );
5 var bIsChecked = parentChk.checked;
6
7 for (i = 0 ; i < oElements.length;i ++ )
8 {
9 if ( IsCheckBox(oElements[i]) &&
10 IsMatch(oElements[i].id, ChildId))
11 {
12 oElements[i].checked = bIsChecked;
13 }
14 }
15 }
16
17 function IsMatch(id, ChildId)
18 {
19 var sPattern = ' ^ GridView1. * ' + ChildId + '$';
20 var oRegExp = new RegExp(sPattern);
21 if (oRegExp.exec(id))
22 return true ;
23 else
24 return false ;
25 }
26
27 function IsCheckBox(chk)
28 {
29 if (chk.type == 'checkbox') return true ;
30 else return false ;
31 }
32 </ script >
33
其中Check()函式中,主要是去尋找所有Tag為Input的Element,再去過濾它的id名稱。 因為GridView中的子控制項命名有一定的規則,檢視HTML程式碼可以發現GridView同一個欄位CheckBox命名為以 GridView的ID開頭,而以CheckBox的ID為結尾;所以IsMatch()函式中,就是利用這個規則去判斷是否為同欄位的 CheckBox。
執行的結果如下