[RESOLVIDO]t:selectOneMenu + a4j:support + Datatable

Pessoal,

Mais uma vez venho solicitar ajuda.

Até encontrei problemas semelhantes… mas as soluções apresentadas eu não consegui resolver.

Meu objetivo é quando selecionar uma opção do comboBox, recarregar a tabela.

O meu problema é que quando o método que recarrega é chamada o valor do idCargo está sempre nulo.

Abaixo o código:

[code]
<h:form id=“frmCadParticipantes” rendered="#{UsuarioSessionBean.usuarioLogado}">

                       <t:selectOneMenu id="menuSltCargos" value="#{cadParticipanteBean.idCargo}" styleClass="comboBox" immediate="true">
                          <f:selectItem itemLabel="Todos" itemValue="0"/>
                          <f:selectItems id="lstCargos" value="#{cadParticipanteBean.comboBoxCargos}"/>
                          <a4j:support event="onchange" reRender="lstParticipantes" actionListener="#{cadParticipanteBean.atualizaDataTable}"
                                       ajaxSingle="true"/>
                       </t:selectOneMenu>

              <rich:dataTable id="lstParticipantes" var="lstParticipantes" value="#{cadParticipanteBean.listaParticipantes}" styleClass="tabela_cadastro" headerClass="cabecalho" width="780px">

                 <t:column width="8%">
                    <center>
                       <f:facet name="header">
                          <h:outputText value="Convidar"/>
                       </f:facet>
                       <h:selectBooleanCheckbox id="parti" value="#{lstParticipantes.selecionado}"/>
                    </center>
                 </t:column>

                 <t:column width="5%">
                    <center>
                       <f:facet name="header">
                          <h:outputText value="Código"/>
                       </f:facet>
                       <h:outputText id="idUsuario" value="#{lstParticipantes.idUsuario}"/>
                    </center>
                 </t:column>

                 <t:column width="32%">
                    <center>
                       <f:facet name="header">
                          <h:outputText value="Nome Completo"/>
                       </f:facet>
                    </center>
                    <h:outputText id="nomeCompleto" value="#{lstParticipantes.nomeCompleto}"/>
                 </t:column>

                 <t:column width="25%">
                    <center>
                       <f:facet name="header">
                          <h:outputText value="Cargo"/>
                       </f:facet>
                    </center>
                    <h:outputText id="dscCargo" value="#{lstParticipantes.dscCargo}"/>
                 </t:column>                     

                 <t:column width="25%">
                    <center>
                       <f:facet name="header">
                          <h:outputText value="E-mail"/>
                       </f:facet>
                    </center>
                    <h:outputText id="email" value="#{lstParticipantes.email}"/>
                 </t:column>

              </rich:dataTable>
        </h:form>[/code]

Cara, tenta retirar o atributo immediate na linha 3.

Retirei e tbm não funcionou.

Alias qdo estou depurando, todo os atributos do meu Bean chegam com valores null.

Normalmente eu uso da seguinde maneira (utilizando seu problema como exemplo):

<t:selectOneMenu id="menuSltCargos" value="#{cadParticipanteBean.idCargo}" valueChangeListener="#cadParticipanteBean.atualizaDataTable}" styleClass="comboBox" > <f:selectItem itemLabel="Todos" itemValue="0"/> <f:selectItems id="lstCargos" value="#{cadParticipanteBean.comboBoxCargos}"/> <a4j:support event="onchange" reRender="lstParticipantes"/> </t:selectOneMenu>

Caso não dê certo, tente usar o a4j:keepAlive, pois talvez seja o problema de se perder nas requisições de páginas.

Valeu pela ajuda diego.

Mas com o keepalive piorou o resultado.

Ele zerou a minha tabela.

O dia todo tentando fazer isso funcionar. :?

Cara, é seguinte:
Toda vez que você usa a tag ajaxSingle=“true” você “processa” SOMENTE esse componente, no caso de um a4j:support o componente pai dele, ou seja, será atribuido ao ManagedBean somente esse cara.
Isso é econômico quando você só quer passar esse cara mesmo, mas caso queira passar mais coisas pro ManagedBean você tem duas opções:

1 - tira a tag ajaxSingle=“true”, que por default é false;
2 - especifica na tag process="" os ids dos componentes que deseja processar, separados por vírgula, ai esses serão atribuidos ao ManagedBean;

Vale a pena estudar o conjunto das seguintes tags quando se usa a4j:

  • ajaxSingle :processa somente esse componente e no caso de a4j:support o componente pai
  • process : adiciona a lista de componentes processados os ids especificados aqui, separados por virgula
  • ajaxRendered : presente nos a4j:outputPanel, que tem por default false e se setado true será reRenderizado a TODA requisição ajax;
  • reRender : indica quais componentes você quer re-renderizar;
  • limitToList : tem como padrão false, mas caso seja setado true limitará a lista especificada no reRender os componentes que serão re-renderizados e mesmo que haja algum com ajaxRendered=“true” esse não será re-renderizado.

Cara, fica muito atento a essas 5 tags, se forem bem utilizadas da pra incrementar uma boa performance em ajax no seu sistema JSF, uma vez que carregará somente o necessário.
Demorei pra pegar a “sincronia” desses caras, infelizmente ninguém me alertou e aprendi na raça.
Recomendo usar o a4j:outputPanel com ajaxRendered = “true” somente quando tiver um <h:messages> ou rich:messages dentro dele, pra exibir a mensagem de erro sem que seja necessário especifca-lo em todo reRender.

Boa sorte!!!

ps: tem alguns componentes, como o selectOneMenu que não funcionam sempre quando tão no process de algum a4j quando estão em ModalPanels, é uma pena =/

Tchello valeu pela explicação.

Mesmo tirando o ajaxSingle não funcionou.

Troca isso:

<a4j:support event="onchange" reRender="lstParticipantes" actionListener="#{cadParticipanteBean.atualizaDataTable}" ajaxSingle="true"/>

Por isso:

 <a4j:support event="onchange" reRender="lstParticipantes" action="#{cadParticipanteBean.atualizaDataTable}"  /> 

E posta aqui o método atualizaDataTable preu dar uma olhada por favor.

Abraços.

Só pra teste faça o seguinte, no seu código original postado, coloque a parte do comboBox em um form a4j:form e a parte da tabela em outro form a4j:form… e no seu <a4j:support tire o ajaxSingle=“true” porque não precisaria nesse caso…

O método é este:

public String getAtualizaDataTable() { this.populaTabela(); return ""; }

O método populaTabela é este:

public void populaTabela() { try { List<ListaParticipanteBean> lst; if (this.getIdCargo() == null || this.getIdCargo() == 0) { lst = new ParticipanteDao().getConsulta(); } else { lst = new ParticipanteDao().getConsulta(2,this.idCargo.toString()); } setListaParticipantes(new ListDataModel(lst)); } catch (SQLException e) { FacesContext.getCurrentInstance().addMessage(null,new FacesMessage(FacesMessage.SEVERITY_ERROR,e.getMessage(),null)); } }

Se montar o selectOneMenu sem o a4j:support… e usar um botão para fazer a mesma coisa funciona.

Alterou o que sugeri ali em cima?
Experimente trocar o <h:form> por a4j:form.

Galera fiz as modificações que vocês sugeriram e não funcionou. :frowning:

Abaixo o código atual:

[code] <a4j:form id=“frmCadParticipantes” rendered="#{UsuarioSessionBean.usuarioLogado}">


















Reunião:
<h:outputText id=“reuniao” value="#{cadParticipanteBean.tema}"/>
Local:
<h:outputText id=“local” value="#{cadParticipanteBean.localReuniao}"/>
Data:
<h:outputText id=“dataReuniao” value="#{cadParticipanteBean.dataReuniao}"/>
Hora:
<h:outputText id=“horaReuniao” value="#{cadParticipanteBean.horaReuniao}"/>
Cargo:
<t:selectOneMenu id=“menuSltCargos” value="#{cadParticipanteBean.idCargo}" styleClass=“comboBox”>
<f:selectItem itemLabel=“Todos” itemValue=“0”/>
<f:selectItems id=“lstCargos” value="#{cadParticipanteBean.comboBoxCargos}"/>
<a4j:support event=“onchange” reRender=“lstParticipantes” actionListener="#{cadParticipanteBean.atualizaDataTable}"/>
</t:selectOneMenu>


</a4j:form>
        <a4j:form id="frmLstCadParticipantes" rendered="#{UsuarioSessionBean.usuarioLogado}">
           <table width="800px" id="tabela_logoff">
              <tr>
                 <td align="right" colspan="2" width="60%">
                    <h:commandButton id="btnSalvar" value="Salvar" styleClass="cmdBotao" action="#{cadParticipanteBean.cadastrar}"/>
                    <h:commandButton id="btnLimpar" value="Limpar" styleClass="cmdBotao">
                    </h:commandButton>
                 </td>
                 <td align="left" width="40%">
                    <h:messages errorClass="msgError" infoClass="msgInfo" fatalClass="msgError"/>
                 </td>
              </tr>
           </table>
           <br><center/><b/>Marque os Participantes que deseja convidar para a Reuni&atilde;o
           <div align="center" style="height:211px; overflow:auto;">
              <rich:dataTable id="lstParticipantes" var="lstParticipantes" value="#{cadParticipanteBean.listaParticipantes}" styleClass="tabela_cadastro" headerClass="cabecalho" width="780px">

                 <t:column width="8%">
                    <center>
                       <f:facet name="header">
                          <h:outputText value="Convidar"/>
                       </f:facet>
                       <h:selectBooleanCheckbox id="parti" value="#{lstParticipantes.selecionado}"/>
                    </center>
                 </t:column>

                 <t:column width="5%">
                    <center>
                       <f:facet name="header">
                          <h:outputText value="Código"/>
                       </f:facet>
                       <h:outputText id="idUsuario" value="#{lstParticipantes.idUsuario}"/>
                    </center>
                 </t:column>

                 <t:column width="32%">
                    <center>
                       <f:facet name="header">
                          <h:outputText value="Nome Completo"/>
                       </f:facet>
                    </center>
                    <h:outputText id="nomeCompleto" value="#{lstParticipantes.nomeCompleto}"/>
                 </t:column>

                 <t:column width="25%">
                    <center>
                       <f:facet name="header">
                          <h:outputText value="Cargo"/>
                       </f:facet>
                    </center>
                    <h:outputText id="dscCargo" value="#{lstParticipantes.dscCargo}"/>
                 </t:column>

                 <t:column width="25%">
                    <center>
                       <f:facet name="header">
                          <h:outputText value="E-mail"/>
                       </f:facet>
                    </center>
                    <h:outputText id="email" value="#{lstParticipantes.email}"/>
                 </t:column>

              </rich:dataTable>
              <t:saveState value="#{cadParticipanteBean.idReuniao}"/>
              <t:saveState value="#{cadParticipanteBean.idCargo}"/>
              <t:saveState value="#{cadParticipanteBean.tema}"/>
              <t:saveState value="#{cadParticipanteBean.localReuniao}"/>
              <t:saveState value="#{cadParticipanteBean.dataReuniao}"/>
              <t:saveState value="#{cadParticipanteBean.horaReuniao}"/>
           </div>
        </a4j:form>[/code]

Aqui o método que popula a tabela:

public void populaTabela() { try { List<ListaParticipanteBean> lst; if (this.getIdCargo() == null || this.getIdCargo() == 0) { lst = new ParticipanteDao().getConsulta(); } else { lst = new ParticipanteDao().getConsulta(2,this.idCargo.toString()); } setListaParticipantes(new ListDataModel(lst)); } catch (SQLException e) { FacesContext.getCurrentInstance().addMessage(null,new FacesMessage(FacesMessage.SEVERITY_ERROR,e.getMessage(),null)); } }

E aqui o método que deveria ser chamado pelo a4j:support

public String getAtualizaDataTable() { this.populaTabela(); return ""; }

Resolvido.

apenas mudei o nome do método de getAtualizaDataTable

para atualizaDataTable

E funcionou.

Valeu pela ajuda.

[quote=w1l14n]Resolvido.

apenas mudei o nome do método de getAtualizaDataTable

para atualizaDataTable

E funcionou.

Valeu pela ajuda.[/quote]
Olá w1l14n, blz??

Cara, estava lendo seu post pra ver se me dava uma luz pra resolver meu problema q é muito parecido com o seu… tem como vc postar seu método getConsulta() da tua classe ParticipanteDao???

Me ajudaria muito.

Valeu!!!