Click here to Skip to main content
15,867,594 members
Articles / Web Development / XHTML
Article

Maintaining States of Selected CheckBoxes in Different Pages inside the GridView

Rate me:
Please Sign up or sign in to vote.
4.96/5 (65 votes)
25 Dec 2008CPOL4 min read 216.3K   5.1K   128   36
This article describes how to manage states of the Checkboxes inside the GridView in different pages.
Preview.gif

Introduction

Here, I am going to present how to maintain selected CheckBoxes’ states in different pages inside the GridView control.

Background

If you have a Gmail account then probably you have observed a great feature of maintaining selected CheckBoxes states in different pages on Inbox Grid, i.e. suppose that you are in the first page of your Inbox & select some mails through CheckBoxes & move to the second page. You also select some mails there and further move to the next page. Finally you return back to the first/second page where you find that all the previously selected mails are already selected. This means that Gmail maintains all the selected mails’ states in deferent pages of Inbox Grid. Now if you select mails in different pages of the Inbox Grid & click Delete link, then only current page’s selected mails are deleted. But my clients wanted some more advanced features. Actually my client’s requirement was to delete all pages’ selected mails by clicking on Delete link. So I started to work on it & finally came up with this solution.

Implementation Details

To implement this functionality, I've divided it into three parts:

  • Selecting / Deselecting all the CheckBoxes Inside a GridView.
    I've achieved this functionality using HeaderClick & ChildClick JavaScript methods.
  • Restoring selected CheckBoxes states Inside a GridView for particular pages.
    I've achieved this functionality by invoking RestoreState method in the window.onload event.
  • Storing selected Checkboxes Row-Ids.
    I've used HiddenField hdnFldSelectedValues for this purpose. It maintains Row-Ids of selected CheckBoxes’ separated by ‘|’.

HTML Code

I have used a TemplateField inside the GridView & put a CheckBox and a HiddenField in the ItemTemplate as well as another CheckBox in the HeaderTemplate of the TemplateField. To identify each GridView Row uniquely, I've used AutoIncrement column in the datasource & bind it to the HiddenField hdnFldId. But it can be anything, e.g. row id from the database, etc.

ASP.NET
<asp:GridView ID="gvCheckboxes" runat="server" 
	AutoGenerateColumns="False" AllowPaging="True"        
                  OnPageIndexChanging="gvCheckboxes_PageIndexChanging" 
			OnRowDataBound="gvCheckboxes_RowDataBound">
   <Columns>
      <asp:TemplateField HeaderText="Select">
         <ItemTemplate>
            <asp:CheckBox ID="chkBxSelect" runat="server" />
            <asp:HiddenField ID="hdnFldId" runat="server" Value='<%# Eval("Id") %>' />
         </ItemTemplate>
         <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="50px" />
         <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="50px" />
         <HeaderTemplate>
            <asp:CheckBox ID="chkBxHeader" onclick="javascript:HeaderClick(this);" 
		runat="server" />
         </HeaderTemplate>
      </asp:TemplateField>
         <asp:BoundField DataField="RandomNo" HeaderText="Random Number">
         <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="150px" />
         <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="150px" />
      </asp:BoundField>
      <asp:BoundField DataField="Date" HeaderText="Date">
         <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="75px" />
         <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="75px" />
      </asp:BoundField>
      <asp:BoundField DataField="Time" HeaderText="Time">
         <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="100px" />
         <ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="100px" />
      </asp:BoundField>
   </Columns>
   <RowStyle BackColor="Moccasin" />
   <AlternatingRowStyle BackColor="NavajoWhite" />
   <HeaderStyle BackColor="DarkOrange" Font-Bold="True" ForeColor="White" />
</asp:GridView>

I've also added a HiddenFiled in the page to keep track of Row-Ids of corresponding selected CheckBoxes.

ASP.NET
<asp:HiddenField ID="hdnFldSelectedValues" runat="server" />

Attaching Click Events

I've attached onclick event on header CheckBox as:

ASP.NET
<asp:CheckBox ID="chkBxHeader" 
	onclick="javascript:HeaderClick(this);" runat="server" />

I've also attached onclick event on each Row-CheckBox through RowDataBound event of the GridView as:

C#
if (e.Row.RowType == DataControlRowType.DataRow && 
	(e.Row.RowState == DataControlRowState.Normal ||
                e.Row.RowState == DataControlRowState.Alternate))
{
   CheckBox chkBxSelect = (CheckBox)e.Row.Cells[0].FindControl("chkBxSelect");
   CheckBox chkBxHeader = (CheckBox)this.gvCheckboxes.HeaderRow.FindControl
				("chkBxHeader");
   HiddenField hdnFldId = (HiddenField)e.Row.Cells[0].FindControl("hdnFldId");
   chkBxSelect.Attributes["onclick"] = string.Format
                                       (
                                         "javascript:ChildClick(this,document.
					getElementById('{0}'),'{1}');",            
                                          chkBxHeader.ClientID, hdnFldId.Value.Trim()
                                       );
}

Page’s window.onload Event

I've used window.onload event to initialize global variables as well as to restore the previous states of all CheckBoxes in a particular column inside the GridView.

JavaScript
//Reference of the GridView. 
var TargetBaseControl = null;
//Total no of checkboxes in a particular column inside the GridView.
var CheckBoxes;
//Total no of checked checkboxes in a particular column inside the GridView.
var CheckedCheckBoxes;
//Array of selected item's Ids.
var SelectedItems;
//Hidden field that will contain string of selected item's Ids separated by '|'.
var SelectedValues;
        
window.onload = function()
{
   //Get reference of the GridView. 
   try
   {
      TargetBaseControl = document.getElementById('<%= this.gvCheckboxes.ClientID %>');
   }
   catch(err)
   {
      TargetBaseControl = null;
   }
            
   //Get total no of checkboxes in a particular column inside the GridView.
   try
   {
      CheckBoxes = parseInt('<%= this.gvCheckboxes.Rows.Count %>');
   }
   catch(err)
   {
      CheckBoxes = 0;
   }
            
   //Get total no of checked checkboxes in a particular column inside the GridView.
   CheckedCheckBoxes = 0;
            
   //Get hidden field that will contain string of selected item's Ids separated by '|'.
   SelectedValues = document.getElementById('<%= this.hdnFldSelectedValues.ClientID %>');
            
   //Get an array of selected item's Ids.
   if(SelectedValues.value == '')
      SelectedItems = new Array();
   else
      SelectedItems = SelectedValues.value.split('|');
                
   //Restore selected CheckBoxes' states.
   if(TargetBaseControl != null)
      RestoreState();
}

GridView’s Header Checkbox’s Click Event

This event gets fired whenever GridView’s header CheckBox is clicked. In this event, states of all Row-CheckBoxes is changed depending upon the state of the header CheckBox as well as Id of each Row is maintained in the SelectedItems array if header CheckBox is checked, else removed from the SelectedItems array. Values of SelectedValues <code><code>HiddenField & CheckedCheckBoxes counter are also updated in this event.

JavaScript
function HeaderClick(CheckBox)
{            
    //Get all the control of the type INPUT in the base control.
    var Inputs = TargetBaseControl.getElementsByTagName('input');
            
    //Checked/Unchecked all the checkBoxes in side the GridView & 
    //modify selected items array.
    for(var n = 0; n < Inputs.length; ++n)
        if(Inputs[n].type == 'checkbox' && Inputs[n].id.indexOf('chkBxSelect',0) >= 0)
        {
            Inputs[n].checked = CheckBox.checked;
            if(CheckBox.checked)
                SelectedItems.push(document.getElementById(Inputs[n].id.replace
			('chkBxSelect','hdnFldId')).value);
            else
                DeleteItem(document.getElementById(Inputs[n].id.replace
			('chkBxSelect','hdnFldId')).value);
        }
                        
    //Update Selected Values. 
    SelectedValues.value = SelectedItems.join('|');
                        
    //Reset Counter
    CheckedCheckBoxes = CheckBox.checked ? CheckBoxes : 0;
}

GridView’s Rows Checkboxes’s Click Event

This event gets fired whenever any CheckBox of GridView’s Rows CheckBoxes is clicked. In this event, first CheckedCheckBoxes counter is updated & state of the header CheckBox is changed accordingly. After that entry for Row-Id containing this particular ChecBox is maintained/removed in/from the SelectedItems array. Then value of SelectedValues HiddenField is updated from the SelectedItems array.

JavaScript
function ChildClick(CheckBox, HCheckBox, Id)
{               
   //Modify Counter;            
   if(CheckBox.checked && CheckedCheckBoxes < CheckBoxes)
      CheckedCheckBoxes++;
   else if(CheckedCheckBoxes > 0) 
      CheckedCheckBoxes--;
                
   //Change state of the header CheckBox.
   if(CheckedCheckBoxes < CheckBoxes)
      HCheckBox.checked = false;
   else if(CheckedCheckBoxes == CheckBoxes)
      HCheckBox.checked = true;
                
   //Modify selected items array.
   if(CheckBox.checked)
      SelectedItems.push(Id);
   else
      DeleteItem(Id);
                
   //Update Selected Values. 
   SelectedValues.value = SelectedItems.join('|');
}  

RestoreState Method

This method is invoked in the window.onload event. This method is basically used to restore the previous states of all CheckBoxes in a particular column inside the GridView in deferent pages. If the entry of a particular CheckBox is found in the SelectedItems array, then its state becomes checked. After that state of the header CheckBox is also updated.

JavaScript
function RestoreState()
{
   //Get all the control of the type INPUT in the base control.
   var Inputs = TargetBaseControl.getElementsByTagName('input');
            
   //Header CheckBox
   var HCheckBox = null;
            
   //Restore previous state of the all checkBoxes in side the GridView.
   for(var n = 0; n < Inputs.length; ++n)
      if(Inputs[n].type == 'checkbox' && Inputs[n].id.indexOf('chkBxSelect',0) >= 0)
         if(IsItemExists(document.getElementById(Inputs[n].id.replace
		('chkBxSelect','hdnFldId')).value) > -1)
         {
            Inputs[n].checked = true;          
            CheckedCheckBoxes++;      
         }
         else
            Inputs[n].checked = false;   
      else if(Inputs[n].type == 'checkbox' && 
		Inputs[n].id.indexOf('chkBxHeader',0) >= 0) 
         HCheckBox = Inputs[n];  
                    
   //Change state of the header CheckBox.
   if(CheckedCheckBoxes < CheckBoxes)
      HCheckBox.checked = false;
   else if(CheckedCheckBoxes == CheckBoxes)
      HCheckBox.checked = true;  
}

DeleteItem Method

This method is used to remove an entry for a particular CheckBox from the SelectedItems array.

JavaScript
function DeleteItem(Text)
{
   var n = IsItemExists(Text);
   if( n > -1)
      SelectedItems.splice(n,1);
}

IsItemExists Method

This method is used to check whether an entry for a particular CheckBox exists in the SelectedItems array or not.

JavaScript
function IsItemExists(Text)
{
   for(var n = 0; n < SelectedItems.length; ++n)
      if(SelectedItems[n] == Text)
         return n;
                 
      return -1;  
}  

Deleting Selected Items From Different Pages

Now finally to delete all selected CheckBoxes in all different pages. Simply get all the selected Ids & delete selected items using appropriate method in the Link's/Button's delete event handler as:

C#
protected void btnDelete_Click(object sender, EventArgs e)
{
   //Get Ids
   string[] IDs = hdnFldSelectedValues.Value.Trim().Split('|');
   
   //Code for deleting items
   foreach (string Item in IDs)
   {
      //Call appropriate method for deletion operation.
   }
}

Conclusion

So this is my solution. If you have some other ideas about this functionality, please share them with me.

Supporting Browsers

I have tested this functionality using the following browsers:

Browsers.png

History

  • 18th December, 2008 -- Original version posted
  • 26th December, 2008 -- Article updated

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Technical Lead Infogain India Pvt Ltd
India India


Samir NIGAM is a Microsoft Certified Professional. He is an insightful IT professional with results-driven comprehensive technical skill having rich, hands-on work experience n web-based applications using ASP.NET, C#, AJAX, Web Service, WCF, jQuery, Microsoft Enterprise Library , LINQ, MS Entity Framework, nHibernate, MS SQL Server & SSRS.



He has earned his master degree (MCA) from U.P. Technical University, Lucknow, INDIA, his post graduate dipoma (PGDCA ) from Institute of Engineering and Rural Technology, Allahabad, INDIA and his bachelor degree (BSc - Mathematics) from University of Allahabad, Allahabad, INDIA.



He has good knowledge of Object Oriented Programming, n-Tier Architecture, SOLID Principle, and Algorithm Analysis & Design as well as good command over cross-browser client side programming using JavaScript & jQuery,.



Awards:



Comments and Discussions

 
QuestionCan maintain check boxes Using session wrapper in another class please help me out Pin
Member 104014255-Oct-15 2:35
Member 104014255-Oct-15 2:35 
BugLittle bug in this code Pin
Member 1045285422-Oct-14 20:19
Member 1045285422-Oct-14 20:19 
GeneralRe: Little bug in this code Pin
Member 1181641910-May-19 0:21
Member 1181641910-May-19 0:21 
QuestionMaintaining States of Selected CheckBoxes in Different Pages inside the GridView Pin
DNYANESHWAR KAWATHE6-Jul-12 3:15
DNYANESHWAR KAWATHE6-Jul-12 3:15 
QuestionIndeed very helpul. Need a little help Pin
Member 298021718-Nov-11 3:26
Member 298021718-Nov-11 3:26 
Generalthis is not working in update panel Pin
apprajju17-Mar-11 2:30
apprajju17-Mar-11 2:30 
Questionissue with select all? Pin
SeeItNow20-Aug-09 3:31
SeeItNow20-Aug-09 3:31 
Samir,

Like the others, I'm very grateful to you for posting this. I used it, and added some additional arrays for other row items I wanted to save (since gridview won't let you work with visible=false data items, as far as I know).

I noticed something as I was trying to test it (in your version as well).

It seems that if you do the following, duplicate items start appending to the array:

1. check the select all box
2. page to next page
3. go back to previous page and uncheck some items.
4. page to next page again.
5. go back and check the select all box. It looks like the previously unchecked items are checked again. But, also if you look at the array, the list of all the ids on the page are appended to the array causing duplicates of ids that were checked previously.

I added the following label and code so I could see the array from page to page:

<asp:Label ID="lblCheckboxState" runat="server"></asp:Label>

in Page_Load:
//debug check box saved state
lblCheckboxState.Text =
"&nbsp; Ids: " + hdnFldSelectedValues.Value.Trim() +
".";

I haven't found a solution yet - wish I knew JavaScript as well as you do. But, I'll work on it and let you know what I find.

Thanks again,
-Bill
AnswerRe: issue with select all? Pin
SeeItNow20-Aug-09 5:19
SeeItNow20-Aug-09 5:19 
AnswerError in databinding Pin
Member 357803213-Apr-11 4:44
Member 357803213-Apr-11 4:44 
QuestionExample for column accessing Pin
Berthold Lohrentz19-Mar-09 8:42
Berthold Lohrentz19-Mar-09 8:42 
QuestionHow to make it work with AJAX ? Pin
Ben Teo1-Mar-09 16:11
Ben Teo1-Mar-09 16:11 
AnswerRe: How to make it work with AJAX ? Pin
Derec Roofie31-Mar-09 1:27
Derec Roofie31-Mar-09 1:27 
GeneralDoes not work with a gridview placed on pop window Pin
ojaytee22-Feb-09 21:11
ojaytee22-Feb-09 21:11 
GeneralIt helped me a lot. Pin
Member 323966127-Jan-09 18:54
Member 323966127-Jan-09 18:54 
GeneralRe: It helped me a lot. Pin
Samir NIGAM27-Jan-09 20:16
Samir NIGAM27-Jan-09 20:16 
GeneralNice Artical Pin
Anand Ashish7-Jan-09 0:18
Anand Ashish7-Jan-09 0:18 
GeneralRe: Nice Artical Pin
Samir NIGAM7-Jan-09 2:17
Samir NIGAM7-Jan-09 2:17 
GeneralFantastic work Pin
4866030_us2-Jan-09 21:07
4866030_us2-Jan-09 21:07 
GeneralRe: Fantastic work Pin
Samir NIGAM5-Jan-09 2:09
Samir NIGAM5-Jan-09 2:09 
Generalreally nice Pin
Mohamad Kaifi22-Dec-08 1:26
Mohamad Kaifi22-Dec-08 1:26 
GeneralRe: really nice Pin
Samir NIGAM22-Dec-08 17:40
Samir NIGAM22-Dec-08 17:40 
GeneralGreat Article Pin
Viral Upadhyay18-Dec-08 7:00
Viral Upadhyay18-Dec-08 7:00 
GeneralRe: Great Article Pin
Samir NIGAM18-Dec-08 18:07
Samir NIGAM18-Dec-08 18:07 
GeneralYou r the man......... :) Pin
Mr Ashish Anand18-Dec-08 2:15
Mr Ashish Anand18-Dec-08 2:15 
GeneralRe: You r the man......... :) Pin
Samir NIGAM18-Dec-08 18:03
Samir NIGAM18-Dec-08 18:03 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.