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

p:dataTable não atualiza por completo

Olá, estou com uma página .xhtml que possui alguns forms e dataTables. A tabela de listagem de livros cadastrados está apresentando um problema estranho. Quando cadastro algum livro o footer da tabela é atualizado, mas a tabela em si não, tanto que nem chega a acrescentar um botão de paginação quando cadastro mais que 10 livros por exemplo (estou paginando com 5 itens na tabela). O mesmo acontece quando tento excluir um livro. O footer com o tamanho da lista de livros no bean é atualizado mas a tabela em si não. Somente com um refresh na página.

A tabela com problemas fica abaixo do comentário "" com id="tabelaLivros"

Código completo do xhtml:

<?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:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:p="http://primefaces.org/ui"
    xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<h:head />

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

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

    <ui:define name="titulo">Livros</ui:define>
    <ui:define name="conteudo">

        <h:form id="formCamposLivro">

            <!-- CAMPOS DO LIVRO -->
            <p:fieldset legend="Novo Livro" toggleable="true">
                <p:panel header="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="O título não deve possuir tamanho superior a 40 caracteres." styleClass="formLivro">
                            <f:validateLength maximum="40" />
                            <f:ajax event="blur" />
                        </p:inputText>

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

                        <p:outputLabel value="Preço:" for="preco" />
                        <p:inputNumber id="preco" value="#{livroBean.livro.preco}" symbol="R$ " styleClass="formLivro">
                            <f:validateDoubleRange minimum="1" maximum="1000" />  
                            <f:ajax render="msgs" event="blur"/>
                            <p:ajax update="preco" />  
                        </p:inputNumber>  

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

                        <p:outputLabel value="Gênero:" for="generoLivro" />
                        <p:selectOneMenu value="#{livroBean.livro.genero}" required="true" id="generoLivro">
                            <f:selectItem itemLabel="Selecione" itemValue="#{null}"/>
                            <f:selectItems value="#{livroBean.generos}" />
                        </p:selectOneMenu>

                    </h:panelGrid>
                </p:panel>

                <!-- LISTA DE AUTORES -->
                <p:panel header="Autores">
                    <h:panelGrid columns="4">
                        <p:outputLabel value="Nome:" for="autor" />
                        <p:selectOneMenu id="autor" value="#{livroBean.autorId}">
                            <f:selectItem itemLabel="Selecione" noSelectionOption="true"/>
                            <f:selectItems value="#{livroBean.autores}" var="autor"
                                itemLabel="#{autor.nome}" itemValue="#{autor.id}" />
                        </p:selectOneMenu>

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

                        <p:commandLink value="Cadastrar novo autor" action="autor?faces-redirect=true" immediate="true" update="@all"/>
                    </h:panelGrid>

                    <p:dataTable value="#{livroBean.autoresLivro}" var="autor"
                        id="tabelaAutores" emptyMessage="Sem autor." type="definition">
                        <p:column width="50px;" headerText="Remover">
                            <p:commandButton action="#{livroBean.removerAutorDoLivro(autor)}" process="@this" icon="fa fa-fw fa-remove" update="tabelaAutores"/>
                        </p:column>
                        <p:column headerText="Nome do autor">
                            <h:outputText value="#{autor.nome}"/>
                        </p:column>
                    </p:dataTable>
                    </p:panel>

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

        <!-- LIVROS CADASTRADOS -->
        <h:form id="formLivros">
            <p:fieldset legend="Livros Cadastrados">
                <p:dataTable value="#{livroBean.livros}" var="livro"
                    id="tabelaLivros" emptyMessage="Sem resultados." widgetVar="tabelaLivrosVar" filteredValue="#{livroBean.livros}" paginator="true" rows="5">
                    <p:column headerText="Título" sortBy="#{livro.titulo}" filterBy="#{livro.titulo}" filterMatchMode="contains">
                        <h:outputText value="#{livro.titulo}" />
                    </p:column>
                    <p:column headerText="ISBN">
                        <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 pattern="R$ #0.00" />
                        </h:outputText>
                    </p:column>

                    <p:column headerText="Gênero" sortBy="#{livro.genero}"
                        filterBy="#{livro.genero}" filterMatchMode="exact">
                        <f:facet name="filter">
                            <p:selectOneMenu onchange="PF('tabelaLivrosVar').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 headerText="Data de Lançamento" sortBy="#{livro.dataLancamento.time}">
                        <h:outputText value="#{livro.dataLancamento.time}">
                            <f:convertDateTime pattern="dd/MM/yyyy" />
                        </h:outputText>
                    </p:column>
                    <p:column headerText="Remover">
                        <p:commandLink value="Remover" action="#{livroBean.removerLivro(livro)}" update="tabelaLivros" process="@this">
                            <p:confirm header="Confirmação" icon="ui-icon-alert" message="Deseja realmente excluir: #{livro.titulo}"/>
                        </p:commandLink>
                    </p:column>
                    <p:column headerText="Alterar">
                        <p:commandLink value="Alterar" update=":formCamposLivro">
                            <f:setPropertyActionListener value="#{livro}"
                                target="#{livroBean.livro}" />
                        </p:commandLink>
                    </p:column>
                    <p:column headerText="Visualizar">
                        <p:commandButton update=":dialogForm:livroDetail" icon="ui-icon-search" title="Ver" oncomplete="PF('livroDialog').show();">
                            <f:setPropertyActionListener value="#{livro}" target="#{livroBean.livro}" />
                        </p:commandButton>
                    </p:column>
                    <f:facet name="footer">
                        #{fn:length(livroBean.livros)} livros cadastrados.
                    </f:facet>
                </p:dataTable>
            </p:fieldset>
        </h:form>

        <h:form id="dialogForm">
            <p:dialog id="livroDialog" header="Informações do Livro" widgetVar="livroDialog" modal="true" showEffect="fade" hideEffect="fade" resizable="false" width="300">
                 <p:outputPanel id="livroDetail" style="text-align:center" layout="block">
                    <p:panelGrid  columns="2" rendered="#{not empty livroBean.livro}" columnClasses="value"  style="width:100%;">
                        <f:facet name="header">
                            #{livroBean.livro.titulo} 
                        </f:facet>

                        <h:outputText value="Código" />
                        <h:outputText value="#{livroBean.livro.id}" />

                        <h:outputText value="Preço" />
                        <h:outputText value="#{livroBean.livro.preco}" />

                        <h:outputText value="ISBN" />
                        <h:outputText value="#{livroBean.livro.isbn}" />

                        <h:outputText value="Data" />
                        <h:outputText value="#{livroBean.livro.dataLancamento.time}">
                            <f:convertDateTime pattern="dd/MM/yyyy" />
                        </h:outputText>

                        <h:outputText value="Gênero" />
                        <h:outputText value="#{livroBean.livro.genero}" />

                        <h:outputText value="Autores" />
                        <p:dataList value="#{livroBean.livro.autores}" var="autor" type="definition">
                            <h:outputText value="#{autor.nome}"/>
                        </p:dataList>
                    </p:panelGrid>
                </p:outputPanel>
            </p:dialog>
        </h:form>

    </ui:define>
    <ui:define name="nomePagina">Livros</ui:define>
</ui:composition>

</html>

Métodos de gravação e exclusão:

    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();

        } else {
            dao.atualiza(this.livro);
            this.livros = dao.listaTodos();
        }

        this.livro = new Livro();
    }

    public void removerLivro(Livro livro) {
        DAO<Livro> dao = new DAO<Livro>(Livro.class);
        dao.remove(livro);
        this.livros = dao.listaTodos();
    }
2 respostas

Removi filteredValue="#{livroBean.livros}" e voltou a funcionar normal. Esse atritubo é usado somente quando quero usar carregamento Lazy?

solução!

pela documentação ele deve ser usado só quando o filtro está habilitado. Vc referencia uma lista que mantém os dados filtrados. => https://www.primefaces.org/docs/vdl/4.0/primefaces-p/dataTable.html

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