How to create Dynamic Pagination

Viewed 1584

I have done server side pagination in MVC but i am unable to show numbers and Next and prev link button dynamically.Please provide me with some idea.

  <nav aria-label="Page navigation example">
            <ul class="pagination">
                @for (int i = 1; i <= Model.PageCount; i++) // PageCount is Number of total Pages
                {

                    <li class="page-item">
                        @if (i != Model.CurrentPageIndex) //Current Page say 1..2...3..etc
                        {

                            <a class="page-link" href="javascript:;" onclick="myClick(@i)">@i</a>

                        }
                        else
                        {
                            <span>@i</span>
                        }
                    </li>
                }
            </ul>
        </nav>

My problem is if i have a total of 10 pages (say).I want to show Link buttons for number 1 to 5 the Next button .So that pagination navigation becomes dynamic .please help

1 Answers

If I understand correctly, your concern is that you want to restrict the number of links generated so that instead of links to every page, starting from 1 and ending at PageCount, the user sees only a range of the full list of links.

The idea here is to introduce yet another parameter, call it numbersToShow, that represents the total number of links you want to render.

For example, when there are 10 pages, the total number of links could be like 5.

An example function to compute the starting and ending index of this subset could be like this one:

static (int min, int max) GetPagingRange( int currentPage, int totalPages, int numbersToShow = 5 )
{
    if ( currentPage < 1 || totalPages < 1 || currentPage > totalPages ) throw new ArgumentException();
    if ( numbersToShow < 1 ) throw new ArgumentException();

    var min = Math.Max(1, currentPage - numbersToShow/2);
    var max = Math.Min(totalPages, currentPage + numbersToShow/2 + Math.Max( 0, min - currentPage + numbersToShow/2 ) );

    return (min, max);
}

What happens here is that we start at the current page and try making it the middle of the dynamic range (so we take numbersToShow/2 to the left and to the right). Both Math.Min and Math.Max make sure we stay in the valid range.

There's also another component when computing max that tries to compensate the lack of the left portion of the range when you render first few pages.

Consider this example usage that shows what range values are returned:

    Console.WriteLine( "Total pages:    10" );
    Console.WriteLine( "Numers to show: 5" );

    int totalPages = 10;

    for ( int currentPage = 1; currentPage <= totalPages; currentPage++ )                 
    {
        var result = GetPagingRange( currentPage, totalPages );
        Console.WriteLine( $"CurrentPage: {currentPage}, starting page index: {result.min} ending page index: {result.max}");
    }   

The output here is

Total pages:    10
Numers to show: 5
CurrentPage: 1, starting page index: 1 ending page index: 5
CurrentPage: 2, starting page index: 1 ending page index: 5
CurrentPage: 3, starting page index: 1 ending page index: 5
CurrentPage: 4, starting page index: 2 ending page index: 6
CurrentPage: 5, starting page index: 3 ending page index: 7
CurrentPage: 6, starting page index: 4 ending page index: 8
CurrentPage: 7, starting page index: 5 ending page index: 9
CurrentPage: 8, starting page index: 6 ending page index: 10
CurrentPage: 9, starting page index: 7 ending page index: 10
CurrentPage: 10, starting page index: 8 ending page index: 10

Note that although the compensation works for starting pages (e.g. when the current page is 1, the range is 1 to 5), there's no compensation when few last pages are rendered (e.g. on the last 10th page the range is 8 to 10). This could possibly be improved or you can leave it as is.

The code is also available in the fiddle.

Related