Automatic Ajax

You are viewing an old version (v. 5) of this page.
The latest version is v. 27, last edited on Apr 10, 2013 (view differences | )
<< View previous version | view page history | view next version >>

Definition

Automatic Ajax is a mechanism in the ICEfaces framework that calculates precise/minimal page updates from one JSF lifecyle to the next, eliminating the need for standard JSF <f:ajax> tags in the page.

Comparing Automatic Ajax with Standard JSF Ajax

JSF <f:ajax> Tag

JSF 2.0 includes Ajax capabilities with the <f:ajax> tag. <f:ajax> adds client-side behavior to it's parent component, enabling it to perform an Ajax submission, cause execution of the JSF lifecycle, and ultimately render new view content to be inserted in the page. The page designer controls what type of event causes the submit to occur, and defines what components participate in the execute phase, and what components must render as a result of the execute. The following page snippet illustrates an input field causing an output field to update when the user modifies and tabs out of the input field.

<h:form>
    <h:panelGrid columns="1">
        <h:inputText id="myinput" value="#{myBean.value}">
            <f:ajax execute="@this" event="blur" render="myoutput"/>
        </h:inputText>
        <h:outputText id="myoutput" value="#{myBean.value}"/>
    </panelGrid>
</h:form>

The sequence of events resulting in a page update based on this markup is illustrated below.

  1. User interacts with the input field and tabs out of it.
  2. onBlur event causes <f:ajax> tag to submit.
  3. JSF lifecycle executes on the inputText component only.
  4. Model is updated with new text value.
  5. JSF render phase runs on outputText component only.
  6. Response is generated with page update containing markup associated with outputText.
  7. DOM update is applied to the outputText text field in the DOM.

The application of <f:ajax> is simple in a trivial use case such as this, but as page complexity increases so does the complexity of defining appropriate <f:ajax> tags, and if you get it wrong, your application can become ill behaved.

Nice to have a convoluted diagram of a complex page and all sorts of arrows

In the final analysis, it proves unreasonable to wire <f:ajax> tags into a complex page to achieve optimal/minimal page updates. It becomes necessary to wire together broader regions of a page that may need updating based on some event, resulting in larger page updates than actually required.

Automatic Ajax with ICEfaces

ICEfaces Automatic Ajax feature guarantees minimal page updates under any condition, and does not require the page developer to consider how, when or why page updates occur. The key to Automatic Ajax is the use of [Direct-to-DOM] (D2D) rendering in the ICEfaces framework. D2D does just what it says, and writes the output of the JSF rendering phase into a server-side DOM that represents exactly what the client DOM needs be. Using a cached version of the DOM, the framework calculates precisely the set of DOM updates required to affect the changes in the page at the completion of any JSF lifecycle.

While D2D handles the page updating aspect, it is still necessary to initiate the whole process through some UI event. ICEfaces provides the Single Submit features, which causes a component to submit itself automatically when the user interacts with it. It act much like a

<f:ajax execute="@this", render="@all"/>

but does not update the entire page, as the D2D mechanism intercepts the page update and calculates the precise, minimal set of updates required. In the ICEfaces Advanced Components, Single Submit is controlled through the singleSubmit attribute. For other components, the <icecore:singleSubmit> tag can wrap any number of components and enable them for single submission.

Returning now to our trivial example, the JSF markup in an ICEfaces page would look like:

<icecore:singleSubmit>
<h:form>
    <h:panelGrid columns="1">
        <h:inputText id="myinput" value="#{myBean.value}"/>
        <h:outputText id="myoutput" value="#{myBean.value}"/>
    </panelGrid>
</h:form>
</icecore:singleSubmit>

The sequence of events resulting in a page update based on this markup is illustrated below.
Unable to render embedded object: File (ICEfaces-2.0-Auto-Ajax-2.png) not found.

  1. User interacts with the input field and tabs out of it.
  2. onBlur event cause singleSubmit to occur on inputText.
  3. JSF lifecycle executes on the inputText component only.
  4. Model is updated with new text value.
  5. JSF render phase runs on entire component tree producing a server-side DOM.
  6. DOM differences are calculated and page update to outputText is generated in the response.
  7. DOM update is applied to the outputText text field in the DOM.

The beauty of this solution is that regardless of how complex the page becomes, minimal additional markup is required to ensure it behaves properly. You only needs to define what components are enabled with singleSubmit, and the ICEfaces framework does the rest.

Optimizing Automatic Ajax

Automatic Ajax optimizes development time, but there is a trade off at run time as it is necessary to render the entire page to produce the DOM for comparison. It is possible to optimize this rendering with <f:ajax> tags that override the render="@all" behavior used to singleSubmit on a given component. Attaching a <f:ajax> tag as a child of any component will override the singleSubmit behavior of that component and allow the developer to specify a subset of the component tree that should render. The ICEfaces framework detects this partial rendering and performs D2D only on that specific subset of the component tree.

Returning to our trivial example, the following markup will ensure that only the outputText is rendered.

<icecore:singleSubmit>
<h:form>
    <h:panelGrid columns="1">
        <h:inputText id="myinput" value="#{myBean.value}">
            <f:ajax execute="@this" event="blur" render="myoutput"/>
        </h:inputText>
        <h:outputText id="myoutput" value="#{myBean.value}"/>
    </panelGrid>
</h:form>
</icecore:singleSubmit>

Of course, this sort of optimization is unnecessary in such a trivial example, but could prove useful in more complex pages. Most importantly, it is an optimization, not a necessity to make the application behave properly. Optimizations can be applied near the end of the development cycle, when the characteristics of the application are well understood, and proper behavior has been well established.

Enter labels to add to this page:
Please wait 
Looking for a label? Just start typing.

© Copyright 2017 ICEsoft Technologies Canada Corp.