9:26 0 0
Paginacion en ASP NET Core

Paginacion en ASP NET Core

  DrUalcman |  julio 222020

En MVC hay un nugget para hacer paginación muy fácil de utilizar, pero para NET Core no encontré nada realmente bueno y sencillo, por lo que me puse manos a la obra y aquí os tengo mi solución. De hecho lo he probado en ASP Web Forms y en MVC y también sunciona. Y es muy fácil de usar. Pero como siempre, abierto a mejoras que se te ocurran tras leer este artículo.

Explicación

Para poder utilizar la paginación tenemos que recurir a utilizar LINQ sobre el objeto que contiene los datos. Como norma general trabajaremos con DataTable o DataView, que ambos los podemos convertir fácilmente a IQuerable, pero también podemos pasar una lista (List) de objetos (class) con los datos.

Otras dos variables que necesitamos pasar el el número de página y el tamaño de la lista devuelta.

Por último tenemos una pequeña dependencia de un archivo CSS con el estilo de la paginación generada. Pero este estilo es complemtante personalizable, y siempre puedes cambiar la función donde se crea la paginación y acomodarla más a tu página web.

Directamente el código

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

public class PagedList : List
{
#region properties
public int CurrentPage { get; private set; }
public int TotalPages { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public bool HasPrevious => CurrentPage > 1;
public bool HasNext => CurrentPage < TotalPages;
#endregion

#region constructor
public PagedList(List items, int count, int pageNumber, int pageSize)
{
TotalCount = count;
PageSize = pageSize;
CurrentPage = pageNumber;
TotalPages = (int)Math.Ceiling(count / (double)pageSize);

AddRange(items);
}
#endregion

#region Methods
public static PagedList ToPagedList(DataTable data, int pageNumber, int pageSize)
{
IQueryable source = drualcman.dataBases.AsQuerable(data);
int count = source.Count();
List items = source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();

return new PagedList(items, count, pageNumber, pageSize);
}

public static PagedList ToPagedList(DataView data, int pageNumber, int pageSize)
{
IQueryable source = drualcman.dataBases.AsQuerable(data.ToTable());
int count = source.Count();
List items = source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();

return new PagedList(items, count, pageNumber, pageSize);
}

public static PagedList ToPagedList(IQueryable source, int pageNumber, int pageSize)
{
int count = source.Count();
List items = source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();

return new PagedList(items, count, pageNumber, pageSize);
}

public static PagedList ToPagedList(IEnumerable source, int pageNumber, int pageSize)
{
int count = source.Count();
List items = source.Skip((pageNumber - 1) * pageSize).Take(pageSize).ToList();

return new PagedList(items, count, pageNumber, pageSize);
}
#endregion

#region HTML
public static StringBuilder PagedListPager(PagedList data)
{
return PagedListPager(data, string.Empty);
}
public static StringBuilder PagedListPager(PagedList data, string page)
{
if (!string.IsNullOrEmpty(page))
{
if (page.IndexOf("?") < 0) page += "?";
else page += "&";
}
else page = "?";

StringBuilder pagin = new StringBuilder();
pagin.Append("< div class="pagination-container">< ul class="pagination">");
int i;
if (data.CurrentPage > 5) i = data.CurrentPage - 5;
else i = 1;
int c = 0;
if (data.CurrentPage > 6)
{
pagin.Append($"< li class="PagedList-skipToFirst">< a href="{page}page=1"><<< /a>< /li>");
pagin.Append($"< li class="PagedList-skipToPrevious">< a href="{page}page={data.CurrentPage - 1}"><< /a>< /li>");
pagin.Append($"< li class="disabled PagedList-ellipses">< a>...< /a>< /li>");
}
else if (data.CurrentPage == 1) pagin.Append(string.Empty);
else pagin.Append($"< li class="PagedList-skipToNexts">< a href="{page}page={data.CurrentPage - 1}"><< /a>< /li>");

do
{
if (i <= data.TotalPages)
{
if (i == data.CurrentPage) pagin.Append($"< li class="active">< span>{i}< /span>< /li>");
else pagin.Append($"< li>< a href="{page}page={i}">{i}< /a>< /li>");
}
else c = 10;
i++;
c++;
} while (c < 10 && i <= data.TotalPages);
i = i-1;
if (data.CurrentPage < data.TotalPages - 4)
{
pagin.Append($"< li class="disabled PagedList-ellipses">< a>...< /a>< /li>");
pagin.Append($"< li class="PagedList-skipToNext">< a href="{page}page={data.CurrentPage + 1}">>< /a>< /li>");
pagin.Append($"< li class="PagedList-skipToLast">< a href="{page}page={data.TotalPages}">>>< /a>< /li>");
}
else if (data.CurrentPage == data.TotalPages) pagin.Append(string.Empty);
else pagin.Append($"< li class="PagedList-skipToNext">< a href="{page}page={data.CurrentPage + 1}">>< /a>< /li>");
pagin.Append("< /ul>< /div>");
return pagin;
}
#endregion
}

Modo de uso

Como norma general yo lo utilizo desde una clase que llamo ViewModel, pero puedes utilizarlo directamente desde el controllador y pasar como modelo la clase PagedList (ojo. la T en el model debe de ser exactamente el tipo de datos a recibir, DataRow, DataView o la class que estás utilizando en el List).

Controlador

	[HttpGet]
        public IActionResult Index(int page = 1)
        {
            DataView dv = [datos];
            int pageSize = 10;
            return View(PagedList.ToPagedList(dv, page, pageSize));
        }
Vista
@model PagedList
@{
    ViewData["Title"] = "Index";
    string url = Url.Action("index", "home");
}

    < div class="block-table-wp">
        < div class="table-container">
            < table class="table is-fullwidth border mb-0">
< thead>
                    < tr>
                        < th>Id< /th>
                    < /tr>
                < /thead>
                < tbody>
                    @{
                        if (Model.Count > 0)
                        {
                            foreach (DataRow item in Model)
                            {
                                < tr>
                                    < td>@item["Id"]< /td>
                                < /tr>
                            }
                        }
                        else
                        {
                           
                                < td class="text-center text-bold">No data in this table< /td>
                            < /tr>
                        }
                    }
                < /tbody>
                < tfoot>
                    < tr>
                        < td>
                            @Html.Raw(PagedList.PagedListPager(Model, url))
                        < /td>
                    < /tr>
                < /tfoot>
            < /table>
        < /div>
    < /div>
Conclusiones

No olvidar que hay que hacer referencia al namespace donde hayais copiado la clase, tanto en el controlador como en el web.config de la web.


Happy codding


#ASP #CASHARP #CORE #MVC



0 Comentarios

 
 
 

Archivo