In ASP.NET MVC, the Client Side Validation of controls are done using jQuery and 2 plugins called jQuery Validation & jQuery Unobtrusive Validation.
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.
You will find the 3 files will be added to the Scripts folder of your application.
First add the below codes to the BundleConfig.cs file which is kept inside the 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 the View:
@{
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.
Example: 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 have to create a JS file where jQuery codes will be written. These codes will do my Client Side Validation.
Right click on the Scripts folder and add a new JavaScript File. Give it a name as custom.validation.js.
Add the following 2 lines of code to this file:
$(function () {
}(jQuery));
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 the Unobtrusive js file.
@Scripts.Render("~/CustomValidation")
Do you remember I created 4 classes inside the CustomValidation.cs class to do my Server Side Validations? Now I will extend 3 classes – ValidBirthDate, SexValidation & RequiredTerms to create the Client Side Validations for my controls.
For Client Validation to work, derive all these 3 classes from IClientValidatable interface and add GetClientValidationRules() method to them.
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 the GetClientValidationRules() method that returns client validation rules for that class. So first I created an object of ModelClientValidationRule class and set the values for 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 property is set to whatever is 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 which are ‘min’ and ‘max’, and these parameters will be sent to my jQuery validbirthdate function.
Next I 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().
This method takes 3 parameters – value, element, params.
In the jQuery.validator.addMethod() I wrote my jQuery code that extracts the min and max parameters values. Then check if the value of the date in birthDate control is between them or not. If it is in between them, then I return ‘true’ else return ‘false’.
This method links jQuery Unobtrusive Validation plugin with the validbirthdate method and shows the client side error message. It has 3 parameter –
a. name of jQuery function
b. name of parameters passed
c. 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.
If you run you application and inspect the birthDate control with Chrome Developer Tools in the browser, then you will see the html of the control has some data attributes added to it. It’s 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 & 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 the ClientValidationEnabled & UnobtrusiveJavaScriptEnabled in my view.
The data attributes stores the information to perform the client side validation. That’s the reason you only need little jQuery code besides attributes to do jQuery Validations.
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 set 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 neither M nor 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.
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 the 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.
In order to validate user’s skills so that he should select at least 3 skills (this is a collection property and not a simple one). So 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 I show 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.
I have given a CKEditor for ‘PreviousJobDescription’ property. The CKEditor hides the text area and it it’s 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 custom jQuery code in the View:
$("#submitButton").click(function () {
$("#previousJobDescription").show();
CKupdate();
});
function CKupdate() {
CKEDITOR.instances["previousJobDescription"].updateElement();
}
Run your project and then click the submit button. You will find all Client Side Validation Error messages shown to you. Check the download link given below: