user1412240 user1412240 - 3 months ago 8
C# Question

how to "Paginate" results into rows not pages

This one is very difficult for me to word, which is what is failing me in my google searching, i brand new to asp.net and it's giving me some difficulties with the logic of this requirement

I have a bunch of results which are displayed primarily as images with some text overlayed.

I have some HTML that is required to show these images, but it uses custom styling to show each "row" of images, it uses div's for a custom look.

What i'm needing to do, is work out a way in the cshtml file display a html block to start a row, and then output the html for 6 of the items, then close off that row and begin another one and rinse repeat until completed, but i cannot for the life of me work out how i would go about that in asp.net.

This might be a very very simple issue, but due to my inability to word this correctly for google, I'm really struggling to find anything online.

The closest visual example i can think of is something like Netflix, but without the ability to scroll the movies, so all the movies are listed in those rows.

i'm currently using the following method,

@foreach (var item in Model)
{
html...
}


My original thought was to have a counter and do a conditional statement when the count hit's six, closing the row and starting a new one, but i cannot work out how to mix that much html into code blocks.

@{
int count = 0;
foreach(var item in model)
{
count++;
//Output current item's html
if(count == 6)
{
//End current row, start new row
count = 0;
}
}


but as i mentioned, i can only find how to mix single html elements in with code blocks using the @: method, and i need a block of html.

Adding my controller code as requested, I have it kinda working using viewbag, but the groupedModel seems to split each movie into a separate row.

// GET: Movies
public ActionResult Index(string movieGenre, string searchString)
{
var GenreList = new List<string>();

var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;

GenreList.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreList);

var movies = from m in db.Movies
select m;

if(!String.IsNullOrEmpty(searchString))
{
movies = movies.Where(s => s.Title.Contains(searchString));
}

if(!string.IsNullOrEmpty(movieGenre))
{
movies = movies.Where(x => x.Genre == movieGenre);
}

var groupedModel = movies.AsEnumerable().Select((e, i) => new { Element = e, Index = i }).GroupBy(e => e.Index % 6).Select(g => g.Select(e => e.Element));
ViewBag.grouped = groupedModel;

return View(movies);
}


and my view (With most of the HTML removed for ease of reading):

@model IEnumerable<MvcMovie.Models.Movie>

@{
ViewBag.Title = "Index";
}

<p>
@Html.ActionLink("Create New", "Create")

@using (Html.BeginForm("Index", "Movies", FormMethod.Get))
{
<p>
Genre: @Html.DropDownList("movieGenre", "All")
Title: @Html.TextBox("SearchString")
<input type="submit" value="Filter" />
</p>
}
</p>

@foreach(var group in ViewBag.grouped)
{
<div class="MovieRow">
@foreach (var item in group)
{
<div class="bob-title">@Html.Display((item as MvcMovie.Models.Movie).Title)</div>
}
</div>
}


EDIT:

The only problem i have left now, is that i can't seem to get the item variables to output, none of the
@Html.Display((item as MvcMovie.Models.Movie)
sections output anything.

Answer

First, let's group your model to get groups with 6 elements (better to do it in the controller, not in the view):

var groupedModel = Model.Select((e, i) => new { Element = e, Index = i })
                        .GroupBy(e => (e.Index - 1) / 6)
                        .Select(g => g.Select(e => e.Element));

than you will iterate these group and display them:

@foreach(var group in groupedModel)
{
    <div id="rowDiv">
    @foreach(var element in group)
    {
        <div id="elementDiv">// element div here
            // display element info here
        </div>// element div end
    }
    </div>    // row div end
}