Boa noite,
Estou desenvolvendo um projeto onde tenho uma tela de cadastro de treinamentos. Para cada material do treinamento eu incluo um texto com instruções e um arquivo. Estou gerando o formulário dinamicamente através do botão “Adicionar material”.
O problema ocorre na seguinte situação: eu adiciono um material, digito as instruções e seleciono um arquivo e depois disso, eu clico novamente em “Adicionar material”:
Para exibir os campos dinâmicos eu faço o update no formulário. O problema é que o arquivo selecionado anteriormente se perde. Já tentei atualizar somente o último h:panelGrid
, mas retorna um erro porque ele ainda não existe quando a página é renderizada. Também tentei ignorar o p:fileUpload no update utilizando o update="@(#formularioTreinamento:not(.noUpdate))"
e também não funcionou. Como posso fazer isso funcionar?
Seguem os códigos:
treinamento.xhtml:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui">
<ui:composition template="/WEB-INF/_template.xhtml">
<ui:define name="title">
Treinamentos
</ui:define>
<ui:define name="content">
<h:form id="formularioTreinamento">
<p:growl id="msgs" showDetail="true" rendered="#{not facesContext.validationFailed}" />
<fieldset>
<legend>Cadastrar treinamento</legend>
<h:panelGrid columns="3">
<h:outputLabel value="Nome:" for="nomeTreinamento" />
<h:inputText id="nomeTreinamento" value="#{treinamentoBean.treinamento.nomeTreinamento}" required="true" />
<p:message for="nomeTreinamento" />
</h:panelGrid>
</fieldset>
<fieldset>
<legend>Materiais do treinamento</legend>
<ui:repeat value="#{treinamentoBean.treinamento.treinamentoMateriais}" var="material" varStatus="status" id="teste">
<h:panelGrid columns="4" id="materiais">
<h:outputLabel value="Instruções:" />
<p:inputTextarea value="#{material.instrucoes}" rows="6" cols="50" />
<p:fileUpload id="uploadFileMaterial" value="#{treinamentoBean.uploadedFiles[status.index]}" label="Adicionar arquivo" allowTypes="/(\.|\/)(pdf)$/" mode="simple" skinSimple="true" auto="true" />
<p:commandButton action="#{treinamentoBean.removerMaterial(material)}" value="Remover" icon="ui-icon ui-icon-closethick" />
</h:panelGrid>
</ui:repeat>
<p:commandButton actionListener="#{treinamentoBean.addMaterial()}" update="formularioTreinamento" value="Adicionar material" style="float: right; margin-bottom: 10px; margin-top: 20px;" />
</fieldset>
<p:commandButton id="salvarTreinamento" value="Salvar" update="formularioTreinamento:msgs" actionListener="#{treinamentoBean.salvar}" style="float: right; margin: 3px;" />
</h:form>
</ui:define>
</ui:composition>
</html>
TreinamentoBean.java:
package br.com.mbfarmacias.intranet.bean;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.persistence.EntityManager;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.event.RowEditEvent;
import org.primefaces.model.UploadedFile;
import br.com.mbfarmacias.intranet.dao.DAO;
import br.com.mbfarmacias.intranet.dao.JPAUtil;
import br.com.mbfarmacias.intranet.model.Treinamento;
import br.com.mbfarmacias.intranet.model.TreinamentoMaterial;
@ManagedBean
@ViewScoped
public class TreinamentoBean {
private Treinamento treinamento = new Treinamento();
private List<Treinamento> treinamentos;
private List<UploadedFile> uploadedFiles;
@PostConstruct
public void init(){
EntityManager em = JPAUtil.getEntityManager();
this.treinamentos = (List<Treinamento>) em.createNamedQuery("Treinamento.findAll", Treinamento.class).getResultList();
em.close();
this.treinamento.setTreinamentoMateriais(new ArrayList<>());
this.uploadedFiles = new ArrayList<>();
}
public void salvar(){
try{
new DAO<Treinamento>(Treinamento.class).adiciona(this.treinamento);
this.treinamento = new Treinamento();
addMensagem("Sucesso", "Treinamento adicionado", false);
} catch (Exception e) {
this.treinamento = new Treinamento();
addMensagem("Erro", "Treinamento não foi adicionado", true);
}
}
public void addMaterial(){
/*this.treinamentoMateriais.add(new TreinamentoMaterial());
System.out.println("adicionou: " + treinamentoMateriais.size());*/
this.treinamento.getTreinamentoMateriais().add(new TreinamentoMaterial());
System.out.println("adicionou1: " + this.treinamento.getTreinamentoMateriais().size() + "(" + uploadedFiles.size() + ")");
for (UploadedFile uploadedFile : uploadedFiles) {
System.out.println("nome: " + uploadedFile.getFileName());
}
}
public void removerMaterial(TreinamentoMaterial treinamentoMaterial){
this.treinamento.getTreinamentoMateriais().remove(treinamentoMaterial);
System.out.println("removeu: " + this.treinamento.getTreinamentoMateriais().size());
}
public void apagar(Treinamento treinamento){
new DAO<Treinamento>(Treinamento.class).remove(treinamento);
addMensagem("Sucesso", "Treinamento removido", false);
}
public void atualizar(Treinamento treinamento){
new DAO<Treinamento>(Treinamento.class).atualiza(treinamento);
addMensagem("Sucesso", "Treinamento atualizado", false);
}
public void onRowEdit(RowEditEvent event) {
Treinamento treinamento = (Treinamento) event.getObject();
atualizar(treinamento);
}
public void onRowCancel(RowEditEvent event) {
addMensagem("Edição cancelada","", false);
}
public void addMensagem(String resumo, String detalhe, boolean erro){
if(erro){
FacesMessage mensagem = new FacesMessage(FacesMessage.SEVERITY_ERROR, resumo, detalhe);
FacesContext.getCurrentInstance().addMessage(null, mensagem);
} else{
FacesMessage mensagem = new FacesMessage(FacesMessage.SEVERITY_INFO, resumo, detalhe);
FacesContext.getCurrentInstance().addMessage(null, mensagem);
}
}
public Treinamento getTreinamento() {
return treinamento;
}
public void setTreinamento(Treinamento treinamento) {
this.treinamento = treinamento;
}
public List<Treinamento> getTreinamentos() {
return treinamentos;
}
public void setTreinamentos(List<Treinamento> treinamentos) {
this.treinamentos = treinamentos;
}
public List<UploadedFile> getUploadedFiles() {
return uploadedFiles;
}
public void setUploadedFiles(List<UploadedFile> uploadedFiles) {
this.uploadedFiles = uploadedFiles;
}
}
Alguém tem alguma sugestão?