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

Nao altera ou remove

Ao pesquisar o nome do livro, ele filtra porem quando clico em Alterar ou Remover, o livro nao remove, aparece no console que o atributo livro é nulo. Quando não filtro, funciona normalmente. O que pode ser?

7 respostas
        <h:form id="tabelaDeLivros">
        <br />

                <p:dataTable id="tabelaLivros" value="#{livroBean.livros}"
                    var="livro" paginator= "true" rows="5" lazy="false">
                    <!--o atributo headerText subtitui o f:facet  -->
                    <f:facet name="header">Livros</f:facet>

                    <!-- Existem outros MatchModes como endsWidth, contains, exact, equals, lte (menos ou igual) e gte (maior ou igual)  -->
                    <p:column headerText="Titulo" sortBy="#{livro.titulo}" filterBy="#{livro.titulo}" filterMatchMode="contains" >
                        <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}" 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/yyy HH:mm" />
                            <!-- timeZone="America/Sao_Paulo" -->
                        </h:outputText>
                    </p:column>
                    <!--CARREGANDO DADOS PARA O TEXT BOX E PERMITE ALTERAÇÂO  -->
                    <p:column>
                        <f:facet name="header">Alterar</f:facet>

                         <p:commandButton style="margin:10px" icon="fa fa-fw fa-edit" update=":livro">
                            <f:setPropertyActionListener target="#{livroBean.livro}" value="#{livro}" /> <!-- Outra forma de buscar o livro pelo get ao inves de chamar o metodo carregar no commandbutton  -->
                        </p:commandButton>
                    </p:column>
                    <!--EFETUA REMOÇÃO DO LIVRO  -->
                    <p:column  >
                        <f:facet name="header">Remover</f:facet>
                             <p:commandButton style="margin:10px" icon="fa fa-fw fa-trash" action="#{livroBean.remover(livro)}" update="tabelaDeLivros"></p:commandButton> 
<!--                         <p:commandButton update="@form" process="@this"  actionListener="#{livroBean.remover(livro)}" icon="fa fa-fw fa-remove" />
 -->                    </p:column>
                </p:dataTable>

        </h:form>
public class LivroBean implements Serializable {

    private static final long serialVersionUID = 1L;

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


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

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

    }

    public List<Livro> getLivros() {

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

        return livros;
    }

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

    public void 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."));// pegando a exception e jogando como
                                                                                // mensagem na tela
            return;
        }
        // IF para incluir se for um livro novo ou atualizar os dados de um livro
        DAO<Livro> dao = new DAO<Livro>(Livro.class);
        if (this.livro.getId() == null) {
            dao.adiciona(this.livro);
            this.livros = dao.listaTodos();

        } else {
            dao.atualiza(livro);
        }

        this.livro = new Livro();
    }

    // carregando livro nos textbox para alteração // Nao usado mais
    public void carregar(Livro livro) {
        System.out.println("Carregando livro: '" + livro.getTitulo() + "' para alteracao");
        this.livro = livro;

    }

    // metodo para remover o livro
    public void remover(Livro livro) {
        System.out.println("Removendo livro: " + livro.getTitulo());
        DAO<Livro> dao = new DAO<Livro>(Livro.class);
        dao.remove(livro);
        this.livros = dao.listaTodos();
    }

    public void gravarAutor() {
        Autor autor = new DAO<Autor>(Autor.class).buscaPorId(this.autorId);
        this.livro.adicionaAutor(autor);
    }

    // Removendo autor do livro e usando o metodo na classe Livro.
    public void removerAutorDoLivro(Autor autor) {
        this.livro.removeAutor(autor);
    }

    // Tratamento de validação manual do xhtml
    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;
        }
}

    public Integer getLivroId() {
        return livroId;
    }

    public void setLivroId(Integer livroId) {
        this.livroId = livroId;
    }

    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 void setLivros(List<Livro> livros) {
        this.livros = livros;
    }




    /*
     * O Redirecionamento para a pagina poderia ser feito tambem atraves da classe
     * java, util quando se tem biredirecionamento de paginas com IF Usa se na
     * action no xhtml "#{livroBean.formAutor}" Explicacao>
     * https://cursos.alura.com.br/course/jsf/task/1978
     * 
     * public String formAutor() {
     * 
     * return "autor?faces-redirect=true";
     * 
     * }
     */

}

Detalhe, se eu pesquiso na tabela algo ele filtra direito, mas se depois eu apagar essa pesquisa, e usar a paginação os campos da tabela ficam Vazios, Preço vira R$0,00 e Data a data atual.

Fala ai Thiago, tudo bem ?

O primefaces com esse lance de filtro, assume o form para ele, ai seu botão acaba não tendo nenhum comportamento.

Você vai precisar colocar para rodar isso através de um ajax :

<f:ajax render="lista" immediate="true" /> Ou com f:setPropertyActionListener

No botão alterar já até tenho f:setPropertyActionListene

Porém mesmo assim ele assume o valor como nulo apos filtrar e clicar no botão

<p:commandButton style="margin:5px" icon="fa fa-fw fa-edit" update=":livro">
        <f:setPropertyActionListener target="#{livroBean.livro}" value="#{livro}" /> <!-- esta tag  -->
</p:commandButton>

Você não definiu action no seu button.

solução!

Olá Matheus, descobri o problema, na verdade não estava nem no xhtml e nem no bean. O problema estava na minha classe modelo, que eu não havia implementado o Serializable na classe Livro.

Obrigado de qualquer forma :)