I'm trying to apply a responsive design to my ASP.NET MVC 4 application. I want to loop my model and render 3 items per line. Each line shall be wrapped in a div. The result should look something like this:
<div class='ResponsiveWrapper'>
<div>
<!-- item1 -->
</div>
<div>
<!-- item2 -->
</div>
<div>
<!-- item3 -->
</div>
</div>
<div class='ResponsiveWrapper'>
<div>
<!-- item4 -->
...
In order to do so, I'm trying to use ternary operators:
@{ var i = 0; }
@foreach (var item in Model)
{
@Html.Raw(i == 0 ? Html.Encode("<div class='section group'>") : "")
<div>
//Responsive Content comes here
</div>
@Html.Raw(i == 2 ? Html.Encode("</div>") : "")
@(i<3 ? i++ : i=0)
}
Now I have 2 problems:
The HTML tags which the ternary operators should render come in plain text. I tried different combinations of @Html.Raw
and @Html.Encode
and Strings, but it nothing worked for me
It seems like the last ternary operator renders the current value of the variable i
. How can I prevent this?
Additional information/code explanation
The logic already works fine:
i
Variable is the count variable.If i = 0
I first render the start <div>
tag of the wrapper and than I render the current model.item
If i = 1
I only render the current model.item
If i = 2
I first render the current model.item
and than the </div>
end tagThank you
UPDATE
Both, MajoB's and Chris Pratt's approaches basically work. Since MajoB's solution was more detailed, I went with that one. However, I had to make some modifications in order to get it to work:
At the controller, I had to assure, that an IList
is being returned, rather than an IEnumerable
public ActionResult Index()
{
return View(db.leModel.ToList());
}
In the View, I had to change the signature (like 1, IList
instead of IEnumerable
)
@model IList<leProject.Models.leModel>
Various modifications in the Razor code (otherwise it would throw me exceptions)
Final code:
<div class="ResponsiveWrapper">
@for (var i = 0; i < Model.Count; i++)
{
// the lambda expression modelItem => item.leProperty did not work for some reason. So I had to replace the item with Model[i], which means, the following line is not necessary
{ var item = Model[i]; }
<div>
@Html.DisplayFor(modelItem => Model[i].leProperty)
</div>
if ((i + 1) % 3 == 0 || i == (Model.Count - 1))
{
@:</div>
if (Model.Count + 1 - i >= 3)
{
@:<div class="ResponsiveWrapper">
}
}
}
Thank you guys :)
Solution without the wrapper div:
@for(var i = 0; i < Model.Count; i++)
{
@{ var item = Model[i]; }
<div style="float:left;">
<!-- item1 -->
</div>
@if((i+1) % 3 == 0)
{
<div style="clear:both;"></div>
}
}
Solution with wrapper:
<div class="ResponsiveWrapper">
@for(var i = 0; i < Model.Count; i++)
{
@{ var item = Model[i]; }
<div>
<!-- item1 -->
</div>
@if((i+1) % 3 == 0 || i == (Model.Count-1)) // in case you have for example 7 items in your list
{
@:</div> <!-- end ResponsiveWrapper -->
@if (i != Model.Count-1)
{
@:<div class='ResponsiveWrapper'>
}
}
}