views:

249

answers:

2

I'm developing a web application using ASP .NET MVC 1.0 and jQuery (including the validation plugin). The server-side markup for a typical "edit entity" view is as follows

<label for="FirstName">FirstName:</label>
<%= Html.TextBox("FirstName", Model.FirstName) %>
<%= Html.ValidationMessage("FirstName") %>

When invalid data is posted to the FirstName field, the resulting HTML is

<label for="FirstName">FirstName:</label>
<input type="text" value="" name="FirstName" id="FirstName" class="input-validation-error text">
<span class="field-validation-error">Please enter the first name.</span>

Which is exactly what you would expect from ASP .NET MVC out of the box.

I am now adding client-side validation with jQuery, and would like it to behave in exactly the same way - i.e. the input control is given a class of input-validation-error and a span is added with a class of field-validation-error, for showing the error message.

I'm almost there, but not quite. Using the errorElement option gets the validator to create a span for the error message, rather than a label. Using the errorClass option means that the input element is given a class of input-validation-error.

The problem I've got is that the error message span also gets a class of input-validation-error, and I want it to have field-validation-error.

I've tried using the highlight and unhighlight functions to correct this, but as soon as I start messing with the classes on the span, the validation itself stops working and just posts the form to the server.

Anyone out there got any ideas as to how I can fix this? Thanks.

+1  A: 

Checkout the errorPlacement callback:

$('form').validate({
    errorClass: 'input-validation-error',
    errorElement: 'span',
    errorPlacement: function(error, element) {
        // Insert and manipulate the span element here:
        error.insertAfter(element)
             .removeClass('input-validation-error')
             .addClass('field-validation-error');
    },          
    rules: {
        FirstName: { 
            required: true 
        }
    },
    messages: {
        FirstName: {
            required: 'Please enter the first name.'    
        }
    }
});
Darin Dimitrov
Thanks for this, it pointed me in the right direction.
gilles27
A: 

Looks like the problem I was having was caused by fiddling with the class applied to the input and error elements. The plugin looks for elements with that class in order to show or hide the error message, and also when counting how many invalid elements there are.

To avoid these problems, I stopped using the errorClass: 'input-validation-error' line shown in Darin's answer, and left that as its default value. In the errorPlacement function, I attach the right class to both the error and input elements, as well as inserting the message in the right place in the DOM. This all seems to work now. The JavaScript is as follows

$('form').validate({
errorElement: 'span',
errorPlacement: function(error, element) {
    error.insertAfter(element);
    error.addClass('field-validation-error');
    element.addClass('input-validation-error');
},          
rules: {
    FirstName: { 
        required: true 
    }
},
messages: {
    FirstName: {
        required: 'Please enter the first name.'    
    }
}

});

Thanks to Darin for his input as it pointed me in the right direction.

gilles27
When working on a slightly different example to this, I also ran into a problem with the field-validation-error class being removed. I fixed it by changing part of line 621 from label.removeClass() to label.removeClass( this.settings.errorClass ). I'm using version 1.6 of the plugin, non-minified.
gilles27