Reputation: 3289
I have an mvc view that uses "tabs", each of these tabs displays a different form of the same data (available from my viewmodel). The data is displayed as follows:
<div id=tab1>
@foreach (Path p in Model.Paths.Where(r => r.PathType == "HR"))
{
(displays html and data)
}
</div>
<div id=tab2>
@foreach (Path p in Model.Paths.Where(r => r.PathType == "IT"))
{
(displays html and data)
}
</div>
and so on...since each iteration uses the same html and named variable (p), what is the best way of not repeating these values?
Upvotes: 3
Views: 2997
Reputation: 73102
Use a custom display template.
Shared\DisplayTemplates\Path.cshtml
@model YourApp.Model.Path
@* (displays html and data) *@
MainView.cshtml
<div id=tab1>
@Html.DisplayFor(model => model.HrPaths)
</div>
<div id=tab2>
@Html.DisplayFor(model => model.ItPaths)}
</div>
You should split out the Paths
object in your VM into seperate properties, e.g put the .Where
filter into the Controller.
That way, you only have a single template to render out the type (since it's the same type for both properties), you avoid foreach loops, you maintain the HTML in one place, etc.\
You could also go one step further and create a Dictionary<string,IEnumerable<Path>>
in your View Model, where the key is the tab name, the the value is the pre-filtered collection of Path
.
Then your View simply becomes:
@Html.DisplayForModel()
Then the outer template (you will need a UIHint on the VM):
<div [email protected]>
@Html.DisplayFor(model => model.Value)
</div>
Upvotes: 6
Reputation: 48476
Make the loop include the tabs, something like this:
@var i=0;
@foreach (string type in Model.PathTypes)
{
@i++;
<div id="tab@i">
@foreach (Path p in Model.Paths.Where(r => r.PathType == type))
{
(displays html and data)
}
</div>
}
I don't know the MVC 3 client-side syntax, but you get the idea.
Upvotes: 3