Click here to Skip to main content
12,458,167 members (54,499 online)
Click here to Skip to main content
Add your own
alternative version

Tagged as

Stats

14.5K views
1 bookmarked
Posted

jQuery Validate and Jeditable, Part 2

, 4 Jan 2010 CPOL
Rate this:
Please Sign up or sign in to vote.
When using Jeditable,there is no form element to bind jQueryValidate 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 useris done editing.

When using Jeditable, there is no form element to bind jQuery Validate 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, the View might be rendered like so for 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’s ClientSideValidation<TViewModel>() used in Part 1 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 rules as attributes to the matched input elements.  Since 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 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 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 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

.  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’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', cell).valid();
}

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

jQueryValidateJeditable1

…and here after both have invalid values:

jQueryValidateJeditable2

A few notes:

  • Any additional options to be sent to jQuery Validate can be attached to the validateOptions object. I’ve used this to place all error messages into a separate errorLabelContainer (like here).
  • 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 and Mika Tuupola for the good work.  xVal is likewise an excellent library – thanks to Steve Sanderson.



License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

James Kolpack
Software Developer (Senior)
United States United States
No Biography provided

You may also be interested in...

Pro
Pro

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.160826.1 | Last Updated 4 Jan 2010
Article Copyright 2010 by James Kolpack
Everything else Copyright © CodeProject, 1999-2016
Layout: fixed | fluid