Chrome/Opera/IE7 ignore a4j:push event when modal rich:popupPanel emerges
bevor Jun 15, 2012 4:56 AMI have a rich:dataTable where you can export all data by a download button to a csv file. If download has been clicked, a modal processing dialog appears as long as the download is in progress. The only method to let the processing dialog disappear is to use a push event from backing bean which informs the view to hide the processing panel. This looks like this...
xhtml page
<h:commandLink action="#{customerListController.download()}" style="float: right" onclick="#{rich:component('exportProcessPanel')}.show(); return true;">
<h:graphicImage value="resources/images/page_excel.png" />
</h:commandLink>
<a4j:push address="pushCustomer" onerror="alert(event.rf.data)" ondataavailable="#{rich:component('exportProcessPanel')}.hide();" />
<rich:popupPanel id="exportProcessPanel" autosized="true" modal="true" moveable="true" resizeable="false">
<h:panelGrid columns="2"> <h:graphicImage value="resources/images/loading.gif" />
<h:outputText value="Collecting data... (please be patient)" style="margin-left:10px" />
</rich:popupPanel>
important part of the backing bean (customerListController)
@Inject
@Push(topic = "pushCustomer")
Event<String> pushEvent;
.
.
.
public void download() {
download("Customer");
pushEvent.fire("");
}
download method (in the bean's base class)
public void download(String reportName) {
FacesContext faces = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse)faces.getExternalContext().getResponse();
response.setContentType("application/force-download");
response.setHeader("Content-disposition", "inline; filename=\"" + reportName + "Report-" + new Date() + ".csv\"");
try {
ServletOutputStream os = response.getOutputStream();
byte[] byteOrderMark = new byte[]{(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
os.write(byteOrderMark); OutputStreamWriter osw = new OutputStreamWriter(os);
exportHeader(osw, reportName);
dataModel.exportData(osw);
osw.append("\n\n");
osw.flush();
} catch (IOException e)
{
}
faces.responseComplete();
}
used web.xml settings for pushing....
<context-param>
<param-name>org.richfaces.push.handlerMapping</param-name>
<param-value>/__richfaces_push</param-value>
</context-param>
<!-- if we don't set this, JBoss runs continuously into and endless loop of Exceptions that the servlets doesn't support async (although this should be fixed since 7.0.2) -->
<context-param>
<param-name>org.atmosphere.useBlocking</param-name>
<param-value>true</param-value>
</context-param>
<servlet>
<servlet-name>Push Servlet</servlet-name>
<servlet-class>org.richfaces.webapp.PushServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>Push Servlet</servlet-name>
<url-pattern>/__richfaces_push</url-pattern>
</servlet-mapping>
All this works perfect, rich:component('exportProcessPanel')}.hide(); will be executed only on Firefox and Internet Explorer 8. Other browsers completely ignore it, so the process dialog never disappear there. To be more specific: As long as the modal dialog appears, those browsers don't receive any push events. Maybe this has something to do with faces.responseComplete().
The backing beans always fires the push event when download is finished, even in Chrome/Opera,..., so it's not a problem of bean invocation, but obviously a render problem. I'm not sure how to solve that. There is (due to faces.responseComplete() in download method) no possibility to invoke some kind of redirect/refresh of the view. That's why I solved that with a push event, which unfortunately doesn't work in some browsers.
Any ideas?
I'm using Richfaces 4.2 with Jboss 7.1.1.
By the way: If you know a better solution than using a push event, I would be glad to hear it.