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?
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?
<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.
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 :)