In my last ASP.NET assignment, I have to validate controls on the web page like radio button, checkbox, Calendar and so on. When I tried to validate CheckBox Control with RequiredField Validator then I got a runtime exception informing me that the CheckBoxList cannot be validated with this validator. Then I tried with CustomValidator and it work. As my page contain different control so I want to use only a single validator to validate same type of control. For example a single validator to validate both CheckBoxList and RadioButtonList. Then I have searched on Google and find articles from which I came to know we can create our own Custom Validation Control. The main reason to create a custom validation control instead of using a CustomValidator is ‘reusability’ which was my problem.
With the reference of articles (mentioned in references section) I create my own validation control and reuse it for different control. Here I mentioned how I create my own Validation Control and provide both Server and Client Side Validation for the same.
Basic Overview of creating Custom Validation Control:
First thing we have create a class that inherits from BaseValidator
public class <Name of Validation class> : BaseValidatorThen you have to override a few methods:
Let us we start to create a Custom Validation Control by right click on the project > Add New Item > From the Template, choose ‘Class’ > Rename the class to ‘MyValidator’ or anything you like > Choose the Language (C#) > Click on Add.
Visual Studio would prompt you to add the class to the App_Code. Choose yes to do so
As already discussed, we will be deriving from the BaseValidator abstract class. We will need to implement the ‘EvaluateIsValid’ method which returns a Boolean value indicating if the field/control being validated is valid or not.
The code for the server side validation will be similar (as I use C#) to the following:
namespace CustomListValidator
public class MyValidator : BaseValidator
{
public MyValidator()
{
}
protected override bool ControlPropertiesValid()
{
Control ctrl = FindControl(ControlToValidate)as ListControl;
return (ctrl != null);
}
protected override bool EvaluateIsValid()
{
return this.CheckIfItemIsChecked();
}
protected bool CheckIfItemIsChecked()
{
ListControl listItemValidate = ((ListControl)this.FindControl(this.ControlToValidate));
foreach (ListItem listItem in listItemValidate.Items)
{
if (listItem.Selected == true)
return true;
}
return false;
}
}
}
In the code snippet shown above, we override the EvaluateIsValid() method. The ‘ControlToValidate’ is cast to a ListControl, which is an abstract base class for all list-type controls. We then loop through all the ListItems and if one of the items in both the CheckBoxList as well as RadioButtonList is checked by the user, we return true, else we return false.
In order to use this custom validation control on the CheckBoxList and RadioButtonList kept in our page, we will use the <%@ Register %> directive as shown below:
<%@ Register TagPrefix="CLV" Namespace="CustomListValidator" %>
//Add created custom validation control next to the control which you want to validate as we use inbuilt validator
<div>
<asp:CheckBoxList ID="chBoxList1" runat="server">
</asp:CheckBoxList></div>
<CLV:MyValidator runat="server" ID="custLstVal" ControlToValidate=" chBoxList1" ErrorMessage="At least one item in the checkboxlist should be checked" />
<asp:RadioButtonList ID="rbList1" runat="server">
</asp:RadioButtonList>
<CLV:MyValidator runat="server" ID="custRadVal" ControlToValidate="rbList1" ErrorMessage="At least one item in the radiobuttonlist should be checked" />
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
As you will observe, the two controls are being validated by the same custom validation control that we are building. Run the application and click on the button without checking any items in the two controls. Two error messages are displayed when the form is submitted.
Client-Side Validation
We saw how to perform server side validation. Let us see how we can now perform validation directly on the client side, without a postback. To perform client side validation, you would need to override OnPreRender and create the javascript function using a StringBuilder object and output it using Page.ClientScript.RegisterClientScriptBlock().
The code with the OnPreRender and JavaScript function will look similar to the following. This code is to be added in the same class where the server-side validation code was added.
protected override void OnPreRender(EventArgs e)
{
// determines whether the validation control can be rendered
// for a newer ("uplevel") browser.
// check if client-side validation is enabled.
If(this.DetermineRenderUplevel() && this.EnableClientScript)
{
Page.ClientScript.RegisterExpandoAttribute(this.ClientID,
"evaluationfunction", "CheckIfListChecked");
this.CreateJavaScript();
}
base.OnPreRender(e);
}
protected void CreateJavaScript()
{
StringBuilder sb = new StringBuilder();
sb.Append(@"<script type=""text/javascript"">function
CheckIfListChecked(ctrl){");
sb.Append(@"var chkBoxList =
document.getElementById(document.getElementById(ctrl.id).controltovalidate);");
sb.Append(@"var chkBoxCount= chkBoxList.getElementsByTagName(""input"");");
sb.Append(@"for(var i=0;i<chkBoxCount.length;i++){");
sb.Append(@"if(chkBoxCount.item(i).checked){");
sb.Append(@"return true; }");
sb.Append(@"}return false; ");
sb.Append(@"}</script>");
Page.ClientScript.RegisterClientScriptBlock(GetType(),"JSScript", sb.ToString());
}
As you observe, we override the OnPreRender method and use the RegisterExpandoAttribute to assign the function name ‘CheckIfListChecked’ an attribute called ‘evaluationfunction’. The javascript function(CheckIfListChecked) takes one parameter, the validator object and returns ‘true’ if Valid (item in both Radiobuttonlist or CheckBoxList is checked) and ‘false’ if Invalid (Item in either Radiobuttonlist or CheckBoxList is not selected).
Note: If you observe, there is a call to the base.OnPreRender() in the OnPreRender method. This is done to make sure that if the users have turned off javascript on their browsers, then this call passes the control back to the page and allows the rendering to continue by calling base.OnPreRender() .
The javascript function is created using a StringBuilder object and is output using Page.ClientScript.RegisterClientScriptBlock()
The last step would be to add the EnableClientScript="true" to our custom validation controls as shown below:
<CLV:ListValidator runat="server" ID="custLstVal" EnableClientScript="true" ControlToValidate="CheckBoxList1" ErrorMessage="At least one item in the checkboxlist should be checked" />
<CLV:ListValidator runat="server" ID="custRadVal" EnableClientScript="true" ControlToValidate="RadioButtonList1" ErrorMessage="At least one item in the radiobuttonlist should be checked" />
This time when we run the application, the custom validation control handles both server-side as well as client-side validation. If JavaScript is enabled on your browsers, the validation errors are displayed before the form is posted back to the server
No comments:
Post a Comment