I have a form that contains 3 distinct sections that looks something like this:
<form action="/Submit/" method="POST">
<h2>
Your Info:
</h2>
<ul>
<li>
<label>
First Name:
@Html.TextBoxFor(m => m.FirstName)
</label>
</li>
<li>
<label>
Last Name:
@Html.TextBoxFor(m => m.LastName)
</label>
</li>
</ul>
<h2>
Membership:
</h2>
<ul>
<li>
<label>@Html.RadioButtonFor(m => m.MembershipLength_Months, 3) 3 Months</label>
</li>
<li>
<label>@Html.RadioButtonFor(m => m.MembershipLength_Months, 12) 12 Months</label>
</li>
</ul>
<h2>
Billing Info:
</h2>
@Html.EditorFor(m=> m.PaymentInfo)
<input type="submit" value="Submit" />
</form>
What I'd like to do is to have a summary per section. I know I could do something like this under each H2:
@if (ViewData.ModelState.Keys.Contains("FirstName") || ViewData.ModelState.Keys.Contains("LastName"))
{
<div>
summary text
@Html.ValidationMessageFor(m => m.FirstName)
@Html.ValidationMessageFor(m => m.LastName)
</div>
}
But it feels like there should be a cleaner solution. Google has completely failed me and I haven't been able to find a custom helper or validation summary extension that takes a collection to represent the properties to summarize.
Each of the sections contains a good number of fields so the ModelState.Keys comparison gets pretty ugly pretty quickly. Is there a clean way to do this?
But it feels like there should be a cleaner solution.
Yes, you could write a custom, reusable HTML helper to achieve this task:
public static class HtmlExtensions
{
public static IHtmlString Summary<TModel>(
this HtmlHelper<TModel> html,
params Expression<Func<TModel, object>>[] expressions
)
{
var div = new TagBuilder("div");
var sb = new StringBuilder();
foreach (var expression in expressions)
{
var unary = expression.Body as UnaryExpression;
if (unary != null && unary.NodeType == ExpressionType.Convert)
{
var lambda = Expression.Lambda(unary.Operand, expression.Parameters);
sb.AppendLine(html.ValidationMessage(ExpressionHelper.GetExpressionText(lambda)).ToHtmlString());
}
else
{
sb.AppendLine(html.ValidationMessageFor(expression).ToHtmlString());
}
}
div.InnerHtml = sb.ToString();
return new HtmlString(div.ToString());
}
}
which could be used like that:
<h2>
Your Info:
@Html.Summary(
x => x.FirstName,
x => x.LastName
)
</h2>
The helper allows you to list any properties you want to be included in the summary as validation errors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With