Counter for correct answers doesn't work for web application, VB2012 - asp.net

I have to make my previous stand alone project into a web application. Everything works OK, for the most part, however my counter is not. The user has an option to see how many answers they are getting correct and incorrect. I copied most of my code from the original project with the exception of a few tweeks... idk what I'm not doing right.
When you input a correct answer nothing shows, but when you input a wrong answer it shows
correct:0 incorrect:1 and it doesn't change. I tried with making numCorrect and numIncorrect equal 0 as seen below... still nothing.
Any help will be greatly appreciated!
Protected Sub CheckButton_Click(sender As Object, e As EventArgs) Handles CheckButton.Click
'assign numbers to variable for calculation
Dim correctAnswer As Integer
Dim numCorrect As Integer = 0
Dim numIncorrect As Integer = 0
num1 = CInt(Val(FirstNumLabel.Text))
num2 = CInt(Val(SecondNumLabel.Text))
answerNum = CInt(Val(AnswerTextBox.Text))
'calculate the correct answer
Select Case OperationsRadioButtonList.SelectedIndex = 0
Case True
'addition operation
correctAnswer = num1 + num2
Case False
'subtraction operation
correctAnswer = num1 - num2
End Select
'tell user if their input is correct or incorrect
'show images and messages when answer is correct
If answerNum = correctAnswer Then
MessageLabel.Text = "Nice Job!"
HFaceImage.Visible = True
SFaceImage.Visible = False
'add count for numbers correct to summary
numCorrect += 1
'clear textbox for new input and focus to textbox for new
With AnswerTextBox
.Text = ""
.Focus()
End With
'generate new random set
Call RandomNumberGenerator()
Else 'show image and message if answer is incorrect
SFaceImage.Visible = True
HFaceImage.Visible = False
'add count for numbers incorrect to summary
numIncorrect = numIncorrect + 1 '
'display message if incorrect answer was given
MessageLabel.Text = "Try Again!"
'clear textbox for new input and focus to textbox
With AnswerTextBox
.Text = ""
.Focus()
End With
'show the number of correct and incorrect input when summaryCheckBox is checked
If CheckBox.Checked Then
CorrectCounterTextBox.Text = CStr(Val(numCorrect))
IncorrectCounterTextBox.Text = CStr(Val(numIncorrect))
Else
CorrectCounterTextBox.Text = ""
IncorrectCounterTextBox.Text = ""
End If
End If
End Sub

You set the CorrectCounterTextBox and IncorrectCounterTextBox text property inside the wrong answer code block, that is why the labels don't get updated when user gave correct answer. Take it out of the If ... Else ... End If block like below:
'tell user if their input is correct or incorrect
'show images and messages when answer is correct
If answerNum = correctAnswer Then
' your existing code
Else 'show image and message if answer is incorrect
SFaceImage.Visible = True
HFaceImage.Visible = False
'add count for numbers incorrect to summary
numIncorrect = numIncorrect + 1 '
'display message if incorrect answer was given
MessageLabel.Text = "Try Again!"
'clear textbox for new input and focus to textbox
With AnswerTextBox
.Text = ""
.Focus()
End With
' your existing code moved out to below.
End If
'show the number of correct and incorrect input when summaryCheckBox is checked
If CheckBox.Checked Then
CorrectCounterTextBox.Text = CStr(Val(numCorrect))
IncorrectCounterTextBox.Text = CStr(Val(numIncorrect))
Else
CorrectCounterTextBox.Text = ""
IncorrectCounterTextBox.Text = ""
End If
PS: You might want to remove the Dim numCorrect As Integer = 0 and Dim numIncorrect As Integer = 0 lines at the top of your code, otherwise your counters will never get incremented. Save the counters into Session or Viewstate instead.

Related

How can I compare a text box entry against a list of database values in the Text_Changed event

as the title states I am trying to compare or validate a text box entry against a list of acceptable values stored in my database. As of now I have taken the values from my database and store them in a List(of String) and I have a for loop that loops through that list and returns true if the values match, if the values do not match it will return false. Below I have attached the code I am currently working with.
Protected Sub txtSearchOC_TextChanged(sender As Object, e As EventArgs) Handles txtSearchOC.TextChanged
Dim listEType As List(Of String) = New List(Of String)
Dim eType As String = txtSearchOC.Text
Dim strResult As String = ""
lblPrefix.Text = ""
lblList.Text = ""
Dim TypeIDQuery As String = "
SELECT a.OrderCode
FROM SKU AS a
INNER JOIN EnrollmentType AS e ON a.EnrollmentTypeID = e.TypeID
INNER JOIN Enrollment AS f ON e.RecID = f.EnrollmentTypeID
WHERE f.AccountNumber = '12345';
"
Using connEType As New SqlConnection(ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ToString)
Using cmdEType As New SqlCommand(TypeIDQuery, connEType)
cmdEType.Parameters.Add("#AccountNumber", SqlDbType.VarChar, 15).Value = "12345"
connEType.Open()
Using sdrEType As SqlDataReader = cmdEType.ExecuteReader
While sdrEType.Read
listEType.Add(sdrEType("OrderCode").ToString)
End While
End Using
End Using
End Using
For Each Item As String In listEType
strResult &= Item & ", "
Next
For i = 0 To listEType.Count - 1
If eType = listEType(i) Then
lblPrefix.Text = "True"
End If
If eType <> listEType(i) Then
lblList.Text = "Error"
End If
Next
'lblList.Text = strResult
End Sub
In the code I declare my list and a variable to store the text value of the text box. To verify that it pulled the appropriate values from the database I have the strResult variable and can confirm that the appropriate values are being stored.
The problem I am having has to do with the For loop I have at the bottom, when I enter in a valid value that is contained in the listEType, I get the confirmation message of "True" indicating it has matched with one of the values, but I also get the "Error" message indicating that it does not match. If I enter in a value that is not contained in the list I only get the "Error" message which is supposed to happen.
My question is, based on the code I have supplied, why would that For loop be returning both "True" and "Error" at the same time for a valid entry? Also, if there is a better way to accomplish what I am trying to do, I am all ears so to speak as I am relatively new to programming.
Well, as others suggested, a drop down (combo box) would be better.
However, lets assume for some reason you don't want a combo box.
I would not loop the data. You have this amazing database engine, and it can do all the work - and no need to loop the data for such a operation. Why not query the database, and check for the value?
Say like this:
Protected Sub txtSearchOC_TextChanged(sender As Object, e As EventArgs) Handles txtSearchOC.TextChanged
If txtSearchOC.Text <> "" Then
Dim TypeIDQuery As String = "
SELECT a.OrderCode FROM SKU AS a
INNER JOIN EnrollmentType AS e ON a.EnrollmentTypeID = e.TypeID
INNER JOIN Enrollment AS f ON e.RecID = f.EnrollmentTypeID
WHERE f.AccountNumber = #AccoutNumber;"
Using connEType As New SqlConnection(ConfigurationManager.ConnectionStrings("WarrantyConnectionString").ToString)
Using cmdEType As New SqlCommand(TypeIDQuery, connEType)
cmdEType.Parameters.Add("#AccountNumber", SqlDbType.NVarChar).Value = txtSearchOC.Text
connEType.Open()
Dim rstData As New DataTable
rstData.Load(cmdEType.ExecuteReader)
If rstData.Rows.Count > 0 Then
' we have a valid match
lblPrefix.Text = "True"
Else
' we do not have a valid match
lblPrefix.Text = "False"
End If
End Using
End Using
End If
End Sub
So, pull the data into a data table. You can then check the row count, or even pull other values out of that one row. But, I don't see any need for some loop here.

'Initializing data table before use'

how can i solve this please ?
i am doing a simple database project and i have a search field i wrote the following code for searching and displaying data in DataGridView but the
Null Reference Exception keeps showing up because i'm initializing the table with nothing and yet if i don't do so i get 'Used Before Initializing warning.
the question is :how can i initialize the table properly .
Private Sub txtSearch_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles txtSearch.TextChanged
Dim searchText As String = txtSearch.Text
Dim matchText As String = ""
Dim rowMatch As Boolean = False
Dim foundRows As DataTable = Nothing 'this initializig causes the problem of null exception,But how can i Initialize it then?????
For Each rw As DataRow In dataSet.Tables(0).Rows
Dim cl As String = rw.Item(1).ToString ' this cell is FirstName Cell
If searchText.Length > cl.ToString.Length Then
matchText = cl.ToString
Else
matchText = cl.ToString.Substring(0, searchText.Length)
End If
'bellow it adds the Found Row (rw) to the table
If (searchText.Equals(matchText) And searchText <> "" And Not foundRows Is Nothing) Then foundRows.Rows.Add(rw)
Next
'to shows data if the search text field is not empty then show the found matching rows
If (searchText <> "") Then
contactView.DataSource = foundRows
Else ' else show the original tavle again
contactView.DataSource = dataSet.Tables(0)
End If
contactView.Refresh() 'refresh
End Sub
here is the screenshot of the form
i tried to use
Dim foundRows As DataTable = New DataTable
but it shows ArgumentException
This Row already belongs to another Table
i also tried this
but as you can see nothing works please Help !
Yes
i finally got it
i was having a problem in columns
Dim foundRows As DataTable = New DataTable("PseuContact") 'this initializig causes the problem of null exception,But how can i Initialize it then?????
foundRows.Columns.Add("ID")
foundRows.Columns.Add("First Name")
foundRows.Columns.Add("Last Name")
foundRows.Columns.Add("Phone Number")
foundRows.Columns.Add("Mobile Number")
foundRows.Columns.Add("Email Address")
initializing columns is important when declaring new table
this's been the best

How to compare row values of two gridviews with dropdownlist column in asp.net?

I have two gridviews. The first one has a dropdownlist. When a user clicks a button named 'Show' data will be displayed on both gridviews where data comes from database. The row data on column with dropdownlist must be compared to the rows on the first column of the second gridview. If they are equal a messagebox will prompt saying that there's no changes and data will not be saved, else if they are not equal modal pop-up will be displayed asking if data are correct.
Below is my code for comparing but it only reads the value of the 1st row in gridview1.
For i = 0 To GridView1.Rows.Count - 1
Dim ddl As DropDownList = DirectCast(GridView1.Rows(i).Cells(6).FindControl("dropdowncriteria"), DropDownList)
Dim txt As TextBox = DirectCast(GridView1.Rows(i).Cells(7).FindControl("txtreason"), TextBox)
If ddl.SelectedValue = GridView2.Rows(i).Cells(0).Text And txt.Text = GridView2.Rows(i).Cells(1).Text Then
MessageBox("No Changes Made! Nothing will be Saved.")
Return
Else
lblmsg.Text = "Are you sure that all the Data you've Selected/Entered are Correct?"
mdlpopupmsg.Show()
Return
End If
Next
What must be the problem on this?
Thanks in advance.
It only reads the first value (i=0) because the return statements cause the for loop to exit after the first comparison. If you want to compare all the rows you will need a variable to keep track of the result of the if test for each row. Something like this:
Dim hasChanges As Boolean = False
For i = 0 To GridView1.Rows.Count - 1
...
If ddl.SelectedValue = GridView2.Rows(i).Cells(0).Text And txt.Text = GridView2.Rows(i).Cells(1).Text Then
'do nothing
Else
hasChanges = True
End If
Next
If hasChanges Then
MessageBox("Has changes.")
Else
MessageBox("No changes.")
End If
Dim itemt As Double
If (DataGridCart.RowCount() > 0) Then
For i = 0 To DataGridCart.Rows.Count - 1
'if itemt as double
itemt = Val(Trim(txtItem.Text))
If ((DataGridCart.Rows(i).Cells("Item").Value).Equals(itemt)) Then
MsgBox("existing entry")
End If
Next
End If

ASP.Net - Reducing repetitive code for validation - VB

I have a form with many drop down list boxes on. Each of which I am showing or hiding a row of a table based on its value then adding a requiredfieldvalidator to the text box contained in that row. I am doing this on the selectedindexchanged event of each drop down list, the code for which can be seen below:
Protected Sub cbOffCover_SelectedIndexChanged(sender As Object, e As EventArgs) Handles cbOffCover.SelectedIndexChanged
If cbOffCover.SelectedValue = "N" Then
OffCoverRow.Visible = True
Dim rfOffcover As RequiredFieldValidator = New RequiredFieldValidator
With rfOffcover
.ControlToValidate = txtOffCover.ID
.SetFocusOnError = True
.ErrorMessage = "*"
.ForeColor = System.Drawing.Color.Red
End With
OffCoverCell.Controls.Add(rfOffcover)
Else
OffCoverRow.Visible = False
Dim c As Control
For Each c In OffCoverCell.Controls
If c.ID = "rfOffCover" Then
OffCoverCell.Controls.Remove(c)
End If
Next c
End If
End Sub
I then reuse this code for each drop down list to show/hide a differently named row and apply validation to a different text box.
My question being is there a better way of doing this? I don't know exactly how but I can't help but think I don't have to write this much code (or copy/paste) over and over again for each drop down list. Is it possible to write a function/class that will do the work and I can just call that instead? Might seem basic but i'm new to asp/vb. Many thanks
You can put it in a function that returns a boolean. When you call the function, pass it the combobox itself and whatever values you want to validate against. If it matches, return true. Try something like this:
Public Function ValidateComboBox(someComboBox as ComboBox, expectedValue as String)
Dim result as Boolean = False
If someComboBox.SelectedValue = expectedValue Then
result = True
OffCoverRow.Visible = True
Dim rfOffcover As RequiredFieldValidator = New RequiredFieldValidator
With rfOffcover
.ControlToValidate = txtOffCover.ID
.SetFocusOnError = True
.ErrorMessage = "*"
.ForeColor = System.Drawing.Color.Red
End With
OffCoverCell.Controls.Add(rfOffcover)
Else
OffCoverRow.Visible = False
Dim c As Control
For Each c In OffCoverCell.Controls
If c.ID = "rfOffCover" Then
OffCoverCell.Controls.Remove(c)
End If
Next c
End If
Return result
End Function
Of course, modify it to fit your needs. Maybe you only return the value, and do the other stuff inside the control's SelectedIndexChanged method.

ASP.NET How to do For Loop with Controls

For Each Control In Page.Header.Controls
How can I do something as above, at the moment getting the error
"Control is a Type and Cannot be used as an expression"
The Complete Code is as follows
Try
' I only do this on my production servers, so I declare those here.'
If Request.ServerVariables("server_name") = "www.myproductionurl.com" Then
' Allow scripts and css to logged in CMS users'
Dim checkLogin As New Controls.Login
If checkLogin.IsLoggedIn <> True Then
For Each Control In Page.Header.Controls
If Control.GetType.Name = "EktronJsControl" Or Control.GetType.Name = "EktronCssControl" Or Control.GetType.Name = "EktronModalCss" Then
Page.Header.Controls.Remove(Control)
Else
' Removes the extra bubble inline style stuff that wasn't put in a CSS.''
Dim litControl As LiteralControl = Control
If litControl.Text = Nothing Then
litControl.Text = ""
End If
' Removing blank.css file'
Dim htmlLink As HtmlLink = Control
If htmlLink.Href = "/css/blank.css" Then
Page.Header.Controls.Remove(Control)
End If
End If
Next
End If
End If
Catch ex As Exception
End Try`
Sadly... VB.NET compiler says you cannot use "Control" as variable name because "Control" is a type too!!
Just use another identifier :)
Since "Control" is a Class, it can not be used as a variable name. Either change it to another variable name, or surround it in square brackets ... [Control]
The brackets will tell the compiler to treat it as a variable rather than class name.
Change Control variable name to something else.
For Each ctrl In Page.Header.Controls
or
For Each ctrl As Control In Page.Header.Controls
The error message says it all: The word Control is a Type so you need to use something else.
UPDATE in response to comments.
You cannot remove the controls while your using a For Each loop to iterate through them.
Consider changing the code to something like:
For i as Integer = Page.Header.Controls.Length -1 to 0 Step -1
Dim ctrl As Control = CType(Page.Header.Control(i),Control)
If ctrl.GetType.Name = "EktronJsControl" Or ctrl.GetType.Name = "EktronCssControl" Or ctrl.GetType.Name = "EktronModalCss" Then
Page.Header.Controls.Remove(ctrl)
Else
Dim litControl As LiteralControl = ctrl
If litControl.Text = Nothing Then
litControl.Text = ""
End If
End If
Next
Or you could keep a reference to the controls to be removed and remove them after the loop.
Dim removables = New List(Of Control)
For Each ctrl In Page.Header.Controls
If ctrl.GetType.Name = "EktronJsControl" Or ctrl.GetType.Name = "EktronCssControl" Or ctrl.GetType.Name = "EktronModalCss" Then
removables.Add(ctrl)
Else
Dim litControl As LiteralControl = ctrl
If litControl.Text = Nothing Then
litControl.Text = ""
End If
End If
Next
For Each c In removables
Page.Header.Controls.Remove(c)
Next
Also, its unlikely that ctrl will be able to be converted into a LiteralControl and an HtmlLink so you need to add extra checks to determine which it is.
First, I'd like to say I'm sorry that you're working with Ektron :(. I feel your pain.
The syntax of your loop is wrong, you need to specify a variable for your loop. The syntax is:
For Each [variable] As [type] In [collection]
So, change your loop to:
For Each ctrl as Control In Page.Header.Controls
And change all the references for the variable Control in your code to be ctrl.
For more info, see the MSDN article on For Each.
Make a list of Controls to remove after you have enumerated then remove them.
Dim controlsToRemove As New List(Of Control)
For Each ctrl In Page.Header.Controls
If ctrl.GetType.Name = "EktronJsControl" Or ctrl.GetType.Name = "EktronCssControl" Or ctrl.GetType.Name = "EktronModalCss" Then
Page.Header.Controls.Remove(ctrl)
Else
Dim litControl As LiteralControl = ctrl
If litControl.Text = Nothing Then
litControl.Text = ""
End If
Dim htmlLink As HtmlLink = ctrl
If htmlLink.Href = "/css/blank.css" Then
'Page.Header.Controls.Remove(ctrl)
controlsToRemove.Add(ctrl)
End If
End If
Next
For Each ctrlToRemove In controlsToRemove
Page.Header.Controls.Remove(ctrlToRemove )
Next

Resources