3

There are lots of examples on this, and I'm pretty sound with the concept of using recursion to find the control. Once the control has been found on postback, it can be interacted with, etc.

I have an empty asp:table in my HTML markup:

<asp:Table ID="editDataTable" runat="server">
</asp:Table>

And on Page_Load the table is populated with many rows and many columns (I am quite proud that I figured that out). Inside some of the table cells there is a <asp:TextBox />.

You've guessed it, I need to get the value of these text boxes!

(I've got the code for recursion and checked it, and it seems good.)

My table has two columns. The left one contains titles like "Company Name, Telephone", etc. and the right column contains text boxes with its respective title's value. So a user can edit the text box (if the telephone number has change for example) and submit the changes.

Obviously the rows are dynamically added depending on the user.

The problem I'm having is: You need to ADD the control to the page when populating the table. Something along the lines of:

myTable.Control.Add(new TextBox());

In my case, my Table is called editDataTable. So in my code where I add the Rows, I've added the control too, as follows.

for (int i = 0; i < rowCount; i++)
{
    editDataTable.Rows.Add(tblRow[j]); // This is where I add the ROW to my sexy table
    editDataTable.Controls.Add(new TextBox()); // This is where I add the control
}

Those awake amongst you will know that you can't add a text box control to a table!

So finally, my questions are:

  • How do I add the control for The Text Boxes in my table?
  • Where do I add them?
  • Is there any extra advice to help me fulfill my quest of retrieving the text values of my dynamically added text boxes?

Here's my recursive code just in case you were curious:

private void getControls(Control parent)
{
    foreach (Control c in parent.Controls)
    {
        if (c is TextBox && c.ID == null)
        {
            //Stuff
        }

        if (c.Controls.Count > 0)
        {
            getControls(c);
        }
    }
}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
AlexMorley-Finch
  • 6,785
  • 15
  • 68
  • 103
  • 1
    Not a fan of [Control.FindControl](http://msdn.microsoft.com/en-us/library/486wc64h.aspx) method, which essentially does all this for you? Or you don't have the IDs to grab? – Brad Christie Aug 03 '11 at 16:19
  • Control.FindControl Does Not Recurse Through All Control. Only The Page Controls. Plus no Id's anyways – AlexMorley-Finch Aug 03 '11 at 16:24
  • You could generate IDs based on the row and column number. – FishBasketGordo Aug 03 '11 at 16:26
  • How about a nice [recursive FindControl](http://stevesmithblog.com/blog/recursive-findcontrol/)? – Brad Christie Aug 03 '11 at 16:29
  • even if i gave them id's... i still cant access them unless i ADD THE CONTROL! thats what questions about! – AlexMorley-Finch Aug 03 '11 at 16:52
  • Perhaps I'm missing something, but why are you proud of using a `Table` control for this as opposed to using one of the standard repeating controls like the `GridView`? – Roman Aug 03 '11 at 18:26
  • @R0MANARMY: i hope(and have thought) you are missing the OP's irony when using words like "sexy table". – Tim Schmelter Aug 03 '11 at 18:42
  • @Tim Schmelter: Given the last part of his [other](http://stackoverflow.com/questions/6774547/dynamic-table-to-edit-sql-database-data-editable-table) question, I don't think there's irony involved. I'm pretty sure he's trying to use a screwdriver as a hammer. – Roman Aug 03 '11 at 19:15
  • @Tim Schmelter: Based on the earlier attempt at textboxes with `AutoPostBack="true"`, I think he wants update data as textboxes lose focus (which is pretty neat from a usability point of view), but doing full postbacks for a single textbox is not *the right thing to do*. (Or could be an unrelated question I suppose). – Roman Aug 03 '11 at 19:22
  • 1
    @R0MANARMY: I can only think of an intranet environment where this approach could make sense at all. But even there i wouldn't do this even if 100 people ask me why a WebApplication cannot behave just as a WinForm-App. The single case where i've done an auto-update on TextChanged was a timecritical intranet app for few people working with barcode scanners and paid by piecework system. – Tim Schmelter Aug 03 '11 at 19:30

2 Answers2

1

You need to add a TableCell to the TableRow.Cells collection, and add the TextBox to the TableCell.Controls collection:

TableCell cell = new TableCell();
cell.Controls  = new TextBox();
tblRow[j].Cells.Add(cell);
editDataTable.Rows.Add(tblRow[j]);

The most direct way to access the textboxes is to keep them all in a list:

List<TextBox> textBoxes = new List<TextBox>();

and replace cell.Controls = new TextBox(); above with this:

TextBox tb = new TextBox();
textBoxes.Add(tb);
cell.Controls = tb;

And then you can iterate through the textBoxes afterward without having to search for them in a tree.

Mark Cidade
  • 98,437
  • 31
  • 224
  • 236
1

Here is an example of building a dynamic table in ASP.NET during PageLoad, and reading in the values through a postback. Since the table is dynamic, it will NOT be rebuilt when the page is postback to the server. If you want to rebuild the table, you'll need to render it again and use the values you pull in from Request.Form to re-populate it.

HTML Markup

    <asp:Table ID="editDataTable" runat="server">
    </asp:Table>
    <asp:Button runat="server" Text="Submit" OnClick="Submit_Click" />

Code Markup

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            string[] dynamicTable = { "First Name", "Last Name", "Address", "Phone" };

            foreach (string s in dynamicTable)
            {
                TableRow row = new TableRow();
                // Add First Cell with Text to Row
                row.Cells.Add(new TableCell() { Text = s });

                // Create Second Cell
                TableCell textBoxCell = new TableCell();

                // Add Textbox Control to Second Cell
                textBoxCell.Controls.Add(new TextBox() { ID = "Dynamic_" + s.Replace(" ","_") });

                // Add Second Cell to Row
                row.Cells.Add(textBoxCell);

                // Add New Row to Table
                editDataTable.Rows.Add(row);
            }
        }
    }

    protected void Submit_Click(object sender, EventArgs e)
    {
        for (int i = 0; i < Request.Form.Count; i++)
        {
            string key = Request.Form.GetKey(i);
            if (key.Contains("Dynamic_"))
            {
                Response.Write("<p><strong>" + (key.Remove(0,8)).Replace("_"," ") + "</strong>&nbsp;&nbsp;::&nbsp;&nbsp;" + Request.Form[i] + "</p>");
            }
        }
    }
Zachary
  • 6,522
  • 22
  • 34