Reputation: 1146
I have a web app with HTML tables containing input boxes everywhere in it. I want to be able to add rows to these tables from the C# side of things. To accomplish this, I use an asp button that calls this method:
private void AddRow()
{
HtmlTableRow tRow = new HtmlTableRow();
HtmlTableCell cell = new HtmlTableCell();
HtmlTableCell cell2 = new HtmlTableCell();
HtmlTableCell cell3 = new HtmlTableCell();
HtmlTableCell cell4 = new HtmlTableCell();
cell.InnerHtml = "<input type=\"text\" size=\"29\">";
tRow.Cells.Add(cell);
cell2.InnerHtml = "<input type=\"text\" size=\"9\" class=\"units commas\" />";
cell2.Attributes.Add("class", "leftBorder textCenter");
tRow.Cells.Add(cell2);
cell3.InnerHtml = "<input type=\"text\" size=\"8\" class=\"value commas\" />";
cell3.Attributes.Add("class", "leftBorder textCenter");
tRow.Cells.Add(cell3);
cell4.InnerHtml = "<input type=\"text\" size=\"11\" readonly=\"readonly\" tabindex=\"-1\" class=\"totalA1 autoTotal\" /> ";
cell4.Attributes.Add("class", "leftBorder rightBorder textRight");
tRow.Cells.Add(cell4);
someTable.Rows.Add(tRow);
}
This works beautifully...for exactly one row. I can click the button, it adds a row. If I click it again, it doesn't do anything. More specifically, I suspect it's removing the currently added row, restoring the document to the 'default' state, and then adds a row (effectively doing nothing).
Assuming I'm right, I need to somehow be able to append a row to another dynamically created row, instead of just replace it. If I'm not right, I just need a means to be able to continually add rows on a button press.
How would I go about doing this?
EDIT: I should specify, all this could be done in a loop, all at once. I was hoping to get it to work on a button press just for the sake of testing, but it can all be neatly tucked into a loop of some kind. I've had (some) success dropping it in one.
Upvotes: 2
Views: 2266
Reputation: 3043
The sentiments expressed by the other answers is completely correct in that this architecture is very flawed (it does things the way they were done in the mid 2000's, a lifetime ago in web). That being said, you have constraints and you can't change them. Here are two things I would check, one of which was already suggested in a comment:
Postback is interfering with table initialization. When a visitor first loads your aspx page, the browser will perform an HTTP GET request to your page. The IsPostback property of your aspx page class will be false. When the user clicks your button, they will make a POST request to your aspx page, passing along a bunch of variables for the current state of the page if they have modified it on their browser as well as a .NET-specific set of properties indicating what was pressed and what event handler the server should execute (in your case, the event handler calling AddRow will be called, but only after Page_Load is executed first). This is why they suggested wrapping your Page_Load logic in an if(!IsPostback){}.
ViewState is not enabled for the HtmlTable control. The ViewState is the .NET-specific implementation of serializing all that the server knows about the HTML (input boxes, etc.) into a hidden field in your output HTML. If you want .NET to remember what the state of various HTML tags are (what they contain, what the user filled out in each, etc.), then they need to have an entry in the ViewState, which is passed from postback to postback. Be warned, though, as soon as someone refreshes a page without a button click or using back and forward buttons on the browser (because remember they correspond to HTTP GET requests, not HTTP POST requests) the viewstate will be reinitialized anyways. The only way around this is stuffing stuff into the Session. If you're ok with that, then to enable the viewstate, use the .EnableViewState() method on the HtmlTable control, although keep in mind this will increase your web app's page size since .NET will serialize what the table contains into a string and put it in a hidden input variable. This will make it "easy" to write all the server side logic, but at a huge cost if the table becomes very big.
It may seem right now that the path of least resistance is to just make the existing infrastructure work, but believe me you are incurring ever increasing amounts of technical debt that either you or someone else will have to pay up down the line. I would highly recommend moving to a client-side add row method, it's the only way around this postback-viewstate-model madness in webforms.
Upvotes: 1
Reputation: 10139
The absolute best way to do what you need is client side, NOT server side. For what you're doing, it makes no sense to post back to the server EACH TIME you insert a new row (in my opinion). Is there a specific reason you must do this server side (C#)?
Use Javascript (jQuery) to dynamically insert new rows into your table upon the button click. The page won't refresh, it's faster, and makes for a LOT better user experience.
I assume you're familiar with Javascript, but you can tie a client side event to your server side button - just add onclientclick="insertRow();"
where onclientclick
is an attribute of the button control and insertRow()
is a Javascript method defined in your page between <script></script>
tags.
If you need me to write out an example on how to do this, please let me know and I can edit my answer.
Upvotes: 3