Escolha uma Página
(Last Updated On: 27/06/2018)

Paginação nas Grades do Bootstrap do CORE MVC (que funciona)

por | jul 27, 2017 | Desenvolvimento de Aplicações, Tag Helpers | 0 Comentários

Há diversos componentes para fazer paginação de grades no Core MC. Alguns não funcionam, outros estão desatualizados. E a sugestão dada pela própria Microsoft (referência 1), é muito pobre e limitada. Você pode usar o componente cloudscribe.Web.Pagination, que é atualizado e bem poderoso.

Você pode baixar / clonar este repo e executar o projeto PagingDemo.Web para ver várias páginas de demonstração usando o paginador em várias configurações, incluindo ajax e ajax dentro de um modal bootstrap.

Se você vai operar com procedures, antes de tudo instale pelo Gerenciador do NuGet – se ainda não o tem instalado na sua aplicação, o Microsoft.AspNetCore.Identity.EntityFrameworkCore.

Instalando o cloudscribe

Prérequistos:

Para instalar a partir do nuget.org, abra o arquivo project.json do seu aplicativo da Web e na seção de dependências adicione:

"cloudscribe.Web.Pagination": "1.1.*"

Com o Visual Studio 2017 não precisa fazer nada além de ir no gerenciador de pacotes, pesquisar o cloudscribe e pedir para instalar no seu projeto/aplicação. Pode também instalar, se quiser, direto pelo Packet Manager Console. As duas opções estão no menu de Ferramentas (Tools).

Começando pelo Modelo

No diretório de Modelos (Models), crie um modelo que contenha os dados que você quer mostrar na grade (se for um modelo simples, de uma única tabela que você já tenha, use o modelo dessa tabela). O modelo que usei tem dados de duas tabelas (um de pessoas cadastradas no sistema e outra de consultorias (empresas) cadastradas. Meu objetico é mostrar todos os consultores e suas respectivas consultorias (sendo que uma consultoria pode ter um ou mais consultores no sistema).

Modelo de dados

Criei na pasta Models o arquivo Consultores.cs, com os seguites campos:

using cloudscribe.Web.Pagination;
using System.ComponentModel.DataAnnotations;


namespace Coaching.Models //somente para visualização
{
    public class Consultores
    {
        // arquivo de pessas
        [Key]
        public int IdUsuario { get; set; }
        [Display(Name = "Nível de Acesso")]
        public int? NiveldeAcesso { get; set; }
        [Display(Name = "Nome do Consultor")]
        public string Nome { get; set; }
        //arquivo de consultorias
        public int IdConsultoria { get; set; }
        [Required(ErrorMessage = "Favor entrar com o nome da sua consultoria (ou seu nome).")]
        [Display(Name = "Nome da Consultoria")]
       
        public string NomeConsultoria { get; set; }
        public string Telefones { get; set; }
        public string Cidade { get; set; }
        [Display(Name = "Link de Acesso")]
        public string LinkAcesso { get; set; }
        
    }
}

Modelo (OBRIGATÓRIO) de Auxílio para a Paginacão

Crie um modelo muito simples para auxiliar na paginação. No caso, criei o arquivo Paginacao.cs na pasta de modelos (Models). Qualquer que seja o seu modelo de dados (como o acima), este arquivo será “comum” a todas as grids do seu sistema – e nelas quiser ter a paginação.

using cloudscribe.Web.Pagination;
using System.Collections.Generic;


namespace Coaching.Models
{
    public class Paginacao

    {
        public Paginacao()
        {
            Paging = new PaginationSettings();
        }

        public string Query { get; set; } = string.Empty; //só use se for implementar um grid com pesquisa, se não não precisa estar no modelo

        //public List<Product> Products { get; set; } = null; //não precisa neste exemplo
        //public List<Consultores> ListaConsultores { get; set; } = null; //não precisa neste exemplo

        public PaginationSettings Paging { get; set; }
    }
}

Implantando o serviço de Paginação no Startup

No seu Startup.cs você precisará disso em ConfigureServices:

services.AddCloudscribePagination();

É isso.

Implantando o Tag Helper de Paginação de uma forma genérica

Como você pode querer usar a paginação em qualquer página que tenha uma grade (grid), a opção de incluir num arquivo auxiliar de visualização que é sempre lido (o _ViewImports.cshtml) é a opção mais inteligente. Você, assim, não precisa “solicitar” o tag help nas páginas de visualização. Ele estará sempre presente.

Assim, no arquivo  _ViewImports.cshtml, inclua:

@addTagHelper "*, cloudscribe.Web.Pagination"

Colocando o Tag Helper de Paginação na Visualização (View)

Você vai precisar de alguma coisa parecida com isso:

</p>
<p>&amp;amp;lt;div&amp;amp;gt;<br />
                    &amp;amp;lt;span class=&quot;Navigator&quot;&amp;amp;gt;<br />
                        @*navegador*@<br />
                        @*paginação*@<br />
                        &amp;amp;lt;cs-pager cs-paging-pagesize=&quot;@ViewBag.PageSize&quot; cs-paging-pagenumber=&quot;@ViewBag.PageNumber&quot; cs-paging-totalitems=&quot;@ViewBag.TotalItems&quot; cs-show-first-last=&quot;true&quot; cs-pagenumber-param=&quot;page&quot; cs-suppress-empty-nextprev=&quot;true&quot; cs-suppress-inactive-firstlast=&quot;true&quot; cs-first-page-text=&quot;Primeiro&quot; cs-last-page-text=&quot;Último&quot; cs-pager-li-current-class=&quot;active&quot; cs-pager-li-non-active-class=&quot;disabled&quot; asp-controller=&quot;AcRedePessoas&quot; asp-action=&quot;ConsultoresLista&quot;&amp;amp;gt;&amp;amp;lt;/cs-pager&amp;amp;gt;<br />
                    &amp;amp;lt;/span&amp;amp;gt;<br />
&amp;amp;lt;/div&amp;amp;gt;</p>
<p>

Os parametros de tamanho da página (ViewSize), número da página (PageNumber) e número de itens a serem mostrados (TotalItens) são passados através do controlador (controller), que lê os dados da tabela (que veremos mais adiante). No caso deste exemplo, o controlador (controller) é o AcRedePessoas (todos usuários do sistema) que tem uma ação (Action) chamada ConsultoresLista.

Voce pode colocar esta div no final de sua grade. Ou repetí-la, colocando antes do início da grade e depois do término da grade. No caso deste exemplo, optei por deixá-la só no final da grade. O arquiivo de listagem (vizualização) que chamei de ConsultoresLista.cshtml foi gerado com um “scafolding” no modelo de visualização definido no início.

Atenção: se seu molelo não fizer parte do contexto (não for uma tabela simples do sistema), você precisará incluir o mesmo no seu ArquivodeContexto.cs, dentro da pasta de modelos (Models). Só depois disso você recompila o projeto e faz o scafolding.

No meu caso, a inclusão foi feita assim:

using Microsoft.EntityFrameworkCore;

namespace Coaching.Models
{
    public partial class Alicecapella119Context : DbContext
    {
        public virtual DbSet<AcRedepessoas> AcRedepessoas { get; set; }
        public virtual DbSet<Avaliacoes> Avaliacoes { get; set; }
        public virtual DbSet<AvaliacoesRespostas> AvaliacoesRespostas { get; set; }
        public virtual DbSet<CompetenciasBancoGeral> CompetenciasBancoGeral { get; set; }
        public virtual DbSet<Consultorias> Consultorias { get; set; }
        public virtual DbSet<EmailsEnviados> EmailsEnviados { get; set; }
        public virtual DbSet<Empresas> Empresas { get; set; }
        public virtual DbSet<Log> Log { get; set; }
        public virtual DbSet<ParametrosClicks> ParametrosClicks { get; set; }
        public virtual DbSet<PerguntasBancoGeral> PerguntasBancoGeral { get; set; }
        public virtual DbSet<QuestionarioTipos> QuestionarioTipos { get; set; }
        public virtual DbSet<QuestionariosModelos> QuestionariosModelos { get; set; }
        public virtual DbSet<Reguas> Reguas { get; set; }
        public virtual DbSet<ReguasEscalas> ReguasEscalas { get; set; }
        public virtual DbSet<Relacionamento> Relacionamento { get; set; }
        
        //para procedure ou vizualição via linq
        public virtual DbSet<FormularioViewModels.FormularioViewModel> Formulario { get; set; } //visualiza_lista_respostas
        public virtual DbSet<Consultores> Consultores { get; set; } //visualiza_consultores

Note que a última linha acrescenta o modelo de Consultores, como se fosse uma tabela falsa (fake). É útil apenas para visualização, não serve para edição ou deleção ou criação.

Último passo: o controlador da visualizaçao (view)

O controlador é recheado de “mancadas”. Na verdade, é o segredo da paginação.

Itens por página

Primeiro, você tem que definir quantos itens serão mostrados por página, cada vez que ela é mostrada. Isso é feito definindo-se uma variável privada:

private const int DefaultPageSize = 2;

Isso: no caso, quero que cada página apresente apenas 2 registros. Essa constante você define logo no início do controlador, antes das definições dos Actions.

public class AcRedepessoasController : Controller
    {
        private readonly Alicecapella119Context _context;
        private readonly IEmailService _emailService;
        //para navegação. Se tiver mais de uma ação e quiser diferentes tamanhos, defina mais constantes
        private const int DefaultPageSize = 8; //aqui vai sua constante
       
        public AcRedepessoasController(Alicecapella119Context context
            , IEmailService emailService
            )
        {
            _context = context;
            _emailService = emailService;
        }

Página Inicial

Segundo: quando você entra pela primeira vez na visualização (view), pode não ter uma indicação da página que quer ver. Assim é preciso definir que você quer a primeira página:

//Lista Consultores
        public IActionResult ConsultoresLista(int? page)
        {

            if (page == null)
            {
                page = 1;
            }

Total de Registros

Você não sabe quantos registros existem. No exemplo, quantos consultores existem. A alternativa é descobrir. No meu caso, os consultores são todos aqueles registrados com Nível de Acesso = 3:

var TotalDeConsultores = _context.AcRedepessoas.Where(x => x.NiveldeAcesso == 3).Count();

Carregando os dados numa Lista

Esta etapa é fundamental. Os dados precisam ser mostrados no vizualizador que foi montado pelo scafolding. No caso deste exemplo, a lista de consultores que quero mostrar vem de duas tabelas. Assim, criei uuma ListaDeConsultores, da seguinte forma:

var ListaDeConsultores = (from i in _context.AcRedepessoas
                                      join k in _context.Consultorias on i.IdConsultoria equals k.IdConsultoria
                                      where i.NiveldeAcesso == 3
                                      select new Consultores
                                      {
                                          IdUsuario = i.IdUsuario,
                                          NiveldeAcesso = i.NiveldeAcesso,
                                          Nome = i.Nome,
                                          IdConsultoria = k.IdConsultoria,
                                          Cidade = k.Cidade,
                                          LinkAcesso = k.LinkAcesso,
                                          Telefones = k.Telefones
                                      })
                                    .OrderBy(p => p.Nome)
                                    .Skip(offset)
                                    .Take(DefaultPageSize)
                                    .ToList();

Observe que os campos definido obedecem cegamente aos campos do modelo definido em Consultores.cs, E que o modelo pega exatamente o número de registros necessários a partir de um  default (evitando sobrecarregar a memória do sistema), colocando-os numa lista.

Instanciando dados para a paginação

Para permitir o controle de paginação, você deve adicionar dados ao modelo de paginção, o que é gfeito da seguinte forma:

var model = new Paginacao();
            model.Paging.CurrentPage = currentPageNum;
            model.Paging.ItemsPerPage = DefaultPageSize;
            model.Paging.TotalItems = TotalDeConsultores;

Porém, como nosso modelo é simples, precisamos passar para a visualização (view), dados que permitam atualizar o tag helper. Isso é feito com View.Bags.

ViewBag.CurrentPage = currentPageNum;
            ViewBag.ItemsPerPage = DefaultPageSize;
            ViewBag.TotalItems = TotalDeConsultores;
            ViewBag.PageSize = DefaultPageSize;
            ViewBag.PageNumber = currentPageNum;

Uma visão geral  do controller seria, com todas as dicas:

//Lista Consultores
        public IActionResult ConsultoresLista(int? page)
        {
            if (page == null)
            {
                page = 1;
            }
            var currentPageNum = Convert.ToInt32(page);
            var offset = (DefaultPageSize * currentPageNum) - DefaultPageSize;
  
            var ListaDeConsultores = (from i in _context.AcRedepessoas
                                      join k in _context.Consultorias on i.IdConsultoria equals k.IdConsultoria
                                      //join j in _context.AcRedepessoas on p.IdAvaliador equals j.IdUsuario
                                      //where p.DonorId.Equals(filter)
                                      where i.NiveldeAcesso == 3
                                      select new Consultores
                                      {
                                          IdUsuario = i.IdUsuario,
                                          NiveldeAcesso = i.NiveldeAcesso,
                                          Nome = i.Nome,
                                          IdConsultoria = k.IdConsultoria,
                                          Cidade = k.Cidade,
                                          NomeConsultoria=k.NomeConsultoria,
                                          LinkAcesso = k.LinkAcesso,
                                          Telefones = k.Telefones
                                      })
                                    .OrderBy(p => p.Nome)
                                    .Skip(offset)
                                    .Take(DefaultPageSize)
                                    .ToList();
            var TotalDeConsultores = (from i in _context.AcRedepessoas
                                      join k in _context.Consultorias on i.IdConsultoria equals k.IdConsultoria
                                      where i.NiveldeAcesso == 3
                                      select new Consultores
                                      {
                                          IdUsuario = i.IdUsuario,
                                      })
                                    .Count();
            var model = new Paginacao();
  
            model.Paging.CurrentPage = currentPageNum;
            model.Paging.ItemsPerPage = DefaultPageSize;
            model.Paging.TotalItems = TotalDeConsultores;

            ViewBag.CurrentPage = currentPageNum;
            ViewBag.ItemsPerPage = DefaultPageSize;
            ViewBag.TotalItems = TotalDeConsultores;
            //ViewBag.PageSize = DefaultPageSize;
            ViewBag.PageSize = DefaultPageSize; //Convert.ToInt32(Math.Ceiling(Convert.ToDouble(TotalDeConsultores) / Convert.ToDouble(DefaultPageSize)));//currentPageNum;
            //ViewBag.PageNumber = Convert.ToInt32( Math.Ceiling(Convert.ToDouble(TotalDeConsultores) / Convert.ToDouble(DefaultPageSize)));//currentPageNum;
            ViewBag.PageNumber = currentPageNum;
            return View(ListaDeConsultores);
      }

Note que também são passados os parâmetros para o modelo de paginação, ante (ou depois, não importa) dos ViewBags.

 

O Resultado

O resultado é muito bom. Veja imagens:

Ou ainda, depois de clicar em Último:

Conclusão

O tag helper suporta MUITAS opções. Vejamos quais são:

  • cs-paging-pagenumber – 1 (tem que ser um inteiro)
  • cs-paging-totalitems – 1 (é o total de  itens no banco de dados)
  • cs-paging-maxpageitems – 10 (o máximo a ser mostrado por pégina)
  • cs-pagenumber-param – pageNumber (o nome do parametro vai estar no seu controlador – (“controller”)
  • cs-show-first-last – false (se mostra primeiro ou final no controle)
  • cs-first-page-text – < (string do mostra primeiro)
  • cs-first-page-title – First Page (Titulo do Mostra primeiro)
  • cs-last-page-text – > (texto da última página)
  • cs-last-page-title – Last Page (título da última página)
  • cs-previous-page-text – « (símbolo da página anterior)
  • cs-previous-page-title – Previous page (título da Página anterior)
  • cs-next-page-text – » (símbolo da próxima página)
  • cs-next-page-title – Next page (título da próxima página)
  • cs-pager-ul-class – pagination
  • cs-pager-li-current-class – active
  • cs-pager-li-non-active-class – disabled
  • cs-ajax-target – empty – should be the id of the html element to target for ajax updates
  • cs-ajax-mode – replace
  • cs-ajax-success – empty – a callback
  • cs-ajax-failure – empty – a callback
  • cs-ajax-loading – empty – the #id of an image ie animated gif to show while loading
  • cs-ajax-loading-duration – empty – corresponds to data-ajax-loading-duration

O componente é “inteligente” e só aparece na página se o número de registros for MAIOR que a quantidade máxima por página… Por isso, não se assuste nos testes se ele não aparecer… Para testar, use um valor pequeno como 2 o 3 itens por página, principalmente se seu arquivo ainda não está populado.

Para usar o ajax, você deve incluir jquery.unobtrusive-ajax.js na página. Para usar o AlphaPagerTagHelper, você adicionaria algo assim no seu arquivo visualizador (view):

<cs-alphapager cs-alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    cs-selected-letter="@Model.Query"
    cs-all-label="All"
    asp-controller="Paging"
    asp-action="ProductList" 
    cs-selected-letter-param="query"
    ></cs-alphapager>

Obrigado pela sua leitura. Continue visitando este blog e compartilhe artigos em sua rede de relacionamento. Por favor, se quiser, registre sugestões e comentários ao final da página.

Você quer ter uma franquia de hospedagem com tudo para marketing digital e faturamento recorrente?

franquia builderall business