ASP.Net Dynamic Controls (Part 3)
I have received a few requests via email and in comments for more detail on how to get your data back after postback with dynamic controls. This evening I started to put together some code examples and mulled over the details of the article in my head. The first step was to re-read my previous two articles so I could get my bearings on where to start. Part 1 of this series is an initial outline of how to create dynamic controls and use Request.Form to collect the data after postback. Part 2 went into detail on how to figure out which button was clicked to cause postback using a JavaScript technique. In the middle of re-reading the second article I had an epiphany. There is a better way to do that! The proper method is standards compliant, accessible and is outlined in the W3C HTML specifications. So I will put the original article on hold and explain this technique.
What I didn’t realize when I wrote Part 2 of this series was that HTML forms have a built in way to recognize what button was clicked. Here is a relevant quote from the spec explaining it (poorly).
A successful control is “valid” for submission. Every successful control has its control name paired with its current value as part of the submitted form data set. A successful control must be defined within a FORM element and must have a control name.
So that is just a wordy way to say that form elements have their values returned in a name/value pair after the form is submitted. We have all seen the URL GET version (http://…../index.php?name=value&name2=value2) of this and the POST version is the same inside the closed POST package. So the only question is “What is a successful control really?” which requires more digging. Take a look for yourself there are many reasons. The one that is most interesting is “If a form contains more than one submit button, only the activated submit button is successful.” Perfect! So which ever button is clicked will have its name/value pair available to us on the other side of the submit. Lets take a look at an example:
<form method="get" action="self.php">
<input type="submit" name="button1" value="Text on Button1" />
<input type="submit" name="button2" value="Text on Button2" />
</form>
You can see that the name/value pair after the question mark shows which you clicked. Since this does not require JavaScript it is a much more accessible solution to the problem. A wider number of users are now able to participate which takes us closer to our goal of creating a great website. The next step is to figure out how to utilize this information to overcome the chicken and egg problem.
Before going further I thought I would recap the chicken and egg problem so you know why we are doing this in the first place. The simplest example is a dynamic list of, for example, your friends on Facebook. When the page is generated we go to the database and collect all the people you have tagged as friends generating a list on the page. Each entry has some tools so you can interact with your friends, this included a delete button to remove them (perhaps if they Poke you rudely or defamate your wall). In order for the buttons to function we needed to generate the list in the Page_Load event. Now when the user pushes the delete button the page is redrawn. Event handlers fire after Page_Load so we have already added the deleted person back before they are to be deleted. In some cases it wouldn’t be a problem to simply remove them but it is wasted effort. We need a way of knowing about the click before we regenerate the list
Sub Page_Load()
Dim i As Integer
Dim btn As Button
For i = 1 To 10
btn = New Button
btn.ID = "btn" & i
btn.Text = "Button " & i
phFun.Controls.Add(btn)
Next
For i = 1 To 10
If Not String.IsNullOrEmpty(Request.Form("btn" & i)) Then
… ' Perform action on the ith item
End If
Next
End Sub
…
<asp:PlaceHolder ID="phFun" runat="server" />
You will notice that in the last example I don’t set the name or the value property of the button control. ASP.Net does the work behind the scenes, whatever you put for the ID will be the id and name attributes in the HTML and whatever you put in for Text will be the value attribute. I would like to hear from you, let me know if this works for you or if you need help getting it to fit the bill for your project. I’ll be back with the article I was initially going to write sometime next week and somewhere down the road I will make the jump to AJAX dynamic controls, stay tuned.
ASP.Net Dynamic Controls (Part 1) «
ASP.Net Dynamic Controls (Part 2) «
ASP.Net Dynamic Controls (Part 4) »
Categories
Recent
- Browser Logo Shootout
- Blackberry Surreal Theme
- Blackberry JDE API - User Interface Field Reference
- Getting started with the Blackberry Java Development Environment (JDE)
- ASP.Net DropDownList annoyance
- Getting a Blackberry Curve
- Mambo to the beat of the internet
- ASP.Net has 9 to 5 appeal
- ASP.Net CheckBoxes should be able to have values
- Time to take a look at Python I guess
- Country list formatted for MySQL import
- Kinetic Typography: typographic treatment of an audio sample
- MSN Video Sucks
- Five things about me
- Blackberry MP3 Player Instructions



what about linkbutton? How can you verify that a linkbutton was clicked?
I’ve solved the problem using code for coded webcontrols (not ascx and aspx) but cs class inhereting from System.Web.UI.WebControls.WebControl. The solution is to draw the content twice in different places of the lifespan. My experience is that i then can change the content of the page in the event and not get the “lagg” effect (event triggering one postback too late).
This is how i draw the dynamic content (nomatter what it is in webcontrols):
Notice that the above actually works for aspx and ascx files too, but in an inconsistent matter. Can someone please explain to me why this works, since the solution was a aquired by trial and error.
One last thing. Always remember to give the controls and id.
Implementing ,System.Web.UI.INamingContainer seems to work good for webcontrols. Somehow this fails in usercontrols (ascx), but simply setting a unique id works.
That’s nice. What about the following scenario: I’m loading controls that implement the same interface - GetFieldValues and SetFieldValues methods. I’m loading the first control, call SetFieldValues on it and then press “Next”, at this moment I want to call GetFieldValues and load the next control and so on. But it doesnt work just because the controls are dynamically loaded:
protected void Page_Init(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
Session["CurrentControl"] = Stub.GetNextControlUrl();
Control currentControl =
(Control)LoadControl((string)Session["CurrentControl"]);
PlaceHolder1.Controls.Add(currentControl);
SetFields();
}
else
{
Control currentControl =
(Control)LoadControl((string)Session["CurrentControl"]);
PlaceHolder1.Controls.Add(currentControl);
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
GetFields();
Session["CurrentControl"] =
Stub.GetNextControlUrl();
Control currentControl =
(Control)LoadControl((string)Session["CurrentControl"]);
PlaceHolder1.Controls.Clear();
PlaceHolder1.Controls.Add(currentControl);
SetFields();
}
}
SetFields and GetFields just call a method on the controls inside PlaceHolder1 to retreive their field values. The problem is that I want the content of the controls to be retreived calling a method of the interface. Does anyone know how to solve this?
Hi i was reading your article, but i’m having some problems of gettign the values of the dymanic controls that i created.
can you help me finish my work, please?
After you postback the page you can access the controls you created using Request.Form(”control_name”)
Where control_name is the ID you gave the control when you created it. Hope that helps.
c#
1-recreate the controls in page load with the same name
2- use Findcontrol. ie ct1 = FindControl(”control_name1″)
3- ct1 now has all the attributes and Values after postback.