Results 1 to 7 of 7

Thread: Iterate Form Controls

  1. #1

    Thread Starter
    Hyperactive Member johnweidauer's Avatar
    Join Date
    Sep 2002
    Location
    SLC, UT
    Posts
    314

    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.

  2. #2
    Lively Member
    Join Date
    Jan 2001
    Location
    Worcester, MA
    Posts
    77
    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

  3. #3

    Thread Starter
    Hyperactive Member johnweidauer's Avatar
    Join Date
    Sep 2002
    Location
    SLC, UT
    Posts
    314

    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

  4. #4
    Lively Member
    Join Date
    Jan 2001
    Location
    Worcester, MA
    Posts
    77
    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

  5. #5
    Frenzied Member Magiaus's Avatar
    Join Date
    Mar 2002
    Location
    swamp land
    Posts
    1,267

    Red face

    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.

  6. #6
    Hyperactive Member
    Join Date
    Aug 2002
    Location
    Fort Collins, CO
    Posts
    366
    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_Clickobject senderSystem.EventArgs e )
    {
        
    string textBoxID "TextBox" this.TextBoxes.Count.ToString();
        
    addTextBoxtextBoxID );
    }

    /// <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_Clickobject senderSystem.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 )
            {
                
    Response.Writetb.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 )
            {                
                foreach( 
    string textBoxID in this.TextBoxes )
                {
                    
    addTextBoxtextBoxID );
                }
            }
        }
    }

    /// <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 addTextBoxstring textBoxID )
    {
        
    TextBox tb = new TextBox();
        
    tb.ID textBoxID;
        
    pnlTextBoxContainer.Controls.Addtb );
        
    pnlTextBoxContainer.Controls.Add( new LiteralControl"<br />" ) );
        if( !
    this.TextBoxes.ContainstextBoxID ) )
        {
            
    this.TextBoxes.AddtextBoxID );
        }
    }
    </
    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.

  7. #7
    Frenzied Member Magiaus's Avatar
    Join Date
    Mar 2002
    Location
    swamp land
    Posts
    1,267
    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
  •  



Click Here to Expand Forum to Full Width