Mostrando postagens com marcador ASP.NET MVC. Mostrar todas as postagens
Mostrando postagens com marcador ASP.NET MVC. Mostrar todas as postagens

terça-feira, 18 de agosto de 2015

GridView em ASP.NET MVC com Itens Por Página

Neste post irei mostra com implementar a listagem de quantidade de itens por páginas no componente Grid.Mvc. Por padrão ele tem paginação, filtro e ordenação, porém não disponibilizar uma opção para informar a quantidade de itens a serem exibidos, a não ser de forma estática no backend.

Desenvolvi uma solução que está atendendo muito bem as necessidades dos projetos que tenho trabalhado e espero que possa ajudar algum de vocês também.

Toda a documentação de como usar este componente em seu projeto, poder encontrado aqui. O intuito deste poste é mostra apenas inclusão de uma lista para selecionar a quantidade de itens que deverá ser exibida pelo componente.

Após você incorporar o Grid.Mvc em seu projeto é hora de criamos nossa estrutura.

Primeiro devemos criar um classe que irá interceptar as execuções das Actions que contenham dados para GridMvc, isso se dará em forma de anotação, veja:

public class GridMvcAttribute : ActionFilterAttribute
{
    public override void OnActionExecuted(ActionExecutedContext filterContext)
    {
        var controller = (Controller)filterContext.Controller;
        var rd = filterContext.RouteData;
        var request = filterContext.HttpContext.Request;
        var model = controller.ViewData.Model as IQueryable;
 
        var count = model != null ? model.Count() : 0;
 
        int pagesize, page;
 
        if (!int.TryParse(request.Params.Get("grid-page-size"), out pagesize))
            pagesize = GridMvcFilter.DefaultPagesize;
 
        if (!int.TryParse(request.Params.Get("grid-page"), out page))
            page = 1;
 
        var tbFilter = new GridMvcFilter
        {
            Id = rd.Values["id"] as string,
            Action = rd.GetRequiredString("action"),
            Controller = rd.GetRequiredString("controller"),
            GridPage = page,
            GridPageSize = pagesize,
            GridFilter = request.Params.Get("grid-filter"),
            GridOrd = request.Params.Get("grid-ord"),
        };
 
        controller.ViewBag.ItemsPerPage = pagesize;
        controller.ViewBag.ListDropDown = GetListsDropDown(tbFilter, count);  
 
    }
    private static IEnumerable GetListsDropDown(GridMvcFilter tbFilter, int max)
    {
 
        var itemSelected = tbFilter.GridPageSize ?? GridMvcFilter.DefaultPagesize;
        var list = new List();
        const int defaultPageSize = GridMvcFilter.DefaultPagesize;
 
        if (max <= defaultPageSize)
            list.Add(new SelectListItem
            {
                Value = SetLink(tbFilter, defaultPageSize.ToString(CultureInfo.CurrentCulture)),
                Text = defaultPageSize.ToString(CultureInfo.CurrentCulture),
                Selected = true
            });
        else
        {
            for (var i = defaultPageSize; i < max + defaultPageSize; i += defaultPageSize)
            {
                list.Add(new SelectListItem
                {
                    Value = SetLink(tbFilter, i.ToString(CultureInfo.CurrentCulture)),
                    Text = i.ToString(CultureInfo.CurrentCulture),
                    Selected = itemSelected == i
                });
            }
        }
        return list;
    }
 
    private static string SetLink(GridMvcFilter tblParams, string value)
    {
        var filter = tblParams.GridFilter != null ? tblParams.GridFilter.Split(',') : new string[] { };
 
        var gridfilter = "";
        if (filter.Length <= 0)
            return String.Format("/{0}{1}?grid-page={2}&grid-page-size={3}{4}{5}",
                tblParams.Controller,
                (!string.IsNullOrEmpty(tblParams.Action) ? "/" + tblParams.Action : "") +
                (!string.IsNullOrEmpty(tblParams.Id) ? ("/" + tblParams.Id) : ""),
                tblParams.GridPage,
                value,
                tblParams.GridOrd != null ? ("&grid-ord=" + tblParams.GridOrd) : "",
                gridfilter);
 
        gridfilter = filter.Where(item => item.Length > 0).Aggregate(gridfilter, (current, item) => current + ("&grid-filter=" + item));
 
        return String.Format("/{0}{1}?grid-page={2}&grid-page-size={3}{4}{5}",
           tblParams.Controller,
           (!string.IsNullOrEmpty(tblParams.Action) ? "/" + tblParams.Action : "") + (!string.IsNullOrEmpty(tblParams.Id) ? ("/" + tblParams.Id) : ""),
           tblParams.GridPage,
           value,
           tblParams.GridOrd != null ? ("&grid-ord=" + tblParams.GridOrd) : "",
           gridfilter);
    } 
}

Crie também uma classe que conterá a estrutura de filtros, como segue:
public class GridMvcFilter
{
   public const int DefaultPagesize = 10;
   public string Id { get; set; }
   public string Controller { get; set; }
   public string Action { get; set; }
   public string GridOrd { get; set; }
   public string CurrentFilter { get; set; }
   public string GridFilter { get; set; }
   public int? GridPage { get; set; }
   public int? GridPageSize { get; set; }
}
Agora faremos uma pequena alteração no arquivo "_GridPager.cshtml", este arquivo é responsável por renderizar o conteúdo de rodapé do grid. Acrescente este trecho de código, com isso será possível resgatar a lista de páginas gerada pela classe de anotação criada acima.
@{
    var itemsPerPageList = (IEnumerable)ViewBag.ListDropDown;
}

No final do aquivo acrescente o código que irá renderizar a lista, fique a vontade para estilizar.
  @if (Model.ItemsCount > 0)
        {
            
                Página @Model.CurrentPage de @Model.PageCount
                - Exibindo até @Html.DropDownList("grid-page-size", itemsPerPageList, new { @onchange = "location = this.value" })  de @Model.ItemsCount Registros
            
        }

Por a ativação da anotação em uma Action que deve renderizar um Grid.
[GridMvcAttribute]
public ActionResult Index()
{
   var carList = new List();
   for (int i = 1; i <= 50; i++)
   {
      carList.Add(new Car { Id = i, Model = "Model 0" + i, Year = 2010 + i });
   }
   return View(carList.AsQueryable().OrderBy(a=>a.Model));
}

Por último devemos informar ao grid que desejamos utilizar paginação e a quantidade de itens na páginas que desejamos ver.
@Html.Grid(Model).Columns(col =>
{
    col.Add(c => c.Id).Titled("Id").Filterable(true);
    col.Add(c => c.Model).Titled("Model");
    col.Add(c => c.Year).Titled("Year");
}).WithPaging((int)ViewBag.ItemsPerPage).Sortable(true).Filterable(true).WithMultipleFilters()

Atente para o método "WithPaging", nele passamos como parâmetro a variável que foi configurada no na classe GridMvcAttribute.
Todo o projeto é possível encontrar no meu github.