Files
popcyclical-blog-archive/posts/2010-01-02-jquery-validate-and-jeditable-part-2.md
T

139 lines
7.3 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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) wont 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 xVals 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) doesnt create these elements until theyre actively being edited, the rules have nothing to attach to since they dont 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](http://popcyclical.com/content/binary/images/jQueryValidateandJeditable_E71E/xValRuleAdapter.js).  To get the ViewModels 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](http://popcyclical.com/content/binary/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable1_thumb.png)](http://popcyclical.com/content/binary/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable1.png)
…and here after both have invalid values:
[![jQueryValidateJeditable2](http://popcyclical.com/content/binary/images/jQueryValidateandJeditable_E71E/jQueryValidateJeditable2_thumb.png)](http://popcyclical.com/content/binary/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. Ive 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).