a4j:include in ui:repeat (dynamic)
frer Jan 15, 2009 12:19 AMHello,
I'm trying to render a dynamic search page to which I can add different filters.
In this page I have a dropdown of different filters (lets say: firstName, isActive, province).
When a filter is selected, the interface will automatically display the appropriate filter form.
For example in the 3 cases mentionned above the filters would look like:
- firstName <equals|startsWith> <value> - isActive <true|false> - province <quebec|ontario|etc.>
As you can see, they are quite different so my first idea was to create a .xhtml for each of them and have an associated class to each of them.
My xhtml therefore looks like this:
<fieldset class="filter-selector"> <span id="filter-available-criteria-label">#{messages['allowableCriteria.label']}</span> <h:selectOneMenu value="#{personAction.selectedCriterion}" id="filter-available-criteria-selector"> <f:selectItem itemLabel="#{messages['org.mdarad.framework.resources.form.select']}" itemValue="" /> <f:selectItem itemLabel="firstName" itemValue="firstName" /> <f:selectItem itemLabel="isActive" itemValue="isActive" /> <f:selectItem itemLabel="site" itemValue="province" /> <a4j:support event="onchange" ajaxSingle="true" reRender="person-list" action="#{personAction.addCriterion()}"/> </h:selectOneMenu> </fieldset> <div id="filter-criteria-container" class="criteria-container"> <div id="criterion-container" class="criterion-container"> <ui:repeat value="#{personAction.criteria}" var="criterion" > <a4j:include viewId="#{criterion.viewId}"/> </ui:repeat> </div> </div>
As you can see, when the drop down is selected the selectedCriterion is populated with the appropriate value. Then the addCriterion method is called :
public void addCriterion() { if(selectedCriterion == null) { throw new SystemException(); } else if(selectedCriterion.equals("firstName")) { criteria.add(new StringWebCriterion("firstName", "firstName")); } else if(selectedCriterion.equals("isActive")) { criteria.add(new BooleanWebCriterion("isActive", "isActive")); } else if(selectedCriterion.equals("province")) { criteria.add(new AssociationWebCriterion<Province>("province", "province", facadeLocator.getProvinceFacade().fetchList().getResults())); } //Reset the selected Criterion selectedCriterion = null; }
This all seams to work great but my problem is when I iterate over the criteria and do the a4j:include
... <ui:repeat value="#{btsAction.criteria}" var="criterion" > <a4j:include viewId="#{criterion.viewId}"/> </ui:repeat> ...
Seam seems to include a whole page (with my header and everything) instead of only the .xhtml that is dynamically specified. Here is an example of these .xhtml that I want to include (stringFilter.xhtml):
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:a4j="http://richfaces.org/a4j" xmlns:rich="http://richfaces.org/rich" xmlns:c="http://java.sun.com/jstl/core"> <ui:composition > <div id="criterion-actions-remove-container" class="criterion-actions-remove-container"> <a href="javascript:void(0);"><img class="criterion-actions-remove-img" src="/inukshuk/static/img/closeButton.gif" border="0" /></a> </div> <div id="criterion-label-container" class="criterion-label-container"> #{messages[criterion.labelKey]} </div> <div id="criterion-operator-container" class="criterion-operator-container"> <select id="criterion-operator-list" name="criterion-operator-list" size="1"> <ui:repeat value="#{criterion.operatorTypes}" var="operatorType"> <option value="#{operatorType.value}">#{operatorType.label}</option> </ui:repeat> </select> </div> <div id="criterion-value-container" class="criterion-value-container"> <h:inputText id="criterion-criterion-value" value="#{criterion.value}" styleClass="attribute-input"/> </div> <div id="criterion-error-msg-container" class="criterion-error-msg-container"></div> </ui:composition> </html>
Why is it not including only this composition
? Why does it seam to include my whole page once more if it is not in my include (I made sure it was the correct path that was called)?
Also is this the right way to do this kind of dynamic inclusion? I have many other areas in my application where I want to dynamically add portions of the page (without knowing in advance which they will be).
Thank you for your help and advice
Francois