ASP.NET MVC Data Annotation – Client Side Validation of Controls – Textbox, Dropdownlist, Checkbox, Radiobutton

ASP.NET MVC Data Annotation – Client Side Validation of Controls – Textbox, Dropdownlist, Checkbox, Radiobutton

In ASP.NET MVC Client Side Validation of Controls are done using jQuery and 2 plugins (jQuery Validation & jQuery Unobtrusive Validation).

Download jQuery, jQuery Validation & jQuery Unobtrusive Validation from NuGet

The first thing is to include all these 3 in your project, which you can do easily through NuGet.

Run the following commands in NuGet Package Manager Console.

1. For jQuery – PM> Install-Package jQuery -Version 2.2.4
2. For jQuery Validation – PM> Install-Package jQuery.Validation
3. For jQuery Unobtrusive Validation – PM> Install-Package jQuery.Validation.Unobtrusive
These files will be added to the Scripts folder.

jquery and plugins added to script folder

Adding Reference of jQuery, jQuery Validation & jQuery Unobtrusive Validation in View

First add the below codes to the BundleConfig.cs file which is kept inside App_Start folder:

bundles.Add(new ScriptBundle("~/jQuery").Include("~/Scripts/jquery-2.2.4.js"));
bundles.Add(new ScriptBundle("~/jQueryValidate").Include("~/Scripts/jquery.validate.js"));
bundles.Add(new ScriptBundle("~/Unobtrusive").Include("~/Scripts/jquery.validate.unobtrusive.js")); 

Next go to your view and enable ClientValidationEnabled and UnobtrusiveJavaScriptEnabled by adding the below code on top of it:

@{
    HtmlHelper.ClientValidationEnabled = true;
    HtmlHelper.UnobtrusiveJavaScriptEnabled = true;
}

And reference the jQuery and 2 plugins by adding the below code to the bottom of the view:

@Scripts.Render("~/jQuery")
@Scripts.Render("~/jQueryValidate")
@Scripts.Render("~/Unobtrusive")

You are now ready to do Client Side Validation with jQuery in your view. I will be creating jQuery validation for the Job Application form. First you need to look at my previous tutorial – Server Side Validation where I have created this form and did Server Side Validation using Data Annotation.

I will be adding Client Side Validation codes to this form using jQuery.

Client Side Validation on Job Application Form

I will have to create a JS file where jQuery codes will be writer. These codes will do Client Side Validation.

jQuery Code File

Right click on the Scripts folder and add a new JavaScript File, name it custom.validation.js.

Add the following 2 lines of code to this file:

$(function () {
}(jQuery));
You have guessed it right – the jQuery codes on this file will communicate with jQuery Validation and jQuery Unobtrusive Validation plugins to show the client side error messages whenever the input fields are not in correct syntax.

You will also reference this file in your view. So first go to BundleConfig.cs file and add the below code to it:

bundles.Add(new ScriptBundle("~/CustomValidation").Include("~/Scripts/custom.validation.js")); 

And in your view, add the below code after you reference Unobtrusive js file.

@Scripts.Render("~/CustomValidation")
CustomValidation.cs File

Do you remember I created 4 classes inside the CustomValidation.cs file to do my Server Side Validations? Now I will extend 3 classes (ValidBirthDate, SexValidation & RequiredTerms) to create Client Side Validations for my controls.

You cannot achieve MVC’s Client Side Validation on SkillValidation class by implementing IClientValidatable and using jquery.validation.unobtrusive.js. The reason is that client side validation rules are applied to form controls which are simple value type, and not collection (like skills property).

For Client Validation to work, derive all these 3 classes from IClientValidatable interface and add GetClientValidationRules() method to them.

1. Let us first extend the ValidBirthDate class.
Go to the CustomValidation.cs file and inherit it from IClientValidatable interface. Then add GetClientValidationRules() method to it. The updated code of this class is:

public sealed class ValidBirthDate : ValidationAttribute, IClientValidatable
{
    //code for ValidationResult

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        ModelClientValidationRule mvr = new ModelClientValidationRule();
        mvr.ErrorMessage = ErrorMessage;
        mvr.ValidationType = "validbirthdate";
        mvr.ValidationParameters.Add("min", "01-25-1970");
        mvr.ValidationParameters.Add("max", "01-25-2000");
        return new[] { mvr };
    }
}

Explanation: I added GetClientValidationRules() method that returns client validation rules for that class. So first I created an object of ModelClientValidationRule class and set the ErrorMessage, ValidationParameters and ValidationType.

Note that the ValidationType should be set to the name of jQuery function that will be called for doing Client Side Validation.

The ErrorMessage is set to whatever passed to this method from the model. In my model I used the code:

[ValidBirthDate(ErrorMessage = "DOB Should be between 01-25-1970 & 01-25-2000")]

So here the text “DOB Should be between 01-25-1970 & 01-25-2000” will be set for the ErrorMessage.

I added 2 ValidationParameters to this method (min and max) and these parameters will be sent to our jQuery validbirthdate function.

Next you have to add validbirthdate function in the custom.validation.js file, like shown below:

$(function () {

    /*Date of Birth*/
    jQuery.validator.addMethod('validbirthdate', function (value, element, params) {
        var minDate = new Date(params["min"]);
        var maxDate = new Date(params["max"]);
        var dateValue = new Date(value);
        if (dateValue > minDate && dateValue < maxDate)
            return true;
        else
            return false;
    });

    jQuery.validator.unobtrusive.adapters.add('validbirthdate', ['min', 'max'], function (options) {
        var params = {
            min: options.params.min,
            max: options.params.max
        };

        options.rules['validbirthdate'] = params;
        if (options.message) {
            options.messages['validbirthdate'] = options.message;
        }
    });
    /*End*/
   
}(jQuery));

Explanation
Here in the js file I created 2 methods – jQuery.validator.addMethod() and jQuery.validator.unobtrusive.adapters.add().

jQuery.validator.addMethod()
This method takes 3 parameters – value, element, params.

  • value – contains the value of the control. Here it will provide the value of birthDate control.
  • element – contains the id of the control. Here it contains id of the birthDate control.
  • params – are the parameters sent to this method from the GetClientValidationRules () method. Here these are min and max.

In the jQuery.validator.addMethod() I wrote my jQuery code that extracts the min and max parameters values. Then checks if the value of the date in birthDate control is between them or not. If it is in between them, I return true else return false.

jQuery.validator.addMethod()
This method links jQuery Unobtrusive Validation plugin with the validbirthdate method and shows the client side error message. It has 3 parameter – name of jQuery function, name of parameters passed and the call back function.

In the jQuery.validator.unobtrusive.adapters.add() method I have to set the rules (for marking parameters) and messages.

The rules are set to the parameters passed and the message is set to the options.message.

HTML Created For the birthDate Control
If you run you application and inspect the birthDate control with Chrome Developer Tools in the browser you will see the html of the control has some data attributes added to it. Its HTML will look like:

<input class="text-box single-line" data-val="true" data-val-date="The field Date of Birth must be a date." data-val-required="The Date of Birth field is required." data-val-validbirthdate="DOB Should be between 01-25-1970 &amp; 01-25-2000" data-val-validbirthdate-max="01-25-2000" data-val-validbirthdate-min="01-25-1970" id="birthDate" name="birthDate" type="date" value="">

These added attributes come because I have enabled ClientValidationEnabled & UnobtrusiveJavaScriptEnabled in my view.

These data attributes are:
  • data-val that is set to true and specifies that this input needs validation.
  • data-val-required is the error message to be displayed if a value is not provided.
  • data-val-date is the error message to be displayed if a value is not a date.
  • data-val-validbirthdate is the error message to be displayed for the value fails validation on my custom function validbirthdate.
  • data-val-validbirthdate-max for storing the value of max parameter.
  • data-val-validbirthdate-min for storing the value of min parameter.

The data attributes stores the information to perform client side validation. That’s the reason you only need little jQuery code besides attributes to do jQuery Validations.

2. Extend the SexValidation class.
I have a dropdownlist that allows for sex selection. I will extend this class now.

Add the GetClientValidationRules() to it so the code becomes:

public class SexValidation : ValidationAttribute, IClientValidatable
{
    //code for ValidationResult

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        ModelClientValidationRule mvr = new ModelClientValidationRule();
        mvr.ErrorMessage = ErrorMessage;
        mvr.ValidationType = "sexvalidation";
        return new[] { mvr };
    }
} 

Explanation: In the GetClientValidationRules() method sets the ErrorMessage and ValidationType.

Next you have to add sexvalidation function in the custom.validation.js file, like shown below:

/*Sex*/
jQuery.validator.addMethod('sexvalidation', function (value, element, params) {
    if ((value != "M") && (value != "F"))
        return false;
    else
        return true;
});

jQuery.validator.unobtrusive.adapters.add('sexvalidation', function (options) {
    options.rules['sexvalidation'] = {};
    options.messages['sexvalidation'] = options.message;
});
/*End*/

Explanation
I wrote my jQuery code that checks if the selected value of the dropdownlist is not “M” or “F”. If it is then return false else return true.

In the jQuery.validator.unobtrusive.adapters.add() I have to set the rules and messages.
Here there are no parameters send to this method (from SexValidation’s GetClientValidationRules method) so I set them to {}.

The messages is set using options.message.

3. Extend RequiredTerms class.
The terms checkbox has to be checked by the user before they can submit the form. Now I will work on the Client Validation of this checkbox.

Update the RequiredTerms class with the code shown below:

public sealed class RequiredTerms : ValidationAttribute, IClientValidatable
{
    //ValidatioResult code

    public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
    {
        ModelClientValidationRule mvr = new ModelClientValidationRule();
        mvr.ErrorMessage = ErrorMessage;
        mvr.ValidationType = "termsvalidation";
        return new[] { mvr };
    }
}

Explanation
I am setting the Error Message to it and termsvalidation as my jQuery function that will be called for client side validation of this checkbox.

Now go to custom.validation.js file and add the below jQuery code:

/*Terms Validation*/
jQuery.validator.addMethod('termsvalidation', function (value, element, params) {
    if (value != "true")
        return false;
    else
        return true;
});

jQuery.validator.unobtrusive.adapters.add('termsvalidation', function (options) {
    options.rules['termsvalidation'] = {};
    options.messages['termsvalidation'] = options.message;
});
/*End*/

Explanation
Here I am just checking whether the checkbox is not checked. If not checked I return true else false.

Client Side Validation of Skills Property

In order to validate user’s skills so that he should select at least 3 skills, since this is a collection property and not a simple one, I will have to write custom jQuery code for this in the View.

So after @Scripts.Render(“~/CustomValidation”) code, add the below custom jQuery code to your View.

<script>
    $(document).ready(function () {
        $("form").submit(function () {
            Validate();
        });

        $("[id *= Skill]").click(function () {
            Validate();
        });

        function Validate() {
            var errorElement = $('span[data-valmsg-for="skills"]');
            var errorMessage = "Select at least 3 skills";

            if ($("[id *= Skill]:checked").length < 3) 
                errorElement.addClass('field-validation-error').removeClass('field-validation-valid').text(errorMessage);
            else
                errorElement.addClass('field-validation-valid').removeClass('field-validation-error').text('');
        }

    });
</script>

Explanation: On the form submission I call the Validate() method where I am finding the error span control associated with these 6 checkboxes. Then I find out if the checked checkboxes are less than 3, in that case showing the error message on the span element.

I have also created the click event for all these 6 checkboxes and calling the Validate() method in it. So whenever any of these checkboxes is checked or unchecked then the Validate() method is called.

In this way you can validate the controls using custom jQuery code.

Client Side Validation of CKEditor (PreviousJobDescription property)

I have given CKEditor for PreviousJobDescription property. The CKEditor hides the Text Area and it its place show itself. The actual validation will be done of the hidden Text Area and not the CKEditor.

For the Client Side Validation to work on CKEditor you you have to first Show the Text Area and then call the CKEditor’s updateElement() method.

I added a button client event with the below code in my custom jQuery code in the View:

$("#submitButton").click(function () {
    $("#previousJobDescription").show();
    CKupdate();
});
function CKupdate() {
    CKEDITOR.instances["previousJobDescription"].updateElement();
} 
Testing Client Side Validation

Run your project and then click the submit button. You will find all Client Side Validation Error messages shown to you.

DEMO DOWNLOAD

client side validation testing

Share this article -

yogihosting

ABOUT THE AUTHOR

This article has been written by the Technical Staff of YogiHosting. Check out other articles on "WordPress, SEO, jQuery, HTML" and more.