Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

a4j:commandLink stops working after being reRender

I have created this test case that isolates my problem. The a4j:commandLink action is not executed once the poll does an ajax update. It is executed if we close the modalPanel before the reRender of the poll.

Any suggestion? Thanks in advance.

test.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:fnc="http://eyeprevent.com/fnc">
<a4j:outputPanel id="testing">
<rich:modalPanel id="examinationPanel" autosized="true" width="450" rendered="#{test.condition2}">
    <f:facet name="header">
        <h:outputText value="View Examination Images" />
    </f:facet>
    <f:facet name="controls">
        <h:panelGroup>

            <a4j:form>

                <a4j:commandLink action="#{test.close}">
                    <h:graphicImage value="/images/modal/close.png" id="hideExaminationPanel" styleClass="hidelink" />
                </a4j:commandLink>
            </a4j:form>
            <rich:componentControl for="examinationPanel" attachTo="hideExaminationPanel" operation="hide" event="onclick" />

        </h:panelGroup>
    </f:facet>


    <a4j:form>

        <h:panelGrid columns="1" id="timeoutText">
            <h:outputText id="remainingtime" value="condition1" rendered="#{test.condition1}" />
            <h:outputText id="timer" value="condition2" rendered="#{test.condition2}" />

        </h:panelGrid>

        <a4j:poll id="poll" interval="5000" enabled="#{test.poll}" reRender="poll,timeoutText" />



    </a4j:form>
</rich:modalPanel>

Link

TestBean.java

import org.apache.log4j.Logger;
public class TestBean {
private boolean condition1=false;
private boolean condition2=true;
private boolean poll=true;

public void close(){
Logger.getLogger("com.eyeprevent").info("here!");
poll=false;
condition1=true;
condition2=false;

}

public boolean isCondition1() {
return condition1;
}

public void setCondition1(boolean condition1) {
this.condition1 = condition1;
}

public boolean isCondition2() {
return condition2;
}
public void setCondition2(boolean condition2) {
this.condition2 = condition2;
}
public boolean isPoll() {
return poll;
}
public void setPoll(boolean poll) {
this.poll = poll;
}
} 

TestBean is session scoped. Richfaces version 3.3.2.SR1

And also in Chrome 5.0.322.2 dev the modalPanel does not appear. It does under FF and IE7.

like image 662
pakore Avatar asked Feb 24 '10 14:02

pakore


2 Answers

Try any combination of the following:

  • move the <a4j:form> outside the modal panel
  • set the domElementAttachment (of the modal panel) attribute to either form or parent
  • try using <h:form>

Try the following instead of <a4j:commandLink>:

<h:graphicImage value="/images/modal/close.png" styleClass="hidelink"
            onclick="#{rich:component('examinationPanel')}.hide()" id="close" />

and use onhide="notifyClose()" on the modalPanel, where notifyClose() is defined using <a4j:jsFunction>. This is a bit of a workaround, but might work.

like image 127
Bozho Avatar answered Nov 19 '22 11:11

Bozho


This is the working solution. I accepted Bozho's answer as valid because he proposed the workaround that is implemented here, but I just post the complete solution here in case anybody has the same problem.

test.xhtml:

<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:fnc="http://eyeprevent.com/fnc">
<a4j:outputPanel id="testing">
<rich:modalPanel id="examinationPanel" autosized="true" width="450" rendered="#{test.condition2}" onhide="stopTimer('false')">
    <f:facet name="header">
        <h:outputText value="View Examination Images" />
    </f:facet>
    <f:facet name="controls">
        <h:panelGroup>
            <a4j:form>
                <a4j:commandLink action="#{test.close}">
                    <h:graphicImage value="/images/modal/close.png" id="hideExaminationPanel" styleClass="hidelink" />
                </a4j:commandLink>
            </a4j:form>
            <rich:componentControl for="examinationPanel" attachTo="hideExaminationPanel" operation="hide" event="onclick" />
        </h:panelGroup>
    </f:facet>
    <a4j:form>
        <h:panelGrid columns="1" id="timeoutText">
            <h:outputText id="remainingtime" value="condition1" rendered="#{test.condition1}" />
            <h:outputText id="timer" value="condition2" rendered="#{test.condition2}" />
        </h:panelGrid>
        <a4j:poll id="poll" interval="5000" enabled="#{test.poll}" reRender="poll,timeoutText" />
    </a4j:form>
</rich:modalPanel>
</a4j:outputPanel>
<h:form>
<a4j:commandLink oncomplete="#{rich:component('examinationPanel')}.show()" reRender="testing">Link</a4j:commandLink>
<a4j:jsFunction name="stopTimer" actionListener="#{test.close}">
    <a4j:actionparam name="param1" assignTo="#{test.poll}" />
</a4j:jsFunction>
</h:form>
</html>

It's important to keep the a4j:jsFunction outside of the modalPanel tag.

TestBean.java:

import javax.faces.event.ActionEvent;
import org.apache.log4j.Logger;

public class TestBean {
    private boolean condition1 = false;
    private boolean condition2 = true;
    private boolean poll = true;

    public void close(ActionEvent event) {
        Logger.getLogger("com.eyeprevent").info("here!");
        poll = false;
        condition1 = true;
        condition2 = false;
    }

    public boolean isCondition1() {
        return condition1;
    }

    public void setCondition1(boolean condition1) {
        this.condition1 = condition1;
    }

    public boolean isCondition2() {
        return condition2;
    }

    public void setCondition2(boolean condition2) {
        this.condition2 = condition2;
    }

    public boolean isPoll() {
        return poll;
    }

    public void setPoll(boolean poll) {
        this.poll = poll;
    }
}
like image 37
pakore Avatar answered Nov 19 '22 11:11

pakore