Skip to content

Instantly share code, notes, and snippets.

@avipinto
Created July 4, 2011 12:23
Show Gist options
  • Save avipinto/1063281 to your computer and use it in GitHub Desktop.
Save avipinto/1063281 to your computer and use it in GitHub Desktop.
MicrosoftMvcJQueryValidation.js patched so validations will work when moving from MVC2 to MVC3 + added MVC_BindClientValidation to enable rebind when returning a new form via ajax
/// <reference path="jquery-1.6.1.js" />
/// <reference path="jquery.validate.js" />
// register custom jQuery methods
jQuery.validator.addMethod("regex", function(value, element, params) {
if (this.optional(element)) {
return true;
}
var match = new RegExp(params).exec(value);
return (match && (match.index == 0) && (match[0].length == value.length));
});
// glue
function __MVC_ApplyValidator_Range(object, min, max) {
object["range"] = [min, max];
}
function __MVC_ApplyValidator_RegularExpression(object, pattern) {
object["regex"] = pattern;
}
function __MVC_ApplyValidator_Required(object) {
object["required"] = true;
}
function __MVC_ApplyValidator_StringLength(object, maxLength) {
object["maxlength"] = maxLength;
}
function __MVC_ApplyValidator_Unknown(object, validationType, validationParameters) {
object[validationType] = validationParameters;
}
function __MVC_CreateFieldToValidationMessageMapping(validationFields) {
var mapping = {};
for (var i = 0; i < validationFields.length; i++) {
var thisField = validationFields[i];
mapping[thisField.FieldName] = "#" + thisField.ValidationMessageId;
}
return mapping;
}
function __MVC_CreateErrorMessagesObject(validationFields) {
var messagesObj = {};
for (var i = 0; i < validationFields.length; i++) {
var thisField = validationFields[i];
var thisFieldMessages = {};
messagesObj[thisField.FieldName] = thisFieldMessages;
var validationRules = thisField.ValidationRules;
for (var j = 0; j < validationRules.length; j++) {
var thisRule = validationRules[j];
if (thisRule.ErrorMessage) {
var jQueryValidationType = thisRule.ValidationType;
switch (thisRule.ValidationType) {
case "regularExpression":
case "regex":
jQueryValidationType = "regex";
break;
case "stringLength":
case "length":
jQueryValidationType = "maxlength";
break;
}
thisFieldMessages[jQueryValidationType] = thisRule.ErrorMessage;
}
}
}
return messagesObj;
}
function __MVC_CreateRulesForField(validationField) {
var validationRules = validationField.ValidationRules;
// hook each rule into jquery
var rulesObj = {};
for (var i = 0; i < validationRules.length; i++) {
var thisRule = validationRules[i];
switch (thisRule.ValidationType) {
case "range": //new
var min = thisRule.ValidationParameters["minimum"] || thisRule.ValidationParameters["min"],
max = thisRule.ValidationParameters["maximum"] || thisRule.ValidationParameters["max"];
__MVC_ApplyValidator_Range(rulesObj, min, max);
break;
case "regularExpression":
case "regex": //new
__MVC_ApplyValidator_RegularExpression(rulesObj,
thisRule.ValidationParameters["pattern"]);
break;
case "required":
__MVC_ApplyValidator_Required(rulesObj);
break;
case "stringLength":
__MVC_ApplyValidator_StringLength(rulesObj,
thisRule.ValidationParameters["maximumLength"]);
break;
case "length"://new
__MVC_ApplyValidator_StringLength(rulesObj,
thisRule.ValidationParameters["max"]);
break;
default:
__MVC_ApplyValidator_Unknown(rulesObj,
thisRule.ValidationType, thisRule.ValidationParameters);
break;
}
}
return rulesObj;
}
function __MVC_CreateValidationOptions(validationFields) {
var rulesObj = {};
for (var i = 0; i < validationFields.length; i++) {
var validationField = validationFields[i];
var fieldName = validationField.FieldName;
rulesObj[fieldName] = __MVC_CreateRulesForField(validationField);
}
return rulesObj;
}
//if we don't add a ValidationMessageFor for fields with no validation, jQuery.Validate will crash onBlur from these fields
//so we must add the class=noValidation to the fields - we will add empty rulles for it
function __MVC_AddDummiesForFieldsWithNoValidation(validationContext)
{
var theForm = $("#" + validationContext.FormId);
var fieldsWithNoValidation = theForm.find(".noValidation");
for (var idx = 0; idx < fieldsWithNoValidation.length; ++idx)
{
validationContext.Fields.push({ FieldName: fieldsWithNoValidation.eq(idx).attr("name"), ValidationRules: [] });
}
}
function __MVC_EnableClientValidation(validationContext) {
// this represents the form containing elements to be validated
var theForm = $("#" + validationContext.FormId);
__MVC_AddDummiesForFieldsWithNoValidation(validationContext);
var fields = validationContext.Fields;
var rulesObj = __MVC_CreateValidationOptions(fields);
var fieldToMessageMappings = __MVC_CreateFieldToValidationMessageMapping(fields);
var errorMessagesObj = __MVC_CreateErrorMessagesObject(fields);
var options = {
errorClass: "input-validation-error",
errorElement: "span",
errorPlacement: function(error, element) {
var messageSpan = fieldToMessageMappings[element.attr("name")];
$(messageSpan).empty();
$(messageSpan).removeClass("field-validation-valid");
$(messageSpan).addClass("field-validation-error");
error.removeClass("input-validation-error");
error.attr("_for_validation_message", messageSpan);
error.appendTo(messageSpan);
},
messages: errorMessagesObj,
rules: rulesObj,
success: function(label) {
var messageSpan = $(label.attr("_for_validation_message"));
$(messageSpan).empty();
$(messageSpan).addClass("field-validation-valid");
$(messageSpan).removeClass("field-validation-error");
}
};
// register callbacks with our AJAX system
var formElement = document.getElementById(validationContext.FormId);
var registeredValidatorCallbacks = formElement.validationCallbacks;
if (!registeredValidatorCallbacks) {
registeredValidatorCallbacks = [];
formElement.validationCallbacks = registeredValidatorCallbacks;
}
registeredValidatorCallbacks.push(function() {
theForm.validate();
return theForm.valid();
});
theForm.validate(options);
}
// need to wait for the document to signal that it is ready
$(document).ready(function ()
{
MVC_BindClientValidation();
});
//added this to enable binding the validation to form fields when the entire form was returned via ajax + it's validation rule object
function MVC_BindClientValidation()
{
var allFormOptions = window.mvcClientValidationMetadata;
if (allFormOptions)
{
while (allFormOptions.length > 0)
{
var thisFormOptions = allFormOptions.pop();
__MVC_EnableClientValidation(thisFormOptions);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment