JSF Formulário para fazer filtro em datatable

Galera,

com JSF (e especificamente com Primefaces),
eu consigo criar um formulário a parte para fazer filtros numa datatable?

Detalhe, estou usando lazy model.

Facilmente.

Pode ser um pouco mais específico?

O datatable nada mais é que um objeto List carregado correto?

Se você utilizar um formulário para filtrar esta List, você pode simplesmente atualizar essa list e solicitar à view que atualize o componente datatable com a lista que foi previamente filtrada no backingbean.

um exemplo seria:

--------- Formulário Filtro ----------

Idade: |------ campo input -------|

|-- Botão Filtrar --|


neste momento, o form não tem nada a ver com o seu datatable que já está carregado, porém, vamos supor que ele carregue com a variável carregarListaPessoas que possui seu respectivo get/set, então, basta só falar pro datatable que o value é #{seuBean.carregarListaPessoa} que este saberá como carregar a lista que está no padrão javabeans. Até aqui eu creio que você não teve problema nenhum correto?

o que difere é que no seu backingbean, no momento que você acionar o botão filtrar, de alguma forma você vai ter que realizar o filtro, aqui entra estilo de programação, você faz da forma que você mais gosta ou sabe fazer.

private List<Pessoa> carregarListaPessoas;

public getCarregarListaPessoas(){
   return this.carregarListaPessoas;
}

puplic void setCarregarListaPessoas(List<Pessoa> carregarListaPessoas){
   this.carregarListaPessoas = carregarListaPessoas;
}

//até aqui também creio que está tudo bem familiar pra ti né? :D
//aqui no construtor tu vai inicializar e carregar a variável

public ConstrutorDaClasse(){
   this.carregarListaPessoas = new ArrayList<Pessoa>();
   this.carregarListaPessoas = umMetodoQueCarregaDadosParaListaDePessoas();
}

//agora você já tem a sua página iniciando com todas as pessoas, e vem a hora de filtrar

public filtrarPorIdade(){
   List<Pessoa> listaTemp = new ArrayList<Pessoa>();
   for (Pessoa p : this.carregarListaPessoas){
      if (p.getIdade == this.idadeQueFoiPassadoNoForm)
          listaTemp.add(p);
   }
   this.carregarListaPessoas = listaTemp;
   RequestContext.getCurrentInstance().update("idDoForm");
}

foi feito no dedo, possivelmente tem um errinho ou outro por aí, mas a IDE concerta =p
Também não lembro direito se é assim o requestContext;

Mas a idéia do todo deu pra entender né? :lol: :lol:

Cara muito obrigado pela paciencia e boa vontade em responder o post.

Bom, o problema é que eu tenho o datatable com lazyloading. Então já tem alguns filtros na tabela.
Agora imagine que na tabela eu tenho 4 colunas, mas quero filtrar por 10 filtros… Inclusive com JOINs e tal.

Vamo supor, tenho entidade Pessoa com idade, nome.

Ai minha datatable ja tem esses filtros. Tranquilo.

Porém a pessoa tem um relacionamento com Cargo. Onde cargo é outra entidade com id e descricao.
Aí quero fazer um JOIN pra buscar todas as pessoas que possuiem cargo onde “descricao” do cargo = “professor”…

Entendeu? Bom, este é o meu problema. Agora vamos a solução que vc propos.

Eu teria um formulario tudo bem…
Mas primeira duvida, qual atributo do meu MB que o form vai ‘abastecer’?
Ex.:

//meu MB
private Cargo cargoFiltro;
//faço get e set para o cargoFiltro..

Aí tudo bem, imaginando então que o value no meu form ficaria assim:

#{meuMb.cargoFiltro.descricao }

Correto?..

Aí o actionListener do meu botão seria um filtrar normal que iria utilizar esse field cargoFiltro …
Só que eu quero fazer isto com ajax… então eu gostaria de atualizar a tabela assim que eu clicasse no botão.

Então o meu método poderia retornar uma List e eu fazer um “update” no xhtml para atualizar a datatable?

Sim, normalmente. É como eu falei no inicio do post passado, os dados que o datatable carrega são provenientes de uma coleção, então você vai estar trabalhando em cima da coleção, e não dos componentes.
Se você quiser acionar o evento e realizar o update via ajax no componente do datatable vai dar certo também, não perde nada :lol:

Quando existem muitos campos para se realizar o filtro, (4 ou mais no meu ponto de vista), eu crio uma classe que contém os atributos do filtro, assim não preciso criar vários elementros dentro do meu managedbean, e sim uma única instância desse objeto bindado ao form. Também facilita na hora de realizar a query, porque você pode criar algo já com os valores dessa classe intermediária, mesmo que venham em branco ou null.

com primefaces você consegue facilmente, dá uma olhada no showcase deles.

[quote=andre.froes]Sim, normalmente. É como eu falei no inicio do post passado, os dados que o datatable carrega são provenientes de uma coleção, então você vai estar trabalhando em cima da coleção, e não dos componentes.
Se você quiser acionar o evento e realizar o update via ajax no componente do datatable vai dar certo também, não perde nada :lol:

Quando existem muitos campos para se realizar o filtro, (4 ou mais no meu ponto de vista), eu crio uma classe que contém os atributos do filtro, assim não preciso criar vários elementros dentro do meu managedbean, e sim uma única instância desse objeto bindado ao form. Também facilita na hora de realizar a query, porque você pode criar algo já com os valores dessa classe intermediária, mesmo que venham em branco ou null.[/quote]

cara vc pode me mostrar um exemplo disso? Tem algum post no teu blog?
Porque eu vou precisar montar a query dinamicamente também
E eu nao sei mto de JPA. Nem sei se tem como fazer automaticamente.
Vc sabe se tem?

No momento estou usando o Spring Data, e não tenho flexibilidade para criar queries dinamicamente. :frowning:
Será que tem como fazer um “gerador” de query deste tipo “genérico”??

Eu tentei fazer, mas não coloquei relacionamentos ficou assim:

	// filters
	List<Predicate> predicates = new ArrayList<Predicate>();

            //esse filters é um map com o valor do field que quero filtrar e o value que o cara digitou...
	for (Entry<String, String> entry : filters.entrySet()) {
	    //Selecione... não é um filtro válido :)
	    if(entry.getValue().equals(noneSelected)){
		continue;
	    }
            // o foda é aqui!! Por que não estou fazendo Join e tal.
	    Expression<String> literal = criteriaBuilder.literal( "%"+entry.getValue()+"%");
	    predicates.add(criteriaBuilder.like(from.<String> get(entry.getKey()), literal));
	}
	accountQuery.where(predicates.toArray(new Predicate[predicates.size()]));

Cara se vc puder me ajudar será mto legal!
Tô precisando e como nao tenho mto conhecimento
sei q vou perder mto tempo com isto.
:frowning:

Tem como tu dar uma olhada na apostila do K19 de JPA2, ela deve ser o suficiente pra te dar a noção que tu ta precisando, JPA é facil bagaramba :smiley:
http://www.k19.com.br/downloads/apostilas/java/k19-k12-desenvolvimento-web-com-jsf2-e-jpa2

dê uma olhada no showcase do primefaces, tem exemplos com isso.

Beleza vou dar uma lida aqui :slight_smile:
valeu

não tem não :slight_smile:

Cara, dei uma olhada na apostila.
Infelizmente não tem nada que eu possa ajudar para o meu caso.

Nada sobre um bean especifico com os filtros e nada sobre query dinamica com JPA
:frowning:

mas vlw mesmo assim

Tem a possibilidade de você criar uma nativeQuery, isso já deve te suprir uai =S, você criaria na mão a query.

não cara :frowning:
na mão não rola de fazer

Essa daí é em último caso, mas com jpa você pode mapear os campos e realizar o filtro. Eu não entendo de Spring, mas não existe nenhum método que você possa injetar para recuperar os valores?

caraa
acabou de cair a fixa…

tem outro problema ENORME nisso aí!!

como que vou fazer a paginação ??? Se quando clico na tabela o primefaces chama o metodo “load” do LazyDataModel???
Iai?

Quando você atualiza o componente datatable do primefaces ele faz a paginação automatica, isso é tranquilo. No showcase tem um exemplo de carregamendo de dados lazy no datatable se não me engano.

Não é tranquilo não cara!

Não é tranquilo pq o MAP de filtros que o prime vai mandar pro método não contém
os filtros externos do meu formulário.

Entende?