I have a Model that as one of its properties has a list of child models. In my view each child model is validated separately using custom client side validation. Everything is being validated correctly, and the correct validation messages are being displayed.
The only thing is, I have a lot of these child models and editors on screen at a time, and need to make the invalid editors stand out a bit more, by giving the surrounding div a red outline for example (not just the input as is default).
So I need to detect the validity of the child models within their partials views and append the appropriate CSS class to the div. I have read in several places that this can be done with Html.ViewData.ModelState.IsValid
but this seems to pick up on whether or not the ParentModel and ALL the ChildModels are valid or not.
Here is an example of my ParentModel, ChildModel, View for the parent, and partial view for the ChildModels:
public class ChildModel
{
public Guid Child_Id { get; set; }
public List<Guid> Selected_Ids { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
List<ValidationResult> Errors = new List<ValidationResult>();
if (this.Selected_Ids == null || !this.Selected_Ids.Any())
{
Errors.Add(new ValidationResult("You must select at least one id.", new List<string> { "Selected_Ids" }));
}
return Errors;
}
}
public class ParentModel
{
public Guid Parent_Id { get; set; }
public List<ChildModel> Children { get; set; }
public List<Guid> Available_Ids { get; set; }
}
@* View *@
@model ParentModel
<div>
@using(Html.BeginForm())
{
@Html.HiddenFor(m => m.Parent_Id)
@Html.EditorFor(m => m.Children, new { Model.Available_Ids })
<button type="submit">Save</button>
}
</div>
@* Partial View / Editor Template *@
@model ChildModel
@ {
List<Guid> Available_Ids = (List<Guid>)ViewData["Available_Ids"];
}
<div class='child_model @(Html.ViewData.ModelState.IsValid ? string.Empty : "Invalid")'>
@Html.HiddenFor(m => m.Child_Id)
@foreach(Guid Available_Id in Available_Ids)
{
@Html.CheckBoxFor(m => m.Selected_Ids, Available_Id.ToString())
}
</div>