Multiple Custom Validators for One ClientValidationFunction Messing up Label - javascript

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.

Related

Avoid duplicated error messages with ASP.NET CustomValidator

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());
}

Deduct Days from RadDateTimePicker

Does anyone know how to deduct 7 days from the current date in RadDateTimePicker using Javascript?
I didn't find any example on how you deduct days from a RadDateTimePicker.
I would love if anyone can show me examples.
Aspx.code
<table border="0">
<tr>
<td>From:</td>
<td>
<telerik:RadDateTimePicker ID="rdpDateFrom" runat="server" Enabled="True" Width="170px">
<Calendar ID="fromCalendar" runat="server" EnableKeyboardNavigation="True">
<SpecialDays>
<telerik:RadCalendarDay Repeatable="Today" ItemStyle-BackColor="lightblue"></telerik:RadCalendarDay>
</SpecialDays>
</Calendar>
<DateInput ID="DateInput3" ToolTip="From Date input" runat="server"/>
</telerik:RadDateTimePicker>
</td>
</tr>
<tr>
<td>To:</td>
<td>
<telerik:RadDateTimePicker ID="rdpDateTo" runat="server" Enabled="True" Width="170px">
<Calendar ID="toCalendar" runat="server" EnableKeyboardNavigation="True" />
<DateInput ID="DateInput4" ToolTip="To Date input" runat="server"/>
</telerik:RadDateTimePicker>
</td>
</tr>
</table>
JavaScript Code
function OnClientSelectedIndexChanged(sender, eventArgs) {
var range = $find("<%= rcbDateTime.ClientID %>");
var item = eventArgs.get_item();
var From = $find("<%= rdpDateFrom.ClientID %>");
var To = $find("<%= rdpDateTo.ClientID %>");
var todaysDate = new Date();
todaysDate.setDate(todaysDate.getDate());
if (item.get_value() == "1") { //Today's Date
From.set_selectedDate(todaysDate);
To.set_selectedDate(todaysDate);
}
if (item.get_value() == "2") { //Last 7 days
//Calculation
From.set_selectedDate(
To.set_selectedDate(todaysDate);
}
}
More of a comment than an answer:
If I understand the issue (and maybe I don't, there's documentation here), you need to pass date objects to the set_selectedDate method. There seems to be some typos in the OP, so maybe best to just post the corrected code, something like:
var itemValue = item.get_value();
var todaysDate = new Date();
var weekAgo = new Date(+todaysDate);
weekAgo.setDate(weekAgo.getDate() - 7);
//Today's Date
if (itemValue == "1") {
From.set_selectedDate(todaysDate);
To.set_selectedDate(todaysDate);
//Last 7 days
} else if (itemValue == "2") {
From.set_selectedDate(todaysDate);
To.set_selectedDate(weekAgo);
}
If there are more conditions, you might consider using switch instead of if..else.

Select text of the control when validation occurs

I want to highlight text in control when validation occurs.
How can I achieve this?
<script language="javascript" type="text/javascript">
function changeColor(source, args) {
var txt = document.getElementById('<%= txtAge.ClientID %>');
if (args.Value.length >= 3) {
txt.style.background = '#66CCFF';
args.IsValid = false;
}
else {
txt.style.background = 'none';
args.IsValid = true;
}
}
</script>
<asp:TextBox ID="txtAge" runat="server" ></asp:TextBox>
<asp:RequiredFieldValidator ID="rfldtxtAge" ErrorMessage="enter the value" ControlToValidate="txtAge" runat="server" Display="Dynamic" SetFocusOnError="true" ForeColor="Red"></asp:RequiredFieldValidator>
<asp:CustomValidator ID="ctmtxtAge" runat="server" ClientValidationFunction="changeColor" ControlToValidate="txtAge" ErrorMessage="CustomValidator1" ></asp:CustomValidator>
I use this code for highlighting background of control, but I need to highlight the text of control.
Please help me.
Please use
txt.select();
instead of
txt.style.background = '#66CCFF';
please let me know if this does not work.
txt.style.color= '#66CCFF' instead of txt.style.background = '#66CCFF';
use this thing to change the color of the text

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