Updating a page with a portion of another page

The external type of AJAX request prompts the servlet to replace a specified area of one page with a specified area of a second page. Like the refresh type of request, you can pass parameters to the second page. The onPreRenderFunction function can receive these parameters with the J2EELib.getQueryParameter system function.

With this type of request, you specify an area of the first page to be updated, an event to trigger the request, and optionally any parameters to be passed along with the request. Unlike the other types of request, the external AJAX request goes to another page, so the request must specify the page to send the request to and the control from that page to use in place of the first page.

Using this type of AJAX request involves creating two pages: Follow these steps to add an AJAX external request to a web page:
  1. Create a source page to hold the content that you want to use on another page:
    1. Create a JSP file and JSF Handler as you would ordinarily create an EGL-controlled web page.
    2. On this page, add a panel control and give it an ID unique on the page.
    3. Add the content into the panel control. The request will instruct the servlet to take the content from this panel and use it on another page.
    4. In the JSF Handler for the page, configure the onPreRenderFunction to accept the request.

      Because the onPreRenderFunction runs when the page first loads as well as on every AJAX request, you might want to detect which case has caused the function to run. You can do this by testing for the value of the parameter $$ajaxmode. When the function runs as the result of a normal page loading operation, this parameter has a null value; when the function runs as the result of an AJAX request, the parameter will contain a value.

      function onPreRender()
        
        if (J2EELib.getQueryParameter("$$ajaxmode") == NULL)
          //The page is loading for the first time.
          //Perform page loading operations here.
        else
          //The page is loading as the result of an AJAX request.
          //Perform AJAX updating operations here.
        end
      
      end
    5. Once you have determined that the onPreRenderFunction has been invoked as the result of an AJAX request, you can update the controls on the page by setting the values of the variables bound to those controls. You can update only the controls within the panel in the request.
      You can retrieve the parameters passed with the request by using the J2EELib.getQueryParameter() system function. For example, if you passed the value of a text control with the ID nameText, you can retrieve the value of that parameter with the following code:
      outputText = "Hello "::J2EELib.GetQueryParameter("nameText")::"!";
  2. Create the target page into which the content will be placed:
    1. Create a JSP file and JSF Handler as you would ordinarily create an EGL-controlled web page.
    2. On this page, add a panel control and give it an ID unique on the page. The contents of this panel will be replaced with the panel on the source page.
    3. Optionally, add JSF controls to the panel. The panel can be blank or populated with controls when the AJAX request replaces it with the panel on the source page.
  3. Specify the user event that will trigger the AJAX request.

    Do this by adding a JSF behavior to an input control on the page and then selecting an event to trigger the request. The control containing the behavior does not need to be within the panel control, but only input controls can trigger requests.

    For example, you can make the AJAX request occur when the user moves the focus into a particular control. In this case, you use the onFocus event. To perform the request when the user moves focus away from a particular control, you use the onBlur event. Other commonly used events include onClick, onMouseOver, and onSelect.

    1. On the web page, select the input control that you want to use as the trigger.
    2. With the control selected, open the Quick Edit view.
    3. In the Quick Edit view, select the event, such as onBlur, from the left side of the view.
    4. Select the Use pre-defined behavior check box.
    5. In the Action list, select Invoke Ajax behavior on the specified tag.
    6. In the Target list, select the ID of the panel you want to update.
    Now the behavior to trigger the AJAX request is attached to the control. For example, if you attach a behavior to an input text control and set it to use the onBlur event, the code on the page might look like this:
    <h:inputText id="nameText" value="#{myPage.name}" 
      binding="#{myPage.name_Ref}" styleClass="inputText" >
      <hx:behavior event="onblur" id="behavior1" 
        behaviorAction="get" targetAction="updatablePanel">
      </hx:behavior>
    </h:inputText>
    The behavior might look like this example:
    Picture of the behavior in the Quick Edit view
  4. Create the request by specifying the panel to update and the parameters for the request:
    1. On the target page, select the panel control.
    2. With the panel selected, open the Properties view.
    3. On the properties view, go to the Ajax tab under the type of panel control.
    4. On the Ajax tab, select the Allow Ajax updates check box.
    5. Click External as the type of request.
    6. Under the types of requests, click the button labeled Click to edit Ajax request properties.
    7. In the Target list, select the ID attribute of the panel on the target page you want to update.
    8. In the URL field, enter the relative path to the source page. Be sure to use the correct extension of .faces or .jsp for the target page, as explained in Running a web page on a server.
    9. In the Source field, enter the ID of the panel control on the source page. The contents of this panel will replace the contents of the panel on the target page.

      If you leave this field blank, the request will retrieve the entire source page (that is, everything within the <body> tag), not just the panel control.

    10. Add parameters to the request by clicking one of the Add Parameter buttons:

      The parameters in the table labeled Parameter values sent from the browser refer to the value of input controls on the target page. For example, if you want to pass the current value of an input control on the page as a parameter, add that input control's ID here.

      The parameters in the table labeled Parameter values calculated on the server refer either to literal values you type here or to the value of variables in the source page's JSF Handler.

    For example, if you choose to pass the value of an input control on the page, the new request might look like this:
    <hx:ajaxExternalRequest id="ajaxExternalRequest1" 
      target="sourcePanel" params="nameText"
      href="sourcePage.faces" soure="replacePanel">
    </hx:ajaxExternalRequest>

Now when the request is triggered on the target page, the servlet will pass the AJAX external request to the source page, along with any parameters. The servlet invokes the onPreRenderFunction function on the source page and when that function has finished, it removes the panel from the source page and inserts it into the target page.

Example

The following example shows two pages that work together with an AJAX external request as explained in this topic. The target page includes a group of check boxes that allow the user to select a value. The AJAX request passes this value to the source page, which renders a replacement panel based on the value of the message.

The page and its request look like this example:

Picture of the target page with the request in the Properties view

The following is the code of the target page, named targetPage.jsp:

<html>
<head>
<title>targetPage</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="theme/stylesheet.css"
  title="Style">
</head>
<f:view>
<body>
<hx:scriptCollector id="scriptCollector1">

<h:form id="form1" styleClass="form">

  <h:panelGroup id="targetPanel" styleClass="panelGroup">

    <h:outputText id="promptMessage" styleClass="outputText"
      value="What is your  favorite type of friut?">
    </h:outputText>
    
    <h:selectOneRadio disabledClass="selectOneRadio_Disabled"
      enabledClass="selectOneRadio_Enabled" id="fruitName"
      styleClass="selectOneRadio">
      <f:selectItem itemValue="bananas" itemLabel="bananas" />
      <f:selectItem itemValue="apples" itemLabel="apples" />
      <f:selectItem itemValue="grapes" itemLabel="grapes" />
    </h:selectOneRadio>

    <hx:behavior event="onchange" target="fruitName" 
     behaviorAction="get" targetAction="targetPanel">
    </hx:behavior>
    
  </h:panelGroup>
  
  <hx:ajaxExternalRequest id="ajaxExternalRequest1"
    target="targetPanel" href="sourcePage.faces" 
    source="sourcePanel" params="fruitName">
  </hx:ajaxExternalRequest>
    
</h:form>
</hx:scriptCollector>
</body>
</f:view>
</html>
The following are some technical details about the target page:
  • The tag <h:panelGroup> is the JSF panel control that will be updated. It has the ID attribute targetPanel.
  • The tag <h:outputText> is a JSF output text control that displays a static message as a prompt.
  • The tag <h:selectOneRadio> is a JSF check box group control that offers three options. This check box group has the ID attribute fruitName, which will be the parameter passed along with the request.
  • The tag <hx:behavior> specifies the event that triggers the AJAX request. The behavior's attributes point to the ID of the panel control and the radio button group. In this case, the event is onchange, which means that the AJAX request is triggered when the selection in the radio button group changes.
  • The tag <hx:ajaxExternalRequest> defines the AJAX request itself. This tag's target attribute points to the panel control, indicating that this request will run when the panel's event is triggered. The other attributes of the request point to the location of the source page, the ID of the panel to retrieve from the source page, and the parameter to pass with the request. In this case, the request includes the selection in the check box group as a parameter.

The following is the JSF Handler that would go with this page, named targetPage.egl:

package jsfhandlers;

handler targetPage type JSFHandler
  {view = "targetPage.jsp"} 
end

No special code is required in the JSF Handler for the target page. Because this example uses an external request, the request goes to the source page, so that page's JSF Handler will process the request.

Following is the code of the source page, named sourcePage.jsp:

<html>
<head>
<title>sourcePage</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<link rel="stylesheet" type="text/css" href="theme/stylesheet.css"
  title="Style">
</head>
<f:view>
<body>
<hx:scriptCollector id="scriptCollector1" 
preRender="#{sourcePage._preRender}" postRender="#{sourcePage._postRender}">

  <h:panelGroup id="sourcePanel" styleClass="panelGroup">
    <h:outputText id="text1" styleClass="outputText"
      value="#{sourcePage.message}" binding="#{sourcePage.message_Ref}">
    </h:outputText>
  </h:panelGroup>

</hx:scriptCollector>
</body>
</f:view>
</html>

This page contains a panel control that will be used to replace the panel on the target page. In this case, the panel contains a single output field that is bound to a variable in the page's JSF Handler. The page looks like this:

The source page in the editor, along with the Properties view showing the panel control

Following is the JSF Handler that would go with this page, named sourcePage.egl:

package jsfhandlers;

handler sourcePage type JSFHandler
  {onPreRenderFunction = onPreRender, 
   view = "sourcePage.jsp"} 
   
   message string = "No value set";

  function onPreRender()
    if (J2EELib.getQueryParameter("fruitName") != null)
      case (J2EELib.getQueryParameter("fruitName"))
        when ("bananas")
          message = "Bananas are a yellow tropical fruit.";
        when ("grapes")
          message = "Grapes grow on vines and can be made into wine.";
        when  ("apples")
          message = "Apples grow on trees in many parts of the world";
      end
    end
  end
end

This JSF Handler's onPreRenderFunction function first detects whether the function has been called as the result of an AJAX request. If so, the JSF Handler updates the text control on the page to show a message based on the value of the parameter passed along with the request. The request then uses the contents of the panel on the source page to replace the contents of the panel on the target page.


Feedback