jquery - ASP.Net MVC 3 ViewModel, unobtrusive JavaScript and custom validation -
i'm trying write custom validation method in app - have working server side, i'm trying extend implements in unobtrusive javascript client side validation. i'm using viewmodel well, added fun.
here's have trivial test - it's pretty simple - child object has 3 fields - custom validation i'm writing @ least 1 of fields must filled in (obviously actual app has more complex model this):
model:
public class child { public int id { get; set; } [musthavefavouritevalidator("favouritepudding", "favouritegame")] public string favouritetoy { get; set; } public string favouritepudding { get; set; } public string favouritegame { get; set; } }
viewmodel:
public class childviewmodel { public child thechild { get; set; } }
controller:
public actionresult create() { var childviewmodel = new peopleagegroups.viewmodels.childviewmodel(); return view(childviewmodel); }
i've followed documentatation can find online , whipped custom validator looks this:
public class musthavefavouritevalidator:validationattribute, iclientvalidatable { private const string defaulterror = "you must have 1 favourite"; public string firstotherfavourite { get; set; } public string secondotherfavourite { get; set; } public musthavefavouritevalidator(string firstfave, string secondfave) : base(defaulterror) { firstotherfavourite = firstfave; secondotherfavourite = secondfave; } public override string formaterrormessage(string name) { return string.format(errormessagestring, name, firstotherfavourite, secondotherfavourite); } protected override validationresult isvalid(object value, validationcontext validationcontext) { var afavouriteobject = validationcontext.objectinstance.gettype().getproperty(firstotherfavourite); var bfavouriteobject = validationcontext.objectinstance.gettype().getproperty(secondotherfavourite); var afavourite = afavouriteobject.getvalue(validationcontext.objectinstance, null); var bfavourite = bfavouriteobject.getvalue(validationcontext.objectinstance, null); if(value==null && afavourite ==null && bfavourite == null){ return new validationresult(formaterrormessage(validationcontext.displayname), new[] { validationcontext.membername, afavouriteobject.name, bfavouriteobject.name }); } return validationresult.success; } public ienumerable<modelclientvalidationrule> getclientvalidationrules(modelmetadata metadata, controllercontext context) { return new[] { new musthavefavourite(formaterrormessage(metadata.getdisplayname()), firstotherfavourite, secondotherfavourite) }; } }
good stuff, server side validation works. next have model client validation rule:
public class musthavefavourite : modelclientvalidationrule { public musthavefavourite(string errormessage, string firstotherfavourite, string secondotherfavourite) { errormessage = errormessage; validationtype = "musthavefavourite"; validationparameters.add("firstotherfavourite", firstotherfavourite); validationparameters.add("secondotherfavourite", secondotherfavourite); } }
and finally, custom javascript tie together:
(function ($) { jquery.validator.addmethod("musthavefavourite", function (value, element, params) { var $firstotherfavouriteobject = $('#' + params.firstotherfavourite); var firstotherfavourite = $firstotherfavouriteobject.val(); var $secondotherfavouriteobject = $('#' + params.secondotherfavourite); var secondotherfavourite = $secondotherfavouriteobject.val(); if (value == '' && firstotherfavourite == '' && secondotherfavourite == '') { return false; } else { return true; } }); $.validator.unobtrusive.adapters.add("musthavefavourite", ["firstotherfavourite", "secondotherfavourite"], function (options) { options.rules['musthavefavourite'] = { firstotherfavourite: options.params.firstotherfavourite, secondotherfavourite: options.params.secondotherfavourite }; options.messages['musthavefavourite'] = options.mesage; } ); } (jquery));
the problem occurs in generated html, text elements have id prefixed "thechild_" - makes sense since viewmodel declares child object, however, custom function doesn't have prefix on element names. there way pass prefix through javascript without hacking this:
jquery.validator.addmethod("musthavefavourite", function (value, element, params) { var $firstotherfavouriteobject = $('#thechild_' + params.firstotherfavourite); var firstotherfavourite = $firstotherfavouriteobject.val();
which mind kind of defeats idea of creating validation serverside , hooking gumf go through unobtrusive validation since i've created piece of javascript can used combination of form/viewmodel combination.
you can modify validator check prefix, , add prefix selector elements checked, outline in answer question: mvc3 custom validation: compare 2 dates. need either (1) change selectors search name, instead of id, or (2) split id using _
instead of .
.
Comments
Post a Comment