Search code examples
javaajaxjsfrichfaces

a4j:commandLink executes action after double clicking


I have a table of users with an a4j:commandLink which deletes the corresponding user, but the problem is that I need to click twice for the action to execute, how can I solve it, here's the code:

            <h:form id="formUsuariosRegistrados">
                <rich:dataScroller for="usersTable" fastControls="hide"
                                   boundaryControls="hide" />
                <rich:dataTable id="usersTable" rows="10" var="user"
                                value="#{administrationBean.tablaUsuarios}">
                    <f:facet name="header">
                        <rich:columnGroup>
                            <rich:column>
                                <h:outputText value="Nombre"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Usuario"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Dependencia"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Email"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Tipo usuario"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Tipo dependencia"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Fecha límite"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value=""/>
                            </rich:column>
                        </rich:columnGroup>
                    </f:facet>
                    <rich:column>
                        <h:outputText value="#{user.nombre}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.usuario}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.dependencia}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.correo}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.tipoUsuario}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.tipoDependencia}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.fechaLimiteCarga}"/>
                    </rich:column>
                    <rich:column>
                        <a4j:commandLink value="Eliminar" immediate="true"
                                         execute="@form"
                                         onclick="return confirm('Esta seguro(a) que deseea continuar?')"
                                         render="@form :formFechaLimite :formModificarContrasena"
                                         action="#{administrationBean.doEliminarUsuario(user.usuario)}"/>
                    </rich:column>
                </rich:dataTable>
            </h:form>

UPDATE

Here's another piece of code that I added to the same view, but now happen two things:

  1. When View is first loaded, if I click on the a4j:commandLink on the table, the action gets called fine.

  2. After doing 1, when I try to check (or uncheck) the <h:sekectBooleanCheckBox> now this component executes ajax after clicking twice.

  3. I tried what BalusC's answers says but I think I am not doing it right with this new form.

    Please advise, cheers

        <h:form id="formFechaLimite">
            <rich:panel style="width: 400px" id="panelFechaLimite">
                <f:facet name="header">
                    <h:outputText value="Fecha limite de carga"/>
                </f:facet>
    
                <h:outputLabel for="fechaLimite" value="Fecha Limite"/>
                <br/>
                <rich:calendar id="fechaLimite"
                               value="#{administrationBean.fechaLimite}"
                               datePattern="dd/MM/yyyy">
                    <a4j:ajax event="change" render="usuarios fechaLimiteModificada"
                              listener="#{administrationBean.doHideEtiquetaFechaModificada}"/>
                </rich:calendar>
                <br/>
                <h:outputLabel for="todosUsuarios"
                               value="Aplicar a todos los usuarios? "/>
                <h:selectBooleanCheckbox id="todosUsuarios"
                                         value="#{administrationBean.fechaTodosUsuarios}">
                    <a4j:ajax event="change" render="usuarios fechaLimiteModificada"
                              listener="#{administrationBean.doCheckBoxChanged}"/>
                </h:selectBooleanCheckbox>
                <br/>
                <a4j:outputPanel id="usuarios">
                    <rich:select value="#{administrationBean.selectedUser}"
                                 defaultLabel="Seleccione un usuario..."
                                 rendered="#{not administrationBean.fechaTodosUsuarios}">
                        <f:selectItems value="#{administrationBean.selectUser}"/>
                        <a4j:ajax event="selectitem" render="fechaLimiteModificada"
                                  listener="#{administrationBean.doHideEtiquetaFechaModificada}"/>
                    </rich:select>
                </a4j:outputPanel>
                <br/><br/>
                <a4j:commandButton value=" Aplicar " execute="@form"
                                   render="@form :panelUsuarios :formUsuariosRegistrados :usersTable"
                                   action="#{administrationBean.doCambiarFechaLimite}"/>
                <a4j:outputPanel id="fechaLimiteModificada">
                    <h:outputText value="Fecha límite modificada !"
                                  rendered="#{administrationBean.renderedEtiquetaFechaModicada}"
                                  style="color: #D17100; font-size: 14px;"/>
                </a4j:outputPanel>
            </rich:panel>
            <br/>
        </h:form>
    
        <br/>
    
        <rich:panel style="width: 800px" id="panelUsuarios">
            <f:facet name="header">
                <h:outputText value="Administración de usuarios"/>
            </f:facet>
            <h:form id="formUsuariosRegistrados">
                <rich:dataScroller for="usersTable" fastControls="hide"
                                   boundaryControls="hide" />
                <rich:dataTable id="usersTable" rows="10" var="user"
                                value="#{administrationBean.tablaUsuarios}">
                    <f:facet name="header">
                        <rich:columnGroup>
                            <rich:column>
                                <h:outputText value="Nombre"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Usuario"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Dependencia"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Email"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Tipo usuario"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Tipo dependencia"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value="Fecha límite"/>
                            </rich:column>
                            <rich:column>
                                <h:outputText value=""/>
                            </rich:column>
                        </rich:columnGroup>
                    </f:facet>
                    <rich:column>
                        <h:outputText value="#{user.nombre}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.usuario}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.dependencia}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.correo}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.tipoUsuario}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.tipoDependencia}"/>
                    </rich:column>
                    <rich:column>
                        <h:outputText value="#{user.fechaLimiteCarga}"/>
                    </rich:column>
                    <rich:column>
                        <a4j:commandLink value="Eliminar" immediate="true"
                                         execute="@form"
                                         ondblclick="return confirm('Esta seguro(a) que deseea continuar?')"
                                         render="@form :formFechaLimite :formModificarContrasena"
                                         action="#{administrationBean.doEliminarUsuario(user.usuario)}"/>
                    </rich:column>
                </rich:dataTable>
            </h:form>
    
            <br/>
    
        </rich:panel>
    

Solution

  • In the other form wherein you're updating the shown form with the table, make sure that you include the client ID of the form in the ajax render. Otherwise the updated form will lose its view state and thus nothing will be processed on 1st submit. After the 1st submit the form get its view state back and subsequent submits will be processed successfully.

    E.g.

    <h:form>
      ...
        <h:commandButton value="Submit" action="#{bean.submit}">
            <f:ajax execute="@form" render=":otherPanel :otherForm" />
        </h:commandButton>
    </h:form>
    
    <h:panelGroup id="otherPanel">
        ...
        <h:form id="otherForm">
            ...
        </h:form>
        ...
    </h:panelGroup>
    

    This problem is related to JSF spec issue 790 and is fixed for the upcoming JSF 2.2. PrimeFaces 3.x doesn't have this problem as its modified JSF ajax engine has already taken this into account.

    See also: