Introduction
Selecting multiple checkboxes inside a GridView control has been lot in discussion but I was unable to find any solution to following problems:
- If page has two or more GridViews?
- If Gridviews are in usercontrol?
- If page has a Masterpage?
So to sort out these problems I picked an article that was of great help "GridView CheckBox Selection With a Twist". And here are few changes.
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 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" />
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)')");
}
}
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!