Updating Areas of Your Page Using the ajaxZone Tag
If you have a group of one or more components that you want to be asynchronously updated at the same time as a result of the same user-initiated event, you wrap the component tags on the page with the ajaxZone tag. The ajaxZone tag supports several attributes that allow you to customize its behavior. This section gives simple examples of using the execute, render, and inspectElement attributes. Refer to the Dynamic Faces Tag Library documentation for more information on the complete set of attributes supported by the ajaxZone tag.
The following piece of a JSP page shows a simple use of the ajaxZone tag.
<jsfExt:ajaxZone> <h:selectOneMenu id="fruit" value="#{fruitBean.selectedFruit}"> valueChangeListener="#{fruitBean.updateFruit}"> <f:selectItems value="#{fruitBean.fruits}"/> </h:selectOneMenu> <h:outputText id="fruitMessage" value="#{fruitBean.fruitMessage}"/> </jsfExt:ajaxZone>
This example lets the user select an item from the menu, causing a message to render asynchronously to the output component tag. Because this example does not set any attributes on the ajaxZone tag, it will exhibit the default behavior, which is that all input components in the zone will execute as a result of an onclick event and all components in the zone will be asynchronously rendered as a result of the event. The updateFruit value-change event listener updates the model value of the fruitMessage component so that when it is re-rendered, the appropriate value is displayed on the page.
Using the ajaxZone Tag's execute and render Options
Most examples that use the ajaxZone tag will likely have multiple zones in one page. The way to get actions on one zone to affect the components in other zones is to use the execute and render options. The zones.jsp page of the simpleDynamicFaces application does the same thing as the fireAjaxTx.jsp page, but it does it using ajaxZone tags instead of attaching fireAjaxTransaction calls directly onto the components:
<h:form prependId="false" id="form"> ... <h:panelGrid columns="2" cellpadding="4"> <h:outputText value="Select a fruit:"/> <h:outputText value="Select a variety:"/> <jsfExt:ajaxZone id="zone1" execute="zone1" render="zone2,zone3"> <h:selectOneRadio id="fruit" value="#{fruitInfoBean.fruit}" valueChangeListener="#{fruitInfoBean.changeFruit}"> <f:selectItems value="#{fruitInfoBean.fruits}"/> </h:selectOneRadio> </jsfExt:ajaxZone> <jsfExt:ajaxZone id="zone2" execute="zone2" render="zone3"> <h:selectOneMenu id="variety" value="#{fruitInfoBean.variety}" valueChangeListener="#{fruitInfoBean.updateVariety}"> <f:selectItems value="#{fruitInfoBean.varieties}"/> </h:selectOneMenu> </jsfExt:ajaxZone> </h:panelGrid> <jsfExt:ajaxZone id="zone3"> <h:outputText id="varietyInfo" value="#{fruitInfoBean.varietyInfo}" /> </jsfExt:ajaxZone> </h:form>
This page has three zones demarcated using the ajaxZone tag. The first zone, zone1, contains the fruit radio button group component. The second zone, zone2, contains the variety menu component. And the third zone, zone3, contains the varietyInfo output component.
Notice that the zone1 tag sets the execute attribute to zone1. It also sets the render attribute to zone2,zone3. When the user selects a fruit from the radio button group, the fireAjaxTransaction method executes with the execute and render options given by the tag. Because the execute attribute specifies zone1, only the components in zone1 will go through the execute phases of the life cycle. The render attribute specifies all three zones, and so all three zones will re-render when the Ajax transaction completes.
As shown in the markup for zone2, when the user selects a variety from the variety menu, the variety component will go through the execute phases of the life cycle, and zone2 and zone3 will be re-rendered when the Ajax transaction completes.
Of course, you can implement this example by attaching fireAjaxTransaction calls to the fruit and variety components, as shown in Updating Single Components Using the fireAjaxTransaction Function. This is because there is only one component in each zone. If you have multiple components that you want to be executed or rendered as a result of the same event then you would use ajaxZone tags.
Using the ajaxZone Tag's inspectElement Option
When a page containing ajaxZone tags is first rendered, the inspectElement function executes on all of the child elements of a zone. It identifies the elements contained in the zone that should initiate an Ajax transaction when the zone's specified event occurs. By default, the inspectElement function identifies input, option, and button elements. To change this behavior, you can use the inspectElement attribute of the ajaxZone tag along with a custom inspectElement function to specify which elements in the zone you want to initiate an Ajax transaction as a result of the zone's default event, which is onclick.
The inspectElement.jsp page of the simpleDynamicFaces example includes a button in zone2 that, when clicked, renders the fruitSale component in zone3. The fruitSale component displays special offers for the fruit variety that the user has selected from the variety menu. Here are zone2, zone3, and the custom inspectElement function from the inspectElement.jsp page:
... <jsfExt:ajaxZone id="zone2" execute="zone2" render="zone2,zone3" inspectElement="inspectElement"> <h:selectOneMenu id="variety" value="#{fruitInfoBean.variety}" valueChangeListener="#{fruitInfoBean.updateVariety}"> <f:selectItems value="#{fruitInfoBean.varieties}"/> </h:selectOneMenu> <h:commandButton id="specials" value="See Special Offers" actionListeners="#{fruitInfoBean.specialsSubmit}" onclick="DynaFaces.fireAjaxTransaction(this, {execute: 'specials', render: 'fruitSale'});"/> </jsfExt:ajaxZone> ... <jsfExt:ajaxZone id="zone3"> ... <h:outputText id="fruitSale" style="color: maroon; font-family: Arial; font-weight: bold; font-size: medium" value="#{fruitInfoBean.fruitSaleValue}"/> </jsfExt:ajaxZone> <script type="text/JavaScript"> <!-- function inspectElement(element) { var result=false; if (null != element) { var tagName = element.nodeName; if (null != tagName) { if (-1 != tagName.toLowerCase().substring("option")) { result = true; } } } return result; } --> </script>
As shown in the preceding markup, the zone2 tag includes an inspectElement element that refers to the inspectElement JavaScript function at the end of the page. This function says that only option elements from this zone should fire Ajax transactions when the zone is activated. This is because the commandButton component fires its own Ajax transaction, which results in different behavior, so the input element representing this component should not be included in the list of elements that inspectElement identifies as those that participate in the Ajax transaction generated by events occurring in the rest of the zone.