0

I have a asp:panel that on a button click, I add some number of checkboxes to dynamically.

On another button click, I need to look at these checkboxes and check if they are checked.

This is a follow up question to one I posted earlier. The first issue was I could not find the dynamically generated controls at all on postback.

Now, I can find them. The problem is the Checked property is always false despite checking the checkbox on the UI.

The markup with the panel that the checkboxes get placed into, and the two buttons:

<asp:Panel runat="server" ScrollBars="Vertical" ID="pnlEmailCheckboxes" Height="150">
    <br/>
    <asp:CheckBox runat="server" Text="Other" ID="cbOtherEmail"/>
    <asp:TextBox ID="txtOtherEmail" runat="server" Style="width: 270px;" CssClass="textbox-default"></asp:TextBox>
    <br/>
</asp:Panel>
<asp:LinkButton ID="btnSendEmail" Text="<span>Send Email</span>" runat="server" CssClass="page-footer-button-highlight" OnClick="btnSendEmail_Click"></asp:LinkButton>
<asp:LinkButton ID="btnCloseEmail" Text="<span>Close</span>" runat="server" CssClass="page-footer-button" CausesValidation="false" OnClick="btnCloseEmail_OnClick"></asp:LinkButton>

The event that generates the textboxes:

protected void btnEmail_Click(object sender, EventArgs e)
{
    List<CheckBox> cbList = new List<CheckBox>();
    for (int i = 0; i < 10; i++)
    {
        CheckBox cb = new CheckBox();
        cb.Text = "text" + i;
        cb.ID = Guid.newGuid().ToString();
        cb.ClientIDMode = ClientIDMode.Static;
        pnlEmailCheckboxes.Controls.AddAt(0, cb);
        pnlEmailCheckboxes.Controls.AddAt(0, new LiteralControl("<br/>"));
        cbList.Add(cb);
    }

    Session["checkboxes"] = cbList;
    mpeEmail.Show();
}

The button that tries to retrieve the textboxes (does not work):

protected void btnSendEmail_Click(object sender, EventArgs e)
{
    //the email recipients
    List<string> emailRecipients = new List<string>();

    List<CheckBox> cbList = (List<CheckBox>)Session["checkboxes"];

    foreach (CheckBox cb in cbList)
    {
        CheckBox cbClient = (CheckBox) pnlEmailCheckboxes.FindControl(cb.ClientID); //I've also tried to find it by cb.ID
        //ALWAYS FALSE
        if (cbClient.Checked) emailRecipients.Add(cb.Text.Trim());
    }

    //Ive also tried this, it does not contain the dynamically generated checkboxes
    //var cbControls = pnlEmailCheckboxes.Controls.OfType<CheckBox>();
}

Edit:

The client side html even shows the with the correct ID that matches the ID I'm searching for.

<input id="00e3a485-2083-4ef8-810b-6ed4fb1f62f9" type="checkbox" name="ctl00$Body$00e3a485-2083-4ef8-810b-6ed4fb1f62f9">
James Wierzba
  • 16,176
  • 14
  • 79
  • 120
  • I prefer to use a Repeater of checkboxes instead of adding them dynamically. In your case you have to create checkboxes again after postback (OnLoad). Similar question: http://stackoverflow.com/questions/17589268/dynamically-created-controls-losing-data-after-postback – Emanuele Jan 12 '17 at 08:30
  • @Emanuele I am indeed creating the controls on the postback, however that link lead me to the realization that the controls being re-created need to have the same IDs as the old controls to be mapped to the re-created controls. thanks. – James Wierzba Jan 12 '17 at 16:02
  • Nice. Can i suggest to use a "more controlled" naming convention for checkboxes? EG chk1, chk2... – Emanuele Jan 12 '17 at 16:22
  • @Emanuele Sure but those names are purely for this stack-overflow question in the interest of a MCVE "minimum complete verifiable example" or whatever the acronym is. My actual code is different. – James Wierzba Jan 12 '17 at 16:29

1 Answers1

0

Dynamic controls need to be re-created on each postback (which was already happening, given I was creating them in the page OnInit function).

However, the problem is that I was using a newly genered Guid as the ID for each control. This was causing the re-generated controls on each postback to not be mapped to the postdata from the old controls.

protected void btnEmail_Click(object sender, EventArgs e)
{
    List<CheckBox> cbList = new List<CheckBox>();
    for (int i = 0; i < 10; i++)
    {
        CheckBox cb = new CheckBox();
        cb.Text = "text" + i;

        //cb.ID = Guid.newGuid().ToString(); //don't do this.
        cb.ID = "checkbox" + i; // <------ do this, have a consistent ID

        cb.ClientIDMode = ClientIDMode.Static;
        pnlEmailCheckboxes.Controls.AddAt(0, cb);
        pnlEmailCheckboxes.Controls.AddAt(0, new LiteralControl("<br/>"));
        cbList.Add(cb);
    }

    Session["checkboxes"] = cbList;
    mpeEmail.Show();
}
James Wierzba
  • 16,176
  • 14
  • 79
  • 120