Solucionado (ver solução)
Solucionado
(ver solução)
4
respostas

Após utilizar um dos filtros do p:dataTable e apagar o campo de busca a página 2 e as demais ficam sem dados

Adicionamos as propriedades "filterBy" e "filterMatchMode" nos "p:column" do "p:dataTable", porém ao testar me deparei com um problema.

Exemplo: Digitei a letra "A" no filtro por nome do livro e o dataTable é filtrado corretamente, porém, após apagar os dados do campo utilizado, ao navegar para a página dois, as linhas da lista do dataTable estão vazias e o mesmo acontece para as demais páginas, inclusive se voltar para a página 1 os dados somem do dataTable.

Segue minha view "Livro.xhtml" e o bean "LivroBean.java":

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core"
    xmlns:p="http://primefaces.org/ui"
    xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:fn="http://xmlns.jcp.org/jsp/jstl/functions">

<ui:composition template="_template.xhtml">

    <f:metadata>
        <f:viewParam name="livroId" value="#{livroBean.livroId}" />
        <f:viewAction action="#{livroBean.carregarLivroPeloId}"
            if="#{param.livroId != null}" />
    </f:metadata>

    <ui:define name="titulo">
        <p:outputPanel>Cadastro de Livro</p:outputPanel>
    </ui:define>

    <ui:define name="conteudo">
        <h:form>
            <p:messages id="messages" />
            <p:fieldset legend="Dados do Livro">
                <h:panelGrid columns="2">

                    <p:outputLabel value="Titulo:" for="titulo" />
                    <p:inputText id="titulo" value="#{livroBean.livro.titulo}"
                        required="true" requiredMessage="Título obrigatório."
                        validatorMessage="Título não deve ter mais de 40 caracteres!">
                        <f:validateLength maximum="40" />
                        <f:ajax event="blur" render="messages" />
                    </p:inputText>

                    <p:outputLabel value="ISBN:" for="isbn" />
                    <p:inputMask id="isbn" value="#{livroBean.livro.isbn}"
                        validator="#{livroBean.comecaComDigitoUm}"
                        mask="999-9-99-999999-9">
                        <f:ajax event="blur" render="messages" />
                    </p:inputMask>

                    <p:outputLabel value="Preço:" for="preco" />
                    <p:inputNumber id="preco" value="#{livroBean.livro.preco}"
                        validatorMessage="Preço deve ser no mínimo R$1,00 e no máximo R$1000,00."
                        symbol="R$" symbolPosition="p" decimalSeparator=","
                        thousandSeparator=".">
                        <f:validateDoubleRange minimum="1" maximum="1000" />
                    </p:inputNumber>

                    <p:outputLabel value="Data de Lançamento:" for="dataLancamento" />
                    <p:calendar id="dataLancamento"
                        value="#{livroBean.livro.dataLancamento.time}"
                        pattern="dd/MM/yyyy" timeZone="America/Sao_Paulo" mask="true"
                        locale="pt" />


                </h:panelGrid>
            </p:fieldset>
            <br />
            <p:fieldset legend="Dados do Autor">

                <p:panelGrid columns="4">
                    <p:outputLabel value="Selecione o Autor:" for="autor" />

                    <p:selectOneMenu value="#{livroBean.autorId}" id="autor">
                        <f:selectItems value="#{livroBean.autores}" var="autor"
                            itemLabel="#{autor.nome}" itemValue="#{autor.id}" />
                    </p:selectOneMenu>

                    <p:commandButton value="Gravar Autor"
                        action="#{livroBean.gravarAutor}" process="@this autor"
                        update="tabelaAutores">
                    </p:commandButton>

                    <p:commandLink value="Cadastrar novo autor"
                        action="#{livroBean.formAutor}" immediate="true" update="@all" />
                </p:panelGrid>

                <p:dataList value="#{livroBean.autoresDoLivro}" var="autor" type="definition" id="tabelaAutores" emptyMessage="Nenhum autor selecionado">
                    <f:facet name="header">Autores</f:facet>

                    #{autor.nome}

                    <p:commandButton icon="fa fa-fw fa-remove" action="#{livroBean.removerAutorDoLivro(autor)}" update="tabelaAutores"  process="@this"> </p:commandButton>                
                </p:dataList>
            </p:fieldset>

        <br />
            <p:commandButton value="Gravar" action="#{livroBean.gravar}" process="@form" update="@form :formTabelaLivros:tabelaLivros"></p:commandButton>
        </h:form>
        <br /><br />

        <h:form id="formTabelaLivros">
            <p:dataTable value="#{livroBean.livros}" var="livro" id="tabelaLivros" paginator="true" rows="5">
                <f:facet name="header">Livros</f:facet>
                <p:column headerText="Título" sortBy="#{livro.titulo}" filterBy="#{livro.titulo}" filterMatchMode="startsWith">
                    <h:outputText value="#{livro.titulo}" />
                </p:column>
                <p:column headerText="ISBN" sortBy="#{livro.isbn}" filterBy="#{livro.isbn}" filterMatchMode="contains">
                    <h:outputText value="#{livro.isbn}" />
                </p:column>
                <p:column headerText="Preço" sortBy="#{livro.preco}" filterBy="#{livro.preco}" filterMatchMode="startsWith">
                    <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 de Lançamento" sortBy="#{livro.dataLancamento.time}" filterBy="#{livro.dataLancamento.time}" filterMatchMode="contains">
                    <h:outputText value="#{livro.dataLancamento.time}">
                        <f:convertDateTime pattern="dd/MM/yyyy HH:mm" />
                    </h:outputText>
                </p:column>
                <p:column headerText="Alterar">
                    <h:commandLink value="Editar"
                        action="#{livroBean.carregarDadosLivro(livro)}"></h:commandLink>
                </p:column>
                <p:column headerText="Remover">
                    <h:commandLink value="Remover" action="#{livroBean.remover(livro)}"></h:commandLink>
                </p:column>
            </p:dataTable>
        </h:form>
    </ui:define>
    <ui:define name="rodape">
        Cadastro de livros.
    </ui:define>
</ui:composition>

</html>

LivroBean.java:

package br.com.caelum.livraria.bean;

import java.util.List;
import java.util.Locale;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
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.util.RedirectView;

@ManagedBean
@ViewScoped
public class LivroBean {

    private Livro livro = new Livro();
    private Integer autorId;
    private Integer livroId;
    private List<Livro> livros;

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

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

        DAO<Livro> dao = new DAO<Livro>(Livro.class);
        if (this.livro.getId() == null) {
            dao.adiciona(this.livro);
            this.livros = dao.listaTodos();
        } else {
            new DAO<Livro>(Livro.class).atualiza(this.livro);
        }

        return new RedirectView("livro");
    }

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

    public void remover(Livro livro){
        System.out.println("Removendo livro...");
        new DAO<Livro>(Livro.class).remove(livro);
    }

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

    // carrega livro pelo ID
    public void carregarLivroPeloId(){
        this.livro = new DAO<Livro>(Livro.class).buscaPorId(livroId);
    }

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

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

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

    public List<Livro> getLivros() {
        DAO<Livro> dao = new DAO<Livro>(Livro.class);
        if(this.livros == null){
            this.livros = dao.listaTodos();
        }
        return livros;
    }

    // chamando formulário autor
    public RedirectView formAutor(){
        return new RedirectView("autor");
    }

    //validators
    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 deve começar com 1."));
        }
    }

    //FiltroPreço
    public boolean precoEMenor(Object valorColuna, Object filtroDigitado, Locale 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;
        }
    }

    // getters and setters
    public Integer getAutorId() {
        return autorId;
    }

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

    public Livro getLivro() {
        return livro;
    }

    public void setLivro(Livro livro) {
        this.livro = livro;
    }

    public Integer getLivroId() {
        return livroId;
    }

    public void setLivroId(Integer livroId) {
        this.livroId = livroId;
    }
}
4 respostas
solução!

Olá Esequiel, tudo bem?

Não sou expert com relação ao Primefaces, mas lembro de um projeto que estava usando o primefaces e precisei implementar Serializable nas classes para o filtro funcionar.

Espero que essa informação ajude de alguma forma!

Abs

Rafael... Muito obrigado. Precisei implementar Serializable nos meus modelos.

Deu certo parceiro!

Só implementar Serializable nos Model?

Olá Guilherme,

Isto mesmo.

Você implementa a classe Serializable e manda gerar o serial ID automaticamente.

Depois, tudo funciona normal.

É que perdia a referência do objeto. O Serializable resolve.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software