Reputation: 1891
I have the following class used for custom validation:
[AttributeUsage(AttributeTargets.Property, AllowMultiple=false, Inherited=true)]
public sealed class RequiredIfAnyTrueAttribute : ValidationAttribute, IClientValidatable
{
private const string DefaultErrorMessage = "{0} is required";
public List<string> OtherProperties { get; private set; }
public RequiredIfAnyTrueAttribute(string otherProperties)
: base(DefaultErrorMessage)
{
if (string.IsNullOrEmpty(otherProperties))
throw new ArgumentNullException("otherProperty");
OtherProperties = new List<string>(otherProperties.Split(new char[] { '|', ',' }));
}
public override string FormatErrorMessage(string name)
{
return string.Format(ErrorMessageString, name);
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value == null)
{
foreach (string s in OtherProperties)
{
var otherProperty = validationContext.ObjectType.GetProperty(s);
var otherPropertyValue = otherProperty.GetValue(validationContext.ObjectInstance, null);
if (otherPropertyValue.Equals(true))
return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
}
}
return ValidationResult.Success;
}
public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context)
{
var clientValidationRule = new ModelClientValidationRule()
{
ErrorMessage = FormatErrorMessage(metadata.GetDisplayName()),
ValidationType = "requiredifanytrue"
};
clientValidationRule.ValidationParameters.Add("otherproperties", string.Join("|",OtherProperties));
return new[] { clientValidationRule };
}
}
My ViewModel is:
public class SampleViewModel
{
public bool PropABC { get; set; }
public bool PropXYZ { get; set; }
[RequiredIfAnyTrue("PropABC|PropXYZ")]
public int? TestField { get; set; }
}
When my strongly typed view renders, everything sees to work fine. If PropABC or PropXYZ is selected then I am required to enter a value for TestField. Both client and server-side validation is functional.
However, given the following sequence of events:
In order to resolve #5 I would typically attach click events to the checkboxes via jquery onready to refire the validation.
Is there a preferred/recommended way to manually force client-side validation given MVC3 + unobstrusive + jquery?
Upvotes: 0
Views: 1894
Reputation: 131
FoolProof is still in beta and does not work with nested viewmodel, also with arrays
Upvotes: 0
Reputation: 10924
Shawn, attaching to events is the best approach to get validation to refire.
I would suggest creating a class called "validate" (or something along those lines), adding it to each element to be validated, and then use jQuery to attach to the click and blur events (and possibly the change event) of each element with that class, and validate the element like so:
$("form").validate().element(this);
Upvotes: 1
Reputation: 11341
Do you need to write your own attributes? If not I think you may be able to avoid "reinventing the wheel"
FoolProof works great. you get get it as a NuGet package.
NuGet: install-package foolproof
It includes a lot of greate attributes for various combinations of on-the-fly required fields and such.
Upvotes: 1