Primefaces Dialog Framework - Open dialog - close it - open another dialog

25,678

Solution 1

Solution:

  • Open just one dialog: RequestContext.getCurrentInstance().openDialog("dialog1.xhtml", options, null);
    • The dialog flow is controlled by an ajax update of the main panel, where the rendered attribute is bound to a bean property and therefore completely controlled by the bean.

dialog1.xhtml:

<p:dialog class="userRegisterDialog" header="#{bean.dailogHeader}" 
                          modal="true" resizable="false" draggable="false">

    <p:ajax event="close" listener="#{bean2.closeRegistration}" update=":update"/>

    <p:panel id="update">
        <p:panel id="step1" rendered="#{bean.showStep1}">
            <h:form>
                <p:commandButton class="continueButton" value="Button1" actionListener="#{bean.doStep1}" update=":update"/>
            </h:form>
        </p:panel>
        <p:panel id="step2" rendered="#{bean.showStep2}">                        
            <h:form>
                <p:commandButton class="closeButton" value="Button2" actionListener="#{bean.doStep2}" update=":update"/>
            </h:form>               
        </p:panel>
    </p:panel>
</p:dialog>

The dialog bean:

import java.io.Serializable;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

@ManagedBean
@ViewScoped
public class Bean implements Serializable 
    {

    private boolean showStep1 = true;
    private boolean showStep2 = false;

    public void doStep1(ActionEvent actionEvent) {

        if(doSomething())
        {
            setShowStep1(false);            
            setShowStep2(true);
        }
    }            

    public void doStep2(ActionEvent actionEvent) {

        if(doSomething2())
        {
            RequestContext.getCurrentInstance().closeDialog(null);
        }
    }

    // Getter and setter ...    
}

Another bean for the dialog closing:

@ManagedBean
@RequestScoped
public class Bean2 implements Serializable {
    public void closeRegistration() { 
         FacesContext.getCurrentInstance().getViewRoot().getViewMap().remove("bean");
    }    
}

The method closeRegistration removes the viewscoped bean. Therefore another call of the the dialog within the same page will start the dialog flow from the beginning.

Solution 2

using onHide you can open another dialog like this.

<p:dialog class="userRegisterDialog" header="#{bean.dailogHeader}" modal="true" resizable="false" draggable="false" onHide="PF('dialog2').show();>
</p:dialog>

It also work when close dialog using escape key.

Share:
25,678
Admin
Author by

Admin

Updated on December 13, 2020

Comments

  • Admin
    Admin over 3 years

    Primefaces 5.0, JSF 2.2, Wildfly 8.1

    The following use case:

    1. Click a command button in a view (with some parameters)
    2. The bean method looks something up in the database - if necessary dialog1 is shown. In dialog1 there is a form and a command button.
    3. The command button in dialog1 is clicked, the bean method looks something up in the database.
    4. Dialog1 is closed and dialog2, depending on the result of the bean method, is shown.

    bean1.java:

    public void buttonClicked() {
    
        Map<String, Object> options = new HashMap<>();
        options.put("modal", true);
        options.put("widgetVar", "dialog1");
        options.put("id", "dlg1");
    
    if(somethingTrue()) {
    RequestContext.getCurrentInstance().openDialog("dialog1.xhtml", options, null);
        }
    }
    

    Everything fine. Dialog1 shows up.

    dialog1.xhtml:

    <h:body>
        <h:form>
            <p:commandButton value="Button" actionListener="#{bean2.dialog1ButtonClicked}" />
        </h:form>
    </h:body>
    

    bean2.java:

    public void dialog1ButtonClicked() {        
        Map<String, Object> options = new HashMap<>();
        options.put("modal", true);
        options.put("widgetVar", "dialog2");
        options.put("id", "dlg2");    
    
    if(somethingTrue()) {
        RequestContext.getCurrentInstance().openDialog("dialog2.xhtml", options, null);
        }
    }
    

    dialog2.xhtml:

    <h:body>        
        The operation was successful.
    </h:body>
    

    Dialog2 shows up within dialog1!

    How can I close dialog1 and show dialog2 NOT within dialog1?

    I tried closing dialog1 with Primefaces Dialog Framework before opening dialog2:

    RequestContext.getCurrentInstance().closeDialog(null);
    RequestContext.getCurrentInstance().openDialog("dialog2.xhtml", options, null);
    

    Dialog2 doesn't show up.

    I tried opening dialog2 after the AJAX callback <p:ajax event="dialogReturn" listener="#{bean1.dialogClosed}"/> Dialog2 doesn't show.

    I tried the client side Java Script call: onclick="PF('dialog1').hide()"

    Dialog2 still shows up nested into dialog1.