locked
Custom CompareValidator Control RRS feed

  • Question

  • User1491655232 posted

     This is my first custom control (so don't laugh Tongue out) 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
  • 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