---
title: "jQuery Validate and Jeditable, Part 2"
date: 2010-01-02T23:47:00-06:00
slug: jquery-validate-and-jeditable-part-2
published: true
---

When using [Jeditable](http://www.appelsiini.net/projects/jeditable), there is no form element to bind [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) rules with.  Instead, when an editable element is clicked or activated, it dynamically creates a new form and input element and destroys them after the user is done editing.  For the ViewModel from [Part 1](/2010/01/01/jQueryValidateAndJeditablePart1.aspx), the View might be rendered like so for [Jeditable](http://www.appelsiini.net/projects/jeditable):

```
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<ValidateViewModel>" %>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<% using(Html.BeginForm()) {%>
    <%= Html.ValidationSummary() %>
    <label for="StringRequired">StringRequired:</label>
    <div class="editable" id="StringRequired" name="StringRequired">
        <%= Model.StringRequired %>
    </div>
    
    <label for="DoubleRange13_100">DoulbeRange13_100:</label>
    <div class="editable" id="DoubleRange13_100" name="DoubleRange13_100">
        <%= Model.DoubleRange13_100%>
    </div>
<%} %>
</asp:Content>
```

[xVal](http://xval.codeplex.com/)’s `ClientSideValidation<TViewModel>()` used in [Part 1](/2010/01/01/jQueryValidateAndJeditablePart1.aspx) won’t work to validate this.  The reason?  It generates a script that binds validation directly to the form elements on page load.  The rendered script looks for the ViewModel looks like:

```
<script type="text/javascript">
xVal.AttachValidator(null, 
    {"Fields":[
      {
         "FieldName":"StringRequired",
         "FieldRules":[
            {
               "RuleName":"Required",
               "RuleParameters":{

               },
               "Message":"This string is required"
            },
            {
               "FieldName":"DoubleRange13_100",
               "FieldRules":[
                  {
                     "RuleName":"Range",
                     "RuleParameters":{
                        "Min":"13",
                        "Max":"100",
                        "Type":"decimal"
                     },
                     "Message":"Must be between 13 and 100"
                  }
               ]
            }
         ]
      }
    ]}, {})
</script>
```

The rules are in the xVal’s StandardJSON format and the `AttachValidator` function (in `xVal.jquery.validate.js`) scans the DOM and attaches [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) rules as attributes to the matched input elements.  Since [Jeditable](http://www.appelsiini.net/projects/jeditable) doesn’t create these elements until they’re actively being edited, the rules have nothing to attach to since they don’t exist yet.  Fortunately, [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) provides several strategies for defining the rules.  In addition to being able to attach attributes to the input elements, the rules can be placed in a separate data structure.  [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) refers to these as “static rules”.  Instead of attaching the xVal rule set directly to the elements, it can be adapted to the static rule set that [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) can use directly.  The structure for the ViewModel rules will look like: 

```
{
    rules: {
        StringRequired: {
            required: true
        },
        DoubleRange13_100: {
            number: true,
            range: ["13”, "100"]
        }
    }
    messages: {
        StringRequired: {
            required: "This string is required."
        },
        DoubleRange13_100: {
            range: "Must be between 13 and 100"
        }
    }
}

```

I've adapted some javascript to do this conversion - it's available [here](../media/images/jQueryValidateandJeditable_E71E/xValRuleAdapter.js).  To get the ViewModel’s rules into this format for javascript consumption, this line is added:

```
<script type="text/javascript">
    var validateOptions 
        = convertXvalToValidateOptions(
            <%= Html.ClientSideValidationRules<ValidateViewModel>()%>
        );
</script>

```

  

To get these attached to form elements as soon as the user activates them, [Jeditable](http://www.appelsiini.net/projects/jeditable)’s “plugin” feature is utilized:

```
$(function() { // <- on document ready
    // register plugin with Jeditable to tie in jQuery Validate
    $.editable.types['text'].plugin = bindValidate;
    
    // attach Jeditable to each element with class "editable"
    // Note: this must be done one-by-one so that the 
    // element's name can be assigned to Jeditable's "name" 
    // option which is used by jQuery Validate
    $('.editable').each(function() {
        var element = $(this);
        
        element.editable(
            'SaveUrlOrFunctionGoesHere',
            {
                // submit when the element is blurred
                onblur: 'submit',
                onsubmit: jeditableValidate,
                // assign the name of the input element 
                // from the element's name - this is needed 
                // because it's what jQuery Validate uses 
                // to bind the rules to the input element
                name: element.attr('name')
            }
        );
    });
});

// Jeditable plugin
function bindValidate(settings, self) {
    // attach jQuery Validate to 
    // Jeditable's dynamically created form
    $('form', self).validate(validateOptions);
}

// runs before values are submitted to server
function jeditableValidate(settings, self) {
    // validate the Jeditable dynamically created form
    return $('form', self).valid();
}

```

With this glue in place, the form elements will now be validated with the rules defined in the ViewModel.  All fields valid:

[![jQueryValidateJeditable1](../media/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable1_thumb.png)](../media/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable1.png)

…and here after both have invalid values:

[![jQueryValidateJeditable2](../media/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable2_thumb.png)](../media/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable2.png)

A few notes:

- Any additional options to be sent to [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) can be attached to the `validateOptions` object. I’ve used this to place all error messages into a separate `errorLabelContainer` (like [here](http://stackoverflow.com/questions/61456/mvc-net-jquery-validation)). 

- I feel that AttachValidator function in `xVal.jquery.validate.js` from could become more loosely coupled by separating the rule conversion from the DOM element attachment.

I think both of these jQuery libraries provide a great benefit when creating interactive and helpful forms.  Kudos to [Jörn Zaefferer](http://bassistance.de/) and [Mika Tuupola](http://www.appelsiini.net/) for the good work.  xVal is likewise an excellent library – thanks to [Steve Sanderson](http://www.codeplex.com/site/users/view/SteveSanderson).