Primefaces Growl onclose event?

2.1k views Asked by At

Is there any way to detect when the growl dialog has been closed, and act on that event?

No ajax events are listed for growl in the PrimeFaces userguide, nor are there any onclose or oncomplete javascript handler attributes.

The reason I need this, is that i use a poller which is deactivated when a dialog is opened, and i wish to reactivate the poller after the growl message is closed.

I was reactivating the poller after the original dialog was closed, but for some reason the addition of the growl broke the reactivation of the poller. The restarted poller polled once till the growl appeared, then stopped.

So .. my idea is to move the reactivation of the poller till after the growl is closed.

The code is in several fragments, one fragment has the poller, which can be started and stopped via a toolbar button (only the poller shown here):

  <h:form id="form-toolbar">

        <!-- poller -->
        <p:poll id="pollerDataTable"
           widgetVar="p4mPollerDataTable"
           interval="10"
           async="true"
           global="false"
           update=":form-toolbar:dtItems"
           listener="#{controller.refreshDataTable}"
           autoStart="false" />

        [snip]

   </h:form>

One fragment has the growls:

   <h:form id="form-body-growl">
       <p:growl id="growlSuccess" for="success" severity="info" infoIcon="/img/LOGO_H150.png"
                warnIcon="/img/LOGO_H150.png" errorIcon="/img/LOGO_H150.png"
                sticky="false" life="3000"/>
       <p:growl id="growlError" severity="warn, error" infoIcon="/img/LOGO_H150.png"
                warnIcon="/img/LOGO_H150.png" errorIcon="/img/LOGO_H150.png"
                sticky="true" globalOnly="true"/>
   </h:form>

One fragment has a command button to show the dialog:

    <p:commandButton id="tbBtnNew"
                     icon="ui-icon-plus"
                     title="#{facesUtilsBean.getLocalizedText(webUiConstBean.BUNDLE_BASE_NAME_UI_STRING, 'toolbar.tooltip.new')}"
                     actionListener="#{controller.onShowNewDialog}"
                     update=":form-dlgNew:new"
                     onsuccess="p4mDlgNew.show();"/>
    <p:tooltip for="tbBtnNew" showEffect="fade" hideEffect="fade" />

Another contains the dialog being opened:

    <!-- new dialog -->
    <h:form id="form-dlgNew">
        <p:dialog header="New" id="dlgNew"
                  widgetVar="p4mDlgNew" resizable="false" dynamic="true" modal="true" closable="false">

            <div class="dialog-container">
                <h:panelGrid id="new" columns="3" columnClasses="formText, formValue, formValidation" styleClass="defaultTable" style="width:100%;" rendered="#{not empty controller.editingItem}">
                    <ui:insert name="newDialogColumns"/>
                    <p:spacer/>
                    <p:column colspan="2">
                        <p:commandButton styleClass="cmdButtonSaveCancel" ajax="false"
                                         value="#{facesUtilsBean.getLocalizedText(webUiConstBean.BUNDLE_BASE_NAME_UI_STRING, 'dialog.save.button')}"
                                         actionListener="#{controller.onSaveNewDialog}" update=":form-toolbar:dtItems, :form-body-growl:growlSuccess, :form-body-growl:growlError"
                                         onsuccess="p4mDlgNew.hide();" process="new"/>
                        <p:commandButton styleClass="cmdButtonSaveCancel" ajax="false"
                                         value="#{facesUtilsBean.getLocalizedText(webUiConstBean.BUNDLE_BASE_NAME_UI_STRING, 'dialog.cancel.button')}"
                                         actionListener="#{controller.onCancelNewDialog}" update=":form-toolbar:dtItems" onsuccess="p4mDlgNew.hide();" process="@this"/>
                    </p:column>
                </h:panelGrid>
            </div>
        </p:dialog>
    </h:form>

And then in the backing bean there are event handlers which pause and resume polling

public void suspendPolling() {
    RequestContext requestContext = RequestContext.getCurrentInstance();
    requestContext.execute(POLLER_DATATABLE_CLIENT_ID + ".stop();");
}


public void resumePolling() {
    RequestContext requestContext = RequestContext.getCurrentInstance();
    requestContext.execute(POLLER_DATATABLE_CLIENT_ID + ".start();");
}


public void onShowNewDialog(ActionEvent event) {
    if (isAutoRefreshActive()) {
        suspendPolling();
    }

    [snip]
}


/**
 * Called by new button template when 'cancel' button clicked.
 * Refreshes data and resumes polling if necessary.
 */
public void onCancelNewDialog(ActionEvent event) {

    [snip]

    if (isAutoRefreshActive()) {
        resumePolling();
    }
}


/**
 * Called by new button template when 'accept' button clicked.
 * Refreshes data and resumes polling if necessary.
 */
public void onSaveNewDialog(ActionEvent event) throws PSoftIOException {

    [snip]

    if (isAutoRefreshActive()) {
        resumePolling();
    }

}

So, please, would there be a way to move the resumePolling functionality till after the growls are closed?

Or .. alternatively (and better even), a way to fix the orginial problem, that the growls broke the poller?

Cheers

[edit ]

Further Information regarding the active status of the poller.

We check and controll the active status of the poller using the following code in the Bean:

private ToolBarRefreshController getToolBarRefreshController() {
    return (ToolBarRefreshController) FacesUtils.resolveBean("toolBarRefreshController");
}

private boolean isAutoRefreshActive() {
    ToolBarRefreshController toolBarRefreshController = getToolBarRefreshController();
    if (toolBarRefreshController == null) {
        return false;
    }

    return toolBarRefreshController.isAutoRefreshActive();
}

public void startAutoRefresh() {
    // nesting starting polling must be prevented
    if (!isAutoRefreshActive()) {
        refreshDataTable();
        resumePolling();
        getToolBarRefreshController().setAutoRefreshActive(true);
    }
}


public void stopAutoRefresh() {
    // nesting stopping polling must be prevented
    if (isAutoRefreshActive()) {
        suspendPolling();
        getToolBarRefreshController().setAutoRefreshActive(false);
    }
}
1

There are 1 answers

1
Tankhenk On BEST ANSWER

The Primefaces userguide says the following thing about using requestContext.execute:

RequestContext provides a way to execute javascript when the ajax request completes, this approach is easier compared to passing callback params and execute conditional javascript.

So if you want to use the RequestContext.execute never put your commandbuttons on ajax="False" because then the requestContext doesn't work.

Also check if your Poller is running already is a good practice because i noticed that if you call POLLER_DATATABLE_CLIENT_ID + ".start();" The poller starts with a new instance but you can't stop this anymore. I don't know if this is a bug or expected behaviour.

For a clean check you can use the following code to check if the poller needs to be started again:

requestContext.execute("if(!" POLLER_DATATABLE_CLIENT_ID +".isActive()){" POLLER_DATATABLE_CLIENT_ID +".start()}");