Looping through textboxes and labels - asp.net

Im doing this project for an online test in ASP.NET in VB im using Microsoft visual studios 2012.
Im trying to get a loop going through my textboxes and check them against a word this will be change to be validated against a database to see if the answer are correct but when I do my loop I cannot get my text from the textbox.
Please see below
Private Sub GoGoGo()
Dim Textboxname As String '
Dim textbox As Object
Dim TextboxText As Object
Dim Labelname As String
Dim label As Object
Dim LabelText As Object
Dim Number As Integer = 1
Dim MaxTime As Integer = 9
Dim Currentloop As Integer = 1
For check As Integer = Currentloop To MaxTime
If Currentloop <= MaxTime Then
Textboxname = "TextQ" + Number
textbox = Textboxname
TextboxText = textbox
textbox.ReadOnly = True
End If
If Currentloop <= MaxTime Then
Labelname = "Label" + Number
label = Labelname
LabelText = label.Text
label.Visible = True
End If
Number = Number + 1
If TextboxText = "" Then
label.Text = "no imput"
label.ForeColor = Drawing.Color.Black
End If
If TextboxText = "server" Then
label.Text = "Correct"
label.ForeColor = Drawing.Color.Green
End If
If TextboxText = "Wrong" Then
label.Text = "Wrong"
label.ForeColor = Drawing.Color.Red
End If
If check = 9 Then
Exit For
End If
Next
End Sub

It looks like you are trying to use the string identifier of the control in place of the the actual control. Instead, you should take this identifier and search for the actual control on the page. You can do this using the FindControl method
Your function would therefore look something like (not compile tested):
Private Sub GoGoGo()
'
Dim oTextBox As TextBox
Dim oLabel As Label
Dim MaxTime As Integer = 9
Dim Currentloop As Integer = 1
For check As Integer = Currentloop To MaxTime
If Currentloop <= MaxTime Then
'NB You may have to use a recursive call to FindControl. See below.
oTextBox = CType(Page.FindControl("TextQ" & CStr(check)), TextBox)
OTextBox.ReadOnly = True;
End If
If Currentloop <= MaxTime Then
'NB You may have to use a recursive call to FindControl. See below.
oLabel = CType(Page.FindControl("Label" & CStr(check)), Label)
oLabel.Visible = True
End If
If oTextBox.Text = "" Then
oLabel.Text = "no imput"
oLabel.ForeColor = Drawing.Color.Black
End If
If oTextBox.Text = "server" Then
oLabel.Text = "Correct"
oLabel.ForeColor = Drawing.Color.Green
End If
If oTextBox.Text = "Wrong" Then
oLabel.Text = "Wrong"
oLabel.ForeColor = Drawing.Color.Red
End If
Next
End Sub
Some notes:
You don't need all of those variables. Instead, just find the actual controls, and interact with the properties directly - just check the TextBox.Text value when you need to, and set the Label.text property directly. The set is especially important as you want to update the original control property so it is shown on the page.
Similarly, you don't need Number - you can use check as this is your loop counting variable.
Whether you use the + operator or the & operator for string concatenation is up to you. There's already a good question and several answers here.
You also don't need the exit condition for the loop - the loop will exit as soon as you reach MaxTime. If you want it to exit early, just vary your To condition (e.g. Currentloop To MaxTime - 1)
UPDATE:
Page.FindControl will only work with controls that are immediate children of the root element on the page. Instead, you should try calling FindControl recursively. You should also make sure that a control with the id TextQ1 exists - look in the HTML source for the page on the client to make sure a TextBox with this id exists.
There are many examples of this on the net. Here's a VB.Net version (source: http://www.pavey.me/2007/09/recursive-pagefindcontrol-for-vbnet.html) that you can add to your page:
Public Function FindControlRecursive(Of ItemType)(ByVal Ctrl As Object, ByVal id As String) As ItemType
If String.Compare(Ctrl.ID, id, StringComparison.OrdinalIgnoreCase) = 0 AndAlso TypeOf Ctrl Is ItemType Then
Return CType(Ctrl, ItemType)
End If
For Each c As Control In Ctrl.Controls
Dim t As ItemType = FindControlRecursive(Of ItemType)(c, id)
If t IsNot Nothing Then
Return t
End If
Next
Return Nothing
End Function
Your line in the code above would then become:
oTextBox = FindControlRecursive(of TextBox)(Page.Controls(0), "TextQ" & CStr(check))
You'd also need to do the same for the Label control.

It Look like you are using only name istead of textbox try with the code below
Private Sub GoGoGo()
Dim Textboxname As String '
Dim textbox As TextBox
Dim TextboxText As Object
Dim Labelname As String
Dim label As Object
Dim LabelText As Object
Dim Number As Integer = 1
Dim MaxTime As Integer = 9
Dim Currentloop As Integer = 1
For check As Integer = Currentloop To MaxTime
If Currentloop <= MaxTime Then
Textboxname = "TextQ" + Number
textbox = Ctype(Me.Controls(Textboxname), TextBox)
TextboxText = textbox.Text
textbox.ReadOnly = True
End If
If Currentloop <= MaxTime Then
Labelname = "Label" + Number
label = Labelname
LabelText = label.Text
label.Visible = True
End If
Number = Number + 1
If TextboxText = "" Then
label.Text = "no imput"
label.ForeColor = Drawing.Color.Black
End If
If TextboxText = "server" Then
label.Text = "Correct"
label.ForeColor = Drawing.Color.Green
End If
If TextboxText = "Wrong" Then
label.Text = "Wrong"
label.ForeColor = Drawing.Color.Red
End If
If check = 9 Then
Exit For
End If
Next
End Sub

Related

Loop through checkbox ID's to see if any are checked

I have a ballot for a election system and I need to loop through all the checkboxes on the ballot to see if they are checked or unchecked. You can only select (for example) 1 of the 5 boxes available. I am stuck and can not for the life of me figure this out. The following code is my function that runs when the user clicks the submit button.
This code works and submit my ballot but does not check the number of checkboxes checked.
For Each row As Object In candidatesTable.Rows
If row(1) = ballot_ID Then
Dim checkBox_ID = row(0)
Dim CB As New CheckBox()
CB = mainBallotDiv.FindControl(checkBox_ID)
If CB.Checked Then
Dim addVote As Integer = row("votes")
addVote += 1
candidatesAdapter.addVoteToCandidate(addVote, row(0))
Dim section_ID As Integer = row(2)
Dim voter As String = userGnumber
Dim vote As Integer = checkBox_ID
Dim hasVoted As Boolean = True
votesAdapter.InsertVotes(ballot_ID, section_ID, voter, vote, hasVoted)
End If
End If
Next
Response.Redirect("~/voting/voted.aspx")
I have added a couple things to try and get this to run correctly but no luck, my code currently is the following.
Dim checkedCount As Integer
For Each row As Object In candidatesTable.Rows
If row(1) = ballot_ID Then
Dim checkBox_ID = row(0)
Dim CB As New CheckBox()
CB = mainBallotDiv.FindControl(checkBox_ID)
Dim section_idFromCB As Integer = candidatesAdapter.getsectionIDfromcandidateID(CB.ID)
Dim voteLimit As Integer = sectionsAdapter.votesbysectionid(section_idFromCB)
If CB.Checked Then
checkedCount += 1
Debug.Write(checkedCount)
If checkedCount > voteLimit Then
' error
Response.Write("<script language=""javascript"">alert('You can not select that many check boxes.');</script>")
Response.Redirect(Request.RawUrl)
Else
' pass
For Each Nrow As Object In candidatesTable.Rows
If Nrow(1) = ballot_ID Then
Dim NcheckBox_ID = row(0)
Dim NCB As New CheckBox()
NCB = mainBallotDiv.FindControl(NcheckBox_ID)
If NCB.Checked Then
Dim addVote As Integer = row("votes")
addVote += 1
candidatesAdapter.addVoteToCandidate(addVote, row(0))
Dim section_ID As Integer = row(2)
Dim voter As String = userGnumber
Dim vote As Integer = checkBox_ID
Dim hasVoted As Boolean = True
votesAdapter.InsertVotes(ballot_ID, section_ID, voter, vote, hasVoted)
End If
End If
Next
Response.Redirect("~/voting/voted.aspx")
End If
End If
End If
Next
Any help would be appreciated, and thanks in advance.
Here is my recommendation...
You can put them in a List(Of CheckBox) then you can access them anytime as needed as well as get any property you would need.
Dim lstChecked As New List(Of CheckBox)
lstChecked = divcontrol.Controls.OfType(Of CheckBox).Where(Function(ch) ch.Checked = True).ToList
lstChecked would be any CheckBox that would be checked...
For Each checkBox In Me.Controls.OfType(Of CheckBox)
' do something
Next

asp.net Unable to cast object of type 'System.String' to type 'System.Data.DataTable' Using VB

i have a question, why i get the error:
Unable to cast object of type 'System.String' to type System.Data.DataTable
Protected Sub gvInqProqurement_RowCommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs)
Try
If e.CommandName.Equals("AddNew") Then
Dim txtItem As TextBox = gvInqProqurement.FooterRow.FindControl("txtItem")
Dim txtItemMaterial As TextBox = gvInqProqurement.FooterRow.FindControl("txtItemMaterial")
Dim txtItemDesc As TextBox = gvInqProqurement.FooterRow.FindControl("txtItemDesc")
Dim txtItemSize As TextBox = gvInqProqurement.FooterRow.FindControl("txtItemSize")
Dim txtItemBrand As TextBox = gvInqProqurement.FooterRow.FindControl("txtItemBrand")
Dim txtItemQty As TextBox = gvInqProqurement.FooterRow.FindControl("txtItemQty")
Dim ddlItemUnit As DropDownList = gvInqProqurement.FooterRow.FindControl("ItemUnit")
Dim txtCerNeeds As TextBox = gvInqProqurement.FooterRow.FindControl("txtCerNeeds")
Dim txtRemarks As TextBox = gvInqProqurement.FooterRow.FindControl("txtRemarks")
Dim hfItem As HiddenField = gvInqProqurement.FooterRow.FindControl("hfItem")
If String.IsNullOrEmpty(txtItem.Text) Then
Throw New Exception("Invalid Data. Item Must Be Filled In.")
End If
Dim dtItem As New DataTable
dtItem = ViewState("InqProcurement_New.dtItem")
For i As Integer = 0 To dtItem.Rows.Count - 1
If hfItem.Value = dtItem.Rows(i).Item("FKItem").ToString Then
Throw New Exception("Item Already Selected.")
End If
Next
If Not String.IsNullOrEmpty(dtItem.Rows(0).Item(0).ToString()) Then
dtItem.Rows.Add()
Else
gvInqProqurement.Rows(0).Cells(9).Visible = True
gvInqProqurement.Rows(0).Cells(10).Visible = True
End If
dtItem.Rows(dtItem.Rows.Count - 1).Item("ItemCode") = txtItem.Text
dtItem.Rows(dtItem.Rows.Count - 1).Item("ItemMaterial") = txtItemMaterial.Text
dtItem.Rows(dtItem.Rows.Count - 1).Item("ItemDescription") = txtItemDesc.Text
dtItem.Rows(dtItem.Rows.Count - 1).Item("ItemSize") = txtItemSize.Text
dtItem.Rows(dtItem.Rows.Count - 1).Item("BrandName") = txtItemBrand.Text
dtItem.Rows(dtItem.Rows.Count - 1).Item("Quantity_InqProcurement") = txtItemQty.Text
dtItem.Rows(dtItem.Rows.Count - 1).Item("FKUnit") = ddlItemUnit.SelectedValue
dtItem.Rows(dtItem.Rows.Count - 1).Item("FKCertificate") = txtItemQty.Text
dtItem.Rows(dtItem.Rows.Count - 1).Item("Remarks") = txtItemQty.Text
ViewState("InqProcurement_New.dtItem") = dtItem
gvInqProqurement.DataSource = dtItem
gvInqProqurement.DataBind()
End If
Catch ex As Exception
Me.cvErrorMessage.IsValid = False
Me.cvErrorMessage.ErrorMessage = ex.Message
End Try
End Sub
how do i fix this error?
Convert the value returned from the viewstate into DataTable by using the Ctype. You can even use DirectCast
Dim dtItem As New DataTable
if ViewState("InqProcurement_New.dtItem") isnot nothing then
dtItem = CType(ViewState("InqProcurement_New.dtItem"),DataTable)
end if
You might have to think about the case when it is null...
This is maybe not the reason for the error you are having but you may have a syntax error in the first line.
this line:
If Not String.IsNullOrEmpty(dtItem.Rows(0).Item(0).ToString) Then
should be as follows:
If Not String.IsNullOrEmpty(dtItem.Rows(0).Item(0).ToString()) Then
just change the following Code
If String.IsNullOrEmpty(ViewState("InqProcurement_New.dtItem").Tostring())=false then
If Not String.IsNullOrEmpty(Convert.Tostring(dtItem.Rows(0).Item(0))) Then
dtItem.Rows.Add()
Else
gvInqProqurement.Rows(0).Cells(9).Visible = True
gvInqProqurement.Rows(0).Cells(10).Visible = True
End If
in this case if u use .ToString() method then our program should throw null reference exception. and in Convert.ToString() our program doesn't throw any exception. bcoz by default it takes a blank value instead of null.
Check the type of the ViewState("InqProcurement_New.dtItem") in the line dtItem = ViewState("InqProcurement_New.dtItem")
It may return a string value.

Index was out of range. Must be non-negative and less than the size of the collection - chart databind

I'm trying to build a datatable and then bind it to a gridview and chart object. The gridview appears fine but when I build the x,y array and bind them to the chart object I get the error above.
I've read many forums to understand that the index is looking at a field that is out of range but I've queried in the immediate window all the fields and the are clearly values there. There error occurs as soon as I bind it to the chart object and I don't know why the chart object doesn't just display properly.
This is my aspx codebehind:
Dim dt As DataTable = New DataTable()
dt.Columns.Add("CompanyName")
dt.Columns.Add("Amount")
dt.Columns.Add("Proportion")
Using DBContext As New fundmatrixEntities
Dim queryUnits = (From c In DBContext.Units Where c.SavingApplicationId = savAppId Select New With {.LoanAppId = c.LoanApplicationId}).Distinct().ToList()
Dim companyName As String = ""
Dim savingsAmount As String = ""
Dim totalProportion As String = ""
Dim totalSavingsAmount As String = ""
For Each loan In queryUnits
If Not loan.LoanAppId Is Nothing Then
companyName = classSQLDirect.ExecQuery("SELECT companyname FROM companyprofile where loanapplicationid='" & loan.LoanAppId.ToString & "'")
savingsAmount = classSQLDirect.ExecQuery("SELECT SUM(Amount) from unit where SavingApplicationId='" & savAppId.ToString & "' and LoanApplicationId='" & loan.LoanAppId.ToString & "'")
totalSavingsAmount = classSQLDirect.ExecQuery("SELECT amount FROM SavingApplication WHERE SavingApplicationId='" & savAppId.ToString & "'")
totalProportion = ((savingsAmount / totalSavingsAmount) * 100) & "%"
dt.Rows.Add(companyName, savingsAmount, totalProportion)
End If
Next
gvwBusinesses.DataSource = dt
gvwBusinesses.DataBind()
End Using
Dim x As String() = New String(dt.Rows.Count - 1) {}
Dim y As String() = New String(dt.Rows.Count - 1) {}
For i As Integer = 0 To dt.Rows.Count - 1
x(i) = dt.Rows(i)(0).ToString()
y(i) = dt.Rows(i)(2).ToString()
Next
chart1.Series(0).Points.DataBindXY(x, y)
chart1.Series(0).ChartType = SeriesChartType.Pie
The code errors on the line
chart1.Series(0).Points.DataBindXY(x, y)

Accessing multiple dynamic controls values

I am adding multiple controls dynamically based on a dropdownlist that the user selects. i.e. if the user selects 3 then 3 sets of the controls are added. My problem is not in adding the controls, I can add them fine, I haven't added all my code but the main parts to understand what I am doing.
Once the controls have been created, the relevant info is captured. On the Update click I need to access the values of these dynamic controls by looping through in the correct order and retrieve the values and write to the database. I can't seem to access them correctly.
Hopefully I am making sense. Any help would be appreciated. Thanks
''Loop through first set of controls and get values and then the next set etc..
Dim Description as string = ''Get Textbox value
Dim Type as string = ''Get RadComboBox value
Dim XFieldName as string = ''Get RadComboBox value
Dim Colour as string = ''Get RadColorPicker value
Below is my Code:
VB
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
RecreateControlsTxt("txt", "TextBox")
RecreateControlsChart("comboChart", "RadComboBox")
RecreateControls("combo", "RadComboBox")
RecreateControlsCP("cp", "RadColorPicker")
End Sub
Protected Sub AddControls_Click(sender As Object, e As EventArgs) Handles AddControls.Click
For i As Integer = 0 To ddlFieldNames.SelectedIndex
CreateTextbox("txt-" & Convert.ToString(i + 1))
Next
For i As Integer = 0 To ddlFieldNames.SelectedIndex
CreateComboChart("comboChart-" & Convert.ToString(i + 1))
Next
For i As Integer = 0 To ddlFieldNames.SelectedIndex
CreateComboField("combo-" & Convert.ToString(i + 1))
Next
For i As Integer = 0 To ddlFieldNames.SelectedIndex
CreateColourPicker("cp-" & Convert.ToString(i + 1))
Next
End Sub
Private Sub CreateTextbox(ByVal ID As String)
Dim txt As New TextBox()
txt.ID = ID
txt.Height = 20
Me.divDesc.Controls.Add(txt)
End Sub
Private Sub CreateComboField(ByVal ID As String)
Dim combo As New RadComboBox()
combo.ID = ID
combo.DataSource = Me.odsChartsSeriesField
combo.DataTextField = "FieldNames"
combo.DataValueField = "FieldNames"
combo.DataBind()
Me.divField.Controls.Add(combo)
End Sub
Private Sub CreateComboChart(ByVal ID As String)
Dim comboChart As New RadComboBox()
comboChart.ID = ID
Dim item1 As New RadComboBoxItem()
item1.Text = "Line"
item1.Value = "smoothedLine"
item1.ImageUrl = ("Images/linechart.png")
comboChart.Items.Add(item1)
Dim item2 As New RadComboBoxItem()
item2.Text = "Column"
item2.Value = "column"
item2.ImageUrl = ("Images/bar chart.png")
comboChart.Items.Add(item2)
Dim item3 As New RadComboBoxItem()
item3.Text = "Pie"
item3.Value = "pie"
item3.ImageUrl = ("Images/pie chart.jpg")
comboChart.Items.Add(item3)
Me.divChart.Controls.Add(comboChart)
End Sub
Private Sub CreateColourPicker(ByVal ID As String)
Dim cp As New RadColorPicker()
cp.ID = ID
cp.ShowIcon = True
cp.Style("padding-top") = "1px"
cp.CssClass = "CustomHeight"
Me.divCol.Controls.Add(cp)
End Sub
Protected Sub Update_Click(sender As Object, e As EventArgs) Handles Update.Click
Try
Dim alltxt = divDesc.Controls.OfType(Of TextBox)()
Dim allcomboChart = divChart.Controls.OfType(Of RadComboBox)()
Dim allcomboField = divField.Controls.OfType(Of RadComboBox)()
Dim allcp = divCol.Controls.OfType(Of RadColorPicker)()
''Loop through first set of controls and get values and then the next etc..
Dim Description as string = ''Get Textbox value
Dim Type as string = ''Get RadComboBox value
Dim XFieldName as string = ''Get RadComboBox value
Dim Colour as string = ''Get RadColorPicker value
If Page.IsValid Then
Dim da As New dsSVTableAdapters.Chart
Dim Result As String = da.Series(60, Description, Type, Colour, "YFieldName", XFieldName)
End If
Catch ex As Exception
lblResult.Text = ex.Message
End Try
End Sub
You have a repeated set of controls. Therefore you need a corresponding repeated set of variables that store these values.
I suggest creating a class where you can store a variable (or property) set.
Public Class ControlSet
Public Property Description As String
Public Property Type As String
Public Property XFieldName As String
Public Property Colour As String
End Class
Create an array that holds these values
Dim Values = New ControlSet(ddlFieldNames.SelectedIndex) {}
And retrieve the values in a loop
For i As Integer = 0 To Values.Length - 1
Values(i).Description = CType(divDesc.FindControl("txt-" & Convert.ToString(i + 1)), TextBox).Text
Values(i).Type = CType(divChart.FindControl("comboChart-" & Convert.ToString(i + 1)), RadComboBox).SelectedValue
Values(i).XFieldName = ...
...
Next
Also use the ID of the control; this helps to avoid confusion in case you have several controls of the same type.
you can use .FindControl(string id) method, and you should keep the controls count in your view state or session:
Protected Sub Update_Click(sender As Object, e As EventArgs) Handles Update.Click
Try
''Loop through first set of controls and get values and then the next etc..
For i As Integer = 0 To controlsCount - 1
Dim Description as string = ((TextBox)divDesc.FindControl("txt-" & Convert.ToString(i + 1))).Text ''Get Textbox value
Dim Type as string = ((RadComboBox)divChart.FindControl("comboChart-" & Convert.ToString(i + 1))).SelectedValue ''Get RadComboBox value
Dim XFieldName as string = ((RadComboBox)divField.FindControl("combo-" & Convert.ToString(i + 1))).SelectedValue ''Get RadComboBox value
Dim Colour as string = ((RadColorPicker)divField.FindControl("cp-" & Convert.ToString(i + 1))).SelectedValue ''Get RadColorPicker value
If Page.IsValid Then
Dim da As New dsSVTableAdapters.Chart
Dim Result As String = da.Series(60, Description, Type, Colour, "YFieldName", XFieldName)
Next
End If
Catch ex As Exception
lblResult.Text = ex.Message
End Try
End Sub

asp.net vb.net why is this IF not working?

I used to have this working as so....
Dim AnnEnt As Label = FormView1.FindControl("Holiday_RemainingLabel")
txtNoofDays.Text.ToString()
AnnEnt.Text.ToString()
If txtNoofDays.Text >= AnnEnt.Text Then
lblHolRequestResponse.Text = "Your holiday could not be saved"
Else
I've recently change it to this and it no longer works
Dim remain As TextBox = FormView1.FindControl("Holiday_RemainingTextBox")
txtNoofDays.Text.ToString()
remain.Text.ToString()
If txtNoofDays.Text >= remain.Text Then
lblHolRequestResponse.Text = "Your holiday could not be saved"
Else
What is the difference between the textbox in the formview and label in the formview to keep this from working?
i've since tried...
Dim days = txtNoofDays.Text
days.ToString()
AnnEnt.Text.ToString()
remain.Text.ToString()
If remain.Text.ToString < days.ToString Then
lblHolRequestResponse.Text = "Your holiday could not be saved"
If you want to compare strings numerical, cast them to numbers.
For example(asssuming they are ints):
Dim remain As TextBox = FormView1.FindControl("Holiday_RemainingTextBox")
Dim remaining = Int32.Parse(remain.Text)
Dim numOfDays = Int32.Parse(txtNoofDays.Text)
If numOfDays >= remaining Then
lblHolRequestResponse.Text = "Your holiday could not be saved"
End If
Int32.Parse Method
Otherwise you're comparing alphabetically.
String.CompareTo Method

Resources