0 Replies Latest reply on Apr 25, 2009 8:08 AM by scott duke

    TabPanel with switchType

    scott duke Novice

      I have a detail user screen called Uzer.xhtml. At the bottom of the screen are 2 tabs. The first is a phone number listing and the second is an address listing.

      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
       xmlns:s="http://jboss.com/products/seam/taglib"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:a4j="http://richfaces.org/a4j"
       xmlns:rich="http://richfaces.org/rich"
       template="/layout/template.xhtml">
      
       <ui:define name="body">
      
       <rich:panel>
       <f:facet name="header">User Details</f:facet>
      
       <s:decorate id="companyDecoration" template="/layout/display.xhtml">
       <ui:define name="label">Company</ui:define>
       <h:inputText id="company"
       size="50"
       maxlength="50"
       disabled="true"
       value="#{uzerHome.instance.company}">
       <a4j:support event="onblur" reRender="companyDecoration" bypassUpdates="true"/>
       </h:inputText>
       </s:decorate>
      
      
       <s:decorate id="nameDecoration" template="/layout/display.xhtml">
       <ui:define name="label">Name</ui:define>
       <h:inputText id="name"
       size="40"
       maxlength="40"
       required="true"
       disabled="true"
       value="#{uzerHome.instance.name}">
       <a4j:support event="onblur" reRender="nameDecoration" bypassUpdates="true"/>
       </h:inputText>
       </s:decorate>
      
      
       <s:decorate id="emailDecoration" template="/layout/display.xhtml">
       <ui:define name="label">Email</ui:define>
       <h:inputText id="email"
       size="40"
       maxlength="40"
       disabled="true"
       value="#{uzerHome.instance.email}">
       <a4j:support event="onblur" reRender="emailDecoration" bypassUpdates="true"/>
       </h:inputText>
       </s:decorate>
      
      
      ...
      
      
       <div style="clear: both" />
      
       </rich:panel>
      
       <div class="actionButtons">
       <s:button view="/role/admin/UzerEdit.xhtml"
       id="edit"
       value="Edit" />
       <s:button view="#{empty uzerFrom ? '/role/admin/UzerList' : uzerFrom}.xhtml"
       id="done"
       value="Done" />
       </div>
      
       <rich:tabPanel switchType="ajax">
      
       <rich:tab label="Phone Numbers">
       <a4j:include viewId="/role/admin/PhoneTable.xhtml">
       <ui:param name="phoneFrom" value="/role/admin/Uzer"/>
       </a4j:include>
      
       <div class="actionButtons">
       <s:button id="addPhone" value="Add Phone Number"
       view="/role/admin/PhoneEdit.xhtml">
       <f:param name="uzerId" value="#{uzerHome.instance.id}" />
       <f:param name="phoneFrom" value="/role/admin/Uzer" />
       </s:button>
       </div>
       </rich:tab>
      
       <rich:tab label="Addresses" immediate="false">
      
       <a4j:include viewId="/role/admin/AddressTable.xhtml" >
       <f:param name="addressListSort" value="address.type"/>
       <f:param name="addressFrom" value="/role/admin/Uzer"/>
       </a4j:include>
      
       <div class="actionButtons">
       <s:button id="addAddress" value="Add Address"
       view="/role/admin/AddressEdit.xhtml">
       <f:param name="uzerId" value="#{uzerHome.instance.id}" />
       <f:param name="addressFrom" value="/role/admin/Uzer" />
       </s:button>
       </div>
       </rich:tab>
      
      
       </rich:tabPanel>
      
      
       </ui:define>
      
      </ui:composition>
      


      The PhoneTable.xhtml and AddressTable.xhtml are similar so I will only show AddressTable.xhtml

      <ui:composition xmlns="http://www.w3.org/1999/xhtml"
       xmlns:s="http://jboss.com/products/seam/taglib"
       xmlns:ui="http://java.sun.com/jsf/facelets"
       xmlns:f="http://java.sun.com/jsf/core"
       xmlns:h="http://java.sun.com/jsf/html"
       xmlns:a4j="http://richfaces.org/a4j"
       xmlns:rich="http://richfaces.org/rich">
      
       <a4j:form id="addressTableForm">
      
       <div class="association" id="addresss">
      
       <h:outputText value="No address exists"
       rendered="#{empty addressList.resultList}"/>
      
       <rich:dataTable id="addressList"
       var="_address"
       value="#{addressList.resultList}"
       rendered="#{not empty addressList.resultList}"
       rows="25">
      
       <rich:column rendered="#{addressFrom eq '/role/admin/AddressList'}">
       <f:facet name="header">
       <s:decorate template="/layout/sort.xhtml">
       <ui:param name="entityListName" value="addressList"/>
       <ui:param name="entityList" value="#{addressList}"/>
       <ui:param name="propertyLabel" value="Name"/>
       <!-- doesn't support two sort fields -->
       <ui:param name="propertyPath" value="uzer.name"/>
       </s:decorate>
       </f:facet>
       <s:link id="view" value="#{_address[1].name}" view="/role/admin/Uzer.xhtml" propagation="none">
       <f:param name="uzerFrom" value="/role/admin/AddressList"/>
       <f:param name="uzerId" value="#{_address[1].id}"/>
       </s:link>
       </rich:column>
      
       <rich:column>
       <f:facet name="header">
       <s:decorate template="/layout/sort.xhtml">
       <ui:param name="entityListName" value="addressList"/>
       <ui:param name="entityList" value="#{addressList}"/>
       <ui:param name="propertyLabel" value="Type"/>
       <!-- doesn't support two sort fields -->
       <ui:param name="propertyPath" value="address.type"/>
       </s:decorate>
       </f:facet>
       #{_address[0].type}
       </rich:column>
      
       ...
      
      
      
       <rich:column>
       <f:facet name="header">Action</f:facet>
       <s:link view="#{empty from ? '/role/admin/Address' : from}.xhtml"
       value="Select"
       id="addressSelect"
       propagation="none">
       <f:param name="addressFrom"
       value="#{addressFrom}"/>
       <f:param name="addressId"
       value="#{_address[0].id}"/>
       </s:link>
       </rich:column>
      
       <f:facet name="footer">
       <rich:datascroller pageIndexVar="pageIndex" pagesVar="pages" maxPages="25"/>
       <ui:remove>
       <rich:datascroller pageIndexVar="pageIndex" pagesVar="pages" boundaryControls="hide" stepControls="hide" fastControls="show">
       <f:facet name="pages">
       <h:outputText style="whitespace: nowrap" value="Page #{pageIndex} of #{pages}"></h:outputText>
       </f:facet>
       </rich:datascroller>
       </ui:remove>
       </f:facet>
      
       </rich:dataTable>
      
       </div>
      
       </a4j:form>
      </ui:composition>
      


      The addressList.java

      @Name("addressList")
      public class AddressList extends EntityQuery<Address>
      {
       private static final long serialVersionUID = 7154978428753938951L;
      
       private static final String[] RESTRICTIONS = {
       // tab list selection
       "address.uzer.id = #{uzerHome.uzerId}",
       // non-tab list selection
       "address.type = #{addressList.address.type}",
       "lower(address.addressee1) like concat('%',lower(#{addressList.address.addressee1}),'%')",
       "lower(address.addressee2) like concat('%',lower(#{addressList.address.addressee2}),'%')",
       "lower(address.address1) like concat('%',lower(#{addressList.address.address1}),'%')",
       "lower(address.address2) like concat('%',lower(#{addressList.address.address2}),'%')",
       "lower(cityStateZip.city) like concat('%',lower(#{addressList.cityStateZip.city}),'%')",
       "lower(cityStateZip.province) like concat('%',lower(#{addressList.cityStateZip.province}),'%')",
       "lower(cityStateZip.zipcode) like concat('%',lower(#{addressList.cityStateZip.zipcode}),'%')",
       };
      
       private Address address = new Address();
       private CityStateZip cityStateZip = new CityStateZip();
      
      
       public AddressList() {
       this.setEjbql("select address, uzer, cityStateZip from Address address join address.uzer uzer join address.cityStateZip cityStateZip");
       this.setRestrictionExpressionStrings(Arrays.asList(RESTRICTIONS));
       }
      
       public Address getAddress() {
       return address;
       }
      
       public CityStateZip getCityStateZip() {
       return cityStateZip;
       }
      
      }
      


      As you can see, my approach is similar to that described in "Seam in Action".

      On the tabPanel in Uzer.xhtml, when I define the switchType to client, the SQL for both tabs are loaded when the Uzer.xhtml is displayed. Switching between the 2 tabs does not reread the data from the database. When I change the switchType to either server(default) or ajax, the SQL for both tabs are loaded when the Uzer.xhtml is displayed. However, switching between the 2 tabs causes both tabs to reload the data from the database.

      1. Is this supposed to happen this way? This seems to be very ineffecient. I would of expected only the active tab to load the data and only load it once.

      2. When I unclude PhoneTable.xhtml and AddressTable.xhtml, is it possible to also have a PhoneTable.page.xml and AddressTable.page.xml? When I try this approach, it appears to not even look at the xml's. I have to place the params in my Uzer.page.xml.