[Resolvido] Problema na criação de componentes dinâmicos com JSF

Olá pessoal

Situação:

Tenho um rich:combobox que ao ser selecionado chama um action no bean para criar dinamicamente vários rich:calendar de acordo com o valor selecionado.

Página:

...
<rich:comboBox id="cmb_quantidade"  immediate="true" value="#{bean.quantidade}">
      <a4j:support event="onchange" action="#{bean.mostrarPanel}"  ajaxSingle="true" reRender="pnl_inputtext" />
</rich:comboBox>

<h:panelGrid id="pnl_inputtext" binding="#{bean.panel}" rendered="#{bean.atualizarPanel}" />

Bean:

...

private boolean atualizarPanel = false;

public String mostrarPanel() {

        getPanel();
        atualizarPanel = true;
        return null;
}

public UIPanel getPanel() {

        criarPanel();
        return panel;
}

private void criarPanel() {

        // Obtém o contexto da aplicação
        Application application = FacesContext.getCurrentInstance().getApplication();
        // Cria um panel
        panel = (UIPanel) application.createComponent(HtmlPanelGrid.COMPONENT_TYPE);
        // Atribui o tipo de redirecionamento
        panel.setRendererType("javax.faces.Grid");
        // Atribui id ao panel
        panel.setId("pnl_inputtext");
        criarComponentes(application);
}

private void criarComponentes(Application application) throws FacesException {

        for (int contador = 1; contador <= this.quantidade; contador++) {

             // Cria um calendar
            HtmlCalendar cldData = (HtmlCalendar) application.createComponent(HtmlCalendar.COMPONENT_TYPE);
            // Atribui id para o inputtext
            cldData.setId("cld_data_" + contador);
         
            // Adiciona o calendar ao panel
            panel.getChildren().add(cldData);
     }
}

Problema:

O evento ocorre, passa pelos métodos mas não exibe o panel na página.

Qualquer ajuda é bem vinda :roll:

Obrigada.

Olá pessoal.

Com a ajuda do Javaubuntu consegui montar gerar os componentes dinamicamente. Segue o como ficou:

Página:

<rich:comboBox id="cmb_quantidade"  value="#{bean.quantidade}"
                           suggestionValues="#{bean.listaDeQuantidade}">
                <a4j:support event="onchange" action="#{bean.mostrarPanelDeData}" ajaxSingle="true" reRender="pnl_data" />
 </rich:comboBox>

<rich:panel id="pnl_data" binding="#{bean.pnlData}" rendered="#{bean.atualizarPanel}" />

Bean:


 public String mostrarPanelDeData() {

        if (quantidade > 0) {
            setPnlData(adicionarComponentes());
            this.atualizarPanel = true;
        } else {
            this.atualizarPanel = false;
        }
        return null;
}

public HtmlPanel adicionarComponentes() {

        for (int contador = 1; contador <= this.extensao.getQuantidadeDeParcelas(); contador++) {

            // Cria um outputlabel
            HtmlOutputLabel lblData = new HtmlOutputLabel();
            // Atribui id para o outputlabel
            lblData.setId("lbl_data_" + contador);
            // Atribui o form para o outputlabel
            lblData.setFor("form_incluir");
            // Atribui valor para o outputlabel
            lblData.setValue(contador + "Data: ");
            // Adiciona o label ao panel
            this.pnlData.getChildren().add(lblData);
            
            // Cria um calendar
            HtmlCalendar cldData = new HtmlCalendar();
            // Atribui id para o calendar
            cldData.setId("cld_data_" + contador);
            // Adiciona a propriedade required
            cldData.getAttributes().put("required", Boolean.TRUE);
            // Adiciona a propriedade requiredMessage
            cldData.getAttributes().put("requiredMessage", "Favor informar a data.");
            // Adiciona a propriedade datePattern
            cldData.getAttributes().put("datePattern", "dd/MM/yyyy");
            // Adiciona a propriedade locale
            cldData.getAttributes().put("locale", "pt_BR");
            // Adiciona o calendar ao panel
            this.pnlDataVencimento.getChildren().add(cldDataDeVencimento);
        }
        return this.pnlData;
    }

O problema agora é que quando seleciono alguma opção no combobox todos os outros campos do formulário ficam vazios :frowning:

Como resolver isso???

Pessoal, ainda não encontrei a solução :frowning:

Troquei o rich:combobox por um a4j:commandButton mas mesmo assim, ao clicar no botão os outros campos são limpos.
Mas não chega a enviar o form pois tenho campos obrigatórios com exibição de mensagens que não são exibidas.

Qualquer ajuda é sempre bem vinda…

Pessoal

Consegui resolver com a4j:commandButton, foi só colocar as propriedades ajaxSingle=“false” e immediate=“true”.

Segue a solução:

Página

<h:panelGroup>
                <a4j:commandButton id="btn_adicionar" value="Adicionar"
                                   action="#{bean.adicionar}"
                                   reRender="pnl_data, btn_remover"
                                   ajaxSingle="false" immediate="true" />

                <a4j:commandButton id="btn_remover" value="Remover"
                                   action="#{bean.remover}"
                                   reRender="pnl_data"
                                   ajaxSingle="false" immediate="true"
                                   rendered="#{bean.mostrarBotaoRemover}" />
</h:panelGroup>

<rich:panel id="pnl_data" binding="#{bean.pnlDatas}"
                        rendered="#{bean.atualizarPanel}" styleClass="sem_borda" />

Bean

    /**
     * Método responsável por atribuir ao panel um panel com componente
     * adicionado.
     */
    public void adicionarData() {

        setPnlDatas(adicionarComponentes());
        this.mostrarBotaoRemover = true;
    }

    /**
     * Método responsável por atribuir ao panel um panel sem o último componente.
     */
    public void removerData() {
        setPnlDatas(removerComponentes());
    }

    /**
     * Método responsável por remover o último componente inserido no panel.
     * @return pnlDatas Panel com o componente removido.
     */
    public HtmlPanel removerComponentes() {

        if (this.contador > 0) {
            this.contador--;
            this.pnlDatas.getChildren().remove(contador);
        }
        if (this.contador == 0) {
            this.mostrarBotaoRemover = false;
        }
        return this.pnlDatas;
    }

    /**
     * Método responsável por adicionar componentes ao panel de assim que é
     * pressionado o botão Adicionar
     * @return pnlDatas Panel com os componentes adicionados.
     */
    public HtmlPanel adicionarComponentes() {

        HtmlPanelGroup pgpComponentes = new HtmlPanelGroup();

        // Cria um outputlabel
        HtmlOutputLabel lblData = new HtmlOutputLabel();
        // Atribui id para o outputlabel
        lblData.setId("lbl_data_" + contador);
        // Atribui o form para o outputlabel
        lblData.setFor("form_incluir");
        // Atribui valor para o outputlabel
        lblData.setValue((contador + 1) + "ª Data: ");
        // Adiciona o label ao panel
        pgpComponentes.getChildren().add(lblData);

        // Cria um label
        HtmlOutputLabel lblBR = new HtmlOutputLabel();
        // Adiciona um atributo de escape ao label
        lblBR.getAttributes().put("escape", Boolean.FALSE);
        // Atribui id para o label
        lblBR.setId("lbl_br_" + contador);
        // Atribui valor para o label
        lblBR.setValue(&quot;<br />");
        // Adiciona o label ao panel
        pgpComponentes.getChildren().add(lblBR);

        // Cria um calendar
        HtmlCalendar cldData = new HtmlCalendar();
        // Atribui id para o calendar
        cldData.setId("cld_data_" + contador);
        // Adiciona a propriedade required
        cldData.getAttributes().put("required", Boolean.TRUE);
        // Adiciona a propriedade requiredMessage
        cldData.getAttributes().put("requiredMessage", "Favor informar a data.");
        // Adiciona a propriedade datePattern
        cldData.getAttributes().put("datePattern", "dd/MM/yyyy");
        // Adiciona a propriedade locale
        cldData.getAttributes().put("locale", "pt_BR");
        // Adiciona o calendar ao panel
        pgpComponentes.getChildren().add(cldDataDeVencimento);

        // Adiciona o label ao panel
        pgpComponentes.getChildren().add(lblBR);

        // Cria um richmessage
        HtmlRichMessage msgErro = new HtmlRichMessage();
        // Referencia o inputtext para exibição da mensagem
        msgErro.setFor("cld_data_" + contador);
        // Adiciona a propriedade styleClass
        msgErro.getAttributes().put("styleClass", "alerta");
        // Adiciona o message ao panel
        pgpComponentes.getChildren().add(msgErro);

        // Adiciona o label ao panel
        pgpComponentes.getChildren().add(lblBR);

        // Adiciona o panel group ao panel
        this.pnlDatas.getChildren().add(pgpComponentes);

        // Incrementa o contador de panel group
        this.contador++;

        // Retorna o panel com o componente adicionado.
        return this.pnlDatas;
    }

Se alguém souber como resolver utilizando o rich:combobox… Compartilhe :wink: