Umbraco pagination
Asked Answered
S

5

7

First time Umbraco user.

I'm looking to add pagination to the following basic loop:

@foreach (var example in CurrentPage.Children.OrderBy("createDate descending").Take(8)){

   //Do Stuff//

}

Any ideas? Thanks

Sieve answered 23/7, 2014 at 9:12 Comment(0)
S
22

After a good amount of work and research, here is my final code for pagination in umbraco. Replace the examples with your stuff, and pageSize is the amount of posts shown on each page.

@{
    var pageSize = 8;
    if(Model.Content.HasValue("numberOfItemsPerPage")){
    pageSize = Model.Content.GetPropertyValue<int>("numberOfItemsPerPage");}

    var page = 1; int.TryParse(Request.QueryString["page"], out page);
    var items = Umbraco.TypedContent(Model.Content.Id).Children.Where(x => x.DocumentTypeAlias == "exampleAlias" && x.IsVisible());
                var totalPages = (int)Math.Ceiling((double)items.Count() / (double)pageSize);

                if (page > totalPages)
                {
                    page = totalPages;
                }
                else if (page < 1)
                {
                    page = 1;
                }

            foreach (var item in items.Skip((page - 1) * pageSize).Take(pageSize).OrderBy("createDate descending"))
{

     <div class="example-div">
            <h2>@item.GetPropertyValue("example")</h2>
    </div>
}

if (totalPages > 1)
{
    <div class="pagination">
        <ul>
            @if (page > 1)
            {
                <li><a href="?page=@(page-1)">Prev</a></li>
            }
            @for (int p = 1; p < totalPages + 1; p++)
            {
                <li class="@(p == page ? "active" : string.Empty)">
                    <a href="?page=@p">@p</a>
                </li>
            }
            @if (page < totalPages)
            {
                <li><a href="?page=@(page+1)">Next</a></li>
            }
        </ul>
    </div>
}
}

Hope this stops a headache for someone.

Sieve answered 24/7, 2014 at 10:20 Comment(2)
Hi there. Thanks a lot for this. I've been looking through a fair few pagination scripts, and this is by far the most simplest to implement and works spot on.Geesey
Why are you doing Umbraco.TypedContent(Model.Content.Id)? Umbraco.Content IS a IPublishedContent. You are hitting the cache while you have the model already at your disposalClari
F
4

Phil's answer is great, but I would recommend putting the order on the items variable rather than the foreach - that way if any more complicated sorting is necessary it's being done before the pagination is implemented.

The updated code snippets would be:

@{
    var pageSize = 8;
    if(Model.Content.HasValue("numberOfItemsPerPage")){
    pageSize = Model.Content.GetPropertyValue<int>("numberOfItemsPerPage");}

    var page = 1; int.TryParse(Request.QueryString["page"], out page);
    var items = Umbraco.TypedContent(Model.Content.Id).Children.Where(x => x.DocumentTypeAlias == "exampleAlias" && x.IsVisible()).OrderByDescending(x => x.CreateDate);
    var totalPages = (int)Math.Ceiling((double)items.Count() / (double)pageSize);

    if (page > totalPages)
    {
        page = totalPages;
    }
    else if (page < 1)
    {
        page = 1;
    }

    foreach (var item in items.Skip((page - 1) * pageSize).Take(pageSize)
    {
        <div class="example-div">
            <h2>@item.GetPropertyValue("example")</h2>
        </div>
    }

   if (totalPages > 1)
   {
       <div class="pagination">
           <ul>
               @if (page > 1)
               {
                   <li><a href="?page=@(page-1)">Prev</a></li>
               }
               @for (int p = 1; p < totalPages + 1; p++)
               {
                   <li class="@(p == page ? "active" : string.Empty)">
                       <a href="?page=@p">@p</a>
                   </li>
               }
               @if (page < totalPages)
               {
                   <li><a href="?page=@(page+1)">Next</a></li>
               }
           </ul>
       </div>
    }
}
Filthy answered 7/10, 2015 at 22:0 Comment(0)
U
1

My 50 cents

Jeroen Breuer created a github project called Hybrid Framework in which he has added some route hijacking to an umbraco side to do paging and have strongly typed models. Take a look at it and i'm sure you will like it. It also uses caching i believe.

There was also a video about this i saw but i could not find it anymore.

Hope this helps people trying to implement Paging and some other nice stuff to you Umbraco projects.

UPDATE: found the video on GitHub in readme

Ulphi answered 20/8, 2014 at 21:14 Comment(1)
I'm also a big fan of Jeroen Breuer' Hybrid Framework. The above is great but it's nicer if you don't have to refresh the whole page when paging and the Hybrid Framework shows you how to Ajaxify it. MattKazim
N
0

These are all great answers, especially the pointer to Jeroen Breuer's library, but just in the name of being thorough and talking about all options -- if you are using jquery in your project and if you have relatively small result sets you could also go with a simple front end only solution.

You'd just bind the entire results list and then use a library like JPList (http://jplist.com ) as I have done here. Go to http://www.charterpublic.org/find-a-school/ and type in city Denver for example. You'll see there are 50+ results. I bind the entire results list then use jplist to make it sortable/pageable etc.

@if (results.Any())
{
    <div class="list">
    @foreach (var result in results.OrderByDescending(r => r.Name))
    {
        <div class="list-item">
        //build your item
        </div>
    }
    </div>
}
<div class="jplist-panel">
    <!-- bootstrap pagination control -->
    <ul class="pagination text-center jplist-pagination"
        data-control-type="boot-pagination"
        data-control-name="paging"
        data-control-action="paging"
        data-range="4"
        data-mode="google-like"></ul>
    <!-- items per page dropdown -->
    <div class="hidden dropdown pull-left jplist-items-per-page"
         data-control-type="boot-items-per-page-dropdown"
         data-control-name="paging"
         data-control-action="paging">
        <button class="btn btn-primary dropdown-toggle"
                type="button"
                data-toggle="dropdown"
                id="dropdown-menu-1"
                aria-expanded="true">
            <span data-type="selected-text">Items per Page</span>
            <span class="caret"></span>
        </button>
        <ul class="dropdown-menu" role="menu" aria-labelledby="dropdown-menu-1">

            <li role="presentation">
                <a role="menuitem" tabindex="-1" href="#" data-number="3">3 per page</a>
            </li>

            <li role="presentation">
                <a role="menuitem" tabindex="-1" href="#" data-number="5">5 per page</a>
            </li>

            <li role="presentation">
                <a role="menuitem" tabindex="-1" href="#" data-number="10" data-default="true">10 per page</a>
            </li>

            <li role="presentation" class="divider"></li>

            <li role="presentation">
                <a role="menuitem" tabindex="-1" href="#" data-number="all">View All</a>
            </li>
        </ul>
    </div>
</div>

Then at the bottom of your view...

<script type="text/javascript">
    $(document).ready(function () {
        $('#demo').jplist({ 
            itemsBox: '.list', 
            itemPath: '.list-item', 
            panelPath: '.jplist-panel' 
        });
    });
</script>

There are other front end libraries that do this, but I found JPList the easiest to use for me.

The downside is it's not lazy loaded so it's a little heavier, but with smallish lists like mine here this was a great and simple solution.

Numismatist answered 12/4, 2016 at 5:0 Comment(0)
S
0

I know that this is old , I used the Phil code recomendations and works very good. But all the pages when incresing the pagination buttons works as infinite regeneration, what I mean is how can I do this as example:

Prev 123456789...Next and when is selected the page 5 for example shows like this:

Prev 5 6 7 8 9 10 11 12 13 ... Next and in the inverse or last page like this:

Prev ... 47 48 49 50 51 52 53 54 55

What I mean guys is to have just a 9 pages on click in the pagination buttons, but I need to implement with the same code that Phil Share :

@{
var pageSize = 8;
if(Model.Content.HasValue("numberOfItemsPerPage")){
pageSize = Model.Content.GetPropertyValue<int>("numberOfItemsPerPage");}

var page = 1; int.TryParse(Request.QueryString["page"], out page);
var items = Umbraco.TypedContent(Model.Content.Id).Children.Where(x => x.DocumentTypeAlias == "exampleAlias" && x.IsVisible());
            var totalPages = (int)Math.Ceiling((double)items.Count() / (double)pageSize);

            if (page > totalPages)
            {
                page = totalPages;
            }
            else if (page < 1)
            {
                page = 1;
            }

        foreach (var item in items.Skip((page - 1) * pageSize).Take(pageSize).OrderBy("createDate descending"))
{

 <div class="example-div">
        <h2>@item.GetPropertyValue("example")</h2>
</div>
}

if (totalPages > 1)
{
<div class="pagination">
    <ul>
        @if (page > 1)
        {
            <li><a href="?page=@(page-1)">Prev</a></li>
        }
        @for (int p = 1; p < totalPages + 1; p++)
        {
            <li class="@(p == page ? "active" : string.Empty)">
                <a href="?page=@p">@p</a>
            </li>
        }
        @if (page < totalPages)
        {
            <li><a href="?page=@(page+1)">Next</a></li>
        }
    </ul>
</div>
}
}

Just to have a limit of 9 pages with the (...) according the page position.

Help!

Sportswoman answered 2/8, 2018 at 6:45 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.