How to display a wait indicator for f:viewAction?

628 Views Asked by At

I have a JSF page that loads the properties of an object (for which the id is passed in the URL). The loading can last more seconds, so I would like to display a wait/busy indicator or a "Loading..." message.

This is done using "viewAction"

<f:metadata>
    <f:viewAction action="#{myBean.loadParams}" />
</f:metadata>

Is there a simple way to accomplish this goal? I'm using Primefaces.

2

There are 2 best solutions below

2
BalusC On BEST ANSWER

PrimeFaces has already a component ready for that: the <p:outputPanel deferred="true">. You only need to make sure that the #{heavyBean} is only referenced in a component (and thus definitely not in a tagfile like <c:xxx> for the reasons explained here) within the <p:outputPanel> and not somewhere else.

...
#{notHeavyBean.property}
...

<p:outputPanel deferred="true">
    ...
    #{heavyBean.property}
    ...
</p:outputPanel>

...
#{anotherNotHeavyBean.property}
...

Then you can do the heavy job in its @PostConstruct method. Do the job you originally did in <f:viewAction> there in the @PostConstruct.

@Named
@ViewScoped
public class HeavyBean implements Serializable {

    @PostConstruct
    public void init() {
        // Heavy job here.
    }

    // ...
}

If you need to access properties of other beans, simply @Inject those beans in the HeavyBean. E.g. in case you needed the ID view param:

<f:viewParam name="id" value="#{notHeavyBean.id}" />

@Inject
private NotHeavyBean notHeavyBean; // Also @ViewScoped.

@PostConstruct
public void init() {
    Long id = notHeavyBean.getId();
    // Heavy job here.
}

The <p:outputPanel> already comes with an animated gif. You can easily customize it via CSS.

.ui-outputpanel-loading {
    background-image: url("another.gif");
}
0
Neo On

I would like to propose also this simple approach:

  • one "landing" page (the page where we first navigate in) with a wait indicator and an autoRun remoteCommand with an event that read the parameter "param" from the URL and save it in the bean.
  • the remoteCommand does a redirect to another page (where the long-running method loadParams is executed) In this way the wait indicator is shown until the second page is ready to be displayed.

Do you see any weaknesses?

Here the landing page:

<!DOCTYPE html>
<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui">
<h:head>
...
</h:head>
<f:metadata>
     <f:event type="postAddToView" listener="#{notHeavyBean.readProperty}" />
     <f:viewParam name="param"/>
</f:metadata>
<h:body>
  <p:outputPanel layout="block">
      <i class="fa fa-circle-o-notch fa-spin layout-ajax-loader-icon" aria-hidden="true" style="font-size: 40px;position: relative;top: 50%;left: 50%;"></i>
  </p:outputPanel>


<h:form>
    <p:remoteCommand action="#{notHeavyBean.redirect}" autoRun="true"/>
</h:form>


</h:body>