Avoid duplicated error messages with ASP.NET CustomValidator - javascript

I have an ASP.NET page defined in this way:
<asp:TextBox
ID="_txtExitDate"
ClientIDMode="Static"
runat="server"
Text='<%#Bind("exit_date","{0:dd/MM/yyyy}")%>'
placeholder="gg/mm/aaaa" />
<asp:CompareValidator
runat = "server"
Type = "Date"
Operator = "DataTypeCheck"
Display = "Dynamic"
ControlToValidate = "_txtExitDate"
ErrorMessage = "Exit date invalid."
SetFocusOnError = "true" />
<asp:CustomValidator
Display="Dynamic"
runat="server"
EnableClientScript="true"
ClientValidationFunction="Validate_Exit"
ControlToValidate="_txtExitDate"
ErrorMessage="Exit date should be minor of today date." />
<asp:TextBox
ID="_txtExitTime"
ClientIDMode="Static"
CssClass="input_small"
runat="server"
Text='<%#Bind("exit_time")%>'
placeholder="hh:mm" />
<asp:RegularExpressionValidator
Display = "Dynamic"
ControlToValidate="_txtExitTime"
runat="server"
ErrorMessage="Exit time invalid"
ValidationExpression="^([01][0-9]|2[0-3]|[1-9]):([0-5][0-9]|[0-9])$"
SetFocusOnError = "true" />
<asp:CustomValidator
Display="Dynamic"
runat="server"
EnableClientScript="true"
ClientValidationFunction="Validate_Exit"
ControlToValidate="_txtExitTime"
ErrorMessage="Exit date should be minor of today date." />
The Javascript code that evaluates CustomValidators is:
function Validate_Exit(sender, args) {
var _txtExitDate = $("input[id$='_txtExitDate ']");
var _txtExitTime = $("input[id$='_txtExitTime ']");
if (isBlank(_txtExitDate.val()) || isBlank(_txtExitTime.val())) {
args.IsValid = true;
return;
}
var _sExit = _txtExitDate .val().substring(0, 10) + " " + _txtExitTime.val().substring(0, 5);
var _exit = moment(_sExit, "DD/MM/YYYY HH:mm:ss");
if (_exit.isAfter(moment())) {
args.IsValid = false;
return;
}
args.IsValid = true;
}
The scope of the form is to allow the user to input only valid date/time values. In particular the CustomValidator is intended to allow the input of a couple of combined values that should be minor of the present date-time.
It works as I expect except for a side effect that it's not compromising but it's graphically annoying.
As you can see the CustomValidator is basically the same and it's applied to both textboxes. If the user fails to write a correct date / time combo it show off the message (that's the same message because it's referred to the composed date/time value). In some case the error message is shown 'twice' and this is in part (graphically) horrible but also a little confusing for the user.
Is there a way to avoid duplicating this check and to provide a control for both textboxes so the user is not confused by a double error message?
Best regards,
Mike

You can use a single CustomValidator to validate both fields. Set the ID of that validator but don't set the ControlToValidate property (here I also set the Text property to show an indicator even when the postback is not triggered):
<asp:CustomValidator
ID="cvDateTime"
Display="Dynamic"
runat="server"
Text="Invalid date!"
EnableClientScript="true"
ClientValidationFunction="Validate_Exit"
ErrorMessage="Exit date should be minor of today date." />
You can set the onchange event handler on both TextBoxes to perform the validation as soon as each field is modified:
<asp:TextBox ID="_txtExitDate" onchange="ValidateOnChange();" ... />
<asp:TextBox ID="_txtExitTime" onchange="ValidateOnChange();" ... />
The validation functions could look like this:
function ValidateOnChange() {
var validator = document.getElementById('<%= cvDateTime.ClientID %>');
validator.isvalid = DoValidateDateTime();
ValidatorUpdateDisplay(validator)
}
function Validate_Exit(source, args) {
args.IsValid = DoValidateDateTime();
}
function DoValidateDateTime() {
var _txtExitDate = $("input[id$='_txtExitDate ']");
var _txtExitTime = $("input[id$='_txtExitTime ']");
if (isBlank(_txtExitDate.val()) || isBlank(_txtExitTime.val())) {
return true;
}
var _sExit = _txtExitDate .val().substring(0, 10) + " " + _txtExitTime.val().substring(0, 5);
var _exit = moment(_sExit, "DD/MM/YYYY HH:mm:ss");
return _exit.isSameOrBefore(moment());
}

Related

Validation for my ASP textboxes is not working using javascript and ASP.NET

I just want to ask why my form validation for my asp textboxes is not working. It should be like when the user does not input a text in the textbox, a description in the paragraph tag will display to please input a text. But it is not working.Please help me on solving this.
Here is the javascript code:
function checkForm() {
var errors = [];
if ($("#itemBrand").value == "") {
errors[0] = "Please input a text!";
}
if ($("#itemModel").value == "") {
errors[1] = "Please input a text!";
}
if (errors.length > 0) {
if (errors[0] != null) {
document.getElementById("itemBrandValidate").innerHTML = errors[0];
}
if (errors[1] != null) {
document.getElementById("itemModelValidate").innerHTML = errors[1];
}
return false;
}
return true;
}
And here is the aspx:
<asp:TextBox ID="itemBrand" runat="server" BackColor="#FFFF66"
BorderColor="Black" BorderWidth="1px" Height="20px" Width="300px">
</asp:TextBox><br />
<p id="itemBrandValidate"></p>
<asp:TextBox ID="itemModel" runat="server" BackColor="#FFFF66"
BorderColor="Black" BorderWidth="1px" Height="20px" Width="300px">
</asp:TextBox><br />
<p id="itemModelValidate"></p>
<asp:Button ID="Button1" runat="server" CssClass="submitButton" Text="Save
Item" OnClick="Button1_Click" OnClientClick="return checkForm()"/>
Add ClientIdMode = "Static" on your textboxes. Otherwise the .NET platform generates an Id which is not the same as the server ID property and your Jquery selector is not working as expected.
For example:
<asp:TextBox ID="itemBrand" ClientIDMode="static" runat="server" BackColor="#FFFF66"
BorderColor="Black" BorderWidth="1px" Height="20px" Width="300px">
</asp:TextBox>
Client side id of asp.net server controls is different from server side id.
You may use ClientIDMode = "Static" (introduced in .NET 4.0) or you might use ClientID as shown below , also I've tried to re-write your validation function a bit.
function checkForm() {
var success = true;
var itemBrandID = "<%= itemBrand.ClientID %>" ;
if ($("#" + itemBrandID).value == "") {
success = false;
document.getElementById("<%= itemBrandValidate.ClientID %>").innerHTML = "Please input a text!";
}
var itemModelID = "<%= itemModel.ClientID %>" ;
if ($("#" + itemModelID).value == "") {
success = false;
document.getElementById("<%= itemModelValidate.ClientID %>").innerHTML = "Please input a text!";
}
return success;
}
Also suggest you to read this excellent post by Rick Strahl on A generic way to find ASP.NET ClientIDs with jQuery
Hope this helps !

Multiple Custom Validators for One ClientValidationFunction Messing up Label

I have 4 text boxes for searching 2 different date columns of a table. (The user can put a range for each column). Using any date is completely optional, because of this I created 4 CustomValidators to use the same ClientValidationFunction. (I can't use a Range or Required Validator because they are optional). Here is the custom function:
function ValidateDateRange(s, args) {
var startDate;
var endDate;
var conToValSplit = document.getElementById(s.controltovalidate).id.split("_");
var controlToValidate = conToValSplit[conToValSplit.length - 1];
switch (controlToValidate) {
case "txtFirstStartDate":
startDate = document.getElementById("<%= txtFirstStartDate.ClientID %>").value;
endDate = args.Value;
break;
case "txtSecondStartDate":
startDate = args.value;
endDate = document.getElementById("<%= txtSecondStartDate.ClientID %>").value;
break;
case "txtSecondEndDate":
startDate = document.getElementById("<%= txtSecondEndDate.ClientID %>").value;
endDate = args.Value;
break;
default:
startDate = args.Value;
endDate = document.getElementById("<%= txtFirstEndDate.ClientID %>").value;
break;
}
if (new Date(args.Value) == "Invalid Date"){
$(s).text("Please enter a valid end date(mm/dd/yyyy).");
args.IsValid = false;
return;
}
if (endDate != '') {
if (new Date(startDate) > new Date(endDate)) {
$(s).text("End date must be after start date.");
args.IsValid = false;
return;
}
args.IsValid = true;
return;
}
Here are the textbox and CustomValidators:
<td class="StartDateLabel">Date From</td>
<td>
<asp:TextBox runat="server" CssClass="StartDate" ID="txtFirStartDate" onBlur="DisplayInvalidLabel"/>
<asp:CustomValidator ID="cusValFromDate" runat="server" ErrorMessage="End date must be after start date." ClientValidationFunction="ValidateDateRange" ControlToValidate="txtFirStartDate"
EnableClientScript="true" SetFocusOnError="true" ValidationGroup=""SearchGroup" CssClass=""Validator" Display="Dynamic">
</asp:CustomValidator>
<span class="To Label"> to </span>
<asp:TextBox runat="server" CssClass="EndDate" ID="txtFirstEndDate" onBlur="DisplayInvalidLabel"/>
<asp:CustomValidator ID="cusValToDate" runat="server" ErrorMessage="End date must be after start date." ClientValidationFunction="ValidateDateRange" ControlToValidate="txtFirstEndDate"
EnableClientScript="true" SetFocusOnError="true" ValidationGroup="SearchGroup" CssClass="Validator" Display="Dynamic">
</asp:CustomValidator>
</td>
<td class="StartDateLabel">Second Date From</td>
<td>
<asp:TextBox runat="server" CssClass="StartDate" ID="txtSecondStartStart" ToolTip="This field allows for ranges. See LEGEND" onBlur="DisplayInvalidLabel()"/>
<asp:CustomValidator ID="custSecStartVal" runat="server" ErrorMessage="End date must be after start date." ClientValidationFunction="ValidateDateRange" ControlToValidate="txtSecondStartStart"
EnableClientScript="true" SetFocusOnError="true" ValidationGroup="SearchGroup" CssClass="Validator" Display="Dynamic">
</asp:CustomValidator>
</td>
<td class="To Label">Second to</td>
<td>
<asp:TextBox runat="server" CssClass="EndDate" ID="txtSecondEndDate" ToolTip="This field allows for ranges. See LEGEND" onBlur="DisplayInvalidLabel()"/>
<asp:CustomValidator ID="custSecEndVal" runat="server" ErrorMessage="End date must be after start date." ClientValidationFunction="ValidateDateRange" ControlToValidate="txtSecondEndDate"
EnableClientScript="true" SetFocusOnError="true" ValidationGroup="SearchGroup" CssClass="Validator" Display="Dynamic">
</asp:CustomValidator>
</td>
The validation works fine. When I enter an invalid value the respective error message shows up next to the defined control. The focus is placed where it needs to be. However if I tab through the 4 entry boxes when I tab out of the third one ("txtSecondStartDate") if I don't enter anything my message from the "txtFirstStartDate" disappears with the invalid date remaining. I know it is resseting the validation to true but I am missing where that it is doing that?
That is the same for all the text boxes. Initially it works but if I click in any other control that has a validator after a couple clicks it clears the messages of the other ones that should remain invalid. I just can't see where it is happeneing?
Well, I figured it out. The problem was comming from the "onBlur" event that I have on each input textbox. I had tied it to another function that was validating so it was causing a mix up when inputs were and weren't happening.

ASP.net CustomValidator - ClientValidationFunction to check value not blank and not initial value

I have following code which validates the value of a textbox to make sure it's not blank but I also need to check that it does not equal the initial value of the textbox (defaultValue).
Here's what I have so far...
Javascript:
function textValidation(source, arguments)
{
if ( arguments.Value != "" ){ // && arguments.Value != arguments.defaultValue
arguments.IsValid = true;
} else {
$(source).parents("div").css({"background-color":"red"});
arguments.IsValid = false;
}
}
.net
<asp:TextBox runat="server" ID="Initial" Text="Initial" defaultValue="Initial" Width="120px" />
<asp:CustomValidator id="Initial_req"
ControlToValidate="Initial"
ClientValidationFunction="textValidation"
ValidateEmptyText="true"
runat="server"
CssClass="errorAsterisk"
Text="*"
ErrorMessage="Complete all correspondence fields" />
You can do what you want using a CSS class to identify the TextBox and retrieve it with jQuery, allowing you to obtain the attribute defaultValue:
Markup:
<asp:TextBox runat="server"
ID="Initial"
Text="Initial"
defaultValue="Initial"
Width="120px"
ValidationGroup="Test"
CssClass="to-validate" />
<asp:CustomValidator ID="Initial_req"
ControlToValidate="Initial"
ClientValidationFunction="textValidation"
ValidateEmptyText="true"
runat="server"
CssClass="errorAsterisk"
Text="*"
ErrorMessage="Complete all correspondence fields"
ValidationGroup="Test" />
<asp:Button ID="btnValidate" runat="server" Text="Validate" ValidationGroup="Test" />
Javascript:
function textValidation(source, arguments) {
var initialValue = $(source).siblings(".to-validate:first").attr("defaultValue");
if (arguments.Value != "" && arguments.Value != initialValue) { // && arguments.Value != arguments.defaultValue
arguments.IsValid = true;
} else {
$(source).parents("div").css({ "background-color": "red" });
arguments.IsValid = false;
}
}
1)You not pass source and arguments parameters in your function .
2) then call this syntax way for ClientValidationFunction="javascript:textValidation(param1,oaram2);return true;"
3)you can use required field validation in text box here
4)or another way is (we dont use any parameter ) for here
A RequiredFieldValidator will prevent blanks as well as initial values.
Use attribute InitialValue.
See here:
Use it to prevent any value that you like being entered into a TextBox. The TextBox doesn't have to have that value embedded at the start - it just can't be submitted with that value.

Validating Textbox with CustomValidator's ClientValidationFunction not firing

I am having some serious issues with this. I have a two fields like this, both of them being assigned datepickers with jquery.
<asp:TextBox ID="RTRP" runat="server" CssClass="textEntry" Width="120"></asp:TextBox>
<asp:CustomValidator runat="server" ID="CustomValidator3"
ControlToValidate="RTRP"
Text="No date selected"
ValidateEmptyText="True"
ClientValidationFunction="clientValidate"
Display="Static">
</asp:CustomValidator>
<asp:TextBox ID="ContEd" runat="server" CssClass="textEntry" Width="120"></asp:TextBox>
<asp:CustomValidator runat="server" ID="CustomValidator1"
ControlToValidate="ContEd"
Text="No date selected"
ValidateEmptyText="True"
ClientValidationFunction="clientValidate"
Display="Static">
</asp:CustomValidator>
With the following javascript to validate it.
$("#<%=RTRP.ClientID %>").datepicker();
$("#<%=ContEd.ClientID %>").datepicker();
function clientValidate(sender, args) {
args.IsValid = args.Value.length > 0;
}
Both get their datepickers, but the validation function simply refuses to be fired and always allows the form to submit. I am completely lost here, what am I doing wrong?
You are checking if a string's length is less than 0 (what is never true) here:
function clientValidate(sender, args) {
if (args.Value.length < 0) {
args.IsValid = false;
} else {
args.IsValid = true;
}
}
I'm not sure if this is what you want(you could simpy use a RequiredFieldValidator), but...
function clientValidate(sender, args) {
args.IsValid = args.Value.length > 0;
}
If you assign $.datepicker() behaviour to any text, and run page.. you will find that textbox on which you override jQuery datepicker had css set display : none.. so that might be the reason that custom validation not getting for that textbox...
why dont you use
<asp:RequiredFieldValidator id="id" controltovalidate="controlname" erormessage="please enter the dates">
</asp:RequiredFieldValidator>
correct me i am wrong
Change you method to this.and try again
function clientValidate(sender, args)
{
if(Page_ClientValidate())
{
if (args.Value.length < 0)
{
args.IsValid = false;
} else
{
args.IsValid = true;
}
}
}

Ajax Calendar Date Range with JavaScript

I have the following code to compare two dates with the following conditions
Scenario:
On load there are two text boxes (FromDate, ToDate) with Ajax calendar extenders.
On load From Date shows today's date.
when date less than today was selected in both text boxes(FromDate, ToDate), it alerts user saying "You cannot select a day earlier than today!"
When ToDate's Selected date < FromDate's Selected Date, alerts user saying "To Date must be Greater than From date." and at the same time it clears the selected Date in ToDate Text box.
Codeblock:
ASP.NET , AJAX
<asp:TextBox ID="txtFrom" runat="server"
ReadOnly="true"></asp:TextBox>
<asp:ImageButton ID="imgBtnFrom" runat="server" ImageUrl="~/images/Cal20x20.png" Width="20" Height="20" ImageAlign="TextTop" />
<asp:CalendarExtender ID="txtFrom_CalendarExtender" PopupButtonID="imgBtnFrom"
runat="server" Enabled="True"
OnClientDateSelectionChanged="checkDate"
TargetControlID="txtFrom" Format="MMM d, yyyy">
</asp:CalendarExtender>
<asp:TextBox ID="txtTo" runat="server"
ReadOnly="true"></asp:TextBox>
<asp:ImageButton ID="imgBtnTo" runat="server" ImageUrl="~/images/Cal20x20.png" Width="20" Height="20" ImageAlign="TextTop" />
<asp:CalendarExtender ID="txtTo_CalendarExtender"
OnClientDateSelectionChanged="compareDateRange"
PopupButtonID="imgBtnTo"
runat="server"
Enabled="True" TargetControlID="txtTo"
Format="MMM d, yyyy">
</asp:CalendarExtender>
<asp:HiddenField ID="hdnFrom" runat="server" />
<asp:HiddenField ID="hdnTo" runat="server" />
C# Code
protected void Page_Load(object sender, EventArgs e)
{
txtFrom.Text = string.Format("{0: MMM d, yyyy}", DateTime.Today);
if (Page.IsPostBack)
{
if (!String.IsNullOrEmpty(hdnFrom.Value as string))
{
txtFrom.Text = hdnFrom.Value;
}
if (!String.IsNullOrEmpty(hdnTo.Value as string))
{
txtTo.Text = hdnTo.Value;
}
}
}
JavaScript Code
<script type="text/javascript">
function checkDate(sender, args) {
document.getElementById('<%=txtTo.ClientID %>').value = "";
if (sender._selectedDate < new Date()) {
alert("You cannot select a day earlier than today!");
sender._selectedDate = new Date();
// set the date back to the current date
sender._textbox.set_Value(sender._selectedDate.format(sender._format));
//assign the value to the hidden field.
document.getElementById('<%=hdnFrom.ClientID %>').value = sender._selectedDate.format(sender._format);
//reset the to date to blank.
document.getElementById('<%=txtTo.ClientID %>').value = "";
} else {
document.getElementById('<%=hdnFrom.ClientID %>').value = sender._selectedDate.format(sender._format);
}
}
function compareDateRange(sender, args) {
var fromDateString = document.getElementById('<%=txtFrom.ClientID %>').value;
var fromDate = new Date(fromDateString);
if (sender._selectedDate < new Date()) {
alert("You cannot select a Date earlier than today!");
sender._selectedDate = "";
sender._textbox.set_Value(sender._selectedDate)
}
if (sender._selectedDate <= fromDate) {
alert("To Date must be Greater than From date.");
sender._selectedDate = "";
sender._textbox.set_Value(sender._selectedDate)
} else {
document.getElementById('<%=hdnTo.ClientID %>').value = sender._selectedDate.format(sender._format);
}
}
</script>
Error Screen(Hmmm :X)
Now in ToDate, when you select Date Earlier than today or Date less than FromDate, ToDate Calendar shows NaN for Every Date and ,0NaN for Year
It looks like the format method is assuming a numeric argument, but is being passed a string argument. Comment out both else blocks to confirm this. The if blocks seem to always return false for the following reasons:
Since the two dates are strings, their lengths are compared, not their dates
Use Date.parse() on each date to do a numeric comparison
Validate your date format with a hardcoded value, e.g. Date.parse("May 1, 1999")

Categories

Resources