ASP.NET MVC + Flexigrid ( Parte 3 ) – Habilitando e configurando a busca (Dynamic Linq ou Func)

Standard

No artigo anterior vimos como podemos efetuar a ordenação em nosso grid, agora iremos ver como habilitar e configurar a busca nativa do Flexigrid. Porém, antes de começar gostaria de exclarecer que, neste post, estarei demonstrando o uso da ferramenta de busca já existente e nativa no Flexigrid. No decorrer do artigo irei demonstrar alguns prós e contras quanto a esta busca, e sugerir alguns complementos que podem deixar a busca ainda mais útil e potente.

Primeiramente, vamos inserir mais algumas colunas (CPF, Telefone e Endereço) em nossa classe de Cliente, veja:

Imagem 1

Em seguida vamos modificar nosso carregamento do grid, de forma que exiba as colunas criadas anteriormente:

//Para cada cliente cria uma linha no grid
foreach (var item in listaPaginada)
{
    flexigrid.rows.Add(new FlexigridLinha
    {
        //id da linha - opcional
        id = item.codCliente,

        //celulas da linha - cada string representa uma coluna em nosso grid
        //(deve estar na mesma ordem das colunas definidas em nosso script)
        cell = new List<string>
        {
            item.codCliente.ToString(),
            item.nome,
            item.cpf,
            item.telefone,
            item.endereco
        }
    });
}

E em nosso script, vamos incluir as colunas também:

colModel: //Cria as colunas
[
    { display: 'Código', name: 'codCliente', width: $(document).width() * 0.10, sortable: true, align: 'center' },
    { display: 'Nome', name: 'nome', width: $(document).width() * 0.10, sortable: true, align: 'left' },
    { display: 'CPF', name: 'cpf', width: $(document).width() * 0.10, sortable: true, align: 'left' },
    { display: 'Telefone', name: 'telefone', width: $(document).width() * 0.10, sortable: true, align: 'left' },
    { display: 'Endereço', name: 'endereco', width: $(document).width() * 0.30, sortable: true, align: 'left' }
],

Habilitando a busca

Agora, para habilitarmos nossa busca, primeiramente devemos definir quais as colunas poderam ser buscadas, para o exemplo irei definir as colunas Nome, CPF, Telefone e Endereço. Para tanto devemos definir a propriedade searchitems no grid. Veja:

searchitems:
[
	{ display: 'Nome', name: 'nome', isdefault: true },
        { display: 'CPF', name: 'cpf' },
        { display: 'Telefone', name: 'telefone' },
        { display: 'Endereço', name: 'endereco' }
],

NOTA: Observe que a propriedade isdefault define qual o campo padrão que será definido na busca.

Em seguida vamos habilitar a barra de status do grid:

usepager: true

Ao final, nosso script do grid deve estar como abaixo:

Imagem 2

 

Configurando a busca

Inicialmente, as únicas informações que precisamos para realizar a busca é o nome do campo a ser buscado e o valor digitado. Vale ressaltar que, a busca do Flexigrid realiza a busca apenas de um campo por vez, ou seja, escolhido o campo digita-se o texto a ser buscado.

Vamos definir as seguintes propriedades no método CarregaFlexgrid para o recebimento dos campos:

string textoBuscado = Request.Params["query"];
string campoBuscado = Request.Params["qtype"];

Para efetuar a busca com Dynamic Linq, basta realizar o seguinte:

var listaPaginada = listaClientes.Where(String.Format("{0}.Contains(@0)", campoBuscado), textoBuscado)
                                 .OrderBy(campoOrdenacao + " " + tipoOrdenacao)
                                 .Skip((indicePaginaAtual - 1) * itensPorPagina)
                                 .Take(itensPorPagina);

Pronto, desta forma nossa busca já funciona, porém, com algumas resssalvas. :/

Prós x Contras e Sugestões

Se analisarmos, desta forma nossa busca irá funcionar apenas se utilizarmos campos do tipo string, uma vez que estamos utilizando EF para persistência, o mesmo não realiza conversões automáticas. Para um exemplo simples, vamos supor o seguinte situação:

listaClientes.Where(String.Format("{0}.ToString().Contains(@0)", campoBuscado), textoBuscado)

Isto acarretaria um erro em tempo de execução, pois o EF não efetua estes tipos de conversões em Run-Time, no caso o .ToString(). Já com Linq To SQL isso funcionaria sem problemas. 🙂

Uma outra foma de realizarmos a busca seria criar uma Func, veja:

Func<Cliente, bool> whereClause = (i => (i.GetPropValue<string>(campoBuscado)).ToLower().Contains(textoBuscado.ToLower()));

E definindo a extenssão GetPropValue:

public static T GetPropValue<T>(this object component, string propertyName)
{
      return (T)System.ComponentModel.TypeDescriptor.GetProperties(component)[propertyName].GetValue(component);
}

E apenas:

listaClientes.Where(whereClause)

Porém, da mesma forma como monstrado antes, isso funcionaria apenas com strings. Para casos mais complexos recomendo a utilização do PredicateBuilder (mas este é um tema para outro post).

Prós

  • Criação de busca com muita facilidade;
  • Parte integrante do próprio Flexigrid;
  • Rapidez.

Contras

  • Para buscas mais complexas acaba sendo inviável;
  • Busca apenas um campo por vez.

Sugestão

Para cenários mais complexos recomendo a utilização do PredicateBuilder.
Bom, por hoje é isso.

 

Leave a Reply

Your email address will not be published. Required fields are marked *