Asp.net datalist select all checkboxes for each category
I have a page where users can select different document files in a datalist control. Documents are classified into categories using a preprocessing event handler. Documents are selected based on Checkbox controls (not Checkboxlist). So far, so good. Next, I want to check the "Select All" box next to each category name, which should only select the checkboxes under that category. Here is the datalist control:
<asp:DataList ID="DataList1" runat="server" RepeatDirection="Vertical" OnPreRender="DataList1_PreRender" DataKeyField="docid" EnableViewState="false">
<ItemTemplate>
<table cellpadding="0" cellspacing="0" id="tbl_data">
<tr>
<td>
<asp:Label ID="lblHeader" runat="server" Font-Bold="True" Font-Underline="True"></asp:Label>
<asp:Label runat="server" id="lbl_cb_all" visible="false">Select All <input runat="server" id="cb_selectall" type="checkbox" value='<%# Eval("catid") %>' /> </asp:Label>
</td>
</tr>
<tr runat="server" id="tr_data">
<td>
<asp:Label ID="lbl_categoryname" runat="server" Text='<%# Eval("categoryname") %>' Visible="false" /> <!-- Hide this; only used in Code Behind -->
<input runat="server" id="cb_docid" type="checkbox" value='<%# Eval("docid") %>' />
<asp:Hyperlink ID="hpl_docfileencr" Text='<%# Eval("docfileencr") %>' NavigateUrl='<%# "~/PDFEncr/" + DataBinder.Eval(Container.DataItem, "docfileencr") %>' Target="_blank" runat="server" />
<br />
</td>
</tr>
</table>
</ItemTemplate>
and here is the OnPreRender code:
protected void DataList1_PreRender(object sender, EventArgs e)
{
string strTempLabelCategory = "";
foreach (DataListItem item in DataList1.Items)
{
Label lbl_categoryname = item.FindControl("lbl_categoryname") as Label;
if (strTempLabelCategory.ToUpper() != lbl_categoryname.Text.ToString().ToUpper())
{
strTempLabelCategory = lbl_categoryname.Text.ToString().ToUpper();
Label lblHeader = item.FindControl("lblHeader") as Label;
lblHeader.Text = strTempLabelCategory.ToUpper();
Label lbltempdiv = item.FindControl("lbl_cb_all") as Label;
lbltempdiv.Visible = true;
}
}
}
I was looking for something that might work in my code but no luck. And I am too nested in this code to try the Checkboxlist handler (not sure if it helps anyway). Any ideas? I thought I could use: http://www.dotnetcurry.com/ShowArticle.aspx?ID=77 code but don't know how I can do it? If I can somehow bind a checkmark to a tag and then search for all tags, then maybe the link code will help. Thank!
source to share
- Use HiddenFields to store
CatID
andDocID
- Use ASP.NET Controls instead of HTML Inputs for
- Edit the "Check-All Checkbox"
CheckedChanged
:
protected void CheckAllChanged(Object sender, EventArgs e)
{
CheckBox checkAll = (CheckBox)sender;
DataListItem item = (DataListItem)checkAll.NamingContainer;
HiddenField HiddenCatID = (HiddenField)item.FindControl("HiddenCatID");
var catCheckBoxes = DataList1.Items.Cast<DataListItem>()
.Where(li => ((HiddenField)li.FindControl("HiddenCatID")).Value == HiddenCatID.Value)
.Select(li => li.FindControl("cb_docid"));
foreach (CheckBox docCheckBox in catCheckBoxes)
{
docCheckBox.Checked = checkAll.Checked;
}
}
in aspx:
<asp:CheckBox runat="server" OnCheckedChanged="CheckAllChanged" AutoPostBack="true" id="cb_selectall" />
<asp:HiddenField ID="HiddenCatID" runat="server" Value='<%# Eval("CatID") %>' />
<asp:HiddenField ID="HiddenDocID" runat="server" Value='<%# Eval("DocID") %>' />
You also need EnableViewState=true
to store the checkbox state in the DataList and enable check / uncheck.
Edit
Since you have trouble getting it running, here is a complete working example page.
Here are the required aspx controls (note fe <tr runat="server" id="tr_category">)
:
<ItemTemplate>
<table cellpadding="0" cellspacing="0" id="tbl_data">
<tr runat="server" id="tr_category">
<td>
<asp:Label ID="lblHeader" runat="server" Font-Bold="True" Text='<%# Eval("categoryname") %>' Font-Underline="True"></asp:Label>
<asp:Label runat="server" ID="lbl_cb_all">Select All
<asp:CheckBox runat="server" OnCheckedChanged="CheckAllChanged" AutoPostBack="true" id="cb_selectall" />
</asp:Label>
</td>
</tr>
<tr runat="server" id="tr_data">
<td>
<asp:HiddenField ID="HiddenCatID" runat="server" Value='<%# Eval("CatID") %>' />
<asp:CheckBox runat="server" id="cb_docid" />
<asp:HyperLink ID="hpl_docfileencr" Text='<%# Eval("docfileencr") %>' NavigateUrl='<%# "~/PDFEncr/" + DataBinder.Eval(Container.DataItem, "docfileencr") %>'
Target="_blank" runat="server" />
<br />
</td>
</tr>
</table>
</ItemTemplate>
-
Make sure the DataList is only bound to the database
if(!IsPostback)
, otherwise the checkbox selection will not be saved:protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) BindDataList(); }
-
I use
ItemDataBound
insteadPreRender
, which is important to properly reload the ViewState. I've also simplified everything:protected void DataList1_ItemDataBound(Object sender, DataListItemEventArgs e) { if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType==ListItemType.AlternatingItem) { var row = (DataRowView)e.Item.DataItem; var view = row.DataView; var lastRow = e.Item.ItemIndex == 0 ? null : view[e.Item.ItemIndex-1]; var tr_category = (System.Web.UI.HtmlControls.HtmlTableRow)e.Item.FindControl("tr_category"); var sameCategory = lastRow != null && (int)row["catid"] == (int)lastRow["catid"]; tr_category.Visible = !sameCategory; } }
-
CheckAllChanged
remains unchanged.
This works as expected, even if you select one checkbox for the document and check the category checkbox that triggers the postback.
source to share
I think I got this to work with a slight modification to Tim's code. A couple of points: I had to disable the ViewState for the datalist because the check-all trigger would otherwise not check the checkboxes. I do not understand why. In addition, there is no ispostback check on the page_load event, and the datalist binding is bound to every load. I'm not that "optimal" or not. I also made two sets of Asp: RadioButtons: CheckAll and CheckNone instead of checkboxes. Anyway, here's the relevant code:
<asp:DataList ID="DataList1" runat="server" RepeatDirection="Vertical" DataKeyField="docid"
EnableViewState="false" OnItemDataBound="DataList1_ItemDataBound">
<ItemTemplate>
<table cellpadding="0" cellspacing="0" id="tbl_data">
<tr runat="server" id="tr_category">
<td>
<asp:Label ID="lblHeader" runat="server" Font-Bold="True" Text='<%# Eval("categoryname") %>'
Font-Underline="True"></asp:Label>
<asp:Label runat="server" ID="lbl_cb_all">Select: All
<asp:RadioButton runat="server" OnCheckedChanged="CheckAllChanged" AutoPostBack="true"
ID="rb_selectall" GroupName="selectallnone" />
| None
<asp:RadioButton runat="server" OnCheckedChanged="CheckAllChangedNone" AutoPostBack="true"
ID="rb_selectnone" GroupName="selectallnone" />
<asp:HiddenField ID="HiddenCatID" runat="server" Value='<%# Eval("CatID") %>' />
<asp:HiddenField ID="HiddenDocID" runat="server" Value='<%# Eval("docid") %>' />
</asp:Label>
</td>
</tr>
<tr runat="server" id="tr_data">
<td>
<asp:CheckBox runat="server" ID="cb_docid" Value='<%# Eval("docid") %>' />
<asp:HyperLink ID="hpl_docfileencr" Text='<%# Eval("docfileencr") %>' NavigateUrl='<%# "~/PDFEncr/" + DataBinder.Eval(Container.DataItem, "docfileencr") %>'
Target="_blank" runat="server" />
<br />
</td>
</tr>
</table>
</ItemTemplate>
</asp:DataList>
protected void DataList1_ItemDataBound(Object sender, DataListItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var row = (DataRowView)e.Item.DataItem;
var view = row.DataView;
var lastRow = e.Item.ItemIndex == 0 ? null : view[e.Item.ItemIndex - 1];
var tr_category = (System.Web.UI.HtmlControls.HtmlTableRow)e.Item.FindControl("tr_category");
var sameCategory = lastRow != null && (int)row["catid"] == (int)lastRow["catid"];
tr_category.Visible = !sameCategory;
}
}
protected void CheckAllChanged(Object sender, EventArgs e)
{
RadioButton checkAll = (RadioButton)sender;
DataListItem item = (DataListItem)checkAll.NamingContainer;
HiddenField HiddenCatID = (HiddenField)item.FindControl("HiddenCatID");
var catCheckBoxes = DataList1.Items.Cast<DataListItem>()
.Where(li => ((HiddenField)li.FindControl("HiddenCatID")).Value == HiddenCatID.Value)
.Select(li => li.FindControl("cb_docid"))
.ToList();
foreach (CheckBox docCheckBox in catCheckBoxes)
{
// docCheckBox.Checked = checkAll.Checked;
docCheckBox.Checked = true;
}
}
protected void CheckAllChangedNone(Object sender, EventArgs e)
{
RadioButton checkAll = (RadioButton)sender;
DataListItem item = (DataListItem)checkAll.NamingContainer;
HiddenField HiddenCatID = (HiddenField)item.FindControl("HiddenCatID");
var catCheckBoxes = DataList1.Items.Cast<DataListItem>()
.Where(li => ((HiddenField)li.FindControl("HiddenCatID")).Value == HiddenCatID.Value)
.Select(li => li.FindControl("cb_docid"))
.ToList();
foreach (CheckBox docCheckBox in catCheckBoxes)
{
docCheckBox.Checked = false;
}
}
// the partial code from the "Order" button is executed; note the use of HiddenField
CheckBox cb = li.FindControl("cb_docid") as CheckBox;
if (cb != null)
{
if (cb.Checked)
{
HiddenField docid = li.FindControl("HiddenDocID") as HiddenField;
string dbcmd = @"Insert Into [order_details] (orderid,docid) Values (" + orderid + "," + docid.Value.ToString() + ")";
source to share