Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine in the backing bean if a p:dialog is open?

Is there a way to tell from the backing bean if a Primefaces Dialog is opened in the browser?

This is how I show a dialog on the facelet:

<p:menuitem value="Click me" oncomplete="dialogWidget.show();" />

When I look up the Dialog object from the ViewRoot, both dialog.isVisible() and dialog.isInView() returns true even though the dialog is not shown. Alternatively, is there a flag that tells me whether the main window is grayed out (this happens when a modal dialog is shown)?

Background info: I'm trying to figure out where to display my FacesMessages. My application can display messages in 2 locations: main window or in dialog pop-ups. When a modal dialog is in opened, I want the message to only display in the dialog. If there is no dialog shown, I want the message to display in the main window.

like image 438
citress Avatar asked Feb 28 '13 19:02

citress


1 Answers

Keeping track of dialog's status in a backing bean via listeners

You can keep dialog's open status as a boolean varable in you bean.

For this you can attach an actionListerer attribute of <p:menuItem> that will set the bean's boolean openStatus property to true. To switch that property back to false, essentially handling close, you can nest <p:ajax event="close" listener="#{dialogBean.dialogClosed}"> within your <p:dialog> with appropriately defined listeners.

The bean:

@ManagedBean
@ViewScoped
public class DialogBean implements Serializable {

    private boolean openStatus = false;//getter + setter

    public void dialogOpened(ActionEvent event) {
        openStatus = true;
    }

    public void dialogClosed(CloseEvent event) {
        openStatus = false;
    }

}

The view:

<h:form>
    <p:menu>
        <p:menuitem value="Open dialog" oncomplete="dialog.show();" update="dialogopen"/>
    </p:menu>
    <p:dialog widgetVar="dialog">
        <h:outputText value="This is your dialog"/>
        <p:ajax event="close" listener="#{dialogBean.dialogClosed}" update="dialogopen"/>
    </p:dialog>
    <h:outputText id="dialogopen" value="Is dialog open? #{dialogBean.openStatus}"/>
</h:form>

Updating bean property via <p:remoteCommand>

As far as dialogWidgetVar.show() and dialogWidgetVar.hide() are compeletely client side events, there state of a component doesn't include the "status of openness" of a dialog. As you can get from the primefaces documentation dialog.isVisible() gets the visible attribute of a <p:dialog>, which instructs to open the dialog on page load. As for dialog.isInView() method it simply checks if the component is present in the view, or not, and that also doesn't have any reference to the dialog's state you're after.

Also note that binding your dialog to a backing component variable of type org.primefaces.component.dialog.Dialog would give rise to the infamous issue.

Nonetheless, if you don't want to hook up extra listener to menuitem, your best bet is to use <p:remoteCommand>, that would do the update for you. Note, that close listener should be present so that the variable would be set back to false.

Modified bean:

@ManagedBean
@ViewScoped
public class DialogBean implements Serializable {

    private boolean openStatus = false;//getter + setter

    public void dialogClosed(CloseEvent event) {
        openStatus = false;
    }

}

Modified view:

<h:form>
    <p:menu>
        <p:menuitem value="Open dialog" oncomplete="dialog.show(); updateOpenStatus();"/>
    </p:menu>
    <p:dialog widgetVar="dialog">
        <h:outputText value="This is your dialog"/>
        <p:ajax event="close" listener="#{dialogBean.dialogClosed}" update="dialogopen"/>
    </p:dialog>
    <p:remoteCommand name="updateOpenStatus" update="dialogopen">
        <f:setPropertyActionListener value="#{true}" target="#{dialogBean.openStatus}"/>
    </p:remoteCommand>
    <h:outputText id="dialogopen" value="Is dialog open? #{dialogBean.openStatus}"/>
</h:form>
like image 80
skuntsel Avatar answered Oct 07 '22 13:10

skuntsel