Consistent validation with ASP .NET MVC and jQuery

Consistent validation with ASP .NET MVC and jQuery

Recently I have been developing a couple of small web applications with version 1 of ASP .NET MVC, using jQuery’s validation plugin to provide a better client-side experience. As some of you may be aware, the validation features in the first release of MVC were sparse, although Phil and the team have certainly corrected this with the recent second version.

One aim I had with my validation features was to deliver consistent behaviour and appearance between client and server, so that users would get the same experience whether they had scripting turned on or off. It proved a little awkward at first, but I got there in the end, so thought I would post the results to my blog in case anyone else is trying to do the same.

When creating a strongly-typed view, MVC provides templates for common scenarios, e.g. Create, Edit, Details and so on. This gives the developer a head start and removes the need for a lot of monotonous coding. The server-side markup it generates for each field in the Create and Edit views is similar to the following

<label for=”FirstName”>FirstName:</label> <%= Html.TextBox(“FirstName”) %> <%= Html.ValidationMessage(“FirstName”)

As you can see, each property of the model (in this case, the first name of a person) gets a label, an input control for editing its value, and any validation messages linked to the field are shown next to it. When this is rendered to the client, we get HTML like this

<label for=”FirstName”>FirstName:</label> <input class=”input-validation-error” id=”FirstName” name=”FirstName” type=”text” value=”” /> <span class=”field-validation-error”>First name must be entered.</span>

Whilst jQuery’s validation provides similar results straight out of the box, it’s not quite what I need. For starters, it uses a label to show the error message, whereas MVC uses a span. This is easily corrected by using the errorElement option of the plugin. So the script for the validator now looks like this

$().ready(function() {   $(‘form’).validate({       errorElement: ‘span’,       rules: { FirstName: { required: true } },       messages: { FirstName: { required: ‘Please enter the first name.’ } }   }); });

However that left me with a tricky problem – the input and error elements don’t have the correct classes attached to them, so the styling rules are not being applied. As you can see from the earlier markup, MVC applies the field-validation-error class to the element containing the error message, and the input-validation-error class to the element containing the invalid value. This is different to the jQuery plugin, which applies the error class to both elements.

Initially I tried playing around with the errorClass option, but could only get one or other of the correct classes applied. In the end I used the highlight and unhighlight functions, which are called when an error message is shown or hidden, respectively. By default, highlight adds the errorClass to the input element, and also removes the validClass. The validClass (valid by default) allows you to style the element to indicate that it contains valid input. My custom implementation of highlight continues to do this, but adds another couple of lines to apply the correct classes to the input element and the error message span. The JavaScript looks like this

highlight: function(element, errorClass, validClass) {   $(element).addClass(errorClass).removeClass(validClass);   $(element).addClass(‘input-validation-error’);   $(element.form).find(‘span[for=’ + element.id + ‘]’)     .addClass(‘field-validation-error’);}

The unhighlight function just does the reverse; I’ve omitted it for the sake of brevity here. I’ve been using this code for a while now and it seems to have had the desired effect. This is a great example of how flexible many of jQuery’s plugins are, as well as providing excellent functionality out of the box.

The sample code for this is available here, I’ve also included a slight change which ensures the validClass is applied correctly if you are targeting styles for it.

Leave a Comment