How to get the checkbox value from a dynamically generated checkbox list in asp.net

24,038

Solution 1

There are two schools of thought; one, that you need to recreate the control hierarchy that was made for the initial view so that the page can restore the view state and form values into the control tree, or two, that you can go with a low tech solution and simply get the values from the form collection.

I personally, like option two, and it's relatively easy to deal with, and since it looks like you're already manually creating the HTML with LiteralControl. Simply provide a name attribute that is shared among your manually created input tags (example shown here for brevity, this is probably not what you will do):

entityContainer.Controls.Add(new LiteralControl("<input type='checkbox' name='mySharedName' />");

Then, to get the values it is as simple as this:

 var selectedValues = Request.Form["mySharedName"];
 // This is now a comma separated list of values that was checked

Then you dont have to worry about the control tree state.

Solution 2

It sounds like you could make life much easier just using a CheckBoxList instead, and binding your result set to it. That would actually nullify the need for any dynamic content.

<asp:CheckBoxList ID="CheckList1" runat="server" DataTextField="TextColumn" DataValueField="ValueColumn" ...>

If that's not an option, then you need to recreate the controls after each postback. There are a couple ways to do this.

The easy way

Check out the DynamicControlsPlaceHolder control. This is a useful little control that takes care of persisting dynamic content behind the scenes. I would suggest this option, as it takes all of the pain away from dynamically created content.

The manual way

Recreate the control(s) during OnInit. Just make sure you assign the same ID to the controls so that ViewState can repopulate the selections:

protected override void OnInit(EventArgs e)
{
    var chk = new CheckBox { ID = "chkBox1" };                 
    PlaceHolder1.Controls.Add(chk);

    base.OnInit(e);
}    

After recreating the control after the postback, you should be able to access the values like this:

foreach (CheckBox chk in PlaceHolder1.Controls.OfType<CheckBox>())
{
    if (chk.Checked)
    {

    }     
}
Share:
24,038
rlcrews
Author by

rlcrews

Full stack developer focusing on AWS

Updated on April 18, 2020

Comments

  • rlcrews
    rlcrews about 4 years

    Within a web form I am dynamically creating a series of chekboxes that are added to an asp:placeholder

    //Generates the List of Entities that may be shared
            protected void GenerateEntityList(string agencyId, string agencyName)
            {
                var selectedAgency = UserFactory.GetAgencyAndSharedDataById(Convert.ToInt64(agencyId));
    
                entityContainer.Controls.Clear();
    
                //builds the entity list based upon entities in DB
                var currentEntities = UserFactory.GetEntityList();
                //add checkboxes
                entityContainer.Controls.Add(new LiteralControl("<input type='checkbox' id='selectAllCB' value='All'>Select All<br/><br/>"));
                foreach (var item in currentEntities)
                {
                    CheckBox entityCheckBox = new CheckBox();
                    int currentItem = item.EntityTypeId.GetValueOrDefault(0);
                    entityCheckBox.Text = item.EntityName.ToString();
    
                    entityCheckBox.CssClass = "am_Checkbox";
                    entityContainer.Controls.Add(entityCheckBox);
                    entityContainer.Controls.Add(new LiteralControl("<br/><br/>"));
    
                    //mark checkboxes as checked if currently stored in the database
                    if (selectedAgency.FirstOrDefault().SecurityDataShares != null && selectedAgency.FirstOrDefault().SecurityDataShares.Count > 0)
                    {
                        foreach (var ce in selectedAgency.FirstOrDefault().SecurityDataShares)
                        {
                            if (ce.EntityId == item.EntityId)
                            {
                                entityCheckBox.Checked = true;
                            }
                        }
                    }
                }
    

    Once created the user has the ability to make or remove selections. When clicking update I would like to return/collect the values from the checkboxes so that I may insert them back into the db.

    //get the text value of every checkbox 
    protected void updateEnties()
    {
        string receivingAgency = ReceivingAgencyID;
        long contributingAgency = QueryID;
    
        List<string> cbValues = new List<string>();
        foreach (CheckBox currentItem in entityContainer.Controls)
        {
            cbValues.Add(currentItem.Text);
        }
    }
    

    However when I attempt to iterate over the collection I am not getting anything back which leads me to believe either I am calling the control incorrectly or it is being destroyed due to the postback. Instead of writing these elements to a place holder should I use another controls like a Listbox control?

    Can someone please provide me with some guidance on how I can retrieving the checkbox values?