joetinger joetinger - 8 days ago 5
Vb.net Question

Table textboxes losing value on postback

I have some code that I found online to add a new row to a table dynamically http://geekswithblogs.net/dotNETvinz/archive/2009/06/29/faq-dynamically-adding-rows-in-asp-table-on-button-click.aspx . The row gets added and all previous data is gone. From the comments it seems like a lot of people had this issue.

ASPX

<asp:UpdatePanel ID="upMaterial" runat="server" UpdateMode="Conditional" ChildrenAsTriggers="true">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName ="Click" />
</Triggers>
<ContentTemplate>
<asp:Table ID="tbMaterials" runat="server" GridLines="Both" Visible="false">
<asp:TableRow>
<asp:TableCell>Qty</asp:TableCell>
<asp:TableCell>Material</asp:TableCell>
<asp:TableCell>Cost</asp:TableCell>
<asp:TableCell>Price</asp:TableCell>
<asp:TableCell>Total</asp:TableCell>
</asp:TableRow>
</asp:Table>
<asp:Button ID="Button1" runat="server" Text="Button" />
</ContentTemplate>
</asp:UpdatePanel>


VB

Public Class _Default
Inherits System.Web.UI.Page
Private numOfRows As Integer = 1

Protected Sub Page_Load(sender As Object, e As EventArgs)
If Not Page.IsPostBack Then
ViewState("RowsCount") = 1
End If
End Sub

Protected Sub addRow(sender As Object, e As EventArgs) Handles Button1.Click
'adds the column row once we know the header row is there
If ViewState("RowsCount") IsNot Nothing Then
tbMaterials.Visible = True
numOfRows = Convert.ToInt32(ViewState("RowsCount").ToString)
GenerateTable(numOfRows)
End If
End Sub

Private Sub GenerateTable(rowsCount As Integer)
'Creat the Table and Add it to the Page

Dim table As Table = tbMaterials

'The number of Columns to be generated
Const colsCount As Integer = 5
'You can changed the value of 3 based on you requirements

' Now iterate through the table and add your controls
For i As Integer = 0 To rowsCount - 1
Dim row As New TableRow()

For j As Integer = 0 To colsCount - 1
Dim cell As New TableCell()
Dim tb As New TextBox()

' Set a unique ID for each TextBox added
tb.ID = "TextBoxRow_" + i.ToString + "Col_" + j.ToString
' Add the control to the TableCell
cell.Controls.Add(tb)
' Add the TableCell to the TableRow
row.Cells.Add(cell)
Next

' And finally, add the TableRow to the Table
table.Rows.Add(row)
Next
'Set Previous Data on PostBacks
SetPreviousData(rowsCount, colsCount)
'Sore the current Rows Count in ViewState
rowsCount += 1
ViewState("RowsCount") = rowsCount
End Sub
Private Sub SetPreviousData(rowsCount As Integer, colsCount As Integer)
Dim table As Table = tbMaterials
If table IsNot Nothing Then
For i As Integer = 0 To rowsCount - 1
For j As Integer = 0 To colsCount - 1
'Extracting the Dynamic Controls from the Table
Dim tb As TextBox = DirectCast(table.Rows(i).Cells(j).FindControl("TextBoxRow_" + i.ToString + "Col_" + j.ToString), TextBox)
'Use Request objects for getting the previous data of the dynamic textbox
tb.Text = Request.Form("TextBoxRow_" + i.ToString + "Col_" + j.ToString)
Next
Next
End If
End Sub

Answer

Can you check using view source from browser if ID you are using to get form variable are the same as name of name of variable you are using in tb.Text = Request.Form("TextBoxRow_" + i.ToString + "Col_" + j.ToString). As we can not use id for request variables.