ASP:CustomValidator continues to execute after error message thrown - asp.net

ASP:CustomValidator continues to execute the rest of my code after the the Validator renders as False. I have a few textboxes (Name, Date, IdNumber, OtherShit)
Here's some code:
<span class="grouping" id="span1" runat="server">
<label>
ID Number</label>
<asp:TextBox ID="tbIdNumber" runat="server" MaxLength="6" Columns="10"></asp:TextBox>
<asp:CustomValidator ID="CustomValidatorIdNumber" runat="server" ErrorMessage="Please enter date."
ControlToValidate="tbIdNumber" OnServerValidate="CustomValidatorLocation_ServerValidate1"> </asp:CustomValidator>
</span>
Followed by the back end code controlling the Validator:
Protected Sub CustomValidatorLocation_ServerValidate1(source As Object, args As ServerValidateEventArgs) Handles CustomValidatorIdNumber.ServerValidate
Dim currentUserId = Things.AuthenticatedData.Get_CurrentUser.Id
If (Convert.ToString(args.Value)) Is currentUserId Then
args.IsValid = True
ElseIf (Convert.ToString(args.Value)) IsNot currentUserId And bdpDate.IsNull Then
args.IsValid = False
End If
End Sub
So each person logged in has an ID that is known to other users. FYI this is a search filter. Basically what I would like to do is this: if the user types in their own ID, then everything is fine and will continue to execute through the code. If the user types in another users ID, they also need to include a date. If no date is include, it throws the error message when they click "Search" (but does not execute the search) until they put in a date. Currently it does all that, but still executes the search. Meh... Help please...

Make sure you put the Page.IsValid() on the right instance of the btnClick... fml. Works perfect now.

Related

How to write a conditional that alerts a user if a text box is changed a second time

What I am trying to do is create a conditional statement that will alert the user if a text box is changed after initially filling that field.
For instance if they enter their name into the text box and then at a later point enter a different name into that text box, I want it to alert the user.
Below is my code of both the text box control as well as a .textchanged event.
Text Box Control:
<div class="txtSearch">
<asp:TextBox ID="txtSearchOC" runat="server" Width="250px" Text="" AutoPostBack="True" TabIndex="13" Font-Bold="True"
ForeColor="#822402" BorderColor="#822402" AutoCompleteType="Disabled" ClientIDMode="Static" />
</div>
.textChanged Event Code:
Protected Sub txtSearchOC_TextChanged(sender As Object, e As EventArgs) Handles txtSearchOC.TextChanged
Dim searchOCText As String = txtSearchOC.Text
Dim isTheSame As Boolean = False
If searchOCText = txtSearchOC.Text Then
isTheSame = True
End If
If isTheSame = True AndAlso searchOCText <> txtSearchOC.Text Then
Call txtSearchOC_Warning()
End If
End Sub
My thought process was to store the first name in a variable called "searchOCText" and then have a boolean that would hold true if searchOCText = txtSearchOC.Text, I would then use that boolean value to test if the text in the text box had changed, but I'm not terribly sure where to go from here as I am pretty new to programming.
So far I have tested the procedure "txtSearchOC_Warning()" and on its own it works and displays the message I am wanting to display. However when I try to call it from the TexChanged procedure nothing happens and I am at a loss as to why. So I am left to believe that the problem lies within my conditional and that I need to start digging there.
Any and all help would be greatly appreciated.
It's better to use JS to perform this validation since it's more efficient and doesn't require a PostBack to trigger. Check the following simple script:
<script>
let oldVal=document.getElementById("<%=txtSearchOC.ClientID%>").value;
function checkChange(val) {
if(oldVal!="")//To check if this change is a first time change
{
alert("The input value has changed to: " + val);
}
oldVal=val;
}
</script>
And your Text Box definition will be:
<asp:TextBox ID="txtSearchOC" runat="server"
onClientClick="checkChange(this.value)" AutoPostBack="false" ...
The problem with your approach is that searchOCText will be always equal to txtSearchOC after the PostBack. Line Dim searchOCText As String = txtSearchOC.Text
If you still want to use this approach you may store searchOCText in a Session like this:
Try
If Session("searchOCText").ToString()= txtSearchOC.Text Then
isTheSame = True
End If
Catch
End Try
Session("searchOCText")=txtSearchOC.Text
Looks like your code has some small mistakes:
TextChanged raised on programmatically setting value and any typing, every stroke. Better to use the LostFocus event.
Variable isTheSame is redundant (always True) because the event raises after text changing.
Actually, your message will never be shown when changing the user contents or not, because you compare user input with the same user input (inequality searchOCText <> txtSearchOC.Text always be False).
I think it is the simplest solution.
Public Class ExtTextBox
Inherits TextBox
Private LastUserInput As String
Protected Sub ExtTextBox_LostFocus(sender As Object, e As EventArgs) Handles Me.LostFocus
Select Case True
Case LastUserInput Is Nothing
LastUserInput = Text
Case Text <> LastUserInput
If MsgBox("Apply change?", MsgBoxStyle.YesNo Or MsgBoxStyle.Question) = MsgBoxResult.Yes Then
LastUserInput = Text
Else
Text = LastUserInput
End If
End Select
End Sub
End Class
Variable LastUserInput (initially Nothing) stores user input.
The first branch of Select Case stores the first user input in LastUserInput.
The second branch updates stored input or restored text according to user decision where the user points to any other element after any edit excluding the first one. You can put any code into the second branch to process new input.

CustomValidator not working

I have a CustomValidator that checks if text entered in textboxes matches certain fields in a database. This was all working great before, but I have modified my page quite a bit since then and it is no longer working. I didn't think I changed anything that would affect this, but apparently I did. All my other validators (required field validators) are working correctly, but my CustomValidator isn't responding.
So anyway, here is my code:
CustomValidator:
<asp:CustomValidator ID="CustomValidator1" runat="server" ControlToValidate="txtCoursePrefix" ErrorMessage="Course number is already taken."></asp:CustomValidator>
VB codebehind:
Protected Sub CustomValidator1_ServerValidate(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs) Handles CustomValidator1.ServerValidate
'Checking for duplicate course numbers
'get values
Dim checkPrefix = txtCoursePrefix.Text
Dim checkNum = txtCourseNum.Text
'db connectivity
Dim myConn As New OleDbConnection
myConn.ConnectionString = AccessDataSource2.ConnectionString
myConn.Open()
'select records
Dim mySelect As New OleDbCommand("SELECT 1 FROM tableCourse WHERE prefix=? AND course_number=?", myConn)
mySelect.Parameters.AddWithValue("#checkPrefix", checkPrefix)
mySelect.Parameters.AddWithValue("#checkNum", checkNum)
'execute(Command)
Dim myValue = mySelect.ExecuteScalar()
'check if record exists
If myValue IsNot Nothing Then
CustomValidator1.SetFocusOnError = True
args.IsValid = False
End If
End Sub
Everything is working up until CustomValidator1.SetFocusOnError = True and args.IsValid = False. I have tested the If statement and it's working correctly, it returns true and anything else I put inside of it executes.
Things you should know when using customvalidators:
If you are validating using a ValidationGroup, don't forget to add it to your CustomValidator.
Set the ControlToValidate property.
A CustomValidator control never fires when the ControlToValidate control is empty unless you set ValidateEmptyText=true.
When using ClientValidationFunction="customClientValidationFunction" use the following signature:
function customClientValidationFunction(sender, arguments) {
arguments.IsValid = true; //validation goes here
}
You should set the property ValidateEmptyText="true" on the CustomValidator. The client and server functions will always be called in that case.
It solved the problem for me.
If the handler is getting called, and you're successfully setting the args.IsValid to false, then what that does is it sets Page.IsValid to false. But unfortunately, that doesn't stop the form from being sumbitted. What you need to do is check that Page.IsValid property in your code that handles your form submit, like in the submit button handler.
So in addition to the code you posted, which sounds like it is working correctly, make sure that you have something like this for your submit handler (C# example):
protected void btnSubmit_Click(object sender, EventArgs e)
{
if (!Page.IsValid)
{
// by simply returning, the error message for the CustomValidator will be displayed
return;
}
// do processing for valid form here
}
Use this
OnServerValidate="CustomValidator1_ServerValidate"
like an example and it will work....
<asp:CustomValidator ID="CustomValidator1" runat="server" ControlToValidate="txtCoursePrefix" ErrorMessage="Course number is already taken." OnServerValidate="CustomValidator1_ServerValidate"></asp:CustomValidator>
Gaurav Agrawal
First of all, put validation group on validators and the button. If that too doesnt work, put OnClientClick='CheckValidate();' and declare the function which will call page_clientvalidate method along with the parameter.. validation group. This would surely work. If that is not working put debugger in the javascript method and debug the same

call a vb.net subrouting from a javascript function?

hi folks i have a subroutine called CheckDate() in the code behind.
How would I call that subroutine from a javascript function?
Cheers,
-Jonesy
You can't call it directly as function call.
because Javascript is a scripting langauge aimed for web browsers.
you may use AJAX or full page post sending the parameters to allow you to execute the subroutine.
Read more about Ajax it is the better way to go.
To expand on what Kronass said there I've found this article to be useful in the past for doing what you want http://encosia.com/2008/05/29/using-jquery-to-directly-call-aspnet-ajax-page-methods/. Encosia also has a heap of other blog plots on this if you do a bit of searching
What you're looking to use is normally called a WebMethod, ScriptMethod or Page Method depending on which framework you're using
One way to do this is by using the ICallbackEventHandler interface. I saw you had a question regarding the AjaxControToolkit CalendarExtender the other day so I'm guessing this question is in relation to that and how you do some validation in a server-side method. ICallbackEventHandler is AJAX, but you can write your validation as a normal method, not a PageMethod/WebMethod. It's slightly more fiddly on the Javascript side, but not by much.
Let's start with our basic textbox and calendar extender:
<form id="form1" runat="server">
<asp:ScriptManager runat="server" ID="ScriptManager" />
<div>
<asp:TextBox runat="server" ID="DateTextBox" />
<ajaxtoolkit:CalendarExtender runat="server" ID="CalendarExtender" TargetControlID="DateTextBox"
PopupButtonID="SelectorButton" OnClientDateSelectionChanged="checkDate" Format="dd MMM yyyy" />
<asp:ImageButton runat="server" ID="SelectorButton" ImageUrl="Path to a pretty graphic" />
<br />
<asp:Label runat="server" ID="ValidDateLabel" />
</div>
</form>
I've added the OnDateSelectionChanged attribute of the extender as this will kick off the process of calling the server-side method; we'll come back to what goes in there shortly.
In the class declaration in your code-behind, you need to say that you are implementing the interface:
Partial Public Class _Default
Inherits System.Web.UI.Page
Implements ICallbackEventHandler
To implement the interface we then need to add two more methods to handle the two methods in the interface, RaiseCallbackEvent and GetCallbackResult. We also need a property for a bit of temporary storage of the date we are trying to validate.
Private mCallbackDate As Date
Private Property CallbackDate() As Date
Get
Return mCallbackDate
End Get
Set(ByVal value As Date)
mCallbackDate = value
End Set
End Property
Public Sub RaiseCallbackEvent(ByVal eventArgument As String) Implements ICallbackEventHandler.RaiseCallbackEvent
'eventArgument will contain the date the user selected from the extender
Dim testDate As Date
If eventArgument = String.Empty Then
Else
If Date.TryParse(eventArgument, testDate) Then
'If we have a legal date selected then store it
Me.CallbackDate = testDate
End If
End If
End Sub
Public Function GetCallbackResult() As String Implements ICallbackEventHandler.GetCallbackResult
Dim result As String = String.Empty
'Get the date that we stored in memory and pass it to our CheckDate function
'We'll pass back to the Javascript in the page the string 'true' if the date is
'valid under our business rules and 'false' if it isn't
If checkDate(Me.CallbackDate) Then
Return "true"
Else
Return "false"
End If
End Function
Public Function checkDate(ByVal dateToCheck As Date) As Boolean
'If the date is in the future then return True, otherwise False
If dateToCheck > Date.Today Then
Return True
Else
Return False
End If
End Function
There's one more bit of server-side we need to add, in Page_Load, which does the hooking up of the Javascript and server-side code. The ClientScriptManager's GetCallbackEventReference function will inject a bit of script into our page that takes care of the communication between browser and server. Then we just need to register a script block that calls the injected script - we'll call this function checkDateOnServer.
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim callbackScript As String
callbackScript = "function checkDateOnServer(arg){" & _
Page.ClientScript.GetCallbackEventReference(Me, "arg", "receiveDateValidation", "") & _
"}"
ClientScript.RegisterClientScriptBlock(Me.GetType, "callback", callbackScript, True)
End Sub
Back to the client-side bits. We need to write a Javascript checkDate function that'll pass the user's selected date into the callback.
function checkDate()
{
// Get the date the user selected
var selectedDate = document.getElementById('DateTextBox').value;
// This will start the callback sequence
checkDateOnServer(selectedDate);
}
The last bit we need to do is receive the value coming back from the server, which we said in Page_Load would be called receiveDateValidation.
function receiveDateValidation(arg, context)
{
var ValidDateLabel = document.getElementById('SelectedDateLabel');
// We get a string value back from the server which is 'true' or 'false'
if (arg == 'true')
{
ValidDateLabel.innerText = 'Your date IS valid';
}
else
{
ValidDateLabel.innerText = 'Your date IS NOT valid';
}
}

Getting edit value from ListView

I'm missing something here, but I've stared at it too long to see it. I've got a simple ListView, with the typical Edit/Update/Cancel buttons. I've got the following set up in my EditITemTemplate when the row goes into edit mode:
<EditItemTemplate>
<asp:Label ID="AccountIdLabel" runat="server" Text='<%#Eval("lan_id")%>' />
<asp:TextBox ID="EmployeeIdTextBox" runat="server" Text='<%#Eval("emp_id")%>' Columns="5" />
</EditItemTemplate>
At this point the user types a value in the EmployeeIdTextBox. When they press Update, it's trying to do the following:
Private Sub ListView_ItemUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewUpdateEventArgs) Handles EmployeeListView.ItemUpdating
Dim accountId = CType(EmployeeListView.EditItem.FindControl("AccountIdLabel"), Label).Text
Dim employeeId = CType(EmployeeListView.EditItem.FindControl("EmployeeIdTextBox"), TextBox).Text
UpdateMap(accountId, employeeId)
EmployeeListView.EditIndex = -1
GetData()
End Sub
The problem is that "employeeId" is coming back with the original value in the text box, not what the user entered. What am I missing?
UPDATE: Found it. As usual, caused by other code not included here in an effort to ask a simple question. :)
Found it - I had code in the ItemCommand event that was handling other events, but it was doing the GetData() at the end regardless of the command, so basically the data was being refreshed right before the ItemUpdating event fired. I tightened up ItemCommand, and it's now working as expected.
I think this is because the ItemUpdating event fires before the ListView updates the record. You probably want to put this code in the ItemUpdated event instead.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listview.itemupdating.aspx

How to enable a button if regex expression is valid

I have a page on which there are two textboxes that have a regular expression on them.
ASPX Code TextBox 1
<asp:TextBox ID="txtCasesInsert" runat="server" Width="50px"></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvCases" ControlToValidate="txtCasesInsert" ValidationGroup="InsertRecord"
runat="server" ErrorMessage="*" ForeColor="Red"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="regexCases" ControlToValidate="txtCasesInsert"
ValidationExpression="[0-9]+(,[0-9]+)*" ForeColor="Red" ErrorMessage="Please seperate numbers with a comma"
runat="server" />
ASPX Code TextBox 2
<asp:TextBox ID="txtPremiumInsert" runat="server" Width="50px"></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvPremium" ControlToValidate="txtPremiumInsert"
ValidationGroup="InsertRecord" runat="server" ErrorMessage="*" ForeColor="Red"></asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="regexPremium" ControlToValidate="txtPremiumInsert"
ValidationExpression="[0-9]+(,[0-9]+)*" ForeColor="Red" ErrorMessage="Please seperate numbers with a comma"
runat="server" />
The regular expression works as intended for both text boxes.
What I need now is to be able to check the text being inputted into those text boxes and if the regular expression is valid, then enable my Insert button, otherwise, keep the button disabled.
Insert Button
<asp:Button ID="btnInsertRecord" Width="100px" Height="25px" runat="server" Text="Add Record"
CssClass="buttonBlue" ValidationGroup="InsertRecord" />
The reason I want to do this, is because when the regex has an error, the page still allows the user to insert data so I thought of disabling the button if the regex isn't successfull to prevent this.
I tried this C# If regex doesn't match then do something and I've also read up on Microsofts Regex documentation to learn more about what I can do with Regex's but I haven't found any information related to what I need.
I also tried creating a function with a TextChanged method hooked onto the textboxes but it didn't work. No error messages, just the button wasn't disabling when I inputted a wrong string. That's the problem I'm also having now with my current code. It's like nothing is happening. I've hooked the debugger on the _premiumMatch.Success line but again, nothing is happening, it just lets me proceed. When I created the TextChanged method for my button, I also tried adding it into my Page Load method but that disabled the button straight away.
Current VB Code (Example with one of the text boxes)
Dim _regex As Regex = New Regex("[0-9]+(,[0-9]+)*")
Dim _premiumMatch = _regex.Match(txtPremiumInsert.Text)
If _premiumMatch.Success Then
Try
Company.Applications.ProductionEngine.BusinessAccess.ExcelFileContentUploadBusinessAccess.InsertLimitInsurance(_branch,
_premium,
_cases,
_ddlMonths,
_ddlYear)
Catch ex As Exception
InformationBox.ShowErrorMessage("Record not added. Please try again")
End Try
loadLimitInsurances()
InformationBox.ShowSuccessMessage("New Record Inserted")
txtBranchInsert.Text = ""
txtPremiumInsert.Text = ""
txtCasesInsert.Text = ""
End If
Not sure what I'm doing wrong. Any suggestions? The above VB code, for now is in my buttons click event but even with an invalid regex, when I click the insert is still performed.
First Edit
Just tried calling the below function in my page load but the button disables straight away and does not become enabled if I input a valid regex. Again, example is for one textbox.
Protected Friend Sub CheckPremium() Handles txtPremiumInsert.TextChanged
Dim _regex As Regex = New Regex("[0-9]+(,[0-9]+)*")
Dim _match As Match = _regex.Match(txtPremiumInsert.Text)
If _match.Success Then
btnInsertRecord.Enabled = True
Else
btnInsertRecord.Enabled = False
End If
End Sub
Second Edit
I have tried the above code and I've activated AutoPostBack on the textbox and still when I type an invalid expression it postbacks and activates my button.
Try this code:
Dim _regex As Regex = New Regex("[0-9]+(,[0-9]+)*")
Dim FoundMatch As Boolean = _regex.IsMatch(textPremiumInsert.Text)
If FoundMatch = True Then
Try
Company.Applications.ProductionEngine.BusinessAccess.ExcelFileContentUploadBusinessAccess.InsertLimitInsurance(_branch,
_premium,
_cases,
_ddlMonths,
_ddlYear)
Catch ex As Exception
InformationBox.ShowErrorMessage("Record not added. Please try again")
End Try
loadLimitInsurances()
InformationBox.ShowSuccessMessage("New Record Inserted")
txtBranchInsert.Text = ""
txtPremiumInsert.Text = ""
txtCasesInsert.Text = ""
End If
The code above uses the Regex.IsMatch method to compare the string passed with the regex pattern. It returns true if the string matches the Regex pattern.

Resources