|
-
May 21st, 2004, 11:23 AM
#1
Thread Starter
Hyperactive Member
Iterate Form Controls
I dynamically create any number of asp:textbox(es) in my page depending on the number of records returned. when the user clicks the button, i want to collect the values of said created asp:textbox(es). my code to obtain the values are as follows, but obviously does not work or i would not have added this thread :
Code:
Dim frmControl as Object
'// AddProds is the name of the form
For Each frmControl In Page.FindControl("AddProds").Controls
Response.Write(frmControl.ID & "<BR />")
Next
my head is ready to if I cant figure this out.
-
May 21st, 2004, 11:39 AM
#2
Lively Member
for Dyanmically created controls you have to use the Request Method to get any input in them back. I went thru what sounds like your going thru already. I was adding any number of controls to a panel and couldnt get them recreated and read the values on postback. The controls need to be built every single time the page refreshes. And to get any info from them you need to know their id's and use the Request("id") to get values from them. If there is another way I dont know it.
"Find all you need in your mind if you take the time" -DT
-
May 21st, 2004, 11:42 AM
#3
Thread Starter
Hyperactive Member
ahhh
Well, that wasnt exactly what I had hoped to hear. However, when you say "Request", do you mean have that action of my form go to another page or use it in the current page? I know you used the Response, but can you tell me how you used it?
Thanks
-
May 21st, 2004, 11:54 AM
#4
Lively Member
Well what I did was have all the things I needed to make controls for in a comma seperated Session variable then I would loop thru them to add them to the panel. This is the code I run every single time the page loads
Code:
Function FillPanel()
Panel1.Controls.Clear()
Session("wherecl") = ""
Dim name(20) As String
Dim s_name(20) As String
Dim cond(20) As String
Dim v1(20) As String
Dim v2(20) As String
Dim i As Integer
Dim numitems As String
name = Split(Session("SearchItems"), ";")
s_name = Split(Session("sys_name"), ";")
cond = Split(Session("condition"), ";")
v1 = Split(Session("val1"), ";")
v2 = Split(Session("val2"), ";")
numitems = Session("ttlitems")
makepsearch()
For i = 0 To (Session("ttlitems") - 1)
Panel1.Controls.Add(New LiteralControl("<table>"))
Dim l As New Label
l.ID = s_name(i) & "lbl" & i
l.Font.Name = "Arial"
l.Font.Size = New FontUnit(8)
l.ForeColor = System.Drawing.Color.FromArgb(3466)
l.Font.Bold = True
If name(i) = "By Town" Then
l.Text = "Town"
Else
l.Text = " " & name(i)
End If
Dim b As New LinkButton
b.Text = "<img src=images/cut.gif alt=""Delete Search Item"" border=0>"
b.ID = i & "removebutton"
AddHandler b.Click, AddressOf editpanel
Panel1.Controls.Add(New LiteralControl("<tr><td align=left width=150>"))
Panel1.Controls.Add(b)
Panel1.Controls.Add(l)
Panel1.Controls.Add(New LiteralControl("</td><td>"))
getcondition(name(i), s_name(i), cond(i), v1(i), v2(i))
Panel1.Controls.Add(New LiteralControl("</font></td></tr>"))
Panel1.Controls.Add(New LiteralControl("</table>"))
Next
end sub
And this is the getcondition function that actually reads the values and fills the controls with any data. This is just a small snippet but looking at it you should be able to understand it.
Code:
Function getcondition(ByVal actual As String, ByVal name As String, ByVal condition As String, ByVal mval As String, ByVal maval As String)
If Trim(actual) = "Listing Class" Then
Dim f As New ListBox
Dim statlist(20) As String
Dim statlistv(20) As String
Dim statusi As String
Dim statusv As String
statusi = "Residential,Condo,Multi-Family,Land,Commercial,Mobile Home"
statusv = "1,2,3,4,5,6"
statlist = Split(statusi, ",")
statlistv = Split(statusv, ",")
Dim i As Integer
f.ID = name
f.EnableViewState = True
f.SelectionMode = ListSelectionMode.Multiple
f.Rows = 6
f.Font.Name = "Arial"
f.Font.Size = New FontUnit(8)
Dim theclasses As String
theclasses = Request(name)
Session(name) = theclasses
For i = 0 To 5
Dim lItem As New ListItem
With lItem
'Add Attributes
.Value = statlistv(i)
.Text = statlist(i)
If InStr(theclasses, litem.value) Or InStr(mval, litem.value) Then
.Selected = True
End If
End With
f.Items.Add(lItem)
Next
Panel1.Controls.Add(f)
If Request(name) <> "" Or mval <> "" Then
Session("class") = Request(name)
'if the page has posted back use request to get the values
If Session("haspassed") = "1" Then
Session("val1") = Session("val1") & Request(name) & ";"
Session("val2") = Session("val2") & " ;"
End If
Else
If Session("haspassed") = "1" Then
Session("val1") = Session("val1") & " ;"
Session("val2") = Session("val2") & " ;"
End If
End If
End If
If condition = "=" And Not (name = "class" Or name = "isnull(len(photo),0)" Or name = "deedtype" Or name = "status" Or name = "county" Or name = "town" Or name = "right(town,2)" Or name = "water_body_type" Or name = "number") And Not (Trim(actual) = "Listing Office" Or Trim(actual) = "Selling Office") Then
Dim s As New TextBox
s.EnableViewState = True
s.ID = name
s.Font.Name = "Arial"
s.Font.Size = New FontUnit(8)
If Request(name) <> "" Or mval <> "" Then
s.Text = Request(name)
Session(name) = s.Text
Else
If name = "oh_start_date" Then
s.Text = Date.Today.ToString
Else
s.Text = maval
End If
End If
Dim minval As String = s.Text
Panel1.Controls.Add(s)
Dim theval As String = Request(name)
If InStr(theval, ",") Or InStr(mval, ",") Then
Session("wherecl") = Session("wherecl") & " and " & name & " in(" & theval & ")"
objdr("Item") = Trim(actual)
objdr("Criteria") = theval
objdr("sys_name") = name
objdr("condition") = condition
objdt.Rows.Add(objdr)
Session("psearch") = objdt
Session("val1") = Session("val1") & theval & ";"
Session("val2") = Session("val2") & " ;"
Else
Session("wherecl") = Session("wherecl") & " and " & name & "='" & theval & "'"
objdr("Item") = Trim(actual)
objdr("Criteria") = theval
objdr("sys_name") = name
objdr("condition") = condition
objdt.Rows.Add(objdr)
Session("psearch") = objdt
If Session("haspassed") = "1" Then
Session("val1") = Session("val1") & theval & ";"
Session("val2") = Session("val2") & " ;"
End If
End If
End If
end function
hopefully this will help you out. I am bulding a real estate database search site. So I keep a couple Session variables for search items like the Display name, system name, search condition(=,<,>, between) and the default values thats what val1 and val2 are.
"Find all you need in your mind if you take the time" -DT
-
May 21st, 2004, 09:57 PM
#5
Frenzied Member
So that's how you solve that little glitchy thing. That was giving me fits the other day till I just changed my design. Can't go back but at least I know now.
Magiaus
If I helped give me some points.
-
May 22nd, 2004, 01:54 AM
#6
Hyperactive Member
for Dyanmically created controls you have to use the Request Method to get any input in them back.
...not true. You just need to keep track of the dynamically created controls, and remember to recreate them on postback. In order for their viewstate to work properly, they have to be recreated in exactly the same order and with the same ID's as they were when they were first created( that's how ViewState is tracked ). If you do that, you'll have no problem iterating through dynamically added controls.
The following code demonstrates a simple way of using an ArrayList to keep track of what controls were dynamically added to the panel. The basic principal is this: In the OnLoad method, check to see if you've previously added any textboxes, if you have recreate them. Button control events like button clicks, always occur after OnLoad so if you've clicked the add textbox button, the other controls would have already been added, so that event handler will just add another textbox id to the list to keep track of. Clicking on the Get Values button means that when the page posts back, the OnLoad fires first(so all of the previously dynamically created textboxes are recreated in proper order) then the the button click event handler for the Get Values button can iterate thru all of the controls in the panel, pick out the textboxes with values and print them out.
PHP Code:
<script language="C#" runat="server">
/// <summary>
/// Maintains the list of dynamically added TextBox controls.
/// </summary>
/// <remarks>An ArrayList is used and stored to viewstate; It's purpose
/// is just to keep track of a list of ID's of textboxes that will
/// need to be recreated on every postback.</remarks>
public ArrayList TextBoxes
{
get
{
ArrayList textBoxes = null;
if( this.ViewState[ "TextBoxes" ] != null )
{
textBoxes = ( ArrayList )this.ViewState[ "TextBoxes" ];
}
else
{
textBoxes = new ArrayList();
this.ViewState[ "TextBoxes" ] = textBoxes;
}
return textBoxes;
}
}
/// <summary>
/// Adds a TextBox to the panel containing the dynamically added textboxes.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnAddTextBox_Click( object sender, System.EventArgs e )
{
string textBoxID = "TextBox" + this.TextBoxes.Count.ToString();
addTextBox( textBoxID );
}
/// <summary>
/// Handles anytime the user wants a comma separated list of values from
/// the dynamically added textboxes.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void btnGetValues_Click( object sender, System.EventArgs e )
{
//Iterate through all of the controls in the panel; we only care
//about the TextBoxes, so we try to cast whatever control is
//currently being iterated over to a textbox, if successful then
//we have a TextBox and need to write it's value out.
foreach( Control ctl in pnlTextBoxContainer.Controls )
{
TextBox tb = ctl as TextBox;
if( tb != null && tb.Text.Trim().Length > 0 )
{
Response.Write( tb.Text );
Response.Write( ", " );
}
}
}
/// <summary>
/// Check to see if this is a postback and that the user
/// has previously added TextBoxes. If TextBoxes have
/// been added before, recreate them here so that
/// their ViewState can be evaluated later(this means that
/// the dynamically created textboxes will retain their
/// values on subsequent postbacks.
/// </summary>
/// <param name="e"></param>
protected override void OnLoad(EventArgs e)
{
if( Page.IsPostBack )
{
if( this.TextBoxes.Count > 0 )
{
foreach( string textBoxID in this.TextBoxes )
{
addTextBox( textBoxID );
}
}
}
}
/// <summary>
/// Creates a TextBox instance, assigns it the textBoxID and
/// adds it to the panel. If textBoxID has not been added
/// previously, then store the ID in the TextBoxes property
/// so we can remember to recreate it on postback.
/// </summary>
/// <param name="textBoxID">ID of the TextBox to create.</param>
private void addTextBox( string textBoxID )
{
TextBox tb = new TextBox();
tb.ID = textBoxID;
pnlTextBoxContainer.Controls.Add( tb );
pnlTextBoxContainer.Controls.Add( new LiteralControl( "<br />" ) );
if( !this.TextBoxes.Contains( textBoxID ) )
{
this.TextBoxes.Add( textBoxID );
}
}
</script>
<html>
<body>
<form runat="server">
<asp:Button ID="btnDoNothing" Runat="server" Text="Submit(Do Nothing)" />
<asp:Button ID="btnAddTextBox" Runat="server" OnClick="btnAddTextBox_Click" Text="Add TextBox" />
<asp:Button ID="btnGetValues" Runat="server" OnClick="btnGetValues_Click" Text="Get Values" /><br />
<asp:Panel ID="pnlTextBoxContainer" Runat="server" />
</form>
</body>
</html>
I've worked on some projects where other details such as type of control needed to be "remembered". Hard to do with an ArrayList. Custom Types need special stuff to be saved to viewstate. A newsgroup post directed me to the Pair Class and the Triplet Class. Each of these can be saved to an arraylist and can be persisted to viewstate. Very handy for saving multiple values per item in an arraylist.
-
May 22nd, 2004, 02:38 PM
#7
Frenzied Member
I have been using a private property(full viewstate) that is an ArrayList to hold a cache of my custom objects. Mainly because I'm lame and haven't used serilization yet. So, that makes since.
The part about the creation order I have to think on. At least in refreance to my project. Very cool.
Ever thought of writing a Control like a TabControl/ViewControl? I'm really think of a control that has multi views that you can design in vs.net and either display a tab for each panel or have the panel hiden and only navable from code. When viewing a tabless panel all tabs are hidden and you have to code in to nav back. It's the designer that it is hurting my brain. I'm trying to get my brain around that right now. This helped.
I'm also trying to figure out how to setup transactions of views. I.E. you have several message aand actions you need to work through with the user. You build add an action for each one. Override the ExecuteAction member and it forms a chain. It's buggy right now. I actual have it working, but it's string key driven, and I don't really like that.
Last edited by Magiaus; May 22nd, 2004 at 02:43 PM.
Magiaus
If I helped give me some points.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|