Reputation: 97
I am a newbie. Just a follow-up question to a previous question: "How to Display a list of objects in MVC View?". My question is: how do I divide this list into multiple lists, each list with 5 objects and segregate each list to a different div?
List Controller: I am filtering out rows from a db with this controller:
public ActionResult FilteredElements()
{
var elem = DB.elements.Where(a => a.Criterion == "criterion")
.OrderByDescending(a => a.ElementFrequency.Count())
.ToList();
return View(elem);
}
The current view I have will enlist all the elements at once:
@foreach (var elem in Model)
{
<a href="@Url.Action("Details", "Table", new{ id = elem.ElementID }, "")">
<img src="@elem.ImagePath" /></a>
}
Instead of listing all the elements at once in one div, I would like to list first 5 elements in first div, next 5 in 2nd div and so on.
Upvotes: 2
Views: 1659
Reputation: 12410
If you don't mind dropping the div
requirement you could get cleaner Razor this way...
@{ int i = 0; }
@foreach (var elem in Model)
{
if (i++ % 5 == 0)
{
<h3>List @(i / 5 + 1)</h3>
}
<a href="@Url.Action("Details", "Table", new{ id = elem.ElementID }, "")">
<img src="@elem.ImagePath" /></a>
}
Otherwise this also seems to work okay...
@{ int i = 0; }
@foreach(var elem in Model)
{
if (i % 5 == 0)
{
@:<div><p>List @(i / 5 + 1)</p>
}
<a href="@Url.Action("Details", "Table", new{ id = elem.ElementID }, "")">
<img src="@elem.ImagePath" /></a>
if (++i % 5 == 0)
{
@:</div>
}
}
Upvotes: 0
Reputation:
An alternative answer which loops with value (v) and index (i) of model item in foreach
View
<div class="group"> // open and closing div tags for structure and default requirement
// add 1 to index to make correct comparison with .Count() and %
@foreach (var elem in Model.Select((v, i) => new { i = i + 1, v }))
{
// display stuff
<a href="@Url.Action("Details", "Table", new{ id = elem.v.ElementID }, "")">
<img src="@elem.v.ImageUrl" />
</a>
// Check if item is multiple of 5 and not the last one in the loop
if(elem.i % 5 == 0 && elem.i != Model.Count()) {
// close and open div . Top and bottom div tags keeps structure
@:</div><div class="group">
}
}
</div>
Upvotes: 0
Reputation: 10209
You have to iterate through that list and make use of linq functions .Skip
and .Take
.
Notes: Using .Skip(listIndex * listSize)
you make sure that you don't display again values from past. And .Take(listSize);
is used to take the amount elements you want to display.
@{
var listSize = 5;
var numberOfLists = Model.Count/listSize;
for (int listIndex = 0; listIndex < numberOfLists; listIndex++)
{
var list = Model.Skip(listIndex * listSize).Take(listSize);
<div id="list@listIndex">
<p>List @listIndex </p>
@foreach(var element in list)
{
<a href="@Url.Action("Details", "Table", new{ id = element.ElementID }, "")">
<img src="@element.ImagePath" /></a>
}
</div>
}
}
Upvotes: 2
Reputation: 2787
okay, so if you want to break your list in sets of say 5 you can use for loop and index instead of foreach for iterating over that list as
@for (int i=0;i<=Model.Count; i+=5)
{
<div class="group">
for(int j=0;(j<5)&&(i+j-1)<Model.Count;j++)
{
<a href="@Url.Action("Details", "Table", new{ id = Model[i+j].ElementID }, "")">
<img src="@Model[i+j].ImagePath" /></a>
}
</div>
}
Upvotes: 0