If I have a page with a form (imagine a simple one with just TextBoxes and a submit button) and I want to allow the user to dynamiccally add more TextBoxes to the form via j
I've begun using jquery in a lot of my webforms applications and have found the combination of dynamic controls and using JSON to communicate with the page's WebMethods give me much more control over how the page is presented and eliminate needless postbacks.
When I want to trigger a postback, I use javascript to populate server controls on the page that are hidden by jquery and then click a server control button. This allows the page to degrade gracefully if the user cannot use javascript.
On the server side look into Request.Form["controlN"] where you will find your old and new fields.
On the server side you can add controls dynamically like:
foreach (Type object in MyDBCollection)
{
Controls.Add (new TextBox ());
}
On client side, make a JS function for creating the inputs, for example:
var numCtrl = 1; // depends on how many you have rendered on server side
var addCtrl = function() {
var in = document.createElement('input');
in.name = "control" + ++i;
in.type = "text";
in.id = "control" + i;
document.getElementById("yourcontainer").appendChild(in);
}
..on the server side just lookup your HTTP params collection, iterate through it, and select only those matching /control\d*/
I have done similiar things to this numerous times. My preferred approach is usually to use a Repeater and a Button (labelled Add
) inside an UpdatePanel.
For the Button_OnClick
event in your code behind do something similiar to this;
Loop through the Items collection of the Repeater
Use item.FindControl("txtUserInput") to get the TextBox for that item
Save the text of each input to List<string>
Add an empty string to the the list
Databind the repeater to this new list
Here's some example code;
<asp:Repeater runat="server" ID="rptAttendees">
<ItemTemplate>
<asp:TextBox runat="server" ID="txtAttendeeEmail" Text='<%# Container.DataItem %>'></asp:TextBox>
</ItemTemplate>
</asp:Repeater>
protected void btnAddAttendee_Click(object sender, EventArgs e)
{
var attendees = new List<string>();
foreach (RepeaterItem item in rptAttendees.Items)
{
TextBox txtAttendeeEmail = (TextBox)item.FindControl("txtAttendeeEmail");
attendees.Add(txtAttendeeEmail.Text);
}
SaveAttendees();
attendees.Add("");
rptAttendees.DataSource = attendees;
rptAttendees.DataBind();
}
If you want to be able to access them in the code behind using the FindControl method, the AJAX UpdatePanel is probably your best bet. Just remember that every time you update the UpdatePanel, your going through the entire page life cycle but only getting the pieces that render in the update panel back from the server, so be weary of the overhead.
If you create them dynamically with Javascript you will not be able to use FindControl to get access to them in the code behind because they won't be re-created during the page event life cycle. Also, be careful because if you're creating a lot of them at the same time with some kind of loop it can slow things down, especially in Internet Explorer.
You may also consider using AJAX and WebServices with WebMethods for submitting the data instead of a post-back if you're creating the controls dynamically with Javascript.
In webforms you won't have a lot of choices if you expect the values to postback and be able to access them in typical fashion. What I would suggest is that you use an Ajax UpdatePanel to allow the controls to be registered at the appropriate point of the page lifecycle (before onLoad), this will also make a difference on whether or not you need the boxes to persist across postbacks. The JS methods involved in the other 2 answers will not persist the textboxes through a postback.
MVC gives you more leeway, since there isn't that crazy page lifecycle, control registration, viewstate, etc to get in your way.
So the big question is, which model/framework for ASP.Net are you using?
Since you are indeed using webforms, I really strongly suggest you go with updatepanels if they'll work for you. it will permit you to add controls in such a way that wont get in the way of eventvalidation, etc.