jsfprimefacesbusyindicatorviewaction

How to display a wait indicator for f:viewAction?


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.


Solution

  • 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");
    }