Two ways of triggering the JavaScript execution

The RequestContext utility class provides an easy way to execute any JavaScript code after the current AJAX request completes. The JavaScript block has to be coded in Java and can be executed by passing it to the execute() method. An alternative approach would be to update a script block on a page and trigger the script execution manually. In this case, the JavaScript block is coded directly into a page.

In this recipe, we will see both solutions for JavaScript execution. For this purpose, we will develop a menu component and toggle the enabling/disabling of menu items with two command buttons. The first command button should toggle enabling/disabling with the server-side approach and the second one with the client-side approach.

How to do it…

Let's write a p:menu tag with three menu items. We also need two p:commandButton tags with appropriate action listeners:

<h:outputText id="indicator"
  value="Enabled? - #{javaScriptExecBean.enabled}"/>

<p:menu id="menu" style="margin:20px 0 10px 0;">
  <p:submenu label="JavaScript Libraries">
    <p:menuitem value="jQuery" url="http://jquery.com"/>
    <p:menuitem value="Yahoo UI" url="http://yuilibrary.com"/>
    <p:menuitem value="Prototype" url="http://prototypejs.org"/>
  </p:submenu>
</p:menu>

<p:commandButton id="toggle1" value="Toggle Menuitems (server-side)"
    process="@this" update="indicator"
    actionListener="#{javaScriptExecBean.toggleMenuitems}"/>

<p:commandButton id="toggle2" value="Toggle Menuitems (client-side)"
    process="@this" update="indicator toggleScriptWrapper"
    actionListener="#{javaScriptExecBean.toggleEnabled}"/>

<h:panelGroup id="toggleScriptWrapper">
  <script type="text/javascript">
  if (#{facesContext.partialViewContext.ajaxRequest}) {
    $('#menu').find('a').each(function() {
      var $this = $(this);
        if ($this.attr('href')) {
          // disable item
          $this.attr('data-href', $this.attr('href'))
          .removeAttr('href')
          .addClass('ui-state-disabled'),
        } else {
          // enable item
          $this.attr('href', $this.attr('data-href'))
          .removeAttr('data-href')
          .removeClass('ui-state-disabled'),
        }
      });
    }
  </script>
</h:panelGroup>

The panelGroup component with the toggleScriptWrapper ID contains the script logic that is executed after each update on this panelGroup component. The bean packs the same logic in a String variable script and executes it with requestContext.execute(script):

@Named
@ViewScoped
public class JavaScriptExecBean implements Serializable {

  private boolean enabled = true;

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

    String script;
    if (enabled) {
      script =
        "$('#menu a').each(function() {"
        + "$(this).attr('data-href', $(this).attr('href'))"
        + ".removeAttr('href')"
        + ".addClass('ui-state-disabled'),});";
    } else {
      script =
        "$('#menu a').each(function() {"
        + "$(this).attr('href', $(this).attr('data-href'))"
        + ".removeAttr('data-href')"
        + ".removeClass('ui-state-disabled'),});";
    }

    requestContext.execute(script);
   enabled = !enabled;
  }

  public void toggleEnabled(ActionEvent ae) {
    enabled = !enabled;
  }

  public boolean isEnabled() {
    return enabled;
  }
}

The following screenshot shows what the disabled menu items look like:

How to do it…

How it works…

Both client-side and server-side scripts implement the same logic. To disable a menu item, its URL has to be copied from the anchor's href attribute to a data-href attribute. The href attribute should be removed then, and the link should be styled with a proper jQuery ThemeRoller class, ui-state-disabled. This style class makes elements appear disabled. To enable a menu item, its URL has to be restored from the data-href attribute and assigned to href. The style class, ui-state-disabled, should be removed.

Also, consider the if statement with the EL expression, #{facesContext.partialViewContext.ajaxRequest}. This statement prevents an initial script execution on page load (the GET request).

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/javaScriptExec.jsf.

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

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