Time for action – creating dialog with a registration form

In this section, we will demonstrate how to use forms in Dialog components and close the dialog conditionally such as in a successful form submission.

  1. Create a dialog containing a user Registration Form using the following code:
    <p:messages id="globalMsgs" globalOnly="true" autoUpdate="true"/>
    <h:outputLink id="registerLink" value="javascript:void(0)" onclick="registrationDlg.show()" title="Registration">
      <p:outputLabel value="Register"/>  
    </h:outputLink>
    
    <p:dialog id="registrationDlgId" widgetVar="registrationDlg" header="Registration Form" focus="registrationFormDlg:firstName">
      
      <h:form id="registrationFormDlg">
        <p:messages id="regmsgs" severity="error"/>
        <h:panelGrid columns="2" width="400px">
          <p:outputLabel value="EmailId:"/>
          <p:inputText value="#{dialogController.registerUser.emailId}" required="true" label="EmailId"/>
          
          <p:outputLabel value="Password"/>
          <p:password value="#{dialogController.registerUser.password}" required="true" label="Password"/>
          
          <p:outputLabel value="FirstName:*" />
            <p:inputText id="firstName" value="#{dialogController.registerUser.firstName}"
                  required="true" label="FirstName"/>
    
            <p:outputLabel value="LastName:" />
            <p:inputText id="lastName" value="#{dialogController.registerUser.lastName}" />
    
            <p:outputLabel value="Phone:" />
            <p:inputText id="phone" value="#{dialogController.registerUser.phone}" />
    
            <p:outputLabel value="DOB:" />
            <p:calendar value="#{dialogController.registerUser.dob}" id="dob"/>
    
          <p:commandButton value="Register" actionListener="#{dialogController.doRegister}" 
                update="@form" oncomplete="handleRegistrationRequest(xhr, status, args)"/>
        </h:panelGrid>
      </h:form>
    </p:dialog>
  2. Create an oncomplete event handler callback JavaScript function handleRegistrationRequest():
    function handleRegistrationRequest(xhr, status, args) 
    {  
      if(args.validationFailed || !args.registered) {  
        $("#registrationDlgId").effect("shake", { times:3 }, 100);  
      } else {  
        registrationDlg.hide();  
        $("#registerLink").fadeOut();
      }  
    }
  3. Create the doRegister() method in the DialogController managed bean:
    public void doRegister() 
    {
      boolean registered = false;
      try {
        System.out.println("Register User "+registerUser);//write code for persisting user data into database
        String msg = "User Registered successfully";
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg));
        registerUser = new User();
        registered = true;
      } catch (Exception e) {
        String msg = e.getMessage();
        String componentId = "registrationFormDlg";
        FacesContext.getCurrentInstance().addMessage(componentId, new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg));
      }
      RequestContext.getCurrentInstance().addCallbackParam("registered", registered);
    }
    Time for action – creating dialog with a registration form

What just happened?

We have created a complex dialog box, which contains the user's Registration Form. By default, focus will be on the FirstName field as we have specified focus="registrationFormDlg:firstName". We hooked-up a JavaScript callback function handleRegistrationRequest(xhr, status, args) for the oncomplete event. When the registration form is submitted, we are checking whether there are any validation errors using args.validationFailed. Also, we are checking whether registration is successful or not with args.registered, which we have added in the DialogController.doRegister() handler method. In case of validation errors or registration failed, we have applied a shake effect for dialog and displayed errors using <p:messages>. On successful registration, we are closing the dialog using registrationDlg.hide() and hiding the register link using $("#registerLink").fadeOut().

Here, we have used a JavaScript - centric approach to conditionally close the dialog. There is another approach to close the dialog conditionally.

If registration is successful then we can close the dialog in the DialogController.doRegister() method using RequestContext.execute("script") as follows:

<p:commandButton value="Register" actionListener="#{dialogController.doRegister}" update="msgs"/>

public void doRegister() 
{  
  try {
    userService.register(registerUser);
    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "User Registered successfully", null));
    RequestContext.getCurrentInstance().execute("registrationDlg.hide();");
    RequestContext.getCurrentInstance().execute("$('#registerLink').fadeOut();");
    registerUser = new User();    
  } catch (Exception e) {
    FacesContext.getCurrentInstance().addMessage("registrationFormDlg", new FacesMessage(FacesMessage.SEVERITY_ERROR, e.getMessage(), null));
  }
}

We will learn more features of the RequestContext utility in the next dialog framework section.

Tip

We should keep in mind the following important tips from the official PrimeFaces User Guide while using the Dialog component:

  • Use appendToBody with care as the page definition and HTML DOM would be different, for example if the dialog is inside a <h:form> component and appendToBody is enabled, on the browser, dialog would be outside the form and may cause unexpected results. In this case, nest a form inside a dialog.
  • Do not place dialog inside tables, containers as in divs with relative positioning or with non - visible overflow defined. In cases such as these, functionality might be broken. This is not a limitation but a result of the DOM model. For example, dialog inside a layout unit, tab view, and accordion are a few of examples. The same applies to confirmDialog as well.