Files
popcyclical-blog-archive/posts/2009-12-31-jquery-validate-and-jeditable-part-1.md
T

83 lines
5.5 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 1"
date: 2009-12-31T21:32:00-06:00
slug: jquery-validate-and-jeditable-part-1
published: true
---
I was recently tasked to add server-and-client-side form validation for an ASP.NET MVC site - which already uses in-place editing courtesy [Jeditable](http://www.appelsiini.net/projects/jeditable).  I really like the field editing experience that Jeditable provides it makes form entry in the browser interactive, is fairly straightforward to integrate, and its adaptable to many scenarios.  It does not, however, have any validation mechanism built in. 
Our project already used [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) for a few forms by using the HTML class definitions like adding class=”required phone” to an INPUT element.  This works great, but doesnt provide any server-side validation tie-in.
Earlier this year, I remembered having seen a [presentation](http://speakerrate.com/talks/1218-useful-jquery-tips-tricks-and-plugins-with-asp-net-mvc) by [Elijah Manor](http://elijahmanor.com/) who mentioned using [xVal](http://xval.codeplex.com/) for robust server and client side validation. And with the news that [MVC 2 will have a built in validation technique similar to xVal](http://haacked.com/archive/2009/10/01/asp.net-mvc-preview-2-released.aspx), it was an easy decision to start investigating this library.
[xVal](http://xval.codeplex.com/) is a pretty easy to get integrated.  The first step is to decorate the model with validation rules Ive decided to use .NET frameworks [DataAnnotations](http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.aspx), which ends up looking like:public class ValidateViewModel
{
[Required(ErrorMessage = "This string is required")]
public string StringRequired { get; set; }
[Range(13, 100, ErrorMessage = "Must be between 13 and 100")]
public double DoubleRange13_100 { get; set; }
}public class ValidatedController
{
public ViewResult Index()
{
return View(new ValidateViewModel());
}
}<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<ValidateViewModel>" %>
<asp:Content ContentPlaceHolderID="MainContent" runat="server">
<% using(Html.BeginForm()) {%>
<%= Html.ValidationSummary() %>
<label for="StringRequired">String Required:</label>
<%= Html.TextBoxFor(m => m.StringRequired) %>
<%= Html.ValidationMessageFor(m => m.StringRequired)%>
<label for="DoubleRange13_100">Doulbe between 13 and 100:</label>
<%= Html.TextBoxFor(m => m.DoubleRange13_100) %>
<%= Html.ValidationMessageFor(m => m.DoubleRange13_100)%>
<%} %>
</asp:Content>
To validate this ViewModel server side, we use a [DataAnnotationsValidationRunner](http://blog.codeville.net/2009/01/10/xval-a-validation-framework-for-aspnet-mvc/) like the one in xVals documentation:[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update(ValidateViewModel model)
{
try {
DataAnnotationsValidationRunner.ValidateModel(model);
// its valid, do the actual update
var domainObject = ValidateDomainModel.Find(model.id);
Map(model, domainObject);
domainObject.Update();
}
catch(RulesException ex) {
ex.AddModelStateErrors(ModelState, null);
}
return ModelState.IsValid ? RedirectToAction("Completed")
: (ActionResult) View();
}public static class DataAnnotationsValidationRunner
{
private static IEnumerable<ErrorInfo> GetErrors(object instance)
{
return from prop in TypeDescriptor.GetProperties(instance).Cast<PropertyDescriptor>()
from attribute in prop.Attributes.OfType<ValidationAttribute>()
where !attribute.IsValid(prop.GetValue(instance))
select new ErrorInfo(prop.Name, attribute.FormatErrorMessage(String.Empty), instance);
}
/// <summary>Validates the given <param name="model">model</param></summary>
/// <exception cref="RulesException">Thrown if any errors are found</exception>
public static void ValidateModel(object model)
{
var errors = GetErrors(model);
if (errors.Any())
throw new RulesException(errors);
}
}
*Aside: the project uses the *[*Active record pattern*](http://en.wikipedia.org/wiki/Active_record_pattern)* via *[*Castle ActiveRecord*](http://www.castleproject.org/activerecord/index.html)* for data access without an intermediate business-logic layer.  For this case, the rules are defined on the ViewModel and are validated in the controller.  This does add some noise in the actions Im definitely interested in other methods for handling this. Such as - perhaps the validation could be placed inside the ViewModel?*
The next step is to add client-side validation.  [xVal](http://xval.codeplex.com/)s built-in [jQuery Validate](http://bassistance.de/jquery-plugins/jquery-plugin-validation/) rule generator makes this ridiculously simple just reference jquery.validate.js and xVal.jquery.validate.js in the view, and then this single line:<%= Html.ClientSideValidation<ValidateViewModel>() %>
The rules defined in the ViewModel will now be validated client side and enforced for server side actions.  This works great for a statically defined HTML form, but I learned that integrating with [Jeditable](http://www.appelsiini.net/projects/jeditable)s dynamic inline forms to be not so straight forward.
Continued in [Part 2](/2010/01/03/jQueryValidateAndJeditablePart2.aspx)…