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

Criar mais de um objeto na mesma página

Boa tarde! Estou fazendo um formulário de uma ordem de serviço, que tem um Cliente e um Defeito. Entretanto, para cada defeito deve ser gerada uma nova OrdemDeServico, mas quero aproveitar os dados do Cliente. E quero manter tudo em uma única página, para não precisar abrir outros formulários.

No inicio, um formulário por ordem de serviço, está fácil.

Bean

@Named
@RequestScoped
public class OrdemServicoBean {

    private OrdemServico os = new OrdemServico();

    @Inject
    private OrdemServicoDAO dao;

    public OrdemServico getOs() {
        return os;
    }

    @Transactional
    public void salvar() {
        dao.save(os);
    }

}

Minha classe OrdemServico possui os atributos Cliente e Defeito...

No formulário, eu quero manter os dados do cliente, porém após apertar determinado botão, deve abrir uma nova div com os dados do defeito... Essa parte na .xhtml eu tento desenrolar depois, minha dúvida é só no AutoInfracaoBean...

Alguém pode me dar uma luz???

9 respostas

Vitor, tudo bem ?

Cara você pode ter quantos objetos quiser na front.

Eu não entendi qual é sua dúvida, não tenho nenhum contexto para poder te ajudar

Olá Matheus, realmente, após reler o que escrevi vi que não soube me expressar.

Bom, meio que já vi como vou fazer isso criando uma List.

Entretanto, estou tendo um outro problema. Coloquei para exibir a lista dessa forma:

<h:dataTable value="#{ordemBean.defeitos}" var="#{defeito}">
         <h:column>
                          <h:outputText value="Cód: #{defeito.codigo}" />
                          <h:outputText value="#{defeito.descricao}" />
        </h:column>
 </h:dataTable>

Ele mostra se eu já incluir um Defeito dentro da Lista Defeitos... Mas se eu clico no botão adicionar, que deveria gerar um novo defeito, que eu coloquei manualmente no código.. por exemplo:

<h:commandButton class="btn btn-success" value="Adicionar defeito" action="#{ordemBean.addDefeito}" />

Estando o método desta forma no OrdemBean:

public void addDefeito() {
        Defeito d = new Defeito("1","Opa");

        this.defeito.getDefeitos().add(d);
    }

Quando clico em Adicionar defeito, aparece esse erro no console:

INFO  [javax.enterprise.resource.webcontainer.jsf.renderkit] (default task-51) AVISO: FacesMessage(s) foram enfileirados, mas podem não ter sido exibidos.
sourceId=j_idt2:data-infracao[severity=(ERROR 2), summary=(Erro de conversão ao definir o valor '' para 'null Converter'. ), detail=(Erro de conversão ao definir o valor '' para 'null Converter'. )]

Faz tempo que quebro a cabeça aqui... :///

Na verdade, nem assim dá certo.. quando botei eles num selectItems, até apareceu o primeiro.. agora que botei nesse dataTable, ta dando esse erro:

Path Info:null Query String:null Stack Trace javax.servlet.ServletException javax.faces.webapp.FacesServlet.service(FacesServlet.java:671)

Oi Vitor, tudo bem? seu projeto esta no GitHub? Você pode passar o link do projeto para a gnt dar uma olhada aqui?Precisariamos dar uma olhada no Bean inteiro e no .xhtml inteiro tb =)

Valeu =)

Esse último erro era de chaves... ainda persiste o problema da conversão e eu não faço a minima ideia do que é... ://

Samir, obrigado pela resposta.

Bom, não está no github, mas eu minimizei ao máximo para que possa copiar tudo pra cá. Nessa minimizada, não aparece mais o erro de conversão. Mas não está aparecendo os nomes na tela, não sei se é problema de Scope.

Vamos lá:

Models:

import java.util.ArrayList;
import java.util.List;

public class Carro {

    List<Condutor> condutores = new ArrayList<>();
    private String modelo;

    public List<Condutor> getCondutores() {
        return condutores;
    }
    public void setCondutores(List<Condutor> condutores) {
        this.condutores = condutores;
    }
    public String getModelo() {
        return modelo;
    }
    public void setModelo(String modelo) {
        this.modelo = modelo;
    }

}

public class Condutor {

    private String nome;

    public Condutor(String nome) {
        this.nome = nome;
    }

    public String getNome() {
        return nome;
    }

    public void setNome(String nome) {
        this.nome = nome;
    }


}

Bean


import java.util.List;

import javax.faces.bean.ViewScoped;
import javax.inject.Named;

@Named
@ViewScoped
public class CarroBean {

    Carro carro = new Carro();

    public void addCondutor() {
        this.carro.getCondutores().add(new Condutor("Teste"));
    }

    public List<Condutor> getCondutores() {
        return this.carro.getCondutores();
    }

    public void limpaCondutores() {
        this.carro.getCondutores().clear();
    }

}

xhtml

<!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:ui="http://xmlns.jcp.org/jsf/facelets"
    xmlns:h="http://xmlns.jcp.org/jsf/html"
    xmlns:f="http://xmlns.jcp.org/jsf/core">

    <h:form>
            <h:dataTable value="#{carroBean.condutores}" var="condutor">
                <h:column>
                     <h:outputText value="#{condutor.nome}" />
                </h:column>
             </h:dataTable>

        <h:commandButton value="Adicionar condutor" action="#{carroBean.addCondutor}" />
        <h:commandButton value="Limpar condutores" action="#{carroBean.limpaCondutores}" />
    </h:form>

</html>

Bom, não tá aparecendo os novos condutores na tela, desta forma.

solução!

Fala Vitor! Entendi o seu problema!

Como vc está com o viewScoped ele dura apenas um request. Se vc mudar para SessionScoped (a classe vai ter que implmentar Serializable) vai funcionar mas o ideal é vc gravar no banco de dados e buscar no banco na hora da inicialização.

Espero ter ajudado =)

Samir, mais uma vez muito obrigado.

Bom, realmente funcionou com o @SessionScoped, mas se o usuário sair da tela, eu queria que apagasse, ou desse um new no Bean. Como posso fazer isso??

Em relação ao BD, não era uma informação que eu gostaria de guardar. O caso concreto é um pouco diferente desse, mas é a mesma ideia.

OI Vitor, desculpe a demora!

nesse caso você precisa usar ajax nos botões:

<h:commandButton value="Limpar condutores" action="#{carroBean.limpaCondutores}" >
    <f:ajax render="@form"/>
</h:commadButton>