Introduction
Selecting multiple checkboxes inside a GridView control has been a lot of discussion but I was unable to find any solution to the following problems.
- If the page has two or more GridViews?
- If Gridviews are in user control?
- If the page has a master page?
And here are a few changes.
Adding Master Page and User Controls
1. Add a master page MasterPage.master.
2. Add two user controls First.ascx and Second.ascx having GridViewFirst and GridviewSecond respectively.
<asp:GridView ID="GridViewFirst" runat="server" AutoGenerateColumns="False" CellPadding="4" Font-Names="Verdana" ForeColor="#333333" GridLines="None">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<input type="checkbox" id="chkAll1" onclick="Check(this,'(GridViewFirst)+')" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Category Name">
<ItemTemplate>
<asp:Label ID="lblCategoryName" runat="server" Text='<%# Eval("CategoryName") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
<PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
<HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
<asp:GridView ID="GridViewSecond" runat="server" AutoGenerateColumns="False" CellPadding="4" Font-Names="Verdana" ForeColor="#333333" GridLines="None">
<Columns>
<asp:TemplateField>
<HeaderTemplate>
<input type="checkbox" id="chkAll2" onclick="Check(this,'(GridViewSecond)+')" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Category Name">
<ItemTemplate>
<asp:Label ID="lblCategoryName" runat="server" Text='<%# Eval("CategoryName") %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
<PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
<HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
Web Page Setup with MasterPage.master
3. Add a web page with MasterPage.master as its master and put the two user controls in it.
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
HtmlGenericControl body = (HtmlGenericControl)Page.Master.FindControl("MasterBody");
body.Attributes.Add("onload", "AttachListener('(GridViewFirst)');AttachListener('(GridViewSecond)')");
}
}
JavaScript Modifications
4. Now few changes in JavaScript. You can validate your JavaScript regular expression here.
var counter1 = 0;
var counter2 = 0;
function GetChildCheckBoxCount(pattern) {
var checkBoxCount = 0;
var elements = document.getElementsByTagName("INPUT");
for (i = 0; i < elements.length; i++) {
if (IsCheckBox(elements[i]) && IsMatch(elements[i].id, pattern)) checkBoxCount++;
}
return parseInt(checkBoxCount);
}
function IsMatch(id, pattern) {
var regularExpresssion = new RegExp(pattern);
if (id.match(regularExpresssion)) return true;
else return false;
}
function IsCheckBox(chk) {
if (chk.type == 'checkbox') return true;
else return false;
}
function AttachListener(pattern) {
var elements = document.getElementsByTagName("INPUT");
for (i = 0; i < elements.length; i++) {
if (IsCheckBox(elements[i]) && IsMatch(elements[i].id, pattern)) {
AddEvent(elements[i], 'click', CheckChild);
}
}
}
function CheckChild(e) {
var evt = e || window.event;
var obj = evt.target || evt.srcElement
if (IsMatch(obj.id, "(GridViewFirst)")) {
if (obj.checked) {
if (counter1 < GetChildCheckBoxCount("(GridViewFirst)")) {
counter1++;
}
} else {
if (counter1 > 0) {
counter1--;
}
}
if (counter1 == GetChildCheckBoxCount("(GridViewFirst)")) {
document.getElementById("chkAll1").checked = true;
} else if (counter1 < GetChildCheckBoxCount("(GridViewFirst)")) {
document.getElementById("chkAll1").checked = false;
}
} else if (IsMatch(obj.id, "(GridViewSecond)")) {
if (obj.checked) {
if (counter2 < GetChildCheckBoxCount("(GridViewSecond)")) {
counter2++;
}
} else {
if (counter2 > 0) {
counter2--;
}
}
if (counter2 == GetChildCheckBoxCount("(GridViewSecond)")) {
document.getElementById("chkAll2").checked = true;
} else if (counter2 < GetChildCheckBoxCount("(GridViewSecond)")) {
document.getElementById("chkAll2").checked = false;
}
}
}
function AddEvent(obj, evType, fn) {
if (obj.addEventListener) {
obj.addEventListener(evType, fn, true);
return true;
} else if (obj.attachEvent) {
var r = obj.attachEvent("on" + evType, fn);
return r;
} else {
return false;
}
}
function Check(parentChk, pattern) {
var elements = document.getElementsByTagName("INPUT");
for (i = 0; i < elements.length; i++) {
if (parentChk.checked == true) {
if (IsCheckBox(elements[i]) && IsMatch(elements[i].id, pattern)) {
elements[i].checked = true;
}
} else {
if (IsCheckBox(elements[i]) && IsMatch(elements[i].id, pattern)) {
elements[i].checked = false;
}
if (IsMatch('GridViewFirst', pattern)) {
counter1 = 0;
} else if (IsMatch('GridViewSecond', pattern)) {
counter2 = 0;
}
}
}
if (parentChk.checked == true && IsMatch('GridViewFirst', pattern)) {
counter1 = GetChildCheckBoxCount(pattern);
} else if (parentChk.checked == true && IsMatch('GridViewSecond', pattern)) {
counter2 = GetChildCheckBoxCount(pattern);
}
}
Hope this helps!