[jboss-user] [JBoss Seam] - Re: how to conditionally render a row of dataTable

ellenzhao do-not-reply at jboss.com
Sun Aug 19 16:36:44 EDT 2007


I read that article. It seems there's a lot work to do in the infrastructure for adding a simple filtering feature....

Here are small view files in my own project demonstrating how I compose views. Hopefully they are readable enough....the foodCont is the name of a manager backing bean.  This file is never directly accessed, but always included in other view files. All my directly-accessed views are started with a verb, shortly describing a use case. 

Here the view-a-food.xhtml:


  | <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  |                       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  | 
  | <!-- version: $Id: view-a-food.xhtml 211 2007-08-16 16:42:02Z ningning $ -->
  | 
  | <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:rich="http://richfaces.ajax4jsf.org/rich"
  |   xmlns:a="https://ajax4jsf.dev.java.net/ajax"
  |   template="layout/template.xhtml">
  | 
  |   <ui:define name="body">
  | 
  |     <h3>Food Item Detail</h3>
  |     <h:messages globalOnly="true" styleClass="message" />
  | 
  |     <ui:include src="/includes/food.xhtml" />
  |     <rich:spacer width="100%" height="7" />
  | 
  |     <div class="section"><s:button value="Ok"
  |       action="#{foodCont.quitAFoodView()}" /></div>
  |   </ui:define>
  | </ui:composition>
  | 


Here the ultimately reusable food.xhtml:


  | <!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  |                       "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  | 
  | <!-- version: $Id: food.xhtml 210 2007-08-16 06:34:57Z ningning $ -->
  | 
  | <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:rich="http://richfaces.ajax4jsf.org/rich"
  |   xmlns:a="https://ajax4jsf.dev.java.net/ajax">
  | 
  |   <div class="section">
  |   <!-- #################### begin error messages ##################### -->
  |   <s:fragment rendered="#{not empty foodCont.getErrors()}">
  |     <rich:dataList value="#{foodCont.getErrors()}" var="error">
  |       <h:outputText value="#{error.getMessage()}" class="error" />
  |     </rich:dataList>
  |     <rich:spacer width="100%" height="7" />
  |   </s:fragment> 
  |   <!-- ####################### end error messages ############## --> 
  |   
  |   <!-- ################# permission guard ######################### -->
  |   <s:fragment
  |     rendered="#{foodCont.getNeedsLogin() and not identity.loggedIn}">
  |     <div class="section"><h:form>
  |       <rich:panel>
  |         <f:facet name="header">Login</f:facet>
  |         <p>You need to login to perform this action</p>
  |         <div class="dialog"><h:panelGrid columns="2"
  |           rowClasses="prop" columnClasses="name,value">
  |           <h:outputLabel for="username">Username</h:outputLabel>
  |           <h:inputText id="username" value="#{foodCont.actor.name}" />
  |           <h:outputLabel for="password">Password</h:outputLabel>
  |           <h:inputSecret id="password"
  |             value="#{foodCont.actor.password}" />
  |           <h:outputLabel for="rememberMe">Remember me</h:outputLabel>
  |           <h:selectBooleanCheckbox id="rememberMe"
  |             value="#{identity.rememberMe}" />
  |         </h:panelGrid></div>
  |       </rich:panel>
  |       <div class="actionButtons"><h:commandButton value="Login"
  |         action="#{foodCont.login}" /></div>
  |     </h:form></div>
  |     <rich:spacer width="100%" height="7" />
  |   </s:fragment> 
  |   <!-- ################## end of permission guard ############### --> 
  |   
  |   <!-- ############### begin atomic fields of a food ################# -->
  |   <s:fragment>
  |     <s:decorate template="/layout/display.xhtml">
  |       <ui:define name="label">Food Description</ui:define>
  |       <h:outputText value="#{foodCont.food.longDesc}" />
  |     </s:decorate>
  | 
  |     <s:decorate template="/layout/display.xhtml">
  |       <ui:define name="label">Food Group: </ui:define>
  |       <h:outputText value="#{foodCont.food.fdGrp.desc_en}" />
  |     </s:decorate>
  | 
  |     <s:fragment rendered="#{foodCont.food.comName != null}">
  |       <s:decorate template="/layout/display.xhtml">
  |         <ui:define name="label">Common Name:</ui:define>
  |         <h:outputText value="#{foodCont.food.comName}" />
  |       </s:decorate>
  |     </s:fragment>
  | 
  |     <s:fragment rendered="#{foodCont.food.facName != null}">
  |       <s:decorate template="/layout/display.xhtml">
  |         <ui:define name="label">Manufacturer Name:</ui:define>
  |         <h:outputText value="#{foodCont.food.facName}" />
  |       </s:decorate>
  |     </s:fragment>
  | 
  |     <s:fragment rendered="#{foodCont.food.sciName != null}">
  |       <s:decorate template="/layout/display.xhtml">
  |         <ui:define name="label">Scientific Name:</ui:define>
  |         <h:outputText value="#{foodCont.food.sciName}" />
  |       </s:decorate>
  |     </s:fragment>
  | 
  |     <s:fragment rendered="#{foodCont.food.refuDesc != null}">
  |       <s:decorate template="/layout/display.xhtml">
  |         <ui:define name="label">Refuse Description:</ui:define>
  |         <h:outputText value="#{foodCont.food.refuDesc}" />
  |       </s:decorate>
  | 
  |       <s:decorate template="/layout/display.xhtml">
  |         <ui:define name="label">Refuse Percentage:</ui:define>
  |         <h:outputText value="#{foodCont.food.refuPercentage}%" />
  |       </s:decorate>
  |     </s:fragment>
  | 
  |     <s:fragment rendered="#{not empty foodCont.food.userOpinions}">
  |       <s:decorate template="/layout/display.xhtml">
  |         <ui:define name="label">Average User Rate:</ui:define>
  |         <h:outputText value="#{foodCont.food.getRateMean()}">
  |           <f:convertNumber type="number" maxFractionDigits="3" />
  |         </h:outputText>
  |         <h:outputText
  |           value=" from #{foodCont.food.getTotalRates()} rates" />
  |       </s:decorate>
  |     </s:fragment>
  | 
  |     <s:decorate template="/layout/display.xhtml">
  |       <ui:define name="label">Current Price per 100g:</ui:define>
  |       <h:outputText value="#{foodCont.food.pricePer100g}">
  |         <f:convertNumber pattern="? ###0.00" />
  |       </h:outputText>
  |     </s:decorate>
  | 
  |     <rich:spacer width="100%" height="7" />
  |   </s:fragment> 
  |   <!-- ############### end of atomic fields of a food ############### -->
  | 
  |   <!-- ################# begin weight convertor #################### -->
  |   <s:fragment rendered="#{not empty foodCont.food.getWeights()}">
  |     <div class="section"><h:form>
  | 
  |       <s:decorate template="/layout/edit.xhtml">
  |         <ui:define name="label">Amount: </ui:define>
  |         <h:inputText value="#{foodCont.food.givenAmount}"
  |           required="true" />
  |       </s:decorate>
  | 
  |       <h:selectOneMenu id="selectUnit" class="value"
  |         value="#{foodCont.food.givenWeight}">
  |         <s:selectItems value="#{foodCont.food.weights}" var="unit"
  |           label="#{unit.msreDesc}"
  |           noSelectionLabel="Select a weight unit..." />
  |         <s:convertEntity />
  |       </h:selectOneMenu>&#160;&#160;
  |         
  |         <h:commandButton type="submit" value="Convert to gram"
  |         action="#{foodCont.food.convertWeight()}" />
  |     </h:form> &#160;&#160; <h:outputText
  |       value="#{foodCont.food.getWeightInGram()}">
  |       <f:convertNumber type="number" maxFractionDigits="3" />
  |     </h:outputText> gram</div>
  |     <rich:spacer width="100%" height="7" />
  |   </s:fragment> 
  |   <!-- ################# end weight convertor #################### -->
  | 
  |   <!-- ############### begin control options ################# -->
  |   <div class="section"><rich:toolBar height="26"
  |     itemSeparator="disc">
  |     <rich:toolBarGroup
  |       rendered="#{(identity.hasRole('admin') and (foodCont.getUseCases().peek() ne 'updateAFood')) or (not identity.loggedIn)}">
  |       <s:link action="#{foodCont.tryUpdateAFood()}" value="Update Price" />
  |     </rich:toolBarGroup>
  | 
  |     <rich:toolBarGroup>
  |       <s:link
  |         action="#{userOpinionCont.startAddOpinion(foodCont.food)}"
  |         value="Rate and/or Comment it"
  |         rendered="#{userOpinionCont.getUseCases().peek() ne 'addOrUpdateUserOpinion'}" />
  |     </rich:toolBarGroup>
  | 
  |     <rich:toolBarGroup>
  |       <s:link action="#{foodCont.food.setRenderNutrients(true)}"
  |         value="Show Nutrient Facts"
  |         rendered="#{not foodCont.food.getRenderNutrients()}" />
  |       <s:link action="#{foodCont.food.setRenderNutrients(false)}"
  |         value="Fold Nutrient Facts"
  |         rendered="#{foodCont.food.getRenderNutrients()}" />
  |       <s:link action="#{foodCont.food.setRenderComments(true)}"
  |         value="Show User Comments"
  |         rendered="#{foodCont.food.getComments().size > 0 and not foodCont.food.getRenderComments()}" />
  |       <s:link action="#{foodCont.food.setRenderComments(false)}"
  |         value="Fold User Comments"
  |         rendered="#{foodCont.food.getComments().size > 0 and foodCont.food.getRenderComments()}" />
  |       <s:link action="#{foodCont.food.setRenderRecipes(true)}"
  |         value="Show Containing Recipes"
  |         rendered="#{foodCont.food.getIngredients().size > 0 and not foodCont.food.getRenderRecipes()}" />
  |       <s:link action="#{foodCont.food.setRenderRecipes(false)}"
  |         value="Fold Containing Recipes"
  |         rendered="#{foodCont.food.getIngredients().size > 0 and foodCont.food.getRenderRecipes()}" />
  |     </rich:toolBarGroup>
  |   </rich:toolBar>
  |   <rich:spacer width="100%" height="7" />
  |   </div>
  |   <!-- ################ end of control options ################## --> 
  |   
  |   <!-- ############### begin of price update form ################## -->
  |   <s:fragment
  |     rendered="#{foodCont.getUseCases().peek() eq 'updateAFood'}">
  |     <div class="section"><h:form>
  |       <s:decorate template="/layout/edit.xhtml">
  |         <ui:define name="label">Current Price per 100g:</ui:define>
  |         <h:inputText value="#{foodCont.food.pricePer100g}"
  |           required="true" />
  |         <h:outputText value=" euro" />
  |       </s:decorate>
  |       <div class="section"><h:commandButton value="update"
  |         action="#{foodCont.doneUpdateAFood()}" /><s:button
  |         value="Cancel" action="#{foodCont.cancelUpdatePrice()}" /></div>
  |     </h:form></div>
  |     <div class="section"><rich:spacer width="100%" height="7" /></div>
  |   </s:fragment> 
  |   <!-- ############### end of price update form ################## -->
  | 
  |   <!-- ############### begin of user opinion form ############### --> 
  |   <s:fragment
  |     rendered="#{userOpinionCont.getUseCases().peek() eq 'addOrUpdateUserOpinion'}">
  |     <div class="section"><ui:include src="user-opinion.xhtml" />
  |     <rich:spacer width="100%" height="7" /></div>
  |   </s:fragment> 
  |   <!-- ################ end of user opinion form ################## -->
  | 
  |   <!-- ##############  begin of nutrient facts ################### --> 
  |   <s:fragment
  |     id="nutrients" rendered="#{foodCont.food.getRenderNutrients()}">
  |     <div class="section">
  |     <h4>Nutrient Facts</h4>
  |     <h:form>
  |       <rich:dataTable id="nutrientFacts" rows="25"
  |         value="#{foodCont.food.getNutrients()}" var="n">
  |         <rich:column>
  |           <f:facet name="header">
  |             <h:outputText value="Nutrient Desc" />
  |           </f:facet>
  |           <h:outputText value="#{n.nutr.nutrDesc}" />
  |         </rich:column>
  | 
  |         <rich:column>
  |           <f:facet name="header">
  |             <h:outputText value="Amount per 100g" />
  |           </f:facet>
  |           <h:outputText value="#{n.nutrVal} #{n.nutr.units}">
  |             <f:convertNumber type="number" maxFractionDigits="3" />
  |           </h:outputText>
  |         </rich:column>
  | 
  |         <rich:column rendered="#{foodCont.food.getWeightInGram()>0}">
  |           <f:facet name="header">
  |             <h:outputText
  |               value="Amount in #{foodCont.food.getGivenAmount()} #{foodCont.food.getGivenWeight().msreDesc}" />
  |           </f:facet>
  |           <h:outputText
  |             value="#{foodCont.food.getWeightInGram() / 100 * n.nutrVal}">
  |             <f:convertNumber type="number" maxFractionDigits="3" />
  |           </h:outputText>
  |            #{n.nutr.units}
  |         </rich:column>
  |       </rich:dataTable>
  |       <rich:datascroller for="nutrientFacts" />
  |     </h:form></div>
  |     <rich:spacer width="100%" height="7" />
  |   </s:fragment> 
  |   <!-- ################# end of nutrient facts #################### -->
  | 
  |   <!-- ################# begin of user comments table #############  -->
  |   <s:fragment id="userCommments"
  |     rendered="#{foodCont.food.getComments().size > 0 and foodCont.food.getRenderComments()}">
  |     <div class="section"><h:form>
  |       <rich:dataTable id="commentsTable" rows="25"
  |         value="#{foodCont.food.getComments()}" var="o">
  |         <rich:column>
  |           <f:facet name="header">
  |             <h:outputText value="User" />
  |           </f:facet>
  |           <h:outputText value="#{o.user.name}" />
  |         </rich:column>
  | 
  |         <rich:column>
  |           <f:facet name="header">
  |             <h:outputText value="Rate" />
  |           </f:facet>
  |           <h:outputText value="#{o.rate}" />
  |         </rich:column>
  | 
  |         <rich:column>
  |           <f:facet name="header">
  |             <h:outputText value="Comment" />
  |           </f:facet>
  |           <h:outputText value="#{o.comment}" />
  |         </rich:column>
  | 
  |         <rich:column>
  |           <f:facet name="header">
  |             <h:outputText value="Date" />
  |           </f:facet>
  |           <h:outputText value="#{o.version}" />
  |         </rich:column>
  |       </rich:dataTable>
  |       <rich:datascroller for="commentsTable" />
  |     </h:form></div>
  |     <rich:spacer width="100%" height="7" />
  |   </s:fragment> 
  |   <!-- ################# end of user comments table #############  -->
  | 
  |   <!-- ################# begin of containing recipes table ########### -->
  |   <s:fragment
  |     rendered="#{foodCont.food.getIngredients().size > 0 and foodCont.food.getRenderRecipes()}">
  |     <div class="section"><h:form>
  |       <rich:dataTable id="recipesTable" rows="25"
  |         value="#{foodCont.food.getIngredients()}" var="i">
  |         <rich:column>
  |           <f:facet name="header">
  |             <h:outputText value="Recipe Id" />
  |           </f:facet>
  |           <h:outputText value="#{i.recipe.id}" />
  |         </rich:column>
  | 
  |         <rich:column>
  |           <f:facet name="header">
  |             <h:outputText value="Recipe Name" />
  |           </f:facet>
  |           <h:outputText value="#{i.recipe.name}" />
  |         </rich:column>
  | 
  |         <rich:column>
  |           <f:facet name="header">
  |             <h:outputText value="Weight Percentage" />
  |           </f:facet>
  |           <h:outputText value="#{i.getWeightPercentage()}">
  |             <f:convertNumber pattern="###0.00%" />
  |           </h:outputText>
  |         </rich:column>
  | 
  |         <rich:column>
  |           <f:facet name="header">
  |             <h:outputText value="Option" />
  |           </f:facet>
  |           <h:commandButton
  |             action="#{foodCont.selectContainingRecipe(i)}"
  |             value="view the recipe" />
  |         </rich:column>
  |       </rich:dataTable>
  |       <rich:datascroller for="recipesTable" />
  |     </h:form></div>
  |     <rich:spacer width="100%" height="7" />
  |   </s:fragment> 
  |   <!-- ################# end of containing recipes table ########### --></div>
  | </ui:composition>
  | 

yes my entity object is very rich of behaviours and transient member fields...

Here a bit navigation rules....

  | <page view-id="/view-a-food.xhtml">
  | 		<navigation from-action="#{foodCont.quitAFoodView()}">
  | 			<rule
  | 				if="#{foodCont.getUseCases().peek() eq 'readFoods'}">
  | 				<redirect view-id="/view-foods.xhtml" />
  | 			</rule>
  | 		</navigation>
  | 		<navigation from-action="#{recipeManager.setRecipe(r)}">
  | 			<redirect view-id="/view-a-recipe.xhtml" />
  | 		</navigation>
  |                 <navigation>....</navigation>
  | 	</page>
  | 

the code in the conversation beans is very lean, just does stuffs like begin/end conversations, push/pop/remove use cases, etc.  

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4075594#4075594

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4075594



More information about the jboss-user mailing list