Name 'txta1' not declared

DangerMouse
04-20-2007, 11:18 AM
Why doesn't it understand my textbox when it's inside my repeater? If I move my asp:textbox id="txta1" outside of the repeater it works fine.

TIA

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ Page Language="VB" %>
<%@ Import Namespace="System.Data.SqlClient" %>

<script runat="server" >

Sub Page_Load
Dim conHP as SqlConnection
Dim cmdSelect as SqlCommand
Dim dtrPrologTest as SqlDataReader

' Retrieve records from database
conHP = New SqlConnection ( "Server=****;UID=****;PWD=****;Database=****" )
cmdSelect = New SQLCommand ( "Select * From PrologTestQuestions", conHP )
conHP.Open()
dtrPrologTest = cmdSelect.ExecuteReader()

' Bind to Repeater
rptPrologTest.DataSource = dtrPrologTest
rptPrologTest.DataBind()

dtrPrologTest.Close()
conHP.Close()
End Sub

Sub Button_Click ( s As Object, e As EventArgs )
Dim conHP as SqlConnection
Dim strInsert as String
Dim cmdInsert as SqlCommand

conHP = New SqlConnection ( "Server=****;UID=****;PWD=****;Database=****" )
strInsert = "Insert PrologTestAnswers ( TestID, a1, a2, a3, a4, a5 ) Values ( @TestID, @a1, @a2, @a3, @a4, @a5 )"
cmdInsert = New SqlCommand ( strInsert, conHP )
cmdInsert.Parameters.Add ( "@TestID", txtTestID.Text )
cmdInsert.Parameters.Add ( "@a1", txta1.Text )
cmdInsert.Parameters.Add ( "@a2", txta2.Text )
cmdInsert.Parameters.Add ( "@a3", txta3.Text )
cmdInsert.Parameters.Add ( "@a4", txta4.Text )
cmdInsert.Parameters.Add ( "@a5", txta5.Text )
conHP.Open()
cmdInsert.ExecuteNonQuery()
conHP.Close()
End Sub

</script>


<html dir="ltr" xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Prolog Test</title>
</head>

<body style="background-color: #ECECEC">

<form id="form1" runat="server">

<table cellpadding="2">
<tr>
<td><img src="images/logo.gif"/></td>
</tr>
<tr>
<td><br/></td>
</tr>
<tr>
<td><h2>Lesson 1</h2></td>
</tr>
<tr>
<td>Test ID<asp:TextBox ID="txtTestID" runat="server"/></td>
</tr>
</table>

<asp:Repeater ID="rptPrologTest" runat="server">

<ItemTemplate>
<table cellpadding="10">
<tr>
<td>1. <%# Container.DataItem ( "q1" ) %></td>
</tr>
<tr>
<td><asp:TextBox ID="txta1" TextMode="MultiLine" Columns="80" Rows="2" runat="server" /></td>
</tr>
<tr>
<td>2. <%# Container.DataItem ( "q2" ) %></td>
</tr>
<tr>
<td><asp:TextBox ID="txta2" TextMode="MultiLine" Columns="80" Rows="2" runat="server" /></td>
</tr>

<tr>
<td>3. <%# Container.DataItem ( "q3" ) %></td>
</tr>
<tr>
<td><asp:TextBox ID="txta3" TextMode="MultiLine" Columns="80" Rows="2" runat="server" /></td>
</tr>

<tr>
<td>4. <%# Container.DataItem ( "q4" ) %></td>
</tr>
<tr>
<td><asp:TextBox ID="txta4" TextMode="MultiLine" Columns="80" Rows="2" runat="server" /></td>
</tr>
<tr>
<td>5. <%# Container.DataItem ( "q5" ) %></td>
</tr>
<tr>
<td><asp:TextBox ID="txta5" TextMode="MultiLine" Columns="80" Rows="2" runat="server" /></td>
</tr>
</table>

</ItemTemplate>

</asp:Repeater>

<p/>

<asp:Button Text="Submit Answers" OnClick="Button_Click" runat="server"/></form>

</body>

</html>

MKoslof
04-21-2007, 10:27 AM
Instead of embedding an ASP control in a HTML table, within your ItemTemplate definition include your asp controls such as text boxes. Then you can bind the entire data repeater to a DataSource via its DataSource and DataBind methods.

The problem is you are embedding the asp server side control within an HTML table, which is not a server side component.

Just remove the Table and in the Item Template define asp server controls and then DataBind :)

DangerMouse
04-23-2007, 01:49 PM
I'm not sure I'm following what you're saying. my table is inside an ItemTemplate, so my asp controls are also inside that same ItemTemplate. I can get this to work if I don't pull my questions from my database and just put the questions in html, but I want to create another form where the admins can change the questions at a later date without touching the code.

I've tried using multiple <ItemTemplates> but it still doesn't recognize my textbox controls inside my repeater. And I should be able to use a table inside a repeater right? I'll try getting rid of it since i really only have one column anyway.

MKoslof
04-23-2007, 01:53 PM
What happens if you remove the HTML <table> and within the <ItemTemplate> simply name your server side asp controls? Does it work. An HTML table is not a server side component.

DangerMouse
04-23-2007, 01:56 PM
Alright I've taken the table out and added an <ItemTemplate> for each row but it still does not recognize my id=txta1 or any of the other textbox id's in the repeater. What am I missing?


<asp:Repeater ID="rptPrologTest" runat="server">

<ItemTemplate>
1. <&#37;# Container.DataItem ( "q1" ) %>
</ItemTemplate>
<ItemTemplate>
<asp:TextBox ID="txta1" TextMode="MultiLine" Columns="80" Rows="2" runat="server" />
</ItemTemplate>
<ItemTemplate>
2. <%# Container.DataItem ( "q2" ) %>
</ItemTemplate>
<ItemTemplate>
<asp:TextBox ID="txta2" TextMode="MultiLine" Columns="80" Rows="2" runat="server" />
</ItemTemplate>
<ItemTemplate>
3. <%# Container.DataItem ( "q3" ) %>
</ItemTemplate>
<ItemTemplate>
<asp:TextBox ID="txta3" TextMode="MultiLine" Columns="80" Rows="2" runat="server" />
</ItemTemplate>
<ItemTemplate>
4. <%# Container.DataItem ( "q4" ) %>
</ItemTemplate>
<ItemTemplate>
<asp:TextBox ID="txta4" TextMode="MultiLine" Columns="80" Rows="2" runat="server" />
</ItemTemplate>
<ItemTemplate>
5. <%# Container.DataItem ( "q5" ) %>
</ItemTemplate>
<ItemTemplate>
<asp:TextBox ID="txta5" TextMode="MultiLine" Columns="80" Rows="2" runat="server" />
</ItemTemplate>

</asp:Repeater>


here's the error message:
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: BC30451: Name 'txta1' is not declared.

Source Error:

Line 34: cmdInsert = New SqlCommand ( strInsert, conHP )
Line 35: cmdInsert.Parameters.Add ( "@TestID", txtTestID.Text )
Line 36: cmdInsert.Parameters.Add ( "@a1", txta1.Text )
Line 37: cmdInsert.Parameters.Add ( "@a2", txta2.Text )
Line 38: cmdInsert.Parameters.Add ( "@a3", txta3.Text )

MKoslof
04-23-2007, 02:00 PM
AHH....ok, now I see the issue. The problem is here:


cmdInsert.Parameters.Add ( "@a2", txta1.Text )

The IDE can not find the EMBEDDED control which exists in the repeater. Sorry, I wasn't following the problem at first. You can put the HTML table back or use an asp:table if you want the table rendered server side.

What you need to do is drill down from the parent object and reference the control that way. You could go by id: ParentID.ChildId, etc. There is also the .FindControl method as well, etc. The control "txta1" isn't recognized since it is encapsulated within a parent repeater control

DangerMouse
04-23-2007, 02:43 PM
can you give me an example of drilling down using my code? I tried identifying it by

cmdInsert.Parameters.Add ( "@a1", rptPrologTest.txta1.Text )

to no avail...


or can you help with how i would use a find control in this example?

Thanks.

wayneph
04-24-2007, 08:07 AM
Well, the first problem is that you should normally only have 1 item template
for a repeater. That is the code that will exist for each record in your data
source. If you just have 5 columns, but a single record there is no need for
a repeater because there aren't multiple records.

If you've got multiple records, you'll need to know which item you're wanting
to work with. The FindControl that MKoslof mentioned would work something
like this:
rptPrologTest.Items(0).FindControl("txta1")

And to get a value out of it you should use DirectCast to get the right type:
DirectCast(rptPrologTest.Items(0).FindControl("txta1"), TextBox).Text

(My example always looks at row 1. Change 0 to what ever row you need.)

DangerMouse
04-24-2007, 10:52 AM
Thanks I will give it a try. Ultimately I'm going to have multiple tests or rows in the prologtestquestions table with about 20 questions per test. Then I'd like to add a drop down for the TestID which will obviously change the test questions. I thought this was going to be easy.... if only I could assign ID's to child controls. that still doesn't make sense to me.

DangerMouse
04-24-2007, 11:18 AM
Heres the code for my button_click:

Sub Button_Click ( s As Object, e As EventArgs )
Dim conHP as SqlConnection
Dim strInsert as String
Dim cmdInsert as SqlCommand
dim a1 as string
dim a2 as string
dim a3 as string
dim a4 as string
dim a5 as string

a1 = DirectCast(rptPrologTest.Items(0).FindControl("txta1"), TextBox).Text
a2 = DirectCast(rptPrologTest.Items(0).FindControl("txta2"), TextBox).Text
a3 = DirectCast(rptPrologTest.Items(0).FindControl("txta3"), TextBox).Text
a4 = DirectCast(rptPrologTest.Items(0).FindControl("txta4"), TextBox).Text
a5 = DirectCast(rptPrologTest.Items(0).FindControl("txta5"), TextBox).Text


conHP = New SqlConnection ( "Server=****;UID=****;PWD=****;Database=****" )
strInsert = "Insert PrologTestAnswers ( TestID, a1, a2, a3, a4, a5 ) Values ( @TestID, @a1, @a2, @a3, @a4, @a5 )"
cmdInsert = New SqlCommand ( strInsert, conHP )
cmdInsert.Parameters.Add ( "@TestID", txtTestID.Text )
cmdInsert.Parameters.Add ( "@a1", a1 )
cmdInsert.Parameters.Add ( "@a2", a2 )
cmdInsert.Parameters.Add ( "@a3", a3 )
cmdInsert.Parameters.Add ( "@a4", a4 )
cmdInsert.Parameters.Add ( "@a5", a5 )
conHP.Open()
cmdInsert.ExecuteNonQuery()
conHP.Close()
End Sub


I'm able to get the page up and running and I type in values in my answer text boxes but when I click my submit button it adds a record in my database but the answer values are empty. Did i put the DirectCast code in the wrong spot? Does it need to be in the same locations as the repeater, and if so, how do I get my variables a1-a5 to pass over to my Sub Button_Click?

MKoslof
04-25-2007, 09:16 AM
If I had to guess you are dealing with post back issues and the state of the repeater and its containing controls.

If you step through your code is "a1" string.empty? My initial hunch is that is the case.

I'm not completely sure how you have this designed. But there are multiple ways to handle post back preservation if this is truly your issue. You can store the values in the ViewState by key and retrieve them as strings whenever you need them. If you are trying to store complex objects in the view state you are going to have to re-stream them out, but considering these are primitive types or string values, you don't need to do that.

wayneph
04-26-2007, 07:19 AM
I just saw one more thing... You're rebinding your datagrid every time you go
through the Page_Load event. That would effectively clear out all of the
controls in the repeater and set them back to their original values.

Only bind the Repeater on the initial load, and after you process your
other events. In Page_Load, you can use If Not IsPostBack Then
to only get the DataBind on the first visit.

DangerMouse
05-02-2007, 11:45 AM
I'm no longer working on this project... but I think the find control method was the way to go. I think if I would have added this to my Sub Button_Click it would have worked. I changed a bunch of the code so I don't really want to go back and test it, but in case anyone runs into this in the future they can try the FindControl()

Dim txta1 as TextBox = e.Item.FindControl("txta1")

EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum