Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 Development Tools
 ASP.NET
 Dynamic Web Textboxes

Author  Topic 

jhermiz

3564 Posts

Posted - 2006-12-14 : 11:11:23
I can do this:

For i As Integer = 1 To n
Panel1.Controls.Add(New TextBox())
Next

To dynamically create n textboxes onto a panel.
I can also do this to create one:

Dim t as New Textbox()
Panel1.Controls.Add(t)

But the issue is if I put the above code behind a button and click it say n times it still only creates one button. I need to be able to display to the user a button, when he / she clicks it it creates a dynamic textbox, they fill it out, and have the option to click that same button again. If they click it again it should create another text box.

I cant use the loop cause i dont want to ask the user how many textboxes...so I just want them to have the ability to click it once / twice / three / n times...

Anyone have an idea ?

Thanks



Keeping the web experience alive -- [url]http://www.web-impulse.com[/url]

RS Blog -- [url]http://weblogs.sqlteam.com/jhermiz[/url]

jhermiz

3564 Posts

Posted - 2006-12-14 : 11:12:46
Just to add on even if I change the id still no luck:

Protected Sub AddTextBox(ByVal i As Integer)
Dim t As New TextBox

t.ID = "T" & CType(i, String)

form1.Controls.Add(t)
End Sub


Keeping the web experience alive -- [url]http://www.web-impulse.com[/url]

RS Blog -- [url]http://weblogs.sqlteam.com/jhermiz[/url]
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2006-12-14 : 11:51:03
might be a viewstate issue? Does Panel1 have its ViewState enabled?

- Jeff
Go to Top of Page

jhermiz

3564 Posts

Posted - 2006-12-14 : 12:21:50
quote:
Originally posted by jsmith8858

might be a viewstate issue? Does Panel1 have its ViewState enabled?

- Jeff



Hi jeff yes viewstate is enabled in Panel1.

I tried something to this effect allowing the user to enter the number, i think that will work:


Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Select Case Me.Button1.Text
Case "Add Sites"
For i As Integer = 0 To Me.TextBox1.Text - 1
Me.Panel1.Controls.Add(New LiteralControl("<br>Enter site " & (i + 1).ToString() & ": "))
Me.Panel1.Controls.Add(New TextBox())
Next
Me.Button1.Text = "Generate Page"
Me.Button1.ForeColor = Drawing.Color.Green

Case "Generate Page"
Dim AList As New ArrayList
For Each c As Control In Panel1.Controls
If c.GetType().ToString().Equals("System.Web.UI.WebControls.TextBox") And c.ID <> "TextBox1" Then
AList.Add(CType(c, TextBox).Text)
'Response.Write((CType(c, TextBox).Text))
End If
Next
End Select

End Sub


However the IF c.GetType().ToString().Equals...
Never adds any of the text from the dynamically controlled text boxes to the arraylist. Its almost like it doesnt know they exist.
Even the control count doesnt list enough items...As I am creating literal controls right after it. Any reason why that IF doesnt execute.



Keeping the web experience alive -- [url]http://www.web-impulse.com[/url]

RS Blog -- [url]http://weblogs.sqlteam.com/jhermiz[/url]
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2006-12-14 : 12:35:50
hmmm .. still not sure.

About checking types: you can do this, I think it's easier and perhaps more efficient (no string conversions and comparisons):

if TypeOf(c) Is TextBox Then
....
End if

I would think that you'd want to store a collection or array or list of some sort with the items that the user is building, store that list in the viewstate, and then bind a repeater, dataGrid or DataList to that array/collection and output your textbox's there .... this way, they should survive postbacks, and you can store information regarding the collection of items that the user is creating. Even just an array of ints, from 1..N, that you bind to might do the trick...

- Jeff
Go to Top of Page

jhermiz

3564 Posts

Posted - 2006-12-14 : 13:06:38
Yep Ill deal with the repeater later as of right now Im just trying to get some sort of concept of getting this to work. I had tried TypeOf(object) already with the same effects. It doesnt seem to recognize my dynamic text boxes, maybe generating them behind a click button is not the way to go...however I would need that event behind the button to do this sort of thing though :(.

I guess Im stumped for now I will keep playing with it.


Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Select Case Me.Button1.Text
Case "Add Sites"
For i As Integer = 0 To Me.TextBox1.Text - 1
Me.Panel1.Controls.Add(New LiteralControl("<br>Enter site " & (i + 1).ToString() & ": "))
Me.Panel1.Controls.Add(New TextBox())
Next
Me.Button1.Text = "Generate Page"
Me.Button1.ForeColor = Drawing.Color.Green
Case "Generate Page"
Dim AList As New ArrayList
For Each c As Control In Panel1.Controls
If TypeOf (c) Is TextBox Then
AList.Add(CType(c, TextBox).Text)
End If
Next
End Select
End Sub



Keeping the web experience alive -- [url]http://www.web-impulse.com[/url]

RS Blog -- [url]http://weblogs.sqlteam.com/jhermiz[/url]
Go to Top of Page

jhermiz

3564 Posts

Posted - 2006-12-14 : 13:29:38
O o found this on the MS site:

quote:

Note When you create dynamic controls on a Web Form, you must create the controls and add them to the controls collection in either the Page_Init event handler or the Page_Load event handler. Otherwise, the controls may not behave as expected.



Err...but I need them created dynamically behind a click of the button...:(


Keeping the web experience alive -- [url]http://www.web-impulse.com[/url]

RS Blog -- [url]http://weblogs.sqlteam.com/jhermiz[/url]
Go to Top of Page

jhermiz

3564 Posts

Posted - 2006-12-14 : 13:57:01
quote:
Originally posted by jhermiz

O o found this on the MS site:

quote:

Note When you create dynamic controls on a Web Form, you must create the controls and add them to the controls collection in either the Page_Init event handler or the Page_Load event handler. Otherwise, the controls may not behave as expected.



Err...but I need them created dynamically behind a click of the button...:(


Keeping the web experience alive -- [url]http://www.web-impulse.com[/url]

RS Blog -- [url]http://weblogs.sqlteam.com/jhermiz[/url]



Jeff after they are created on the first post back they are completly lost. I tried a test by creating one button that creates the dynamic text boxes and another button that does absolutely nothing but clicking on that second button makes the text boxes go bye bye :|.

Issue is I need someone to fill them out and then run an event after they fill them out...


Keeping the web experience alive -- [url]http://www.web-impulse.com[/url]

RS Blog -- [url]http://weblogs.sqlteam.com/jhermiz[/url]
Go to Top of Page

DustinMichaels
Constraint Violating Yak Guru

464 Posts

Posted - 2006-12-14 : 13:57:03
quote:

O o found this on the MS site:


quote:
--------------------------------------------------------------------------------

Note When you create dynamic controls on a Web Form, you must create the controls and add them to the controls collection in either the Page_Init event handler or the Page_Load event handler. Otherwise, the controls may not behave as expected.

--------------------------------------------------------------------------------



Err...but I need them created dynamically behind a click of the button...:(



The page init / page load event gets fired on every request. If you want to check to see if the button was clicked use code like this.


Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
If Not (Request.Form(YourButton.UniqueID) Is Nothing) Then
CreateTextBoxes()
End If
End Sub
Go to Top of Page

jhermiz

3564 Posts

Posted - 2006-12-14 : 13:58:41
quote:
Originally posted by DustinMichaels

quote:

O o found this on the MS site:


quote:
--------------------------------------------------------------------------------

Note When you create dynamic controls on a Web Form, you must create the controls and add them to the controls collection in either the Page_Init event handler or the Page_Load event handler. Otherwise, the controls may not behave as expected.

--------------------------------------------------------------------------------



Err...but I need them created dynamically behind a click of the button...:(



The page init / page load event gets fired on every request. If you want to check to see if the button was clicked use code like this.


Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
Dim button As New System.Web.UI.WebControls.Button()

If Not (Request.Form(YourButton.UniqueID) Is Nothing) Then
CreateTextBoxes()
End If

End Sub




Well I can get them created the issue is once there is another post back they are gone (they being the dynamic text boxes).
I had code run to create them, after they are created I clicked a button that simply does nothing, but since it autopostsback the dynamic boxes disappeared...

So I think that is the issue, how to handle this is another question :).



Keeping the web experience alive -- [url]http://www.web-impulse.com[/url]

RS Blog -- [url]http://weblogs.sqlteam.com/jhermiz[/url]
Go to Top of Page

jsmith8858
Dr. Cross Join

7423 Posts

Posted - 2006-12-14 : 14:22:04
hi Jon -- here is some sample code to help you out, using the technique that I described. We create a class of something called "textboxItem" that will represent whatever info each textbox is holding, and we maintain and store this in an ArrayList in the viewstate. Then, we simply bind a repeater to the ArrayList to display the text boxes.

On a postback, however, we need to get the values out of the textboxes that have been created and store them into the ArrayList, which you see I do on the bAdd_Click() event. Might be better to do this on all postbacks.

anyway, hope this is somewhat helpful.

web page:


<%@ Page Language="vb" AutoEventWireup="false" Codebehind="Example.aspx.vb" Inherits="Test.Example"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<title>Example</title>
<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
</HEAD>
<body>
<form id="Form1" method="post" runat="server">
<asp:button id="bAdd" Text="Click here" Runat="server"></asp:button><br>
<br>
<asp:repeater id="rpt1" Runat="server">
<ItemTemplate>
Text box #<%# Container.DataItem.Index%>:
<asp:TextBox Runat="server" ID="txtBox" Text="<%# Container.DataItem.Value%>" /><br>
</ItemTemplate>
</asp:repeater></form>
</body>
</HTML>


and the code behind:


Public Class Example
Inherits System.Web.UI.Page

Protected WithEvents bAdd As System.Web.UI.WebControls.Button
Protected WithEvents pnl1 As System.Web.UI.WebControls.Panel
Protected WithEvents rpt1 As System.Web.UI.WebControls.Repeater

<Serializable()> Public Class TextBoxItem
Public Index As Integer
Public Value As String

Public Sub New(ByVal pIndex As Integer, ByVal pValue As String)
Index = pIndex
Value = pValue
End Sub
End Class

Public Property Items() As ArrayList
Get
Return CType(Viewstate("Items"), ArrayList)
End Get
Set(ByVal Value As ArrayList)
viewstate("Items") = Value
End Set
End Property

Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'Put user code to initialize the page here
If Not IsPostBack Then
InitTextBoxes()
LoadItems()
End If
End Sub

Private Sub InitTextBoxes()
Items = New ArrayList
End Sub

Private Sub LoadItems()
rpt1.DataSource = Items
rpt1.DataBind()
End Sub

Private Sub bAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bAdd.Click
' first, save values of all existing items:
Dim item As RepeaterItem

For i As Integer = 0 To rpt1.Items.Count - 1
item = rpt1.Items(i)
Dim txt As TextBox = CType(item.FindControl("txtBox"), TextBox)
If Not txt Is Nothing Then
CType(Items.Item(i), TextBoxItem).Value = txt.Text
End If
Next

' now add a new one:
Items.Add(New TextBoxItem(Items.Count, ""))

LoadItems()
End Sub
End Class


- Jeff
Go to Top of Page

jhermiz

3564 Posts

Posted - 2006-12-14 : 14:52:33
Hey jeff sorry I didnt get back to you, the problems I had suddenly went away.

This is SEVERLY BAD BAD CODE that I am going to post, but it was just something that I had to try.
It ended up looking pretty cool, so the code is only for testing purposes, please do not use it in production as it is very dirty especially the CreatePage button.

In any event anyone who wants to try it create a project and use the following html:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="_Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" runat="server">
<title>Untitled Page</title>
</head>
<body>
<form id="form1" runat="server">
<div>
 <asp:Panel ID="Panel1" runat="server" Height="50px" Width="1000px">
How many sites:
<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox> 
<asp:Button ID="Button1" runat="server" Text="Button" />
<asp:Button ID="Button2" runat="server" Text="Cancel" />
<asp:RangeValidator ID="RangeValidator1" runat="server" ControlToValidate="TextBox1"
ErrorMessage="No way!" MaximumValue="100" MinimumValue="1" Type="Integer"></asp:RangeValidator> 
</asp:Panel>
 
</div>
</form>
</body>
</html>


And the following code behind:



Partial Class _Default
Inherits System.Web.UI.Page
Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Select Case Me.Button1.Text
Case "Add Site(s)"
Session("PageCount") = Me.TextBox1.Text
Me.Button1.Text = "Generate Page"
Me.Button1.ForeColor = Drawing.Color.Green
Case "Generate Page"
Dim AList As New ArrayList
For Each c As Control In Panel1.Controls
If TypeOf (c) Is TextBox And c.ID Is Nothing Then
AList.Add(CType(c, TextBox).Text)
End If
Next
CreatePage(AList)
End Select
End Sub
Protected Sub CreatePage(ByVal a As ArrayList)
Dim iR As Integer
Dim k As Integer
Dim count As Integer
k = 0
If Session("PageCount") Mod 2 = 0 Then
'its even
iR = CType(Session("PageCount"), Integer) / 2
Else
iR = (CType(Session("PageCount"), Integer) / 2) + 1
End If
Response.Write("<table width='100%' height='100%' cellpadding='0' cellspacing='0'>")
count = 0

For i As Integer = 0 To iR - 1
Response.Write("<tr>")
While count < a.Count
Response.Write("<td>")
Response.Write("<iframe src='" & a(k).ToString & "' width='100%' height='100%'></iframe></td>")
count = count + 1
k += 1
If count Mod 2 = 0 Then
Exit While
End If
End While
Response.Write("</tr>")
Next
Response.Write("</table>")
End Sub
Protected Sub IterateThroughControls()
For Each c As Control In Panel1.Controls
If TypeOf (c) Is TextBox And c.ID Is Nothing Then
CType(c, TextBox).Text = "http://"
End If
Next
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

If Me.TextBox1.Text.Length > 0 Then
For i As Integer = 0 To Me.TextBox1.Text - 1
Me.Panel1.Controls.Add(New LiteralControl("<br>Enter site " & (i + 1).ToString() & ": "))
Me.Panel1.Controls.Add(New TextBox())
Next
IterateThroughControls()
End If

If Not IsPostBack Then
Me.Button1.Text = "Add Site(s)"
Me.Button1.ForeColor = Drawing.Color.Red
End If
End Sub
Protected Sub Button2_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button2.Click
For Each c As Control In Panel1.Controls
If TypeOf (c) Is TextBox And c.ID Is Nothing Then
CType(c, TextBox).Dispose()
End If
Next

Me.Button1.Text = "Add Site(s)"
Me.Button1.ForeColor = Drawing.Color.Red
Me.TextBox1.Text = 0
End Sub
End Class


I am certain jeff's code is cleaner and more accurate but this was just something I had to play with. Nifty IFRAMES :).



Keeping the web experience alive -- [url]http://www.web-impulse.com[/url]

RS Blog -- [url]http://weblogs.sqlteam.com/jhermiz[/url]
Go to Top of Page
   

- Advertisement -