views:

2098

answers:

2

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"&gt;
<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.

+2  A: 

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.

Bozho
I got this test case from a component in my application which has this problem. The component has the domElementAttachment on "parent", but the link is not working. I'm going to try to move the form...
pakore
Moving the form outside the modalPanel does not help either. Thanks anyway for the answer.
pakore
@pakore - I meant - move the form outside, and get rid of the second form. Did you try that?
Bozho
yes I've tried placing the form wrapping everything in the code. I've tried placing it wrapping the modalPanel tag as well. (Removing all the nested forms in both cases of course). Nothing worked.
pakore
@pakore try `<h:form>`. And see my update
Bozho
@Bozho I need to execute a method in the backing bean when you close the modalPanel clicking on the image (the image is just an "X" on the top-right of the modalPanel). Your updated solution would close the window, indeed but it wouldn't execute #{test.close} method.
pakore
@pakore I see. This sounds like a strange use-case btw, but anyway - check my update. I'm offering a workaround.
Bozho
yeah this could work. I'll let you know. Why is a strange use-case? The idea is just to keep the modalPanel active for N seconds (hence the timer) and if the user closes the modalPanel before N=0, we just disable the poll (and the TimerTask at the server side) to save processing. Maybe if I could read a js variable from the server I could do it...but I don't know if it possible and I don't think it is a good solution though.
pakore
@Bozho reading the doc I discover I could use a4j:actionParam with a4j:jsFunction to send variables to the server side. This is what I was looking for. I'm gonna try to do this ;)
pakore
+2  A: 

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"&gt;
<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;
    }
}
pakore