mghtbgiant
asked on
Custom Validators in congruence with CompareValidator (or RangeValidator) not functioning properly
To begin with, I am working under a very unique architecture. We are in a plug-in ascx based paradigm. Also, this is only a problem under non-IE browsers (namely Netscape 6+ for me) as all client-side validating works fine in IE. The problem is on the server-side.
Anyway, I have a UserControl (.ascx) for a date dange. It has two other ascx objects that wrap asp:textboxes. Both objects have their own range validator. So, we have this:
txtStartDate.hdr.Text = mLingual.FromDate
txtStartDate.Required = True
txtStartDate.ran.Enabled = True
txtStartDate.ran.ErrorMess age = mLingual.InvalidDate
txtStartDate.ran.Type = ValidationDataType.Date
txtStartDate.ran.MinimumVa lue = "01/01/1980"
txtStartDate.ran.MaximumVa lue = "06/06/2079"
for both start and end dates. Now, in the encompassing ascx file there are two custom validators defined below:
<asp:customvalidator id="valDates" display="dynamic" onservervalidate="ServerVa lidationDa tes" cssclass="VALIDATOR" runat="server" />
<asp:customvalidator id="valRange" display="dynamic" onservervalidate="ServerVa lidationRa nge" cssclass="VALIDATOR" runat="server" />
In the code-behind, we have:
'''date validation (fromdate greater than to date)
valDates.ClientValidationF unction = "validateDates"
valDates.ErrorMessage = mLingual.InvalidDateRange
'''date range validation
Session("FTFormatString") = common.MLDateFormatStr(Ses sion("gLoc aleID"))
Session("FTRangeOf") = gRangeOf
Session("FTSpan") = gSpan
Dim denom As String
Select Case gRangeOf.ToLower
Case "m"
denom = mLingual.Months
dateInterval = dateInterval.Month
Case "d"
denom = mLingual.Days
dateInterval = dateInterval.Day
Case "y"
denom = mLingual.Years
dateInterval = dateInterval.Year
End Select
valRange.ClientValidationF unction = "validateRange"
valRange.ErrorMessage = String.Format("{0} {1} {2}", mLingual.RangeExceeds, gSpan, denom)
valDates.Enabled = bValidate
valRange.Enabled = bValidate
trVal.Visible = bValidate
where bValidate is controlled through a property. mLingual is just a class that holds our multilingual text exposed by properties.
One we go.. long story short, everything works, sometimes. Any time you input a plain invalid date into one of the fields, you post-back and are given the error "Invalid Date" which is expected. But, now if you enter a valid date, but and invalid range, for example start: "11/25/2003" end: "11/24/2003", the server-side methods set in OnServerValidate DO NOT RUN. This behavior happens with both RangeValidators used on the individual textboxes and CompareValidators with the type set to Date.
Given the plug-in architecture I have run in to many many event order issues. This, however, I am 99% confident has nothing to do with event order. You can do straight repetitive post-backs and as soon as you enter an invalid date (that fails the Compare/RangeValidator) the CustomValidator OnServerValidate methods DO NOT RUN.
To recap, the OnServerValidate functions run fine, UNTIL you input a bad date. Go to the page first time, run it with "11/25/2003" - "11/24/2003" you will get Invalid Date Range (because I have defined it as such). Now enter "asdfasdf" - "11/24/2003" you will get "Invalid Date" which should be expected. Now, when you rerun the first iteration "11/25/2003" - "11/24/2003" the OnServerValidate methods DO NOT RUN.
any help would be GREATLY appreciated. Thank you very much in advance.
Anyway, I have a UserControl (.ascx) for a date dange. It has two other ascx objects that wrap asp:textboxes. Both objects have their own range validator. So, we have this:
txtStartDate.hdr.Text = mLingual.FromDate
txtStartDate.Required = True
txtStartDate.ran.Enabled = True
txtStartDate.ran.ErrorMess
txtStartDate.ran.Type = ValidationDataType.Date
txtStartDate.ran.MinimumVa
txtStartDate.ran.MaximumVa
for both start and end dates. Now, in the encompassing ascx file there are two custom validators defined below:
<asp:customvalidator id="valDates" display="dynamic" onservervalidate="ServerVa
<asp:customvalidator id="valRange" display="dynamic" onservervalidate="ServerVa
In the code-behind, we have:
'''date validation (fromdate greater than to date)
valDates.ClientValidationF
valDates.ErrorMessage = mLingual.InvalidDateRange
'''date range validation
Session("FTFormatString") = common.MLDateFormatStr(Ses
Session("FTRangeOf") = gRangeOf
Session("FTSpan") = gSpan
Dim denom As String
Select Case gRangeOf.ToLower
Case "m"
denom = mLingual.Months
dateInterval = dateInterval.Month
Case "d"
denom = mLingual.Days
dateInterval = dateInterval.Day
Case "y"
denom = mLingual.Years
dateInterval = dateInterval.Year
End Select
valRange.ClientValidationF
valRange.ErrorMessage = String.Format("{0} {1} {2}", mLingual.RangeExceeds, gSpan, denom)
valDates.Enabled = bValidate
valRange.Enabled = bValidate
trVal.Visible = bValidate
where bValidate is controlled through a property. mLingual is just a class that holds our multilingual text exposed by properties.
One we go.. long story short, everything works, sometimes. Any time you input a plain invalid date into one of the fields, you post-back and are given the error "Invalid Date" which is expected. But, now if you enter a valid date, but and invalid range, for example start: "11/25/2003" end: "11/24/2003", the server-side methods set in OnServerValidate DO NOT RUN. This behavior happens with both RangeValidators used on the individual textboxes and CompareValidators with the type set to Date.
Given the plug-in architecture I have run in to many many event order issues. This, however, I am 99% confident has nothing to do with event order. You can do straight repetitive post-backs and as soon as you enter an invalid date (that fails the Compare/RangeValidator) the CustomValidator OnServerValidate methods DO NOT RUN.
To recap, the OnServerValidate functions run fine, UNTIL you input a bad date. Go to the page first time, run it with "11/25/2003" - "11/24/2003" you will get Invalid Date Range (because I have defined it as such). Now enter "asdfasdf" - "11/24/2003" you will get "Invalid Date" which should be expected. Now, when you rerun the first iteration "11/25/2003" - "11/24/2003" the OnServerValidate methods DO NOT RUN.
any help would be GREATLY appreciated. Thank you very much in advance.
ASKER
Thank you for your reply zrh, however, since the validation functions that are running, are not bound to one of the boxes, they run for both. The two functions that are bound to the CustomValidators are:
1.) One validates that date1 isn't greater than date2
2.) The other validates that the date range doesn't exceed the predefined range.
But, like you mentioned, ControlToValidate is not necessary for CustomValidators and that is how I have them implemented.
Thanks again for your input.
1.) One validates that date1 isn't greater than date2
2.) The other validates that the date range doesn't exceed the predefined range.
But, like you mentioned, ControlToValidate is not necessary for CustomValidators and that is how I have them implemented.
Thanks again for your input.
ASKER
To preface, I apologize for the long post. I want to be as absolutely thorough as possible.
I have created a version of the malfunctioning code outside of my work's architecture and it is still behaving improperly. Create a new ASP.NET WebProject in VisualStudio and paste the below code for your WebForm1.aspx and code-behind. The date range accepted is 10 years. Acceptable dates in each field are from 1/1/1900 - 6/6/2079. IE works great because it never posts. Non-IE (namely Netscape 6+) is not working correctly. You can make the custom validators fail all day long and everything works fine when you then pass a valid range, then attempt another incorrect one. However, if one of the built-in validators (requiredField/range) fails, the page fails as expected.. then fix it, it works, now make a customValidator fail again (ie 01/01/2003 - 01/01/2030), it posts successfully, the routines don't even run. It's as if there is some global end-all-be-all variable (session or something) that only is set in non-IE that, when an inherent validator fails, it bombs, but then when it's fixed, it sets the flag that everything is okay. Page.Validate() is supposedly running, and coming back as true without running my OnServerValidate methods. I have no clue, that's why I'm here. The OnServerValidate Subs don't even run after you fail a built-in validator and then pass it. Period. They do not run regardless of validity of the customValidators.
So, here is a step-by-step procedure to test this behavior.. well assume the project is running in debug mode and netscape is open. put break points on the two ServerValidate methods.. also note, that when they run, they run two times each.
1.) enter 01/01/2003 - 01/20/2003
2.) submit
expected result, success
actual result, success
3.) replace 01/01/2003 with 01/21/2001
4.) submit
expected result, failed (invalid date range - start date greater than end date)
actual result, failed
5.) replace 01/21/2003 with 01/01/2002
6.) submit
expected result, success
actual result, success
7.) replace 01/20/2003 with 01/20/2050
8.) submit
expected result, failed (range exceeds 10 years)
actual result, failed
9.) replace 01/20/2050 with 01/20/2003
10.) submit
expected result, success
actual result, success
11.) blank out "EndDate"
12.) submit
expected result, failed (endDate required)
actual result, failed
13.) replace blank "EndDate" with 01/01/2030
14.) submit
expected result, failed (range exceeds 10 years)
actual result, success!!!!!!!!!!!!!!!!!!! !!!!!!!!!! !!!!!!!
This behavior can be achieved in fewer steps, however, I wanted to illustrate that the CustomValidators are working fine. Also, AS A VERY BIG NOTE, I just turned off all Client-side functionality in IE and got THE SAME BEHAVIOR. Remove ClientValidationFunction on the CustomValidators and change EnableClientScript on the Required/RangeValidators to "False" and you will get the absolute same behavior. I'm really hoping this is my problem, but I really don't think it is. I'm not a proud man and would gladly walk away giving someone with keen eyesight the 500 point bounty I put on this problem. If it's not my problem, maybe someone has a workaround because I also don't feel like paying Microsoft for them to fix their own problem.
Anyway, here is my code:
<!-- BEGIN WebForm1.aspx------------- ---------- ---------- ---------- -- -->
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx. vb" Inherits="ValidatorTest.We bForm1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>WebForm1</title>
<meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
<meta name=vs_defaultClientScrip t content="JavaScript">
<meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
<script language="javascript">
var validRange = false;
function validateDates(source, args) {
if (!document.getElementById( "txtStartD ate").valu e || !document.getElementById(" txtEndDate ").value) {
validRange = false;
return;
}
var startDate = new Date(document.getElementBy Id("txtSta rtDate").v alue);
var endDate = new Date(document.getElementBy Id("txtEnd Date").val ue);
if (startDate == 'NaN' || endDate == 'NaN') {
validRange = false;
return;
}
validRange = (startDate > endDate) ? false : true;
args.IsValid = validRange;
}
function validateRange(source, args) {
if (validRange) {
var startDate = document.getElementById("t xtStartDat e").value;
var endDate = document.getElementById("t xtEndDate" ).value;
<% = "var formatString = '" & Session("FormatString") & "';" %>
<% = "var rangeOf = '" & Session("RangeOf") & "';" %>
<% = "var rangeSpan = '" & Session("RangeSpan") & "';" %>
args.IsValid = (!checkDateRange(startDate , endDate, formatString, rangeOf, rangeSpan)) ? false : true;
}
}
function checkDateRange(startDate, endDate, formatString, rangeOf, numRange) {
var formatIndexes = formatString.split('/');
var mIndex = dIndex = yIndex = 0;
for (var i = 0; i < formatIndexes.length; i++) {
switch (formatIndexes[i].charAt(0 ).toLowerC ase()) {
case 'm':
mIndex = i;
break;
case 'd':
dIndex = i;
break;
case 'y':
yIndex = i;
break;
}
}
if (startDate.indexOf('/') != -1) {
var aryStartDate = startDate.split('/');
} else if (startDate.indexOf('-') != -1) {
var aryStartDate = startDate.split('-');
} else if (startDate.indexOf('.') != -1) {
var aryStartDate = startDate.split('.');
}
var mStartDate = Number(aryStartDate[mIndex ]);
var dStartDate = Number(aryStartDate[dIndex ]);
var yStartDate = Number(aryStartDate[yIndex ]);
var date1 = new Date(String(mStartDate + '/' + dStartDate + '/' + yStartDate));
if (endDate.indexOf('/') != -1) {
var aryEndDate = endDate.split('/');
} else if (endDate.indexOf('-') != -1) {
var aryEndDate = endDate.split('-');
} else if (endDate.indexOf('.') != -1) {
var aryEndDate = endDate.split('.');
}
var mEndDate = Number(aryEndDate[mIndex]) ;
var dEndDate = Number(aryEndDate[dIndex]) ;
var yEndDate = Number(aryEndDate[yIndex]) ;
var date2 = new Date(String(mEndDate + '/' + dEndDate + '/' + yEndDate));
var fromDateArray = startDate.split('/');
var month = Number(fromDateArray[mInde x]);
var day = Number(fromDateArray[dInde x]);
var year = Number(fromDateArray[yInde x]);
var mRange = 0, dRange = 0, yRange = 0;
switch (rangeOf.toLowerCase()) {
case 'y':
yRange = Number(numRange);
break;
case 'm':
mRange = Number(numRange);
break;
case 'd':
dRange = Number(numRange);
break;
}
var maxDate = new Date(String((month + mRange) + '/' + (day + dRange) + '/' + (year + yRange)));
if (maxDate >= date2) { return true;
} else { return false; }
return true;
}
</script>
</head>
<body MS_POSITIONING="GridLayout ">
<form id="Form1" method="post" runat="server">
<table cellspacing="0" cellpadding="0" border="0">
<tr>
<td><span style="font-size: 10pt; font-weight: bold;">Start Date</span></td>
<td><span style="font-size: 10pt; font-weight: bold;">End Date</span></td>
</tr>
<tr>
<td><asp:TextBox ID="txtStartDate" Columns="11" MaxLength="10" Runat="server" /></td>
<td><asp:TextBox ID="txtEndDate" Columns="11" MaxLength="10" Runat="server" /></td>
<td><asp:Label ID="lblPost" Visible="False" Font-Bold="True" Runat="server" /></td>
</tr>
<tr>
<td>
<asp:RequiredFieldValidato r ID="reqStartDate" ControlToValidate="txtStar tDate" EnableClientScript="True" Display="Dynamic" ErrorMessage="Required" Runat="server" />
<asp:RangeValidator ID="ranStartDate" ControlToValidate="txtStar tDate" EnableClientScript="True" Display="Dynamic" ErrorMessage="Invalid Date" Runat="server" />
</td>
<td>
<asp:RequiredFieldValidato r ID="reqEndDate" ControlToValidate="txtEndD ate" EnableClientScript="True" Display="Dynamic" ErrorMessage="Required" Runat="server" />
<asp:RangeValidator ID="ranEndDate" ControlToValidate="txtEndD ate" EnableClientScript="True" Display="Dynamic" ErrorMessage="Invalid Date" Runat="server" />
</td>
</tr>
<tr id="trCustom" visible="false" runat="server">
<td colspan="2" align="center">
<asp:CustomValidator ID="valDates" Display="Dynamic" ClientValidationFunction=" validateDa tes" OnServerValidate="ServerVa lidateDate s" Runat="server" />
<asp:CustomValidator ID="valRange" Display="Dynamic" ClientValidationFunction=" validateRa nge" OnServerValidate="ServerVa lidateRang e" Runat="server" />
</td>
</tr>
</table>
<asp:Button ID="btnSubmit" Text="Submit" Runat="server" />
</form>
</body>
</html>
<!-- END WebForm1.aspx------------- ---------- ---------- ---------- ---- -->
'BEGIN WebForm1.aspx.vb---------- ---------- ---------- ---------- -
Public Class WebForm1
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.Debugg erStepThro ugh()> Private Sub InitializeComponent()
End Sub
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclara tion As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Protected txtStartDate As TextBox
Protected txtEndDate As TextBox
Protected reqStartDate As RequiredFieldValidator
Protected reqEndDate As RequiredFieldValidator
Protected ranStartDate As RangeValidator
Protected ranEndDate As RangeValidator
Protected valDates As CustomValidator
Protected valRange As CustomValidator
Protected trCustom As HtmlTableRow
Protected btnSubmit As Button
Protected lblPost As Label
Private bError As Boolean = False
Private bCustomValidate = True
Private dateInterval As Microsoft.VisualBasic.Date Interval
Private dateFormat As String = "MM/dd/yyyy"
Private rangeOf As String = "y"
Private rangeSpan As Integer = 10
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'''===================BEGI N VALIDATORS================ =======
'requiredFieldValidator
reqStartDate.Enabled = True
reqEndDate.Enabled = True
'rangeValidator
' startDate
ranStartDate.Enabled = True
ranStartDate.MinimumValue = "01/01/1900"
ranStartDate.MaximumValue = "06/06/2079"
ranStartDate.Type = ValidationDataType.Date
' endDate
ranEndDate.Enabled = True
ranEndDate.MinimumValue = "01/01/1900"
ranEndDate.MaximumValue = "06/06/2079"
ranEndDate.Type = ValidationDataType.Date
'customValidator
trCustom.Visible = bCustomValidate
' startDate cant be greater than endDate
valDates.Enabled = bCustomValidate
valDates.ErrorMessage = "Invalid date range"
' dateRange
Session("FormatString") = dateFormat
Session("RangeOf") = rangeOf
Session("RangeSpan") = rangeSpan
valRange.Enabled = bCustomValidate
Dim denom As String
Select Case rangeOf.ToLower
Case "m"
denom = "Month(s)"
dateInterval = dateInterval.Month
Case "d"
denom = "Day(s)"
dateInterval = dateInterval.Day
Case "y"
denom = "Year(s)"
dateInterval = dateInterval.Year
End Select
valRange.ErrorMessage = String.Format("Range exceeds {0} {1}", rangeSpan, denom)
'''====================END VALIDATORS================ ========
End Sub
Protected Sub ServerValidateDates(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtStartDate.Text) Or Not IsDate(txtEndDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(CType(txtStartDate.Tex t, Date) > CType(txtEndDate.Text, Date), False, True)
End Sub
Protected Sub ServerValidateRange(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtStartDate.Text) Or Not IsDate(txtEndDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(DateDiff(dateInterval, CType(txtStartDate.Text, Date), CType(txtEndDate.Text, Date)) <= rangeSpan, True, False)
End Sub
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
If (bError Or Not ranStartDate.IsValid Or Not ranEndDate.IsValid) Then
valDates.Visible = False
valRange.Visible = False
End If
If (IsPostBack) Then
Page.Validate()
lblPost.Text = IIf(Page.IsValid, "Success", "Failed")
lblPost.Visible = IIf(IsPostBack, True, False)
End If
End Sub
End Class
'END WebForm1.aspx.vb---------- ---------- ---------- ---------- ---
I have created a version of the malfunctioning code outside of my work's architecture and it is still behaving improperly. Create a new ASP.NET WebProject in VisualStudio and paste the below code for your WebForm1.aspx and code-behind. The date range accepted is 10 years. Acceptable dates in each field are from 1/1/1900 - 6/6/2079. IE works great because it never posts. Non-IE (namely Netscape 6+) is not working correctly. You can make the custom validators fail all day long and everything works fine when you then pass a valid range, then attempt another incorrect one. However, if one of the built-in validators (requiredField/range) fails, the page fails as expected.. then fix it, it works, now make a customValidator fail again (ie 01/01/2003 - 01/01/2030), it posts successfully, the routines don't even run. It's as if there is some global end-all-be-all variable (session or something) that only is set in non-IE that, when an inherent validator fails, it bombs, but then when it's fixed, it sets the flag that everything is okay. Page.Validate() is supposedly running, and coming back as true without running my OnServerValidate methods. I have no clue, that's why I'm here. The OnServerValidate Subs don't even run after you fail a built-in validator and then pass it. Period. They do not run regardless of validity of the customValidators.
So, here is a step-by-step procedure to test this behavior.. well assume the project is running in debug mode and netscape is open. put break points on the two ServerValidate methods.. also note, that when they run, they run two times each.
1.) enter 01/01/2003 - 01/20/2003
2.) submit
expected result, success
actual result, success
3.) replace 01/01/2003 with 01/21/2001
4.) submit
expected result, failed (invalid date range - start date greater than end date)
actual result, failed
5.) replace 01/21/2003 with 01/01/2002
6.) submit
expected result, success
actual result, success
7.) replace 01/20/2003 with 01/20/2050
8.) submit
expected result, failed (range exceeds 10 years)
actual result, failed
9.) replace 01/20/2050 with 01/20/2003
10.) submit
expected result, success
actual result, success
11.) blank out "EndDate"
12.) submit
expected result, failed (endDate required)
actual result, failed
13.) replace blank "EndDate" with 01/01/2030
14.) submit
expected result, failed (range exceeds 10 years)
actual result, success!!!!!!!!!!!!!!!!!!!
This behavior can be achieved in fewer steps, however, I wanted to illustrate that the CustomValidators are working fine. Also, AS A VERY BIG NOTE, I just turned off all Client-side functionality in IE and got THE SAME BEHAVIOR. Remove ClientValidationFunction on the CustomValidators and change EnableClientScript on the Required/RangeValidators to "False" and you will get the absolute same behavior. I'm really hoping this is my problem, but I really don't think it is. I'm not a proud man and would gladly walk away giving someone with keen eyesight the 500 point bounty I put on this problem. If it's not my problem, maybe someone has a workaround because I also don't feel like paying Microsoft for them to fix their own problem.
Anyway, here is my code:
<!-- BEGIN WebForm1.aspx-------------
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>WebForm1</title>
<meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
<meta name=vs_defaultClientScrip
<meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
<script language="javascript">
var validRange = false;
function validateDates(source, args) {
if (!document.getElementById(
validRange = false;
return;
}
var startDate = new Date(document.getElementBy
var endDate = new Date(document.getElementBy
if (startDate == 'NaN' || endDate == 'NaN') {
validRange = false;
return;
}
validRange = (startDate > endDate) ? false : true;
args.IsValid = validRange;
}
function validateRange(source, args) {
if (validRange) {
var startDate = document.getElementById("t
var endDate = document.getElementById("t
<% = "var formatString = '" & Session("FormatString") & "';" %>
<% = "var rangeOf = '" & Session("RangeOf") & "';" %>
<% = "var rangeSpan = '" & Session("RangeSpan") & "';" %>
args.IsValid = (!checkDateRange(startDate
}
}
function checkDateRange(startDate, endDate, formatString, rangeOf, numRange) {
var formatIndexes = formatString.split('/');
var mIndex = dIndex = yIndex = 0;
for (var i = 0; i < formatIndexes.length; i++) {
switch (formatIndexes[i].charAt(0
case 'm':
mIndex = i;
break;
case 'd':
dIndex = i;
break;
case 'y':
yIndex = i;
break;
}
}
if (startDate.indexOf('/') != -1) {
var aryStartDate = startDate.split('/');
} else if (startDate.indexOf('-') != -1) {
var aryStartDate = startDate.split('-');
} else if (startDate.indexOf('.') != -1) {
var aryStartDate = startDate.split('.');
}
var mStartDate = Number(aryStartDate[mIndex
var dStartDate = Number(aryStartDate[dIndex
var yStartDate = Number(aryStartDate[yIndex
var date1 = new Date(String(mStartDate + '/' + dStartDate + '/' + yStartDate));
if (endDate.indexOf('/') != -1) {
var aryEndDate = endDate.split('/');
} else if (endDate.indexOf('-') != -1) {
var aryEndDate = endDate.split('-');
} else if (endDate.indexOf('.') != -1) {
var aryEndDate = endDate.split('.');
}
var mEndDate = Number(aryEndDate[mIndex])
var dEndDate = Number(aryEndDate[dIndex])
var yEndDate = Number(aryEndDate[yIndex])
var date2 = new Date(String(mEndDate + '/' + dEndDate + '/' + yEndDate));
var fromDateArray = startDate.split('/');
var month = Number(fromDateArray[mInde
var day = Number(fromDateArray[dInde
var year = Number(fromDateArray[yInde
var mRange = 0, dRange = 0, yRange = 0;
switch (rangeOf.toLowerCase()) {
case 'y':
yRange = Number(numRange);
break;
case 'm':
mRange = Number(numRange);
break;
case 'd':
dRange = Number(numRange);
break;
}
var maxDate = new Date(String((month + mRange) + '/' + (day + dRange) + '/' + (year + yRange)));
if (maxDate >= date2) { return true;
} else { return false; }
return true;
}
</script>
</head>
<body MS_POSITIONING="GridLayout
<form id="Form1" method="post" runat="server">
<table cellspacing="0" cellpadding="0" border="0">
<tr>
<td><span style="font-size: 10pt; font-weight: bold;">Start Date</span></td>
<td><span style="font-size: 10pt; font-weight: bold;">End Date</span></td>
</tr>
<tr>
<td><asp:TextBox ID="txtStartDate" Columns="11" MaxLength="10" Runat="server" /></td>
<td><asp:TextBox ID="txtEndDate" Columns="11" MaxLength="10" Runat="server" /></td>
<td><asp:Label ID="lblPost" Visible="False" Font-Bold="True" Runat="server" /></td>
</tr>
<tr>
<td>
<asp:RequiredFieldValidato
<asp:RangeValidator ID="ranStartDate" ControlToValidate="txtStar
</td>
<td>
<asp:RequiredFieldValidato
<asp:RangeValidator ID="ranEndDate" ControlToValidate="txtEndD
</td>
</tr>
<tr id="trCustom" visible="false" runat="server">
<td colspan="2" align="center">
<asp:CustomValidator ID="valDates" Display="Dynamic" ClientValidationFunction="
<asp:CustomValidator ID="valRange" Display="Dynamic" ClientValidationFunction="
</td>
</tr>
</table>
<asp:Button ID="btnSubmit" Text="Submit" Runat="server" />
</form>
</body>
</html>
<!-- END WebForm1.aspx-------------
'BEGIN WebForm1.aspx.vb----------
Public Class WebForm1
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.Debugg
End Sub
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclara
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Protected txtStartDate As TextBox
Protected txtEndDate As TextBox
Protected reqStartDate As RequiredFieldValidator
Protected reqEndDate As RequiredFieldValidator
Protected ranStartDate As RangeValidator
Protected ranEndDate As RangeValidator
Protected valDates As CustomValidator
Protected valRange As CustomValidator
Protected trCustom As HtmlTableRow
Protected btnSubmit As Button
Protected lblPost As Label
Private bError As Boolean = False
Private bCustomValidate = True
Private dateInterval As Microsoft.VisualBasic.Date
Private dateFormat As String = "MM/dd/yyyy"
Private rangeOf As String = "y"
Private rangeSpan As Integer = 10
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'''===================BEGI
'requiredFieldValidator
reqStartDate.Enabled = True
reqEndDate.Enabled = True
'rangeValidator
' startDate
ranStartDate.Enabled = True
ranStartDate.MinimumValue = "01/01/1900"
ranStartDate.MaximumValue = "06/06/2079"
ranStartDate.Type = ValidationDataType.Date
' endDate
ranEndDate.Enabled = True
ranEndDate.MinimumValue = "01/01/1900"
ranEndDate.MaximumValue = "06/06/2079"
ranEndDate.Type = ValidationDataType.Date
'customValidator
trCustom.Visible = bCustomValidate
' startDate cant be greater than endDate
valDates.Enabled = bCustomValidate
valDates.ErrorMessage = "Invalid date range"
' dateRange
Session("FormatString") = dateFormat
Session("RangeOf") = rangeOf
Session("RangeSpan") = rangeSpan
valRange.Enabled = bCustomValidate
Dim denom As String
Select Case rangeOf.ToLower
Case "m"
denom = "Month(s)"
dateInterval = dateInterval.Month
Case "d"
denom = "Day(s)"
dateInterval = dateInterval.Day
Case "y"
denom = "Year(s)"
dateInterval = dateInterval.Year
End Select
valRange.ErrorMessage = String.Format("Range exceeds {0} {1}", rangeSpan, denom)
'''====================END
End Sub
Protected Sub ServerValidateDates(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtStartDate.Text) Or Not IsDate(txtEndDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(CType(txtStartDate.Tex
End Sub
Protected Sub ServerValidateRange(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtStartDate.Text) Or Not IsDate(txtEndDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(DateDiff(dateInterval,
End Sub
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
If (bError Or Not ranStartDate.IsValid Or Not ranEndDate.IsValid) Then
valDates.Visible = False
valRange.Visible = False
End If
If (IsPostBack) Then
Page.Validate()
lblPost.Text = IIf(Page.IsValid, "Success", "Failed")
lblPost.Visible = IIf(IsPostBack, True, False)
End If
End Sub
End Class
'END WebForm1.aspx.vb----------
Hi, your problem was in the order you had things. One thing to remember, the validation is done before the Page_Load event is called. So basically I moved everything from Page_Load to Page_Init (actually I put it in IntitializedComponents, but same difference), and everything from Page_PreRender to Page_Load... Also, I assume from your posted code that you want to have the range invalid if a field is blank. Here is your code again, the aspx page has been left alone, only the .vb file changed:
Public Class WebForm1
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.Debugg erStepThro ugh()> Private Sub InitializeComponent()
'''===================BEGI N VALIDATORS================ =======
'requiredFieldValidator
reqStartDate.Enabled = True
reqEndDate.Enabled = True
'rangeValidator
' startDate
ranStartDate.Enabled = True
ranStartDate.MinimumValue = "01/01/1900"
ranStartDate.MaximumValue = "06/06/2079"
ranStartDate.Type = ValidationDataType.Date
' endDate
ranEndDate.Enabled = True
ranEndDate.MinimumValue = "01/01/1900"
ranEndDate.MaximumValue = "06/06/2079"
ranEndDate.Type = ValidationDataType.Date
'customValidator
trCustom.Visible = bCustomValidate
' startDate cant be greater than endDate
valDates.Enabled = bCustomValidate
valDates.ErrorMessage = "Invalid date range"
' dateRange
Session("FormatString") = dateFormat
Session("RangeOf") = rangeOf
Session("RangeSpan") = rangeSpan
valRange.Enabled = bCustomValidate
Dim denom As String
Select Case rangeOf.ToLower
Case "m"
denom = "Month(s)"
dateInterval = dateInterval.Month
Case "d"
denom = "Day(s)"
dateInterval = dateInterval.Day
Case "y"
denom = "Year(s)"
dateInterval = dateInterval.Year
End Select
valRange.ErrorMessage = String.Format("Range exceeds {0} {1}", rangeSpan, denom)
'''====================END VALIDATORS================ ========
End Sub
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclara tion As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Protected txtStartDate As TextBox
Protected txtEndDate As TextBox
Protected reqStartDate As RequiredFieldValidator
Protected reqEndDate As RequiredFieldValidator
Protected ranStartDate As RangeValidator
Protected ranEndDate As RangeValidator
Protected valDates As CustomValidator
Protected valRange As CustomValidator
Protected trCustom As HtmlTableRow
Protected btnSubmit As Button
Protected lblPost As Label
Private bError As Boolean = False
Private bCustomValidate = True
Private dateInterval As Microsoft.VisualBasic.Date Interval
Private dateFormat As String = "MM/dd/yyyy"
Private rangeOf As String = "y"
Private rangeSpan As Integer = 10
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If (bError Or Not ranStartDate.IsValid Or Not ranEndDate.IsValid) Then
valDates.Visible = False
valRange.Visible = False
End If
If (IsPostBack) Then
Page.Validate()
lblPost.Text = IIf(Page.IsValid, "Success", "Failed")
lblPost.Visible = IIf(IsPostBack, True, False)
End If
End Sub
Protected Sub ServerValidateDates(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtStartDate.Text) Or Not IsDate(txtEndDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(CType(txtStartDate.Tex t, Date) > CType(txtEndDate.Text, Date), False, True)
End Sub
Protected Sub ServerValidateRange(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtStartDate.Text) Or Not IsDate(txtEndDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(DateDiff(dateInterval, CType(txtStartDate.Text, Date), CType(txtEndDate.Text, Date)) <= rangeSpan, True, False)
End Sub
End Class
Hope that is what you wanted,
ZRH
Public Class WebForm1
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.Debugg
'''===================BEGI
'requiredFieldValidator
reqStartDate.Enabled = True
reqEndDate.Enabled = True
'rangeValidator
' startDate
ranStartDate.Enabled = True
ranStartDate.MinimumValue = "01/01/1900"
ranStartDate.MaximumValue = "06/06/2079"
ranStartDate.Type = ValidationDataType.Date
' endDate
ranEndDate.Enabled = True
ranEndDate.MinimumValue = "01/01/1900"
ranEndDate.MaximumValue = "06/06/2079"
ranEndDate.Type = ValidationDataType.Date
'customValidator
trCustom.Visible = bCustomValidate
' startDate cant be greater than endDate
valDates.Enabled = bCustomValidate
valDates.ErrorMessage = "Invalid date range"
' dateRange
Session("FormatString") = dateFormat
Session("RangeOf") = rangeOf
Session("RangeSpan") = rangeSpan
valRange.Enabled = bCustomValidate
Dim denom As String
Select Case rangeOf.ToLower
Case "m"
denom = "Month(s)"
dateInterval = dateInterval.Month
Case "d"
denom = "Day(s)"
dateInterval = dateInterval.Day
Case "y"
denom = "Year(s)"
dateInterval = dateInterval.Year
End Select
valRange.ErrorMessage = String.Format("Range exceeds {0} {1}", rangeSpan, denom)
'''====================END
End Sub
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclara
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Protected txtStartDate As TextBox
Protected txtEndDate As TextBox
Protected reqStartDate As RequiredFieldValidator
Protected reqEndDate As RequiredFieldValidator
Protected ranStartDate As RangeValidator
Protected ranEndDate As RangeValidator
Protected valDates As CustomValidator
Protected valRange As CustomValidator
Protected trCustom As HtmlTableRow
Protected btnSubmit As Button
Protected lblPost As Label
Private bError As Boolean = False
Private bCustomValidate = True
Private dateInterval As Microsoft.VisualBasic.Date
Private dateFormat As String = "MM/dd/yyyy"
Private rangeOf As String = "y"
Private rangeSpan As Integer = 10
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If (bError Or Not ranStartDate.IsValid Or Not ranEndDate.IsValid) Then
valDates.Visible = False
valRange.Visible = False
End If
If (IsPostBack) Then
Page.Validate()
lblPost.Text = IIf(Page.IsValid, "Success", "Failed")
lblPost.Visible = IIf(IsPostBack, True, False)
End If
End Sub
Protected Sub ServerValidateDates(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtStartDate.Text) Or Not IsDate(txtEndDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(CType(txtStartDate.Tex
End Sub
Protected Sub ServerValidateRange(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtStartDate.Text) Or Not IsDate(txtEndDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(DateDiff(dateInterval,
End Sub
End Class
Hope that is what you wanted,
ZRH
ASKER
ZRH,
Thanks again for your response. I am looking into some things. I do not want to show an error message for an invalid range when an invalid date has been entered but I can take care of that. One thing that is coming to mind, due to the sometimes overly frustrating nature of event firing, I don't know if moving the code to Page_Init will work as the variable bCustomValidate is controlled by a property. Basically, I have an .ascx UserControl that encapsulates this date range functionality and when instantiating this control in another page you say whether or not to validate, and then define the range. Anyway, I don't know (and highly doubt) that the property that influences bCustomValidate runs before Page_Init. I know the property will run before Page_Load, but I think Page_Init is the #1 mamma-jamma method.
I'll play with what you're suggesting, and also create me an .ascx control to check the event model. Anyway, I have some more to look at.
Thanks again, I'll post again when I get some things thrown together.
Thanks again for your response. I am looking into some things. I do not want to show an error message for an invalid range when an invalid date has been entered but I can take care of that. One thing that is coming to mind, due to the sometimes overly frustrating nature of event firing, I don't know if moving the code to Page_Init will work as the variable bCustomValidate is controlled by a property. Basically, I have an .ascx UserControl that encapsulates this date range functionality and when instantiating this control in another page you say whether or not to validate, and then define the range. Anyway, I don't know (and highly doubt) that the property that influences bCustomValidate runs before Page_Init. I know the property will run before Page_Load, but I think Page_Init is the #1 mamma-jamma method.
I'll play with what you're suggesting, and also create me an .ascx control to check the event model. Anyway, I have some more to look at.
Thanks again, I'll post again when I get some things thrown together.
ASKER
Seriously, this is frustrating. Your changes functioned properly. However, when I put things into the correct architecture, the same thing happens as before. The properties do indeed run before Page_Init so that isn't an issue. But, now with the right paradigm, the same thing is happening.
Here is the new code:
<!-- BEGIN WebForm1.aspx -------------------------- ---------- ---- -->
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx. vb" Inherits="ValidatorTest.We bForm1"%>
<%@ Register TagPrefix="ctrls" TagName="FromToDates" Src="FromToDates.ascx" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>WebForm1</title>
<meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
<meta name=vs_defaultClientScrip t content="JavaScript">
<meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
</head>
<body MS_POSITIONING="GridLayout ">
<form id="Form1" method="post" runat="server">
<table>
<tr valign="top">
<td><ctrls:FromToDates ID="FromToDates" CustomValidate="True" RangeOf="y" RangeSpan="10" Columns="11" MaxLength="10" Runat="server" /></td>
<td><asp:Label ID="lblPost" Visible="False" Font-Bold="True" Runat="server" /></td>
</tr>
</table>
<asp:Button ID="btnSubmit" Text="Submit" Runat="server" />
</form>
</body>
</html>
<!-- END WebForm1.aspx -------------------------- ---------- ------ -->
'BEGIN WebForm1.aspx.vb -------------------------- ---------- --- -->
Public Class WebForm1
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.Debugg erStepThro ugh()> Private Sub InitializeComponent()
End Sub
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclara tion As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Protected lblPost As Label
Private bPageValid As Boolean
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If (IsPostBack) Then
Page.Validate()
bPageValid = Page.IsValid
End If
End Sub
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
If (IsPostBack) Then
lblPost.Text = IIf(bPageValid, "Success", "Failed")
End If
lblPost.Visible = IIf(IsPostBack, True, False)
End Sub
End Class
'END WebForm1.aspx.vb -------------------------- ---------- ------ -->
<!-- BEGIN FromToDates.ascx -------------------------- ---------- ---- -->
<%@ Control Language="vb" AutoEventWireup="false" Codebehind="FromToDates.as cx.vb" Inherits="ValidatorTest.Fr omToDates" TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<script language="javascript">
var validRange = false;
function validateDates(source, args) {
if (!document.getElementById( findContro l("txtFrom Date", "INPUT")).value || !document.getElementById(f indControl ("txtToDat e", "INPUT")).value) {
validRange = false;
return;
}
var startDate = new Date(document.getElementBy Id(findCon trol("txtF romDate", "INPUT")).value);
var endDate = new Date(document.getElementBy Id(findCon trol("txtT oDate", "INPUT")).value);
if (startDate == 'NaN' || endDate == 'NaN') {
validRange = false;
return;
}
validRange = (startDate > endDate) ? false : true;
args.IsValid = validRange;
}
function validateRange(source, args) {
if (validRange) {
var startDate = document.getElementById(fi ndControl( "txtFromDa te", "INPUT")).value;
var endDate = document.getElementById(fi ndControl( "txtToDate ", "INPUT")).value;
<% = "var formatString = '" & Session("FormatString") & "';" %>
<% = "var rangeOf = '" & Session("RangeOf") & "';" %>
<% = "var rangeSpan = '" & Session("RangeSpan") & "';" %>
args.IsValid = (!checkDateRange(startDate , endDate, formatString, rangeOf, rangeSpan)) ? false : true;
}
}
function checkDateRange(startDate, endDate, formatString, rangeOf, numRange) {
var formatIndexes = formatString.split('/');
var mIndex = dIndex = yIndex = 0;
for (var i = 0; i < formatIndexes.length; i++) {
switch (formatIndexes[i].charAt(0 ).toLowerC ase()) {
case 'm':
mIndex = i;
break;
case 'd':
dIndex = i;
break;
case 'y':
yIndex = i;
break;
}
}
if (startDate.indexOf('/') != -1) {
var aryStartDate = startDate.split('/');
} else if (startDate.indexOf('-') != -1) {
var aryStartDate = startDate.split('-');
} else if (startDate.indexOf('.') != -1) {
var aryStartDate = startDate.split('.');
}
var mStartDate = Number(aryStartDate[mIndex ]);
var dStartDate = Number(aryStartDate[dIndex ]);
var yStartDate = Number(aryStartDate[yIndex ]);
var date1 = new Date(String(mStartDate + '/' + dStartDate + '/' + yStartDate));
if (endDate.indexOf('/') != -1) {
var aryEndDate = endDate.split('/');
} else if (endDate.indexOf('-') != -1) {
var aryEndDate = endDate.split('-');
} else if (endDate.indexOf('.') != -1) {
var aryEndDate = endDate.split('.');
}
var mEndDate = Number(aryEndDate[mIndex]) ;
var dEndDate = Number(aryEndDate[dIndex]) ;
var yEndDate = Number(aryEndDate[yIndex]) ;
var date2 = new Date(String(mEndDate + '/' + dEndDate + '/' + yEndDate));
var fromDateArray = startDate.split('/');
var month = Number(fromDateArray[mInde x]);
var day = Number(fromDateArray[dInde x]);
var year = Number(fromDateArray[yInde x]);
var mRange = 0, dRange = 0, yRange = 0;
switch (rangeOf.toLowerCase()) {
case 'y':
yRange = Number(numRange);
break;
case 'm':
mRange = Number(numRange);
break;
case 'd':
dRange = Number(numRange);
break;
}
var maxDate = new Date(String((month + mRange) + '/' + (day + dRange) + '/' + (year + yRange)));
if (maxDate >= date2) { return true;
} else { return false; }
return true;
}
function findControl(ctlName, ctlType){
var aryCtls = document.getElementsByTagN ame(ctlTyp e);
var ctlRegExp = new RegExp(ctlName + '$');
for (var i = 0; i < aryCtls.length; i++) {
if (aryCtls[i].id.match(ctlRe gExp)) {
return aryCtls[i].id;
}
}
}
</script>
<table cellspacing="0" cellpadding="0" border="0">
<tr>
<td><span style="font-size: 10pt; font-weight: bold;">From Date</span></td>
<td><span style="font-size: 10pt; font-weight: bold;">To Date</span></td>
</tr>
<tr>
<td><asp:TextBox ID="txtFromDate" Runat="server" /></td>
<td><asp:TextBox ID="txtToDate" Runat="server" /></td>
</tr>
<tr>
<td>
<asp:RequiredFieldValidato r ID="reqFromDate" ControlToValidate="txtFrom Date" EnableClientScript="False" Display="Dynamic" ErrorMessage="Required" Runat="server" />
<asp:RangeValidator ID="ranFromDate" ControlToValidate="txtFrom Date" EnableClientScript="False" Display="Dynamic" ErrorMessage="Invalid Date" Runat="server" />
</td>
<td>
<asp:RequiredFieldValidato r ID="reqToDate" ControlToValidate="txtToDa te" EnableClientScript="False" Display="Dynamic" ErrorMessage="Required" Runat="server" />
<asp:RangeValidator ID="ranToDate" ControlToValidate="txtToDa te" EnableClientScript="False" Display="Dynamic" ErrorMessage="Invalid Date" Runat="server" />
</td>
</tr>
<tr id="trCustom" visible="false" runat="server">
<td colspan="2" align="center">
<asp:CustomValidator ID="valDates" Display="Dynamic" OnServerValidate="ServerVa lidateDate s" Runat="server" />
<asp:CustomValidator ID="valRange" Display="Dynamic" OnServerValidate="ServerVa lidateRang e" Runat="server" />
</td>
</tr>
</table>
<!-- END FromToDates.ascx -------------------------- ---------- ------ -->
'BEGIN FromToDates.ascx.vb -------------------------- ---------- - -->
Public Class FromToDates
Inherits System.Web.UI.UserControl
#Region " Global "
Protected txtFromDate As TextBox
Protected txtToDate As TextBox
Protected reqFromDate As RequiredFieldValidator
Protected reqToDate As RequiredFieldValidator
Protected ranFromDate As RangeValidator
Protected ranToDate As RangeValidator
Protected valDates As CustomValidator
Protected valRange As CustomValidator
Protected trCustom As HtmlTableRow
Protected btnSubmit As Button
Private bError As Boolean = False
Private bCustomValidate As Boolean ' = True
Private dateInterval As Microsoft.VisualBasic.Date Interval
Private dateFormat As String = "MM/dd/yyyy"
Private sRangeOf As String ' = "y"
Private iRangeSpan As Integer ' = 10
#End Region
#Region " Properties "
Public WriteOnly Property Columns() As Integer
Set(ByVal Value As Integer)
txtFromDate.Columns = Value
txtToDate.Columns = Value
End Set
End Property
Public WriteOnly Property MaxLength() As Integer
Set(ByVal Value As Integer)
txtFromDate.MaxLength = Value
txtToDate.MaxLength = Value
End Set
End Property
Public Property CustomValidate() As Boolean
Get
Return bCustomValidate
End Get
Set(ByVal Value As Boolean)
bCustomValidate = Value
End Set
End Property
Public Property RangeOf() As String
Get
Return sRangeOf
End Get
Set(ByVal Value As String)
sRangeOf = Value
End Set
End Property
Public Property RangeSpan() As Integer
Get
Return iRangeSpan
End Get
Set(ByVal Value As Integer)
iRangeSpan = Value
End Set
End Property
#End Region
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.Debugg erStepThro ugh()> Private Sub InitializeComponent()
'''===================BEGI N VALIDATORS================ =======
'requiredFieldValidator
reqFromDate.Enabled = True
reqToDate.Enabled = True
'rangeValidator
' startDate
ranFromDate.Enabled = True
ranFromDate.MinimumValue = "01/01/1900"
ranFromDate.MaximumValue = "06/06/2079"
ranFromDate.Type = ValidationDataType.Date
' endDate
ranToDate.Enabled = True
ranToDate.MinimumValue = "01/01/1900"
ranToDate.MaximumValue = "06/06/2079"
ranToDate.Type = ValidationDataType.Date
'customValidator
trCustom.Visible = bCustomValidate
' fromDate cant be greater than toDate
valDates.Enabled = bCustomValidate
valDates.ErrorMessage = "Invalid date range"
' dateRange
Session("FormatString") = dateFormat
Session("RangeOf") = sRangeOf
Session("RangeSpan") = iRangeSpan
valRange.Enabled = bCustomValidate
Dim denom As String
Select Case RangeOf.ToLower
Case "m"
denom = "Month(s)"
dateInterval = dateInterval.Month
Case "d"
denom = "Day(s)"
dateInterval = dateInterval.Day
Case "y"
denom = "Year(s)"
dateInterval = dateInterval.Year
End Select
valRange.ErrorMessage = String.Format("Range exceeds {0} {1}", iRangeSpan, denom)
'''====================END VALIDATORS================ ========
End Sub
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclara tion As System.Object
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
#Region " Methods "
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'
End Sub
Protected Sub ServerValidateDates(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtFromDate.Text) Or Not IsDate(txtToDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(CType(txtFromDate.Text , Date) > CType(txtToDate.Text, Date), False, True)
End Sub
Protected Sub ServerValidateRange(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtFromDate.Text) Or Not IsDate(txtToDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(DateDiff(dateInterval, CType(txtFromDate.Text, Date), CType(txtToDate.Text, Date)) <= RangeSpan, True, False)
End Sub
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
If (bError Or Not ranFromDate.IsValid Or Not ranToDate.IsValid) Then
valDates.Visible = False
valRange.Visible = False
End If
End Sub
#End Region
End Class
'END FromToDates.ascx.vb -------------------------- ---------- --- -->
========================== ========== ========== ========== =====
What I really don't understand is why it works fine until I fail one of the built-in validators. Page.Validate is apparently working fine, it runs, raises the ServerValidate event for the CustomValidator like it's supposed to.. but as soon as you fail a pre-defined validator it loses its mind.
Anyway, that's what I'm working with now. So, I think if we can get this last kink, we got ourselves a solution, and you get yourself 500 points. I really appreciate your help.
Here is the new code:
<!-- BEGIN WebForm1.aspx --------------------------
<%@ Page Language="vb" AutoEventWireup="false" Codebehind="WebForm1.aspx.
<%@ Register TagPrefix="ctrls" TagName="FromToDates" Src="FromToDates.ascx" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<title>WebForm1</title>
<meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">
<meta name="CODE_LANGUAGE" content="Visual Basic .NET 7.1">
<meta name=vs_defaultClientScrip
<meta name=vs_targetSchema content="http://schemas.microsoft.com/intellisense/ie5">
</head>
<body MS_POSITIONING="GridLayout
<form id="Form1" method="post" runat="server">
<table>
<tr valign="top">
<td><ctrls:FromToDates ID="FromToDates" CustomValidate="True" RangeOf="y" RangeSpan="10" Columns="11" MaxLength="10" Runat="server" /></td>
<td><asp:Label ID="lblPost" Visible="False" Font-Bold="True" Runat="server" /></td>
</tr>
</table>
<asp:Button ID="btnSubmit" Text="Submit" Runat="server" />
</form>
</body>
</html>
<!-- END WebForm1.aspx --------------------------
'BEGIN WebForm1.aspx.vb --------------------------
Public Class WebForm1
Inherits System.Web.UI.Page
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.Debugg
End Sub
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclara
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
Protected lblPost As Label
Private bPageValid As Boolean
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If (IsPostBack) Then
Page.Validate()
bPageValid = Page.IsValid
End If
End Sub
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
If (IsPostBack) Then
lblPost.Text = IIf(bPageValid, "Success", "Failed")
End If
lblPost.Visible = IIf(IsPostBack, True, False)
End Sub
End Class
'END WebForm1.aspx.vb --------------------------
<!-- BEGIN FromToDates.ascx --------------------------
<%@ Control Language="vb" AutoEventWireup="false" Codebehind="FromToDates.as
<script language="javascript">
var validRange = false;
function validateDates(source, args) {
if (!document.getElementById(
validRange = false;
return;
}
var startDate = new Date(document.getElementBy
var endDate = new Date(document.getElementBy
if (startDate == 'NaN' || endDate == 'NaN') {
validRange = false;
return;
}
validRange = (startDate > endDate) ? false : true;
args.IsValid = validRange;
}
function validateRange(source, args) {
if (validRange) {
var startDate = document.getElementById(fi
var endDate = document.getElementById(fi
<% = "var formatString = '" & Session("FormatString") & "';" %>
<% = "var rangeOf = '" & Session("RangeOf") & "';" %>
<% = "var rangeSpan = '" & Session("RangeSpan") & "';" %>
args.IsValid = (!checkDateRange(startDate
}
}
function checkDateRange(startDate, endDate, formatString, rangeOf, numRange) {
var formatIndexes = formatString.split('/');
var mIndex = dIndex = yIndex = 0;
for (var i = 0; i < formatIndexes.length; i++) {
switch (formatIndexes[i].charAt(0
case 'm':
mIndex = i;
break;
case 'd':
dIndex = i;
break;
case 'y':
yIndex = i;
break;
}
}
if (startDate.indexOf('/') != -1) {
var aryStartDate = startDate.split('/');
} else if (startDate.indexOf('-') != -1) {
var aryStartDate = startDate.split('-');
} else if (startDate.indexOf('.') != -1) {
var aryStartDate = startDate.split('.');
}
var mStartDate = Number(aryStartDate[mIndex
var dStartDate = Number(aryStartDate[dIndex
var yStartDate = Number(aryStartDate[yIndex
var date1 = new Date(String(mStartDate + '/' + dStartDate + '/' + yStartDate));
if (endDate.indexOf('/') != -1) {
var aryEndDate = endDate.split('/');
} else if (endDate.indexOf('-') != -1) {
var aryEndDate = endDate.split('-');
} else if (endDate.indexOf('.') != -1) {
var aryEndDate = endDate.split('.');
}
var mEndDate = Number(aryEndDate[mIndex])
var dEndDate = Number(aryEndDate[dIndex])
var yEndDate = Number(aryEndDate[yIndex])
var date2 = new Date(String(mEndDate + '/' + dEndDate + '/' + yEndDate));
var fromDateArray = startDate.split('/');
var month = Number(fromDateArray[mInde
var day = Number(fromDateArray[dInde
var year = Number(fromDateArray[yInde
var mRange = 0, dRange = 0, yRange = 0;
switch (rangeOf.toLowerCase()) {
case 'y':
yRange = Number(numRange);
break;
case 'm':
mRange = Number(numRange);
break;
case 'd':
dRange = Number(numRange);
break;
}
var maxDate = new Date(String((month + mRange) + '/' + (day + dRange) + '/' + (year + yRange)));
if (maxDate >= date2) { return true;
} else { return false; }
return true;
}
function findControl(ctlName, ctlType){
var aryCtls = document.getElementsByTagN
var ctlRegExp = new RegExp(ctlName + '$');
for (var i = 0; i < aryCtls.length; i++) {
if (aryCtls[i].id.match(ctlRe
return aryCtls[i].id;
}
}
}
</script>
<table cellspacing="0" cellpadding="0" border="0">
<tr>
<td><span style="font-size: 10pt; font-weight: bold;">From Date</span></td>
<td><span style="font-size: 10pt; font-weight: bold;">To Date</span></td>
</tr>
<tr>
<td><asp:TextBox ID="txtFromDate" Runat="server" /></td>
<td><asp:TextBox ID="txtToDate" Runat="server" /></td>
</tr>
<tr>
<td>
<asp:RequiredFieldValidato
<asp:RangeValidator ID="ranFromDate" ControlToValidate="txtFrom
</td>
<td>
<asp:RequiredFieldValidato
<asp:RangeValidator ID="ranToDate" ControlToValidate="txtToDa
</td>
</tr>
<tr id="trCustom" visible="false" runat="server">
<td colspan="2" align="center">
<asp:CustomValidator ID="valDates" Display="Dynamic" OnServerValidate="ServerVa
<asp:CustomValidator ID="valRange" Display="Dynamic" OnServerValidate="ServerVa
</td>
</tr>
</table>
<!-- END FromToDates.ascx --------------------------
'BEGIN FromToDates.ascx.vb --------------------------
Public Class FromToDates
Inherits System.Web.UI.UserControl
#Region " Global "
Protected txtFromDate As TextBox
Protected txtToDate As TextBox
Protected reqFromDate As RequiredFieldValidator
Protected reqToDate As RequiredFieldValidator
Protected ranFromDate As RangeValidator
Protected ranToDate As RangeValidator
Protected valDates As CustomValidator
Protected valRange As CustomValidator
Protected trCustom As HtmlTableRow
Protected btnSubmit As Button
Private bError As Boolean = False
Private bCustomValidate As Boolean ' = True
Private dateInterval As Microsoft.VisualBasic.Date
Private dateFormat As String = "MM/dd/yyyy"
Private sRangeOf As String ' = "y"
Private iRangeSpan As Integer ' = 10
#End Region
#Region " Properties "
Public WriteOnly Property Columns() As Integer
Set(ByVal Value As Integer)
txtFromDate.Columns = Value
txtToDate.Columns = Value
End Set
End Property
Public WriteOnly Property MaxLength() As Integer
Set(ByVal Value As Integer)
txtFromDate.MaxLength = Value
txtToDate.MaxLength = Value
End Set
End Property
Public Property CustomValidate() As Boolean
Get
Return bCustomValidate
End Get
Set(ByVal Value As Boolean)
bCustomValidate = Value
End Set
End Property
Public Property RangeOf() As String
Get
Return sRangeOf
End Get
Set(ByVal Value As String)
sRangeOf = Value
End Set
End Property
Public Property RangeSpan() As Integer
Get
Return iRangeSpan
End Get
Set(ByVal Value As Integer)
iRangeSpan = Value
End Set
End Property
#End Region
#Region " Web Form Designer Generated Code "
'This call is required by the Web Form Designer.
<System.Diagnostics.Debugg
'''===================BEGI
'requiredFieldValidator
reqFromDate.Enabled = True
reqToDate.Enabled = True
'rangeValidator
' startDate
ranFromDate.Enabled = True
ranFromDate.MinimumValue = "01/01/1900"
ranFromDate.MaximumValue = "06/06/2079"
ranFromDate.Type = ValidationDataType.Date
' endDate
ranToDate.Enabled = True
ranToDate.MinimumValue = "01/01/1900"
ranToDate.MaximumValue = "06/06/2079"
ranToDate.Type = ValidationDataType.Date
'customValidator
trCustom.Visible = bCustomValidate
' fromDate cant be greater than toDate
valDates.Enabled = bCustomValidate
valDates.ErrorMessage = "Invalid date range"
' dateRange
Session("FormatString") = dateFormat
Session("RangeOf") = sRangeOf
Session("RangeSpan") = iRangeSpan
valRange.Enabled = bCustomValidate
Dim denom As String
Select Case RangeOf.ToLower
Case "m"
denom = "Month(s)"
dateInterval = dateInterval.Month
Case "d"
denom = "Day(s)"
dateInterval = dateInterval.Day
Case "y"
denom = "Year(s)"
dateInterval = dateInterval.Year
End Select
valRange.ErrorMessage = String.Format("Range exceeds {0} {1}", iRangeSpan, denom)
'''====================END
End Sub
'NOTE: The following placeholder declaration is required by the Web Form Designer.
'Do not delete or move it.
Private designerPlaceholderDeclara
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
'CODEGEN: This method call is required by the Web Form Designer
'Do not modify it using the code editor.
InitializeComponent()
End Sub
#End Region
#Region " Methods "
Private Sub Page_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'
End Sub
Protected Sub ServerValidateDates(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtFromDate.Text) Or Not IsDate(txtToDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(CType(txtFromDate.Text
End Sub
Protected Sub ServerValidateRange(ByVal source As Object, ByVal args As ServerValidateEventArgs)
If (Not IsDate(txtFromDate.Text) Or Not IsDate(txtToDate.Text)) Then
args.IsValid = False
bError = True
Exit Sub
End If
args.IsValid = IIf(DateDiff(dateInterval,
End Sub
Private Sub Page_PreRender(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PreRender
If (bError Or Not ranFromDate.IsValid Or Not ranToDate.IsValid) Then
valDates.Visible = False
valRange.Visible = False
End If
End Sub
#End Region
End Class
'END FromToDates.ascx.vb --------------------------
==========================
What I really don't understand is why it works fine until I fail one of the built-in validators. Page.Validate is apparently working fine, it runs, raises the ServerValidate event for the CustomValidator like it's supposed to.. but as soon as you fail a pre-defined validator it loses its mind.
Anyway, that's what I'm working with now. So, I think if we can get this last kink, we got ourselves a solution, and you get yourself 500 points. I really appreciate your help.
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:
PAQ with points refunded
Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
TheLearnedOne
EE Cleanup Volunteer
I will leave the following recommendation for this question in the Cleanup topic area:
PAQ with points refunded
Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!
TheLearnedOne
EE Cleanup Volunteer
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
I'll keep thinking about it.
ZRH