Adding AJAX callback parameters – validation within a dialog

This recipe will continue with the discussion on RequestContext that we began in the previous recipes. There may be cases where we need values from backing beans in AJAX callbacks. Let's suppose we have a form in a dialog; when the user submits the form, the dialog should stay open to display any validation errors and it should be closed otherwise.

In this recipe, we will learn how the described task can be done with AJAX callback parameters. We will develop an oncomplete callback for a command button within p:dialog.

How to do it…

The developed page contains a Dialog component with an input field. The dialog will be visible when the page is loaded. There is only one valid input value, PrimeFaces Cookbook. When the user inputs this value and clicks on the Save button, the dialog should be closed. In any other case, it should stay open. The p:commandButton button defines handleComplete(xhr, status, args), an oncomplete callback. It gets processed when the AJAX request completes. There, we check args.validName and close the dialog if this value is true. Here's the code for this discussion:

<p:growl id="growl" autoUpdate="true"/>

<p:dialog header="What is the name of this book?"
  visible="true" widgetVar="dlgWidget">
  <p:inputText id="name" value="#{ajaxCallbackParamBean.name}"/>

  <p:commandButton id="save" value="Save" style="margin:10px;"
    process="@this name" update="name"
    actionListener="#{ajaxCallbackParamBean.save}"
    oncomplete="handleComplete(xhr, status, args)"/>
</p:dialog>

<h:outputScript id="handleCompleteScript" target="body">
  function handleComplete(xhr, status, args) {
    if (args && args.validName) {
      PF('dlgWidget').hide();
    }
  }
</h:outputScript>

The corresponding CDI bean compares the input value with the valid one and creates either an information message or an error message for the growl component. Furthermore, it adds a callback parameter, validName, with the value true for a valid input and false otherwise. Here's the code that encapsulates this discussion:

@Named
@ViewScoped
public class AjaxCallbackParamBean implements Serializable {

  private String name;

  public void save(ActionEvent ae) {
    RequestContext requestContext =
      RequestContext.getCurrentInstance();

    String message;
    FacesMessage.Severity severity;
    UIInput input = (UIInput) ae.getComponent().
      findComponent("name");

    if ("PrimeFaces Cookbook".equals(name)) {
      message = "All right!";
      severity = FacesMessage.SEVERITY_INFO;

      requestContext.addCallbackParam("validName", true);
      input.setValid(true);
    } else {
      message = "Name is wrong, try again";
      severity = FacesMessage.SEVERITY_ERROR;

      requestContext.addCallbackParam("validName", false);
      input.setValid(false);
    }

    FacesMessage msg = new FacesMessage(severity, message, null);
    FacesContext.getCurrentInstance().addMessage(null, msg);
  }

  // getters / setters
  ...
}

The following screenshot shows the dialog and the growl notification that is created when there is an error:

How to do it…

How it works…

The oncomplete callback function takes three arguments: XMLHttpRequest, status string, and optional parameters provided by the RequestContext API. Parameters can be added by the addCallbackParam(key, value) method. They are serialized to JavaScript Object Notation (JSON) and can be accessed in AJAX callbacks by the args argument. In the example, we accessed the value of the validName callback parameter by args.validName. We can add as many callback parameters as we want. Primitive values are supported as well as Plain Old Java Objects (POJOs). POJOs are serialized to JSON as well.

Note

By default, the validationFailed callback parameter is added implicitly if JSF validation fails so that it is possible to check the failed validation with an if statement: if (args.validationFailed == true).

In the bean, we set the valid flag on the input component to false when the book's name is wrong. Making the input component invalid leads to red borders around the input field in the UI.

There's more…

If we had the standard h:inputText component instead of the PrimeFaces' one, the input.setValid(false) setting on the input component would not lead to red borders around the input field in the UI. In this case, we could highlight the invalid input field anyway by adding the ui-state-error style class via JavaScript. Here's the code we are discussing:

function handleComplete(xhr, status, args) {
  if (args && args.validName) {
    PF('dlgWidget').hide();
  } else {
    $('#name').addClass('ui-state-error'),
  }
}

PrimeFaces Cookbook Showcase application

This recipe is available in the demo web application on GitHub (https://github.com/ova2/primefaces-cookbook/tree/second-edition). Clone the project if you have not done it yet, explore the project structure, and build and deploy the WAR file on application servers compatible with Servlet 3.x, such as JBoss WildFly and Apache TomEE.

The showcase for the recipe is available at http://localhost:8080/pf-cookbook/views/chapter11/ajaxCallbacks.jsf.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.138.204.186