ASP.Net - Reducing repetitive code for validation - VB - asp.net

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.

Related

VB.NET: CheckBoxList - programmatically setting Items as Checked

I pass in comma separated values to this function, and check items in a checkboxlist according to the values. But there are no items checked after the function call.
For example, I pass in a string "1,5,8", hoping the 3 items with value of 1,5,8 in the checkboxlist will get "checked = true" status. But they don't.
Private Sub GetListValuesFromCommaSeparatedValueString(ByRef lst As CheckBoxList, s As String)
If IsNothing(s) Or s = "" Then
Exit Sub
End If
Dim array = s.Split(",")
For Each value As String In array
lst.Items.FindByValue(value).Selected = True
Next
End Sub
You'd want the Checked property of CheckBox not Selected.
For Each value As String In array
lst.Items.FindByValue(value).Checked = True
Next
More info on Checked.
You should use checked property, selected highlights only certain item on list
lst.Items.FindByValue(value).Checked = True

Global Variables lose value in another event

I have following global variables
Dim cardNumber As String
Dim txnAmount As String
Dim TerminalID As String
Dim CurrencyCode As String
And Values are assigned on a click Event from the result set returned from SP
dsCards = Utilities.GetVirtualResultNew(txtCardNumber.Text.Trim)
grdTransactionResultSearch.DataSource = dsCards
grdTransactionResultSearch.DataBind()
cardNumber = IIf(IsDBNull(dsCards.Tables(0).Rows(0).Item("pan")), "", dsCards.Tables(0).Rows(0).Item("pan"))
txnAmount = IIf(IsDBNull(dsCards.Tables(0).Rows(0).Item("TotalAmount")), "", dsCards.Tables(0).Rows(0).Item("TotalAmount"))
TerminalID = IIf(IsDBNull(dsCards.Tables(0).Rows(0).Item("TerminalID")), "", dsCards.Tables(0).Rows(0).Item("TerminalID"))
CurrencyCode = IIf(IsDBNull(dsCards.Tables(0).Rows(0).Item("CurrencyCode")), "", dsCards.Tables(0).Rows(0).Item("CurrencyCode"))
I Debugged the code and I can see the values are assigned to them but when I try to access them in another button click event, They are empty
Here is my button click event where These variables are empty
Protected Sub btnAuthorize_Click(sender As Object, e As EventArgs) Handles btnAuthorize.Click
Utilities.InsertAuthorizedTransactions(cardNumber, txnAmount, TerminalID, CurrencyCode)
Label1.Visible = True
END Sub
Whats the problem with my code?
When a button is clicked, then a postback is performed (What is a postback?) which in this case will re-initliase your variables.
The preferred option is probably to store your variables in ViewState (What is ViewState?) in your first button click:
ViewState("cardNumber") = "foo"
ViewState("txnAmount") = "bar"
'etc.
And then access them in your second click.
Note also that you should not use the IIF function in VB.NET but you should instead use the If Operator

How to add a new value to Dropdownlist

I am loading datasource to Dropdown list and binding, but in some scenario new value is coming (case sensitive) so i cannot able to set as selected value for the drop downlist?
How to acheive this, means to show the datagrid selected value as text in drop down list?
Populating data into dropdown list
Me.RmtRouterName.DataSource = Me.datareader_1param("pr_list_dev_by_site",
SiteID, "#enter_value")
Me.RmtRouterName.DataTextField = "devname"
Me.RmtRouterName.DataValueField = "devname"
Reading value from datagrid
tmpstr = MyIIF(Me.SiteInfo1.Tables(SiteInfoTableName).Rows(0), "RmtRouterName")
If (tmpstr = String.Empty) Then
Me.RmtRouterName.SelectedIndex = -1
Else
Me.RmtRouterName.SelectedValue = tmpstr
in some cases the datareader values and datgrid values are mismatching (due to case sensitive) how to overcome this problem
In your Else logic, attempt to find the text value in the drop down list before attempting to set the SelectedValue, like this:
Helper Function:
Public Function FindByTextCaseInsensitive(ByVal ctl As ListControl, ByVal text As String) As ListItem
If ctl Is Nothing Then
Return Nothing
End If
For Each li As ListItem In ctl.Items
If String.Compare(li.Text, text, True) = 0 Then
Return li
End If
Next
Return Nothing
End Function
Now in your Else block, do this:
Else
Dim foundItem As ListItem = FindByTextCaseInsensitive(tmpstr)
If foundItem Is Nothing Then
Me.RmtRouterName.SelectedIndex = -1
Else
Me.RmtRouterName.SelectedValue = tmpstr
End If
End If

Simple bind value to textbox in code behind using Telerik OpenAccess

I cannot find a complete example. Found tons on grid and combobox, but not textbox. This test is to lookup a “PhoneTypeName” from a UserPhoneType table with TypeCode = “0” and assign that first value to a asp.net textbox.
Currently, I am getting “Object reference not set to an instance of an object” when setting the text box to "phonetype.FirstOrDefault.PhoneTypeName.ToString"
Using dbContext As New EntitiesModel()
Dim phonetype As IEnumerable(Of User_PhoneType) = dbContext.User_PhoneTypes.Where(Function(c) c.PhoneTypeCode = "O")
mytextbox.Text = phonetype.FirstOrDefault.PhoneTypeName.ToString
End Using
----EDIT----
I changed as suggested. I ALSO successfully bound the entire list of PhoneTypes to a droplist control...to confirm the data is accessible. It must be the way I am going about querying the table for a single record here.
I get the same error, but at "Dim type = phonetype.First..."
The record is in the table, but it does not appear to be extracted with my code.
Dim phonetype As IEnumerable(Of User_PhoneType) = dbContext1.User_PhoneTypes.Where(Function(c) c.PhoneTypeCode = "M")
Dim type = phonetype.FirstOrDefault
If Object.ReferenceEquals(type, Nothing) = False And Object.ReferenceEquals(type.PhoneTypeName, Nothing) = False Then
mytextbox.Text = type.PhoneTypeName.ToString
End If
In general there are the following two possible reasons for getting this exception:
1) The phonetype list is empty and the FirstOrDefault method is returning a Nothing value.
2) The PhoneTypeName property of the first element of the phonetype list has a Nothing value.
In order to make sure that you will not get the Object reference not set to an instance of an object exception I suggest you add a check for Nothing before setting the TextBox value. It could be similar to the one below:
Dim type = phonetype.FirstOrDefault
If Object.ReferenceEquals(type, Nothing) = False And Object.ReferenceEquals(type.PhoneTypeName, Nothing) = False Then
mytextbox.Text = type.PhoneTypeName.ToString
End If
Fixed it.
I was able to view the SQL string being generated by using this:
mytextbox.text = phonetype.tostring
I saw that the SQL contained "NULL= 'O'"
I did it like the example?!? However, when I added .ToString to the field being queried, it worked.
So the final looks like this:
Using dbContext As New EntitiesModel()
Dim phonetype As IEnumerable(Of User_PhoneType) = dbContext.User_PhoneTypes.Where(Function(c) c.PhoneTypeCode.**ToString** = "O")
mytextbox.Text = phonetype.FirstOrDefault.PhoneTypeName.ToString
End Using
BTW, Dimitar point to check for null first is good advice (+1). The value was nothing as he said.

array not holding value when updated

i can add a value to array(0), but when i then add a value to array(1) it clears the value for array(0). I've tried every way I can think of to declare and create the array. My code looks like this:
Dim aryEstimateInfo() As String = New String(7) {}
Private Sub wzrdEstimateWizard_NextButtonClick(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.WizardNavigationEventArgs) Handles wzrdEstimateWizard.NextButtonClick
Select Case wzrdEstimateWizard.ActiveStepIndex
Case 0 'first estimate wizard step
aryEstimateInfo(0) = rad_lstVehicleType.SelectedItem.ToString
Case 1 'second estimate wizard step
Dim DamageZoneSelected As Boolean = False
For Each cntrl As Control In pnlDamageZone.Controls
If TypeOf cntrl Is RadioButton Then
Dim RadButton As RadioButton = cntrl
If RadButton.Checked Then
DamageZoneSelected = True
DamageZone = RadButton.Text.ToString
Exit For
Else
DamageZoneSelected = False
End If
End If
Next
If DamageZoneSelected = True Then
lblDamageZoneError.Visible = False
aryEstimateInfo(1) = DamageZone
Else
'if no damage zone is selected a message is displayed
wzrdEstimateWizard.ActiveStepIndex = 2
wzrdEstimateWizard.ActiveStepIndex = 1
lblDamageZoneError.Visible = True
End If
Case 2 'third estimate wizard step
'assigns the number of dents to the estimate array
aryEstimateInfo(2) = ddlNumberOfDents.SelectedValue.ToString
'sets the average dent size in the estimate arrau
aryEstimateInfo(3) = ddlDentSize.SelectedValue.ToString
'sets the add-on code and number of oversized dents
If ddlOverSized.Enabled = True Then
'aryEstimateInfo.SetValue("3", 4)
aryEstimateInfo(4) = "3"
aryEstimateInfo(7) = ddlOverSized.SelectedValue.ToString
Else
End If
Case 3 'fourth estimate wizard step
Case Else
End Select
End Sub
I'm using this in an ASP.Net wizard control and in basic, visual studio 2010.
The problem is that each button click is posting back the page, which causes your aryEstimateInfo to be re-created on each postback.
In order to handle this situation elegantly, improve the maintenance of the page, and make it easier to debug this sort of situation in the future, I recommend the following changes:
1) Change the array to a class with properties:
Public Class EstimateInfo
Public VehicleType As String = ""
Public DamageZone As String = ""
Public NumberOfDents As String = ""
Public DentSize As String = ""
Public AddOnCode As String = ""
Public Oversized As String = ""
End Class
Note that all of the properties are declared as string, but the data types should probably be changed to more accurately reflect the underlying content.
This approach will help debugging because you can change the auto-implemented property to a getter/setter so that you can place a breakpoint to see where the value is getting cleared:
Private m_sVehicleType As String = ""
Public Property VehicleType As String
Get
Return m_sVehicleType
End Get
Set (Value As String
' You could set a breakpoint here to discover where the value is getting cleared.
m_sVehicleType = Value
End Set
End Property
And if you need to have the values in a string array for export to a different application or database, for example, you could add a method to the class to produce an appropriate string array.
2) Add a property to the page to store the current answer class in the page's ViewState so that you won't have to continuously re-populate the array. For example:
Private Property EstimateInfo As EstimateInfo
Get
' Add a new record to the viewstate if it doesn't already exist
If ViewState("EstimateInfo") Is Nothing Then
Me.EstimateInfo = New EstimateInfo
End If
Return ViewState("EstimateInfo")
End Get
Set (value As EstimateInfo)
ViewState("EstimateInfo") = value
End Set
End Property
Once you do this, your wizard code becomes much easier to understand and maintain:
Select Case wzrdEstimateWizard.ActiveStepIndex
Case 0 'first estimate wizard step
Me.EstimateInfo.VehicleType = rad_lstVehicleType.SelectedItem.ToString
when you declare the new array someehere in the code you cannot reuse it again after post back.
I suggest to build the array on finish wizard event
you can use the controls in whole steps where ever step you in
I guess it will be fine
otherwise you need to store the array after every update in session or view state but I don't like both
sorry I couldn't view example becoz I'm using mobile

Resources