Reputation: 59
I have a View that contains a ParentModel, which contains 2 Models. I only want to validate the fields of one or the other. Not both. Let´s say I have:
public ParentModel{
public BlueUser BlueUser {get; set;}
public GreenUser GreenUser {get; set;}
}
So the user selects either he is a GreenUser or a BlueUser. Each type of user has different fields, and depending which type of User the user selects, I want to only validate the fields on that specific type of user. How can this be achieved?
EDIT: Both forms/models must be on the same View, maybe with some JQuery or Partials?
Upvotes: 2
Views: 2429
Reputation: 3212
Server side implementation
You should have two forms on view.
Each forms should goes to different action in controller on post.
Client side implementation for animation
Upvotes: 0
Reputation: 28608
Create one form with HtmlHelper<BlueUser>
and the other with HtmlHelper<GreenUser>
, and make them post to different actions.
First, the view model is:
@model ParentModel
Then use HtmlHelperFor
to create an HtmlHelper for each of the submodels:
@{
var blueHtml = Html.HtmlHelperFor(Model.BlueUser);
var greenHtml = Html.HtmlHelperFor(Model.GreenUser);
}
@using (blueHtml.BeginForm("BluePost", null)) {
@blueHtml.EditorForModel()
}
@using (greenHtml.BeginForm("GreenPost", null)) {
@greenHtml.EditorForModel()
}
Lastly, in the controller create a diferent POST action for each form:
[HttpPost]
public ActionResult BluePost(BlueUser model) {
...
}
[HttpPost]
public ActionResult GreenPost(GreenUser model) {
...
}
Here's the extension method:
public static class HtmlHelperFactoryExtensions {
public static HtmlHelper<TModel> HtmlHelperFor<TModel>(this HtmlHelper htmlHelper) {
return HtmlHelperFor(htmlHelper, default(TModel));
}
public static HtmlHelper<TModel> HtmlHelperFor<TModel>(this HtmlHelper htmlHelper, TModel model) {
return HtmlHelperFor(htmlHelper, model, null);
}
public static HtmlHelper<TModel> HtmlHelperFor<TModel>(this HtmlHelper htmlHelper, TModel model, string htmlFieldPrefix) {
var viewDataContainer = CreateViewDataContainer(htmlHelper.ViewData, model);
TemplateInfo templateInfo = viewDataContainer.ViewData.TemplateInfo;
if (!String.IsNullOrEmpty(htmlFieldPrefix))
templateInfo.HtmlFieldPrefix = templateInfo.GetFullHtmlFieldName(htmlFieldPrefix);
ViewContext viewContext = htmlHelper.ViewContext;
ViewContext newViewContext = new ViewContext(viewContext.Controller.ControllerContext, viewContext.View, viewDataContainer.ViewData, viewContext.TempData, viewContext.Writer);
return new HtmlHelper<TModel>(newViewContext, viewDataContainer, htmlHelper.RouteCollection);
}
static IViewDataContainer CreateViewDataContainer(ViewDataDictionary viewData, object model) {
var newViewData = new ViewDataDictionary(viewData) {
Model = model
};
newViewData.TemplateInfo = new TemplateInfo {
HtmlFieldPrefix = newViewData.TemplateInfo.HtmlFieldPrefix
};
return new ViewDataContainer {
ViewData = newViewData
};
}
class ViewDataContainer : IViewDataContainer {
public ViewDataDictionary ViewData { get; set; }
}
}
Upvotes: 8
Reputation: 5313
solution 1
what you do is use Dependency validation , its not built in by default, only the Compare
attribute, you can build your own attributes, like required if radio button value was something or you could use something like Mvc.ValidationTookit
solution 2
when the user choose blue user for example you use javascript to check in the form submit event what did he choose depending on what he choose you will direct him to different actions with appropriate model passed as parameter
Upvotes: 0