AllPower
AllPower

Reputation: 195

ASP.NET MVC - How to limit the number of paging Elements and use '...' (three dots) to filter when there are many records

When there is a very large amount of records, the pagination is showing all the pages and breaking the view.

How would I do to insert that filter, which shows the '..' three points in the middle of the number of pages?

This is the result on the view, if there are many records, it will be impractical enter image description here

PaginationClass

 public class Pagination<T> where T : class
    {
        public Pagination()
        {

        }      

        public Pagination(List<T> itens, int count)
        {
            this.Count = count;
            this.List = itens;
        }
        public IEnumerable<T> List { get; set; } 
        public int Count { get; set; }
    }

Repository Using Dapper here

public Pagination<LocalDaOperacao> ObterLocalOperacaoPaginado(string nome, int pageSize, int pageNumber)
    {
        var cn = this.DbContext.Database.Connection;

        var sql = @"SELECT * FROM LOCAL_OPERACAO local 
                  WHERE (LTRIM(:Nome) IS NULL OR LTRIM(local.NOME) LIKE LTRIM(CONCAT(:Nome, '%')))
                  ORDER BY local.NOME 
                  OFFSET :pageSize * (:pageNumber - 1)  ROWS 
                  FETCH NEXT :pageSize  ROWS ONLY ";

         var sqlCount = @"SELECT COUNT(Id) FROM Local_Operacao local 
                  WHERE (:Nome IS NULL OR local.Nome LIKE CONCAT(:Nome, '%'))";

         var multi2 = cn.QueryMultiple(sqlCount, new { Nome = nome });


        var multi = cn.QueryMultiple(sql, new { Nome = nome, PageSize = pageSize, PageNumber = pageNumber });
        var locais = multi.Read<LocalDaOperacao>();
        var total = multi2.Read<int>().FirstOrDefault();

        var pagedList= new Pagination<LocalDaOperacao>()
        {
            List = locais,
            Count = total
        };

        return pagedList;
    }

Controller

 public const int PageSize = 8;    
    public ActionResult Index(string search, int pageNumber= 1 )
        {
            var pagination= _localDaOperacaoAppService.getAll(search, PageSize ,pageNumber);
            ViewBag.Total = Math.Ceiling((double)pagination.Count / PageSize);
            ViewBag.PageNumber= pageNumber;
            ViewBag.SearchRecord= search;

            return View(pagination.List);
        }

FrontEnd

    <li class="page-item">
        @if (ViewBag.PageNumber> 1)
        {
        <a class="page-link" href="@Url.Action("Index", "LocalDaOperacao", new { search= ViewBag.SearchRecord, pageNumber= ViewBag.PageNumber- 1 })"> Anterior</a>

        }
        else
        {
            <a class="page-item disabled">
                <span class="page-link">Previus</span>
            </a>
        }
    </li>

    @{
        var currentPage= ViewBag.PageNumber;

        for (int i = 1; i <= ViewBag.Total; i++)
        {
            <li @Html.Raw(currentPage== i ? "class=\"page-item active\"" : "") )>
                <a class="page-link" href="@Url.Action("Index", "LocalDaOperacao", new { search= ViewBag.SearchRecord, pageNumber= i })">@i</a>
            </li>
        }

    }

    <li class="page-item">
        @if (ViewBag.PageNumber< ViewBag.Total)
        {                   
             <a class="page-link" href="@Url.Action(" Index", "LocalDaOperacao" , new { search=ViewBag.SearchRecord, pageNumber=ViewBag.NumeroDePaginas + 1 })">Next</a>                 
        }
        else
        {
            <a class="page-item disabled">
                <span class="page-link">Next</span>
            </a>
        }
</ul>

Upvotes: 2

Views: 3682

Answers (1)

Dmitry
Dmitry

Reputation: 327

If you paginator like this:

Previus | 1 | ... | 10 | 11 | 12 | 13 | 14 | ... Last | Next

You can use this code:

 <ul>
    <li class="page-item">
        @if (ViewBag.PageNumber > 1)
        {
            <a class="page-link" href="@Url.Action("Index", "LocalDaOperacao", new { search= ViewBag.SearchRecord, pageNumber= ViewBag.PageNumber- 1 })"> Anterior</a>

        }
        else
        {
            <a class="page-item disabled">
                <span class="page-link">Previus</span>
            </a>
        }
    </li>

    @{
        var currentPage = (int)ViewBag.PageNumber;
        var pageCount = (int)ViewBag.Total;

        // How many pages views right or left of currentPage
        const int PageLeft = 2;
        const int PagesRight = 2;

        // get first page befor ...
        var fromPage = Math.Max(1, currentPage - PageLeft);

        // get last page after ...
        var toPage = Math.Min(pageCount, currentPage + PagesRight);

        if (pageCount - toPage == 1)
        {
            toPage = pageCount;
        }

        if (fromPage > 1)
        {
            // view First page
            <li>
                <a class="page-link" href="@Url.Action("Index", "LocalDaOperacao", new { search= ViewBag.SearchRecord, pageNumber= 1 })">1</a>
            </li>
            if (fromPage > 2)
            {
                // view first ...
                // calculate number page for link ..., it's middle between first page and fromPage
                var middleNumber = (int)Math.Ceiling((double)(fromPage - 2) / 2) + 1;
                <li>
                    <a class="page-link" href="@Url.Action("Index", "LocalDaOperacao", new { search= ViewBag.SearchRecord, pageNumber= middleNumber })">...</a>
                </li>
            }
        }


        // view paginator between currentPage
        for (int i = fromPage; i <= toPage; i++)
        {
            <li @Html.Raw(currentPage == i ? "class=\"page-item active\"" : "") )>
                <a class="page-link" href="@Url.Action("Index", "LocalDaOperacao", new { search= ViewBag.SearchRecord, pageNumber= i })">@i</a>
            </li>
        }


        // view second ...
        if (toPage < pageCount)
        {
            int middleNumber = (int)Math.Ceiling((double)(pageCount - toPage) / 2) + toPage;
            <li>
                <a class="page-link" href="@Url.Action("Index", "LocalDaOperacao", new { search= ViewBag.SearchRecord, pageNumber= middleNumber })">...</a>
            </li>
            // view last page
            if (toPage < pageCount - 1)
            {
                <li>
                    <a class="page-link" href="@Url.Action("Index", "LocalDaOperacao", new { search= ViewBag.SearchRecord, pageNumber= pageCount })">@pageCount</a>
                </li>
            }

        }

    }

    <li class="page-item">
        @if (ViewBag.PageNumber < ViewBag.Total)
        {
            <a class="page-link" href="@Url.Action(" Index", "LocalDaOperacao" , new { search=ViewBag.SearchRecord, pageNumber=ViewBag.NumeroDePaginas + 1 })">Next</a>
        }
        else
        {
            <a class="page-item disabled">
                <span class="page-link">Next</span>
            </a>
        }
</ul>

You can change PageLeft and PagesRight for correct how many view pages befor and after currentPage. It's code should be optimized, but for demostrate algortim view links '...' is normal.

Upvotes: 2

Related Questions