Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can i count loops in mvc3 in @foreach

How can i close <tr> and open <tr> after 3 loop iterations? I have MVC 3 in .NET 4.0. How can I count loop iterations in MVC 3?

Current Code:

@foreach (var articleOnFirstPage in Model.ArticlesOnFirstSite)
{

<tr>
    <td><div class="productsFrame"></div></td>
</tr>

}

I want to get this:

<tr>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
    </tr>
<tr>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
    </tr>
<tr>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
        <td><div class="productsFrame"></div></td>
    </tr>
like image 818
senzacionale Avatar asked Nov 15 '11 20:11

senzacionale


People also ask

How do you use the in keyword in a foreach loop?

Working of C# foreach loop The in keyword used along with foreach loop is used to iterate over the iterable-item. The in keyword selects an item from the iterable-item on each iteration and store it in the variable element. On first iteration, the first item of iterable-item is stored in element.

What is the difference between for loop and foreach loop in Java?

The foreach loop iterate only in forward direction. Performance wise foreach loop takes much time as compared with for loop. Because internally it uses extra memory space as well as. The foreach loop use GetEnumarator () method of the IEnumerable interface. So, the foreach loop can be used with any class that has implemented the interface.

How to use the foreach loop in IEnumerable?

The foreach loop use GetEnumarator () method of the IEnumerable interface. So, the foreach loop can be used with any class that has implemented the interface. Exit the foreach loop by using break, return, Goto and throw. The following example demonstrates the foreach loop on a dictionary collection.

How many times does a foreach loop execute?

The number of times the foreach loop will execute is equal to the number of elements in the array or collection. Here is an example of iterating through an array using the for loop: The same task can be done using the foreach loop. When we run the both program, the output will be:


2 Answers

You could perform the following pornography in your view:

@model IEnumerable<Foo>
<table>
@foreach (var item in from i in Model.Select((value, index) => new { value, index }) group i.value by i.index / 3 into g select g)
{
    <tr>
        @foreach (var x in item)
        {
            <td><div class="productsFrame">@x.SomeProperty</div></td>
        }
    </tr>
}
</table>

or simply use view models and do the grouping in your controller action which obviously is what I would recommend you. The sole fact that you need to do this means that your view model is not adapted to your view's requirements which is to group results by 3. So adapt it. Don't pass IEnumerable<Foo> to your view. Pass IEnumerable<MyViewModel> where obviously MyViewModel will contain the necessary grouping so that in your views you could simply loop or since I hate writing for and foreach loops in views simply use display templates. They will take care of everything and your view will simply look like this:

<table>
    @HtmlDisplayForModel()
</table>

Looks better than the initial pornography isn't it?


As requested in the comments section here's how I would implement this using view models.

As always in an ASP.NET MVC application you start by defining the view models that will reflect the requirements of your view (which I repeat are: show a table with 3 columns):

public class ItemViewModel
{
    public string Title { get; set; }
}

public class MyViewModel
{
    public IEnumerable<ItemViewModel> Items { get; set; }
}

then you move on to the controller that will fill and pass this view model to the view:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        // Obviously in a real world application the data is your domain model
        // and comes from a repository or a service layer depending on the complexity
        // of your application. I am hardcoding it here for the 
        // purposes of the demonstration
        var data = Enumerable.Range(1, 30).Select(x => new { Title = "title " + x });

        var model =
            from i in data.Select((value, index) => new { value, index })
            group i.value by i.index / 3 into g
            select new MyViewModel
            {
                Items = g.Select(x => new ItemViewModel { Title = x.Title })
            };

        return View(model);
    }
}

and finally you write the corresponding view (~/Views/Home/Index.cshtml):

@model IEnumerable<MyViewModel>
<table>
    @Html.DisplayForModel()
</table>

and the ~/Views/Home/DisplateTemplates/MyViewModel.cshtml display template:

@model MyViewModel
<tr>
    @Html.DisplayFor(x => x.Items)
</tr>

and finally the corresponding ~/Views/Home/DisplateTemplates/ItemViewModel.cshtml display template:

@model ItemViewModel
<td>@Html.DisplayFor(x => x.Title)</td>

and that's pretty much it. Simple, clean, following good practices and conventions.

Obviously to bring this a step further you would introduce AutoMapper to perform the actual mapping between your domain models and view models and you will end up with a very elegant solution that will look like this:

public ActionResult Index()
{
    IEnumerable<DomainModel> data = ...
    var viewModel = Mapper.Map<IEnumerable<DomainModel>, IEnumerable<MyViewModel>>(data);
    return View(viewModel);
}

or a step further:

[AutoMap(typeof(IEnumerable<DomainModel>), typeof(IEnumerable<MyViewModel>))]
public ActionResult Index()
{
    IEnumerable<DomainModel> data = ...
    return View(data);
}

Now we are starting to get into serious business.

like image 150
Darin Dimitrov Avatar answered Sep 23 '22 09:09

Darin Dimitrov


The first thing that comes to mind is Phil Haack's better foreach loop

Using it you gain an index and can use it like

<ol>
@Model.Each(@<li>Item @item.Index of @(Model.Count() - 1): @item.Item.Title</li>)
</ol>

What you're specifically looking for should be something like:

@Model.ArticlesOnFirstSite.Each(@<td><div class="productsFrame"></div></td>@(@item.Index % 3 == 0 ? "</tr><tr>" : ""))
like image 28
sclarson Avatar answered Sep 20 '22 09:09

sclarson