Answered by:
Custom CompareValidator Control

Question
-
User1491655232 posted
This is my first custom control (so don't laugh
) and I'm attempting to use the CustomValidator class and validate a date and time. I added the tag to the HTML page and wired up two textboxes but, it's not working. When I add breakpoints in the code for this class it's not being called and I have the Web.Config file debug='true'. I know there is something way off here but, I'm not sure how to proceed and I was unable to locate a good reading on the subject. Can any wise ASP.NET guru's provide me with some assistance?
Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.ComponentModel Namespace JTControls Public Class DateAndTimeValidator Inherits CompareValidator Protected Overrides Function EvaluateIsValid() As Boolean Return Me.ValidateDateTime End Function Protected Overrides Function ControlPropertiesValid() As Boolean Dim ctrlValidate As Control = TryCast(FindControl(ControlToValidate), TextBox) Dim ctrlCompare As Control = TryCast(FindControl(ControlToCompare), TextBox) If ctrlValidate Is Nothing Or ctrlCompare Is Nothing Then Return False ElseIf Not ctrlValidate Is Nothing And Not ctrlCompare Is Nothing Then Return True End If End Function Private Function ValidateDateTime() As Boolean Dim RegExTime As New Regex("^((([0]?[1-9]|1[0-2])(:|\.)[0-5][0-9]((:|\.)[0-5][0-9])?( )?(AM|am|aM|Am|PM|pm|pM|Pm))|(([0]?[0-9]|1[0-9]|2[0-3])(:|\.)[0-5][0-9]((:|\.)[0-5][0-9])?))$") Dim RegExDate As New Regex("^((((0[13578])|([13578])|(1[02]))[\/](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/](([1-9])|([0-2][0-9])|(30)))|((2|02)[\/](([1-9])|([0-2][0-9]))))[\/]\d{4}$|^\d{4}$") If ControlToCompare = "" Or ControlToValidate = "" Then Return False End If If RegExTime.IsMatch(Me.ControlToCompare) = True And RegExDate.IsMatch(Me.ControlToValidate) = True Or _ RegExDate.IsMatch(Me.ControlToCompare) = True And RegExTime.IsMatch(Me.ControlToValidate) = True Then Return True Else : Return False End If End Function End Class End Namespace
Thursday, August 6, 2009 4:05 PM
Answers
-
User-2106054853 posted
Hi,
First, I don't think we shall put any Control into the Validator class. You're writing a Validator control so what's the purpose to add Controls to it as property? You can expose string property that accept Control's ID instead. Then in the code of Validator control you can use FindControl method to get the reference of the control.
Secondly, BaseValidator is intended to validate one control. If you want to validate a lot of controls in one validator you can expose extra string properties, as mentioned above. If you want to add client validation for those controls you have to do a lot of stuffs to hook client side events. In your case you have to hook client side events on your own for either the DateControl or TimeControl control.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, August 13, 2009 2:19 AM
All replies
-
User1738250506 posted
CompareValidator is used to compare two values. Below is the code I have written some time ago for date validation. It is in C# but I hope you can convert it to VB. The base class PortalBaseValidator is my custom class and does not contain any useful code for this discussion.
[DefaultProperty ("Text")] [ToolboxData ("<{0}:DayValidator runat=server></{0}:DayValidator>")] public class DayValidator : PortalBaseValidator { private Control monthControl = null; private Control yearControl = null; protected override void AddAttributesToRender (HtmlTextWriter writer) { base.AddAttributesToRender (writer); if (base.RenderUplevel) { writer.AddAttribute ("evaluationfunction", "DayValidatorEvaluateIsValid"); writer.AddAttribute ("monthcontrol", monthControl.ClientID); writer.AddAttribute ("yearcontrol", yearControl.ClientID); } } protected override bool ControlPropertiesValid () { if (!base.ControlPropertiesValid ()) { return false; } monthControl = FindControl (MonthControlID) as Control; yearControl = FindControl (YearControlID) as Control; if ((monthControl == null) || (yearControl == null)) { return false; } base.CheckControlValidationProperty (MonthControlID, "MonthControlID"); base.CheckControlValidationProperty (YearControlID, "YearControlID"); return true; } protected override bool EvaluateIsValid () { string strDay = base.GetControlValidationValue (ControlToValidate); string strMonth = base.GetControlValidationValue (MonthControlID); string strYear = base.GetControlValidationValue (YearControlID); try { DateTime dtTemp = new DateTime (int.Parse (strYear), int.Parse (strMonth), int.Parse (strDay)); } catch { return false; } return true; } [Category ("Behavior")] [DefaultValue ("")] [Description ("The ID of the Month control")] public string MonthControlID { get { string strValue = ViewState["MonthControlID"] as string; return (strValue ?? (string) (TypeHelper.GetDefaultAttribute (this, "MonthControlID", MemberTypes.Property).Value)); } set { ViewState["MonthControlID"] = value; AddHookupControl (value); } } [Category ("Behavior")] [DefaultValue ("")] [Description ("The ID of the Year control")] public string YearControlID { get { string strValue = ViewState["YearControlID"] as string; return (strValue ?? (string) (TypeHelper.GetDefaultAttribute (this, "YearControlID", MemberTypes.Property).Value)); } set { ViewState["YearControlID"] = value; AddHookupControl (value); } } }
Thursday, August 6, 2009 5:08 PM -
User1491655232 posted
Okay, here is what I've gotten so far but, I don't think I have the properties for the Id's correct. It looks like you're getting the value of the control from viewstate and then somehow getting the ID using the value; anybody know how to translate this to .NET? Here is what I have:
Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.ComponentModel Namespace JTControls Public Class DateAndTimeValidator Inherits BaseCompareValidator Private _DateControl As Control Private _TimeControl As Control Protected Overrides Sub AddAttributesToRender(ByVal writer As System.Web.UI.HtmlTextWriter) MyBase.AddAttributesToRender(writer) If MyBase.RenderUplevel = True Then writer.AddAttribute("evaluationfunction", "DayTimeEvaluatorIsValid") writer.AddAttribute("DateControl", _DateControl.ClientID) writer.AddAttribute("TimeControl", _TimeControl.ClientID) End If End Sub Protected Overrides Function EvaluateIsValid() As Boolean If Me.ValidateDateTime = True Then Return True ElseIf Me.ValidateDateTime = False Then Return False End If End Function Protected Overrides Function ControlPropertiesValid() As Boolean _DateControl = FindControl(DateControl) _TimeControl = FindControl(TimeControl) If _DateControl Is Nothing Or _TimeControl Is Nothing Then Return False End If MyBase.CheckControlValidationProperty("DateControl", "DateControl") MyBase.CheckControlValidationProperty("TimeControl", "TimeControl") If IsDate(_DateControl) = True And IsDate(_TimeControl) = True Then Return True Else Return False End If End Function Private Function ValidateDateTime() As Boolean Dim RegExTime As New Regex("^((([0]?[1-9]|1[0-2])(:|\.)[0-5][0-9]((:|\.)[0-5][0-9])?( )?(AM|am|aM|Am|PM|pm|pM|Pm))|(([0]?[0-9]|1[0-9]|2[0-3])(:|\.)[0-5][0-9]((:|\.)[0-5][0-9])?))$") Dim RegExDate As New Regex("^((((0[13578])|([13578])|(1[02]))[\/](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/](([1-9])|([0-2][0-9])|(30)))|((2|02)[\/](([1-9])|([0-2][0-9]))))[\/]\d{4}$|^\d{4}$") If Me.DateControl = "" Or Me.TimeControl = "" Then Return False End If If RegExTime.IsMatch(Me.DateControl) = True And RegExDate.IsMatch(Me.TimeControl) = True Or _ RegExDate.IsMatch(Me.TimeControl) = True And RegExTime.IsMatch(Me.DateControl) = True Then Return True Else : Return False End If End Function Public Property DateControl() As String Get Dim Value As String = ViewState("DateControl") Return Value End Get Set(ByVal value As String) ViewState("DateControl") = value End Set End Property Public Property TimeControl() As String Get Dim Value As String = ViewState("TimeControl") Return Value End Get Set(ByVal value As String) ViewState("TimeControl") = value End Set End Property End Class End Namespace
Sunday, August 9, 2009 4:57 PM -
User1491655232 posted
I was able to get the validation working on the client side and server side. The only problem I'm having now is the client side validation isn't occurring on the DateControl or TimeControl; it only occurs on the client side when I ALSO set one of the controls to the ControlToValidate property. How do I add this functionality to the DateControl and TimeControl properties? Here is my code for the Custome Validator control:
Imports System.Web Imports System.Web.UI Imports System.Web.UI.WebControls Imports System.ComponentModel Namespace JTControls Public Class DateAndTimeValidator Inherits BaseValidator Private _DateControl As TextBox Private _TimeControl As TextBox Protected Overrides Sub OnPreRender(ByVal e As System.EventArgs) If Me.DetermineRenderUplevel() AndAlso Me.EnableClientScript Then Page.ClientScript.RegisterExpandoAttribute(Me.ClientID, "evaluationfunction", "CheckDateAndTime") Me.CreateJavaScript() End If MyBase.OnPreRender(e) End Sub Protected Sub CreateJavaScript() Dim sb As StringBuilder = New StringBuilder() sb.Append("<script type=""text/javascript"">function CheckDateAndTime(ctrl){") sb.Append("var ctrlDate = document.getElementById(ctrl.DateControl);") sb.Append("var ctrlTime = document.getElementById(ctrl.TimeControl);") sb.Append("var RegExDate = /^((((0[13578])|([13578])|(1[02]))[\/](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/](([1-9])|([0-2][0-9])|(30)))|((2|02)[\/](([1-9])|([0-2][0-9]))))[\/]\d{4}$|^\d{4}$/;") sb.Append("var RegExTime = /^((([0]?[1-9]|1[0-2])(:|\.)[0-5][0-9]((:|\.)[0-5][0-9])?( )?(AM|am|aM|Am|PM|pm|pM|Pm))|(([0]?[0-9]|1[0-9]|2[0-3])(:|\.)[0-5][0-9]((:|\.)[0-5][0-9])?))$/;") sb.Append("if (ctrlDate.value == '' && ctrlTime.value == '')") sb.Append("{return true;}") sb.Append("if (! RegExDate.test(ctrlDate.value) && ! RegExDate.test(ctrlTime.value))") sb.Append("{return false;}") sb.Append("if (! RegExTime.test(ctrlDate.value) && ! RegExTime.test(ctrlTime.value))") sb.Append("{return false;}") sb.Append("return true;}") sb.Append("</script>") Page.ClientScript.RegisterClientScriptBlock(Me.GetType(), "JSScript", sb.ToString()) End Sub Protected Overrides Sub AddAttributesToRender(ByVal writer As System.Web.UI.HtmlTextWriter) MyBase.AddAttributesToRender(writer) If MyBase.RenderUplevel = True Then writer.AddAttribute("DateControl", _DateControl.ClientID) writer.AddAttribute("TimeControl", _TimeControl.ClientID) End If End Sub Protected Overrides Function EvaluateIsValid() As Boolean If Me.ValidateDateTime = True Then Return True ElseIf Me.ValidateDateTime = False Then Return False End If End Function Protected Overrides Function ControlPropertiesValid() As Boolean _DateControl = FindControl(DateControl) _TimeControl = FindControl(TimeControl) If _DateControl Is Nothing Or _TimeControl Is Nothing Then Return False End If MyBase.CheckControlValidationProperty(DateControl, "DateControl") MyBase.CheckControlValidationProperty(TimeControl, "TimeControl") Return True End Function Private Function ValidateDateTime() As Boolean Dim RegExTime As New Regex("^((([0]?[1-9]|1[0-2])(:|\.)[0-5][0-9]((:|\.)[0-5][0-9])?( )?(AM|am|aM|Am|PM|pm|pM|Pm))|(([0]?[0-9]|1[0-9]|2[0-3])(:|\.)[0-5][0-9]((:|\.)[0-5][0-9])?))$") Dim RegExDate As New Regex("^((((0[13578])|([13578])|(1[02]))[\/](([1-9])|([0-2][0-9])|(3[01])))|(((0[469])|([469])|(11))[\/](([1-9])|([0-2][0-9])|(30)))|((2|02)[\/](([1-9])|([0-2][0-9]))))[\/]\d{4}$|^\d{4}$") If _DateControl.Text = "" And _TimeControl.Text = "" Then Return True End If If RegExDate.IsMatch(Me._DateControl.Text) = True And RegExTime.IsMatch(Me._TimeControl.Text) = True Or _ RegExDate.IsMatch(Me._TimeControl.Text) = True And RegExTime.IsMatch(Me._DateControl.Text) = True Then Return True Else : Return False End If End Function Public Property DateControl() As String Get Dim Value As String = ViewState("DateControl") Return Value End Get Set(ByVal value As String) ViewState("DateControl") = value End Set End Property Public Property TimeControl() As String Get Dim Value As String = ViewState("TimeControl") Return Value End Get Set(ByVal value As String) ViewState("TimeControl") = value End Set End Property End Class End Namespace
Tuesday, August 11, 2009 7:18 PM -
User-2106054853 posted
Hi,
To do a server side validation using the Validator control, please refer to:
in the quickstart:
http://quickstarts.asp.net/QuickStartv20/aspnet/doc/validation/default.aspx#types
Wednesday, August 12, 2009 4:57 AM -
User1491655232 posted
Sorry Mr. Chen, that isn't what I need.
To clarify, I have two controls passed to my custom validator (DateControl & TimeControl) and the validator does perform client-side validation as well as server-side validation on both the controls but, I have to set the ControlToValidate for the client side validation to one of the controls for the client-side validation to occur and even then it only occurs on the control that is assigned to the ControlToValidate. I want the client side validation to occur when the text in either the DateControl or TimeControl is changed. I believe it has something to do with Microsoft's validation script library.
Wednesday, August 12, 2009 10:49 AM -
User-2106054853 posted
Hi,
First, I don't think we shall put any Control into the Validator class. You're writing a Validator control so what's the purpose to add Controls to it as property? You can expose string property that accept Control's ID instead. Then in the code of Validator control you can use FindControl method to get the reference of the control.
Secondly, BaseValidator is intended to validate one control. If you want to validate a lot of controls in one validator you can expose extra string properties, as mentioned above. If you want to add client validation for those controls you have to do a lot of stuffs to hook client side events. In your case you have to hook client side events on your own for either the DateControl or TimeControl control.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Thursday, August 13, 2009 2:19 AM