10
respostas

p:selectOneMenu não filtra genero

alguém conseguiu filtrar o genero? o ajax parece não responder...

<p:column headerText="Gênero" sortBy="#{livro.genero}"  filterBy="#{livro.genero}" filterMatchMode="startsWith">
                    <f:facet name="filter">
                        <p:selectOneMenu onchange="PF('tabelaLivros').filter()">
                            <f:selectItem itemLabel="Selecione..." itemValue="#{null}" noSelectionOption="true" />
                            <f:selectItems value="#{livroBean.generos}" />
                        </p:selectOneMenu>
                     </f:facet>
                        <h:outputText value="#{livro.genero}" />
                </p:column>
10 respostas

Oi Aline, boa tarde!

O que acontece quando você tenta fazer o filtro? Aparece alguma mensagem de erro? Carrega mas não mostra nada? Carrega mas continua mostrando todos? Nem carrega nada?Você pode dar um exemplo do teste que fez?

Outra pergunta: você conseguiu adicionar livros com gênero normalmente?

Como está a tag p:dataTable?

Oi Ana, Sim, consigo gravar um livro com Gênero ok. E o livro gravado é exibido também com sucesso no form "formTabelaLivros". Porém ao selecionar um gênero ele não filtra... não ocorre erro... e se estou na página 2 de livros, ele volta para a primeira página.

<!-- LISTA DE LIVROS -->

            <h:form id="formTabelaLivros">
            <p:dataTable value="#{livroBean.livroDataModel}" var="livro" id="tabelaLivros"
                paginator="true" rows="2" lazy="true" widgetVar="tabelaLivros"><!--  gostei mais da solucao anterior em q fazemos apenas 1 consulta ao banco com getLivros -->
                <f:facet name="header">Livros</f:facet>
                <p:column headerText="Titulo" sortBy="#{livro.titulo}" filterBy="#{livro.titulo}" filterMatchMode="contains">
                    <h:outputText value="#{livro.titulo}"/>
                </p:column>
                <p:column sortBy="#{livro.isbn}" filterBy="#{livro.isbn}"  filterMatchMode="contains">
                    <f:facet name="header">ISBN</f:facet>
                    <h:outputText value="#{livro.isbn}" />
                </p:column>
                <p:column headerText="Preço" sortBy="#{livro.preco}" filterBy="#{livro.preco}" filterFunction="#{livroBean.precoEhMenor}">

                    <h:outputText value="#{livro.preco}">
                        <f:convertNumber type="currency" pattern="R$ #0.00"
                            currencySymbol="R$" locale="pt_BR" />
                    </h:outputText>
                </p:column>
                <p:column headerText="Data" sortBy="#{livro.dataLancamento.time}" filterBy="#{livro.dataLancamento.time}" filterMatchMode="contains">

                    <h:outputText value="#{livro.dataLancamento.time}">
                        <f:convertDateTime pattern="dd/MM/yyyy"
                            timeZone="America/Sao_Paulo" />
                    </h:outputText>
                </p:column>
                <p:column headerText="Gênero" sortBy="#{livro.genero}"  filterBy="#{livro.genero}" filterMatchMode="startsWith">
                    <f:facet name="filter">
                        <p:selectOneMenu onchange="PF('tabelaLivros').filter()">
                            <f:selectItem itemLabel="Selecione..." itemValue="#{null}" noSelectionOption="true" />
                            <f:selectItems value="#{livroBean.generos}" />
                        </p:selectOneMenu>
                     </f:facet>
                        <h:outputText value="#{livro.genero}" />
                </p:column>

                <p:column>
                    <f:facet name="header">Alterar</f:facet>
                    <h:commandLink value="altera" action="#{livroBean.carregar(livro)}"/>
                </p:column>                    

                <p:column>
                    <f:facet name="header">Remover</f:facet>
                    <h:commandLink value="remove" action="#{livroBean.remover(livro)}"/>
                </p:column>    
            </p:dataTable>
            </h:form>

Oi Aline,

Qual a versão do Primefaces que está usando?

primefaces-6.2.jar

Tomcat v8.5 Server at localhost

Oi Aline,

Ainda não consegui ver o erro direito. Você poderia colocar também o código das classes LivroBean e Livro?

sim, obrigada pela ajuda.

package br.com.caelum.livraria.modelo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

@Entity
public class Livro implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue
    private Integer id;

    private String titulo;
    private String isbn;
    private double preco;
    @Temporal(TemporalType.DATE)
    private Calendar dataLancamento = Calendar.getInstance();

    @ManyToMany(fetch=FetchType.EAGER)
    private List<Autor> autores = new ArrayList<Autor>();

    private String genero;


    public String getGenero() {
        return genero;
    }

    public void setGenero(String genero) {
        this.genero = genero;
    }

    public List<Autor> getAutores() {
        return autores;
    }

    public void adicionaAutor(Autor autor) {
        this.autores.add(autor);
    }

    public Livro() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public double getPreco() {
        return preco;
    }

    public void setPreco(double preco) {
        this.preco = preco;
    }

    public Calendar getDataLancamento() {
        return dataLancamento;
    }

    public void setDataLancamento(Calendar dataLancamento) {
        this.dataLancamento = dataLancamento;
    }

    public void removeAutor(Autor autor) {
        this.autores.remove(autor);
    }

}
package br.com.caelum.livraria.bean;

import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;

import br.com.caelum.livraria.dao.DAO;
import br.com.caelum.livraria.modelo.Autor;
import br.com.caelum.livraria.modelo.Livro;
import br.com.caelum.livraria.modelo.LivroDataModel;

@ManagedBean
@ViewScoped
public class LivroBean implements Serializable {

    private static final long serialVersionUID = 1L;

    private Livro livro = new Livro();

    private Integer autorId;

    private List<Livro> livros;

    private LivroDataModel livroDataModel = new LivroDataModel();

    private List<String> generos = Arrays.asList("Romance", "Drama", "Ação");



    public List<String> getGeneros() {
        return generos;
    }

    public LivroDataModel getLivroDataModel() {
        return livroDataModel;
    }

    public void setLivros(List<Livro> livros) {
        this.livros = livros;
    }

    public void setAutorId(Integer autorId) {
        this.autorId = autorId;
    }

    public Integer getAutorId() {
        return autorId;
    }

    public Livro getLivro() {
        return livro;
    }

    public List<Livro> getLivros() {
        DAO<Livro> dao = new DAO<Livro>(Livro.class);

        //evitando consultas ao banco de dados:
        if(this.livros == null) {
            this.livros = dao.listaTodos();
        }
        return livros; 
    }

    public List<Autor> getAutores() {
        return new DAO<Autor>(Autor.class).listaTodos();
    }

    public List<Autor> getAutoresDoLivro() {
        return this.livro.getAutores();
    }

    public void carregarLivroPelaId() {
        this.livro = new DAO<Livro>(Livro.class).buscaPorId(this.livro.getId()); 
    }

    public void gravarAutor() {
        Autor autor = new DAO<Autor>(Autor.class).buscaPorId(this.autorId);
        this.livro.adicionaAutor(autor);
        System.out.println("Escrito por: " + autor.getNome());
    }

    public void gravar() {
        System.out.println("Gravando livro " + this.livro.getTitulo());

        if (livro.getAutores().isEmpty()) {
            FacesContext.getCurrentInstance().addMessage("autor",
                    new FacesMessage("Livro deve ter pelo menos um Autor."));
            return;
        }

        DAO<Livro> dao = new DAO<Livro>(Livro.class);
        if(this.livro.getId() == null) {
            dao.adiciona(this.livro);
            this.livros = dao.listaTodos();//qdo adicionar vai tb atualizar a table na tela
        } else {
            dao.atualiza(this.livro);
        }

        this.livro = new Livro();
    }

    public void remover(Livro livro) {
        System.out.println("Removendo livro");
        DAO<Livro> dao = new DAO<Livro>(Livro.class);
        dao.remove(livro);
        this.livros = dao.listaTodos();//qdo remover vai tb atualizar a table na tela
    }

    public void removerAutorDoLivro(Autor autor) {
        this.livro.removeAutor(autor);
    }

    public void carregar(Livro livro) {
        System.out.println("Carregando livro");
        this.livro = livro;
    }

    public String formAutor() {
        System.out.println("Chamanda do formulário do Autor.");
        return "autor?faces-redirect=true";
    }

    public void comecaComDigitoUm(FacesContext fc, UIComponent component,
            Object value) throws ValidatorException {

        String valor = value.toString();
        if (!valor.startsWith("1")) {
            throw new ValidatorException(new FacesMessage(
                    "ISBN deveria começar com 1"));
        }

    }

    public boolean precoEhMenor(Object valorColuna, Object filtroDigitado, Locale locale) { //java.util.Locale
          //tirando espaços do filtro
        String textoDigitado = (filtroDigitado == null) ? null : filtroDigitado.toString().trim();

        System.out.println("Filtrando pelo " + textoDigitado + ", Valor do elemento: " + valorColuna);

        // o filtro é nulo ou vazio?
        if (textoDigitado == null || textoDigitado.equals("")) {
            return true;
        }

        // elemento da tabela é nulo?
        if (valorColuna == null) {
            return false;
        }

        try {
            // fazendo o parsing do filtro para converter para Double
            Double precoDigitado = Double.valueOf(textoDigitado);
            Double precoColuna = (Double) valorColuna;

            // comparando os valores, compareTo devolve um valor negativo se o value é menor do que o filtro
            return precoColuna.compareTo(precoDigitado) < 0;

        } catch (NumberFormatException e) {

            // usuario nao digitou um numero
            return false;
        }
    }
}

Oi Aline,

Já tentou colocar o atributo filteredValue="#{livroBean.filteredLivros}" na tag p:dataTable, juntamente com o atributo private List<Livro> filteredLivros; e seu getter e setter na classe LivroBean?

tentei aqui e teve o mesmo comportamento... acho que pode ter a ver com o "#{livroBean.livroDataModel}" e o "lazy="true"" no "p:dataTable"....

tentei explicitar o ajax dentro do selectOneMenu mas não adiantou...

quando acesso a página livros ele carrega ok com esses selects:

FASE: RESTORE_VIEW 1
/livro.xhtml
FASE: APPLY_REQUEST_VALUES 2
FASE: PROCESS_VALIDATIONS 3
FASE: UPDATE_MODEL_VALUES 4
FASE: INVOKE_APPLICATION 5
FASE: RENDER_RESPONSE 6
mai 25, 2018 2:59:20 PM org.primefaces.component.growl.GrowlRenderer encodeEnd
INFORMAÇÕES: autoUpdate attribute is deprecated and will be removed in a future version, use p:autoUpdate component instead.
Hibernate: select count(livro0_.id) as col_0_0_ from Livro livro0_ limit ?
Hibernate: select autor0_.id as id2_, autor0_.email as email2_, autor0_.nome as nome2_ from Autor autor0_
Hibernate: select livro0_.id as id1_, livro0_.dataLancamento as dataLanc2_1_, livro0_.genero as genero1_, livro0_.isbn as isbn1_, livro0_.preco as preco1_, livro0_.titulo as titulo1_ from Livro livro0_ limit ?
Hibernate: select autores0_.Livro_id as Livro1_1_1_, autores0_.autores_id as autores2_3_1_, autor1_.id as id2_0_, autor1_.email as email2_0_, autor1_.nome as nome2_0_ from Livro_Autor autores0_ inner join Autor autor1_ on autores0_.autores_id=autor1_.id where autores0_.Livro_id=?
Hibernate: select autores0_.Livro_id as Livro1_1_1_, autores0_.autores_id as autores2_3_1_, autor1_.id as id2_0_, autor1_.email as email2_0_, autor1_.nome as nome2_0_ from Livro_Autor autores0_ inner join Autor autor1_ on autores0_.autores_id=autor1_.id where autores0_.Livro_id=?

mas qdo faço o filtro ele faz os selects tb e não reflete na tela:

FASE: RESTORE_VIEW 1
/livro.xhtml
FASE: APPLY_REQUEST_VALUES 2
FASE: PROCESS_VALIDATIONS 3
FASE: UPDATE_MODEL_VALUES 4
FASE: INVOKE_APPLICATION 5
FASE: RENDER_RESPONSE 6
mai 25, 2018 2:59:54 PM org.primefaces.component.growl.GrowlRenderer encodeEnd
INFORMAÇÕES: autoUpdate attribute is deprecated and will be removed in a future version, use p:autoUpdate component instead.
Hibernate: select livro0_.id as id1_, livro0_.dataLancamento as dataLanc2_1_, livro0_.genero as genero1_, livro0_.isbn as isbn1_, livro0_.preco as preco1_, livro0_.titulo as titulo1_ from Livro livro0_ limit ?
Hibernate: select autores0_.Livro_id as Livro1_1_1_, autores0_.autores_id as autores2_3_1_, autor1_.id as id2_0_, autor1_.email as email2_0_, autor1_.nome as nome2_0_ from Livro_Autor autores0_ inner join Autor autor1_ on autores0_.autores_id=autor1_.id where autores0_.Livro_id=?
Hibernate: select autores0_.Livro_id as Livro1_1_1_, autores0_.autores_id as autores2_3_1_, autor1_.id as id2_0_, autor1_.email as email2_0_, autor1_.nome as nome2_0_ from Livro_Autor autores0_ inner join Autor autor1_ on autores0_.autores_id=autor1_.id where autores0_.Livro_id=?

tb coloquei o validatorMessage e não retorna erro:

<p:column headerText="Gênero" sortBy="#{livro.genero}"  filterBy="#{livro.genero}" filterMatchMode="startsWith">
                    <f:facet name="filter">
                        <p:selectOneMenu onchange="PF('tabelaLivros').filter()"    validatorMessage="livros nao encontrados">
                        <!--      <p:ajax update="tabelaLivros" process="col"/> --> 
                            <f:selectItem itemLabel="Selecione..." itemValue="" noSelectionOption="true" />
                            <f:selectItems value="#{livroBean.generos}" />
                        </p:selectOneMenu>
                     </f:facet>
                        <h:outputText value="#{livro.genero}" />
                </p:column>