3

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
    }

}
Loric
  • 1,678
  • 8
  • 28
  • 48
  • When/How are you constructing the bean ? Are you clicking a `p:commandButton` ? If so you could use the `onstart` and `oncomplete` attribute. If not, update your code so I can see how you're doing it. – Andy Jul 31 '13 at 12:32
  • It's a project with a lot of pages. Beans are loaded by click on the menu or by click on button on other pages. So I would like to have something general. I edit my question to try to explain. – Loric Jul 31 '13 at 13:00
  • 1
    well for a more general answer you could do `` 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 Jul 31 '13 at 13:06
  • If you don't understand let me know and I can draw out a more concrete example. – Andy Jul 31 '13 at 13:11
  • Thank for those precisions but in fact I tried this and I would like a solution that works for non ajax processes. Like I click a button and behind the function take a long time to execute so I could start the gif before the call and stop it when the process is over. – Loric Jul 31 '13 at 13:17
  • Off the top of my head I don't see how for non ajax...unless you use a `p:progressbar` http://stackoverflow.com/questions/17657041/progress-bar-primefaces-on-backend-processing/17690809#17690809 – Andy Jul 31 '13 at 13:28
  • I think the problem is the same for a progress bar if I follow this example to fire. `` Because the start is linked on the button event and I would like to start it from everywhere in the html or from the bean. (Or I will need to set the start on each button of my project) – Loric Jul 31 '13 at 13:33
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/34537/discussion-between-andy-and-loric) – Andy Jul 31 '13 at 13:36

1 Answers1

5

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

Loric
  • 1,678
  • 8
  • 28
  • 48
  • I was just going to suggest something similar. Good job ! – Andy Aug 01 '13 at 18:53
  • is it also possible to show a modal dialog for non-ajax load? for ajax i use `p:ajaxStatus` with custom content ``, so my idea is to show/hide the `nonAjaxLoad` dialog using `PF('nonAjaxLoad').show()` and `PF('nonAjaxLoad').hide` from your javascript solution?! – raho Nov 03 '17 at 07:31