Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

RSS iMasters

[Resolvido] ASP .NET MVC 3: Ordenação, filtragem e paginação com

Recommended Posts

Este artigo é baseado no original: Creating an Entity Framework Data Model for an ASP.NET MVC Application (1 of 10) com adaptações e pequenos ajustes feitos por mim.

Antes de prosseguir, verifique se você possui os seguintes recursos instalados:

Esta é terceira parte do artigo e se você esta chegando agora, deve ler obrigatoriamente as partes anteriores, que você pode acessar por esses links: primeira e segunda.

Neste artigo, vamos abordar e implementar a ordenação, filtragem e paginação dos dados usando o Entity Framework 4.1 e os recursos da ASP .NET MVC 3.

Implementando a Ordenação, Filtragem e Paginação

Abra o Visual Web Developer 2010 Express Edition e no menu File, clique em Open Project. A seguir, selecione o projeto que já foi criado no primeiro artigo, com o nome UniversidadeMacoratti e clique em OK.

A estrutura do projeto exibida na janela Solution Explorer deverá ser a seguinte:

44681.gif

 

 

Obs: Se você quiser continuar a partir deste artigo, faça o download do projeto UniversidadeMacoratti_2.zip para abri-lo no Visual Web Developer 2010 Express Edition.

Se executarmos a aplicação e clicarmos na aba Estudantes, iremos obter a página a seguir - a partir da qual poderemos acionar as funcionalidades para ordenação, filtragem e paginação:

44683.gif

Incluindo links para ordenação nas colunas da página Index dos Estudantes

Para incluir links para ordenação nas colunas do cabeçalho da página Index, vamos alterar o método Index do Controller Estudante e incluir o código necessário na view Index.

1- Incluindo a funcionalidade de ordenação no método Index;

Abra o arquivo EstudanteController.vb que está na pasta Controller (Controller/EstudanteController.vb) e substitua o método Index abaixo:

' GET: /Estudante/

 

Function Index() As ViewResult

 

Return View(db.Estudantes.ToList())

 

End Function

Pelo seguinte código:

  '

' GET: /Student/

Public Function Index(ordenacaoOrdem As String)

 

ViewBag.NomeOrdenacaoParm = IIf(String.IsNullOrEmpty(ordenacaoOrdem), "Nome desc", "")

ViewBag.DataOrdenacaoParm = IIf(ordenacaoOrdem = "Data", "Data desc", "Data")

 

Dim estudantes = From est In db.Estudantes

Select est

 

Select Case ordenacaoOrdem

Case "Nome desc"

estudantes = estudantes.OrderByDescending(Function(est) est.SobreNome)

Exit Select

Case "Data"

estudantes = estudantes.OrderBy(Function(est) est.DataMatricula)

Exit Select

Case "Data desc"

estudantes = estudantes.OrderByDescending(Function(est) est.DataMatricula)

Exit Select

Case Else

estudantes = estudantes.OrderBy(Function(est) est.SobreNome)

Exit Select

End Select

 

Return View(estudantes.ToList())

 

End Function

Esse código recebe um parâmetro ordenacaoOrdem a partir de uma query string na URL, a qual é fornecida pela ASP .NET MVC como um parâmetro para o método action. O parâmetro será uma string que pode ser "Nome" ou "Data", opcionalmente seguida por um espaço e a string "desc" para especificar a ordenação decrescente.

A primeira vez que a página é requisitada, não haverá query string e os estudantes serão exibidos na ordem ascendente de sobrenome.

 

Quando o usuário clicar em um link da coluna para realizar a ordenação, o respectivo valor ordenacaoOrdem será fornecido para a query string.

As variáveis ViewBag são usadas de forma que a view pode configurar os hiperlinks das colunas de ordenação com os valores apropriados da query string.

Obs: ViewBag é usada para passar dados dos controllers para as views da mesma forma que ViewData (ViewBag é só um tipo dinâmico).

  •  ViewBag.NomeOrdenacaoParm = IIf(String.IsNullOrEmpty(ordenacaoOrdem), "Nome desc", "")
  • ViewBag.DataOrdenacaoParm = IIf(ordenacaoOrdem = "Data", "Data desc", "Data")

 

O primeiro código define que, se o parâmetro ordenacaoOrdem for null ou vazio (empty), a variável  ViewBag.NomeOrdenacaoParm deverá ser definida para "Nome desc". Caso contrário, deverá ser definido para uma string vazia ("").

Existem quatro possibilidades, dependendo de como os dados estão atualmente ordenados:

  1. Se a ordem atual for Sobrenome ascendente, o link Sobrenome deve especificar Sobrenome descendente, e o link Data de Matrícula deve especificar Data ascendente;
  2. Se a ordem atual for Sobrenome descendente, os links devem indicar Sobrenome ascendente e Data ascendente;
  3. Se a ordem atual for Data ascendente, os links devem indicar Sobrenome ascendente e Data descendente;
  4. Se a ordem atual for Data descendente, os links devem indicar Sobrenome ascendente e Data ascendente;

O método utiliza o LINQ to Entities para especificar a coluna a ser ordenada. O código cria uma variável IQueryable antes da instrução Select Case, modifica-a na instrução Select Case e chama o método ToList, depois da instrução Select Case.

Quando você cria e modifica variáveis IQueryable, nenhuma consulta é enviada para o banco de dados. A consulta não é executada até que você converta o objeto IQueryable em uma coleção, chamando o método ToList. Por isso, esse código resulta em uma única consulta que não é executada até a chamada da instrução return view.

Incluindo hiperlinks no cabeçalho das colunas da View Index para Estudantes

Na pasta Views\Estudante, abra o arquivo Index.vbhtml e substitua os elementos <tr> e <th> para o cabeçalho da linha pelo seguinte código:

<tr>

<th>

SobreNome

</th>

<th>

Nome

</th>

<th>

Data da Matricula

</th>

</tr>

<tr>

<th>

@Html.ActionLink("Sobrenome", "Index", New With {.ordenacaoOrdem = ViewBag.NomeOrdenacaoParm, .currentFilter = ViewBag.CurrentFilter})

</th>

<th>

Nome

</th>

<th>

@Html.ActionLink("Data Matrícula", "Index", New With {.ordenacaoOrdem = ViewBag.DataOrdenacaoParm, .currentFilter = ViewBag.CurrentFilter})

</th>

</tr>

Esse código utiliza a informação da propriedade ViewBag para definir os hiperlinks com os valores das strings para a consulta.

Executando o projeto e clicando na aba Estudantes temos o seguinte resultado:

44685.gif

Para testar a funcionalidade, basta clicar nos links Sobrenome e Data Matricula.

Incluindo uma caixa de procura para estudantes na página Index

Para incluir a funcionalidade que permite filtrar dados dos estudantes, vamos incluir um controle TextBox e um controle Button na view e fazer os ajustes correspondentes no método Index. A caixa de texto (TextBox) vai permitir que o usuário informe uma string para busca no nome e sobrenome do estudante.

Abra o arquivo EstudanteController.vb, que está na pasta Controllers, e vamos alterar o método Index para ter o seguinte código:

       ' GET: /Student/

Public Function Index(ordenacaoOrdem As String, strCriterio As String)

 

ViewBag.NomeOrdenacaoParm = IIf(String.IsNullOrEmpty(ordenacaoOrdem), "Nome desc", "")

ViewBag.DataOrdenacaoParm = IIf(ordenacaoOrdem = "Data", "Data desc", "Data")

 

Dim estudantes = From est In db.Estudantes

Select est

 

If Not String.IsNullOrEmpty(strCriterio) Then

estudantes = estudantes.

Where(Function(est) est.SobreNome.ToUpper().Contains(strCriterio.ToUpper()) _

OrElse est.Nome.ToUpper().Contains(strCriterio.ToUpper()))

End If

 

Select Case ordenacaoOrdem

Case "Nome desc"

estudantes = estudantes.OrderByDescending(Function(est) est.SobreNome)

Exit Select

Case "Data"

estudantes = estudantes.OrderBy(Function(est) est.DataMatricula)

Exit Select

Case "Data desc"

estudantes = estudantes.OrderByDescending(Function(est) est.DataMatricula)

Exit Select

Case Else

estudantes = estudantes.OrderBy(Function(est) est.SobreNome)

Exit Select

End Select

 

Return View(estudantes.ToList())

 

End Function

Fizemos as seguintes alterações no método Index (as inclusões estão destacadas em negrito):

  1. Incluímos o parâmetro strCriterio do tipo string no método Index;
  2. Incluímos uma cláusula Where na instrução LINQ que seleciona somente estudantes cujo nome, ou sobrenome, contenham a string de critério informada na caixa de texto que iremos incluir na view.

Para incluir a caixa de texto na view, abra o arquivo Index.vbhtml na pasta Views\Estudantes e inclua um título, um TextBox e um Button antes da tag table, conforme mostra o texto destacado no trecho de código da página Index.vbhtml abaixo:

@ModelType IEnumerable(Of UniversidadeMacoratti.UniversidadeMacoratti.Models.Estudante)

@Code

ViewData("Title") = "Estudantes"

End Code

<h2>Estudantes</h2>

<p>

@Html.ActionLink("Criar Novo", "Criar")

</p>

 

@Using Html.BeginForm()

@<p>

Procurar por nome: @Html.TextBox("strCriterio", ViewBag.CurrentFilter)  

<input type="submit" value="Procurar" /></p>

End Using

 

<table>

.....

.....

Execute o projeto e informe um texto como critério de busca na caixa de texto e clique no botão Procurar para verificar o resultado:

44687.gif

Implementando a funcionalidade de paginação

Agora, vamos implementar a paginação. E para isso, usaremos o componente PagedList.

Para obter o componente, você pode usar o NuGet, o próprio ambiente do Visual Web Developer ou do Visual Studio via menu Tools -> Extension Manager e pesquisar pelo componente para fazer o seu download:

44689.gif

Se, mesmo seguindo esse caminho, você não conseguir, procure no Google por PagedList e faça o download neste link. Apos o download, clique no menu Project -> Add Reference e, a seguir, clique em Browse e selecione o local onde você instalou o componente. Selecione PagedList.dll e clique em OK.

44692.gif

Após referenciar o componente, abra o arquivo EstudanteController.vb na pasta Controllers e inclua a instrução imports para o PagedList.

Imports PagedList

A seguir, vamos alterar o método Index deste arquivo, conforme o código abaixo:

        ' GET: /Student/

Public Function Index(ordenacaoOrdem As String, filtroAtual As String, strCriterio As String, pagina As System.Nullable(Of Integer))

 

ViewBag.CurrentOrder = ordenacaoOrdem

ViewBag.NomeOrdenacaoParm = IIf(String.IsNullOrEmpty(ordenacaoOrdem), "Nome desc", "")

ViewBag.DataOrdenacaoParm = IIf(ordenacaoOrdem = "Data", "Data desc", "Data")

 

If Request.HttpMethod = "GET" Then

strCriterio = filtroAtual

Else pagina = 1

 

ViewBag.CurrentFilter = strCriterio

 

Dim estudantes = From est In db.Estudantes

Select est

 

If Not String.IsNullOrEmpty(strCriterio) Then

estudantes = estudantes.

Where(Function(est) est.SobreNome.ToUpper().Contains(strCriterio.ToUpper()) _

OrElse est.Nome.ToUpper().Contains(strCriterio.ToUpper()))

End If

 

Select Case ordenacaoOrdem

Case "Nome desc"

estudantes = estudantes.OrderByDescending(Function(est) est.SobreNome)

Exit Select

Case "Data"

estudantes = estudantes.OrderBy(Function(est) est.DataMatricula)

Exit Select

Case "Data desc"

estudantes = estudantes.OrderByDescending(Function(est) est.DataMatricula)

Exit Select

Case Else

estudantes = estudantes.OrderBy(Function(est) est.SobreNome)

Exit Select

End Select

 

Dim paginaTamanho As Integer = 3

Dim paginaNumero As Integer = (If(pagina, 1))

Return View(estudantes.ToPagedList(paginaNumero, paginaTamanho))

 

End Function

Esse código inclui os seguintes parâmetros ao método Index:

  • Página
  • Filtro Atual

Na primeira execução da página, ou se o usuário não clicar no link de paginação, a variável "página" será null. Se o link de paginação for clicado, a variável irá conter o número da página a ser exibida.

A propriedade ViewBag fornece a view com a ordenação atual, pois isso deve ser incluído nos links de paginação, a fim de manter mesma ordenação da paginação:

  ViewBag.CurrentOrder = ordenacaoOrdem

A outra propriedade ViewBag fornece a view com a string do filtro atual, pois essa string deve ser armazenada no TextBox quando a página for exibida. Além disso, a string deve ser incluída nos links de paginação a fim de manter as configurações de filtro durante a paginação.

Se a string de busca for alterada durante a paginação, a página tem que ser resetada para o valor 1, pois um novo filtro pode resultar em dados diferentes na exibição:

If Request.HttpMethod = "GET" Then

strCriterio = filtroAtual

Else pagina = 1

 

ViewBag.CurrentFilter = strCriterio

No final, a consulta é convertida para um PagedList, em vez de ToList, de forma que ele será passado para a view em uma coleção que suporta a paginação:

            Dim paginaTamanho As Integer = 3

Dim paginaIndice As Integer = (If(pagina, 1)) -1

Return View(estudantes.ToPagedList(paginaIndice , paginaTamanho))

O método ToPageList() usa o índice da página, o qual é base 0, em vez do número da página, que é base 1. Por isso estamos subtraindo uma unidade.

Vamos, agora, definir os links de paginação na View Index do Estudante. Abra o arquivo Index.vbhtml na pasta Views\Estudante\ e altere o código conforme abaixo:

@ModelType PagedList.IPagedList(Of UniversidadeMacoratti.UniversidadeMacoratti.Models.Estudante)  

 

@Code

ViewData("Title") = "Estudantes"

End Code

 

<h2>Estudantes</h2>

 

<p>

@Html.ActionLink("Criar Novo", "Criar")

</p>

 

@Using Html.BeginForm()

@<p>

Procurar por nome: @Html.TextBox("strCriterio", ViewBag.CurrentFilter)  

<input type="submit" value="Procurar" /></p>

End Using

 

<table>

<tr>

<th>

@Html.ActionLink("Sobrenome", "Index", New With {.ordenacaoOrdem = ViewBag.NomeOrdenacaoParm, .currentFilter = ViewBag.CurrentFilter})

</th>

<th>

Nome

</th>

<th>

@Html.ActionLink("Data Matrícula", "Index", New With {.ordenacaoOrdem = ViewBag.DataOrdenacaoParm, .currentFilter = ViewBag.CurrentFilter})

</th>

</tr>

 

@For Each item In Model

Dim currentItem = item

@<tr>

<td>

@Html.DisplayFor(Function(modelItem) currentItem.SobreNome)

</td>

<td>

@Html.DisplayFor(Function(modelItem) currentItem.Nome)

</td>

<td>

@Html.DisplayFor(Function(modelItem) currentItem.DataMatricula)

</td>

<td>

@Html.ActionLink("Editar", "Edit", New With {.id = currentItem.EstudanteID}) |

@Html.ActionLink("Detalhes", "Details", New With {.id = currentItem.EstudanteID}) |

@Html.ActionLink("Deletar", "Delete", New With {.id = currentItem.EstudanteID})

</td>

</tr>

Next

 

</table>

 

<div>

Página @(IIf(Model.PageCount < Model.PageNumber, 0, Model.PageNumber))

de @Model.PageCount

 

@If Model.HasPreviousPage Then

@Html.ActionLink("<<", "Index", New With {.pagina = 1, .ordenacaoOrdem = ViewBag.CurrentSort, .currentFilter = ViewBag.CurrentFilter})

@Html.Raw(" ")

@Html.ActionLink("< Anterior", "Index", New With {.pagina = Model.PageNumber - 1, .ordenacaoOrdem = ViewBag.CurrentSort, .currentFilter = ViewBag.CurrentFilter})

Else

@:<<

@Html.Raw(" ")

@:< Anterior

End If

 

@If Model.HasNextPage Then

@Html.ActionLink("Próxima >", "Index", New With {.pagina = Model.PageNumber + 1, .ordenacaoOrdem = ViewBag.CurrentSort, .currentFilter = ViewBag.CurrentFilter})

@Html.Raw(" ")

@Html.ActionLink(">>", "Index", New With {.pagina = Model.PageCount, .ordenacaoOrdem = ViewBag.CurrentSort, .currentFilter = ViewBag.CurrentFilter})

Else

@:Próxima >

@Html.Raw(" ")

@:>>

End If

</div>

O código que foi alterado está destacado em negrito.

@ModelType PagedList.IPagedList(Of UniversidadeMacoratti.UniversidadeMacoratti.Models.Estudante)

No início da página substituímos a declaração ModelType, onde ao invés da view usar o objeto List, agora estamos usando o objeto PagedList. No final da página, temos a definição do código que controla a paginação.

 

<div>

Página @(IIf(Model.PageCount < Model.PageNumber, 0, Model.PageNumber))

de @Model.PageCount

 

@If Model.HasPreviousPage Then

@Html.ActionLink("<<", "Index", New With {.pagina = 1, .ordenacaoOrdem = ViewBag.CurrentSort, .currentFilter = ViewBag.CurrentFilter})

@Html.Raw(" ")

@Html.ActionLink("< Anterior", "Index", New With {.pagina = Model.PageNumber - 1, .ordenacaoOrdem = ViewBag.CurrentSort, .currentFilter = ViewBag.CurrentFilter})

Else

@:<<

@Html.Raw(" ")

@:< Anterior

End If

 

@If Model.HasNextPage Then

@Html.ActionLink("Próxima >", "Index", New With {.pagina = Model.PageNumber + 1, .ordenacaoOrdem = ViewBag.CurrentSort, .currentFilter = ViewBag.CurrentFilter})

@Html.Raw(" ")

@Html.ActionLink(">>", "Index", New With {.pagina = Model.PageCount, .ordenacaoOrdem = ViewBag.CurrentSort, .currentFilter = ViewBag.CurrentFilter})

Else

@:Próxima >

@Html.Raw(" ")

@:>>

End If

</div>

Executando o projeto iremos obter:

44694.gif

Na base da página temos que:

  • O símbolo  <<  indica que iremos para página inicial;
  • O símbolo  >>  indica que iremos para a última página;
  • O símbolo < Anterior vai para página anterior;
  • O símbolo Próxima > vai para próxima página.

Dessa forma, concluímos todos os ajustes nos controllers e views para implementarmos as funcionalidades de ordenação, filtragem e paginação de dados.

Pegue o projeto completo aqui: UniversidadeMacoratti_3.zip

 

http://imasters.com.br/artigo/23591/dotnet/asp-net-mvc-3-ordenacao-filtragem-e-paginacao-com-ef-parte-03

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.