Search code examples
javajsfprimefaceslazy-loadinglazy-initialization

onShow event fires unnecessarily during each page reloading


I have an issue with making a menu in my project using Primefaces. Actually, this menu will get me a possibility to show some small dialogs with settings for the workspace (by clicking on menu items). Each dialog should have data lazy loading from database. Unfortunately, when I include my dialogs in the page (single xhtml file or a couple xhtml files with ui:include), an event onShow happens on each page reload and this is wrong and provoke too many unnecessary requests to the database.

Here is an example:

UI part

<h:form id="form1">
    <p:menubar id="mainMenu">
    <p:submenu label="Main menu" icon="ui-icon-document">
        <p:menuitem value="My settings" onclick="mySettingsWv.show()" url="#" />
    </p:submenu>
    </p:menubar>
</h:form>

<p:dialog id="mySettingsDlg" header="My Settings" widgetVar="mySettingsWv" resizable="false"
          closable="true" modal="true" showEffect="fade" hideEffect="explode" dynamic="true"
          closeOnEscape="true" onShow="#{mybean.onShow()}">
        <h:outputLabel value="Settings dialog" />
</p:dialog>

ManagedBean part:

@ManagedBean (name = "mybean")
@ViewScoped
public class MyBean {
   public static Logger log = Logger.getLogger(MyBean.class);

    public void onShow() {
       log.info("Method onShow is being called on each page reloading, but dialog still has not been shown");
     }
}

If I use action "onclick" for <p:menuitem> for manual calling the necessary method, it still executes it for each page reloading. Also if I try use actionListener, action attributes it don't work. <p:ajax> cannot be attached to <p:menuitem>.

What should I do in that case? What is wrong can be in my code?


Solution

  • Have a look at the primefaces documentation for p:dialog (same problem with p:menuitem and onclick). There the documentation says about onShow:

    Client side callback to execute when dialog is displayed. (emphasis added)

    That means that you can specify a javascript function there, but it does not work that way to specify a action on your backingbean which is called everytime the dialog is shown. What happens in your case is the following: #{mybean.onShow()} is evaluated only when the file is parsed (i.e. the p:dialog is rendered into the HTML) and then the value which is returned by the method is inserted there (i.e. the empty String).

    To fix this you have to define a javascript callback which makes the call on the bean. You can do this by using p:remoteCommand:

    <p:remoteCommand name="onShow" action="#{mybean.onShow}"
          partialSubmit="true" process="@this"/>
    

    And then specify this callback as the onShow attribute:

    <p:dialog id="mySettingsDlg" ...
          onShow="onShow()">