proggrock
proggrock

Reputation: 3289

MVC 3 -- inside a foreach loop, avoiding duplicate html

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

Answers (2)

RPM1984
RPM1984

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

bevacqua
bevacqua

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

Related Questions