I am using Visual Studio with asp.net, vb.net, and webforms.
My issue is that I need to get the user's textbox input from my dynamically generated textboxes.
On my button click BtnStep4Next, I dynamically add ServiceForm.ascx (it is a form with FirstName, LastName, City, etc). I add the Service Form to a list, and the list is stored in a session. There could be, for example, 5 webforms (ServiceForm).
Protected Sub BtnStep4Next_Click(sender As Object, e As EventArgs) Handles BtnStep4Next.Click
Dim formCount As Integer = 0
'Create a list to hold all of the service forms
Dim listServiceForms As New List(Of openapps_luesreg_ServiceForm)
Session("vsServiceForms") = listServiceForms
For Each i In CBLModifications.Items
'Do not show a service form for membership (ID = 1)
If i.Value <> "1" Then
formCount += 1
Dim serviceForm As openapps_luesreg_ServiceForm = New openapps_luesreg_ServiceForm()
'Load a new Service Form to the page
serviceForm = Page.LoadControl("ServiceForm.ascx")
serviceForm.ID = "service" + formCount.ToString
Dim txtCity As TextBox = CType(serviceForm.FindControl("txtCity"), TextBox)
txtCity.ID = "serviceCity" + formCount.ToString
'Dim txtCityRegEx As Regex = CType(serviceForm.FindControl("RegExCity"), Regex)
'txtCityRegEx.ID = "serviceCity" + formCount.ToString
'Add the new Service Form to the panel PnlService Forms
PnlServiceForms.Controls.Add(serviceForm)
'Add the name to the top of the Form
Dim lblServiceName As Label = CType(serviceForm.FindControl("lblServiceName"), Label)
lblServiceName.Text = i.Text
'Add to listServiceForms
listServiceForms.Add(serviceForm)
'Set the list to the ViewState
Session("vsServiceForms") = listServiceForms
End If
Next
End Sub
On a different button click, now I want to grab the user's input they type into the textboxes. My code here though results in empty strings (the original form text) instead of the user's updated input. How can I actually get each textboxes' text that the user enters at this point?
Protected Sub BtnStep5Next_Click(sender As Object, e As EventArgs) Handles BtnStep5Next.Click
Dim listServiceForms As List(Of openapps_luesreg_ServiceForm)
listServiceForms = DirectCast(Session("vsServiceForms"), List(Of openapps_luesreg_ServiceForm))
Dim myCount As Integer = 0
For Each i In listServiceForms
myCount += 1
Dim ctlTxtCity As String = "serviceCity" + myCount.ToString
Dim myCity2 = ctlTxtCity
Dim txtNewCity As TextBox = CType(i.FindControl(ctlTxtCity), TextBox)
Dim myCity = txtNewCity.Text
Next
End Sub
You are writing way too much code. I mean, if I need 10 variables, do I go
No! You do this:
We use array's, collections. I mean even on desktop software. If I need a bunch of rows of repeating data - you use a grid, continues form or whatever other REPEATING type of control to do all this dirty work for you.
Say, I want to enter some Hotel Names. But, ahead of time I had no idea of how many. I mean, any database system + problem WILL have to deal with this type of scenario.
So, you don't try and inject controls. What happens now when you want to get that data back, say save it into the database? You now going to have a WHOLE set of controls that you have to have some numbering system to deal with.
Software not done this way. If you have repeating data, then use a repeating data control.
You can use repeater, listview, gridview. They all support repeating rows of data. The gridviewe or listview is for a grid layout. And the repeater would be the SAME idea, but you now laying out controls (repeating them) and you don't necessary have to use a grid format.
So, lets do a example of adding hotel names.
We have this grid markup:
Not too much markup, but we GET to layout our repeating controls ONE time!!
Now, the code to fill this grid view is this:
Clean, simple code, and the result is this:
Now, even more incredible? I can tab around in that grid - edit like Excel.
So now how do we send back the changes to the database (the ONE save button).
The code looks like this:
So now, note how we can SAVE all the edits in that grid in ONE shot.
And if we decide to add more columns, or maybe even a button we hit to see/view one row, we can do so with great ease.
Lets wire up the add button (adds a row to the grid). When we press it, we get/have/add a new row to the grid.
So the code could be like this:
Wow! - was that not nice and easy to add a WHOLE new grid row?
So, how this "should" work if using desktop MS-Access, FoxPro, or even the web?
Use the controls and bits and parts that allow you to work with repeating data.
There is VERY little need to try and inject controls into the web page. But worse, for repeating sets of data? Then for sure you don't' want to try and manage, and code and try to deal with a "set" of controls who's only job is to display repeating data.
Study the above. I suggest you drop all those controls, the whacks of code, and adopt either a gridview, or even a repeater to manage this problem.
I mean, what is even worse?
What happens if you need to go back to that page to edit data? Now you have to pull the data, and now re-inject all those controls again. So, you NOW need two sets of code. One set to add the new controls, and then later on to go back and display/edit that data, you again have to write another loop to re-inject the controls for display.
edit --------------------------------------
So the follow up question was how to do this for NOT a grid.
Well as noted, we have a "choice" of some controls, and their job is to "repeat" data for us. As noted, for grids, then GridView and ListView are top choices.
But, for non grid, and just some layout (say some fields that is a form or some text boxes)?
Sure, that suggest a Repeter. Note how NEAR exact the same code approach as above works. The is the wonderful part about this approch. Once you do this one time with a grid, then you know and have the skills to do this with say the repeater.
So, say we have this:
Ok, so I might want 2, or 15 of them, right? So we take the layout for above, and put it "inside" of a repeater control.
It will look like this:
So, it really just the markup, but note how we used Eval(). This is a data expression - it ONLY works inside of grids, listview, repeater. However, it even works for say a Radio button list!
Ok, so the above is our markup. So, now the code to load up this repeater looks like this:
And now we get this:
Now, I also dropped in two more plane jane buttons (add, and save).
I just dropped those buttion right after the repater (outside of repeater)
eg:
If you edit ANY of the 3 - tab around - we can now hit save and again in ONE operation send all changes back to the database.
First, lets wire up the add button. When you hit it, then in place of 3 examples, you have 4. The code is thus this:
Again, note how VERY clean and simple this code is.
So, if I just hit that add button, then I would see this:
But, I am 100% free to tab around and edit ANY of the 4 displayed.
So, now we need the save button. That will:
The save button code is thus:
So, we move data from Repeater back to table
Then we tell the system to update that table back to database.
So we did NOT have very much markup.
We were is REALLY great ease able to add a new row, but again let the repeater do all the work of showing that new data row.