jsf/primefaces load indicator during init of the bean

13,024

I have a solution!

It was very simple and there is nothing to do with primefaces or with the JSF bean construction process.

I just added this in my template (that is included for every pages)

<div id="nonAjaxLoad">
    <img src="../images/ajaxload.gif"/>
</div>

Then I added the css below to move it fixed to the bottom right of the page

#nonAjaxLoad {
    width: 50px;
    height: 50px;
    position: fixed;
    bottom: 30px;
    right: 30px;
}

And to make it magical, I added this script

<script>
    $(document).ready(function(){
        $('#nonAjaxLoad').hide();
    });

    $(window).bind('beforeunload', function() {
        $('#nonAjaxLoad').show(); 
    });
</script>

So when I leave the page, the loading indicator is shown and when the other page is loaded, it's hidden.

Thanks to everyone that helped especially @Andy

Share:
13,024

Related videos on Youtube

Loric
Author by

Loric

Updated on September 15, 2022

Comments

  • Loric
    Loric over 1 year

    In my JSF/Primefaces project, I have a lot of data loading in the init (postconstruct) method of my beans. That's why I would like to show an gif indicator during the bean load.

    I tried with primefaces and the Ajax status (programmatic version of the showcase)

    http://www.primefaces.org/showcase/ui/ajaxStatusScript.jsf
    

    So I added this to the template of my project

    <p:dialog modal="true" widgetVar="loadWidget" header="Status"
        draggable="false" closable="false">
    
        <p:graphicImage value="../images/ajaxload.gif" />
    </p:dialog>
    

    I would like to be able to call loadWidget.show(); at the beginning of the init method of my bean and loadWidget.hide(); at the end.

    Do you have an idea where and how to fire the javascript to display the loading gif? Thanks

    EDIT

    I could add that I tried this. Here is the part of my template that include the content of the page. It's not working either the p:dialog is included before or after the content.

    <div class="content">
        <script>loadWidget.show();</script>
            <ui:insert name="body" />
        <script>loadWidget.hide();</script>
    </div>
    

    The console says loadWidget is not defined

    EDIT2

    I will try to explain how my project works. Could be helpful.

    Here is my template

    <html ... >
    
    <f:view contentType="text/html">
    
        <h:head> ... </head>
    
        <h:body>
            <ui:insert name="header" />
            <ui:insert name="menu" />
            <ui:insert name="body" />
            <ui:insert name="footer" />
            ... <!-- Other things -->
        </h:body>
    </f:view>   
    </html>
    

    Then each page defines the body. Example of a page.

    <html ... >
    
    <ui:composition template="myTemplateAbove">
    
        <ui:define name="body">
    
                <h:outputText value="#{beanOfMyFirstPage.myText}" />
                <p:commandButton action="#{beanOfMyFirstPage.goToAnotherPage}" />
                ...
            </ui:define>
    </ui:composition>
    
    </html>
    

    Then each page is linked to a bean that extends a BaseBean.

    @ManagedBean(name = "beanOfMyFirstPage")
    @ViewScoped
    public class beanOfMyFirstPage extends BaseBean {
        // attributes + getters and setters
    
        @PostConstruct
        public void init() {
            super.init();
            ... // actions that take time cause of DB requests for example
        }
    
        public void goToAnotherPage() {
            navigation.handleNavigation(FacesContext.getCurrentInstance(), null, "mySecondPage");
        }
    
        // methods
    }
    

    And the common bean

    public class BaseBean {
    
        @PostConstruct
        public void init() {
            super.init();
            // General actions for all beans
        }
    
    }
    
    • Andy
      Andy
      well for a more general answer you could do <p:ajaxStatus onstart="loadWidget.show()" oncomplete="loadWidget.hide()"/> instead of the div. p:ajaxStatus will monitor all global ajax request and call the p:dialog. The only downside I can see is that it will fire for all ajax. You could set global = "false" for the inputs you're not interested in. But I'm not sure if that's what you're after. If it works let me know and I'll add this as the answer. If not, we'll try to figure more out.
  • Andy
    Andy over 10 years
    I was just going to suggest something similar. Good job !
  • raho
    raho over 6 years
    is it also possible to show a modal dialog for non-ajax load? for ajax i use p:ajaxStatus with custom content <p:dialog id="nonAjaxLoad" widgetvar="nonAjaxLoad"><p:graphicImage/></dialog>, so my idea is to show/hide the nonAjaxLoad dialog using PF('nonAjaxLoad').show() and PF('nonAjaxLoad').hide from your javascript solution?!