myfaces-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Silverman, Glenn" <GSilver...@dylt.com>
Subject How can I create a session scoped Trinidad menu model
Date Thu, 31 Jul 2008 21:05:34 GMT
I need a session-scoped menu model but the documentation says I can't, and that creates a problem
whenever I click on a button to do something when I'm not on the first tab of the menu. Here's
my code...
I have a trinidad switcher control managed by a commandNavigationItem control.

			<tr:navigationPane id="navPaneA" level="1" value="#{root_menu}" var="foo">
				<f:facet name="nodeStamp">
					<tr:commandNavigationItem id="navItemA" text="#{foo.label}"
						action="#{foo.doAction}"/>
				</f:facet>
			</tr:navigationPane>

			<tr:switcher facetName="#{root_menu.navLabel}" defaultFacet="Messages" >
		  		<f:facet name="Messages">
		    		<tr:panelGroupLayout layout="vertical">
						<jsp:include page="../editors/errormessages.jspx"/>
					</tr:panelGroupLayout>
		  		</f:facet>
				<f:facet name="Help Text">
		    		<tr:panelGroupLayout layout="vertical">
						<jsp:include page="../editors/help.jspx"/>
					</tr:panelGroupLayout>
		  		</f:facet>
		        <f:facet name="Buttons">
		           <tr:panelGroupLayout layout="vertical">
						<jsp:include page="../editors/buttons.jspx"/>		
					</tr:panelGroupLayout>
		  		</f:facet>
		  		<f:facet name="Sounds">
		    		<tr:panelGroupLayout layout="vertical">
						<jsp:include page="../editors/sounds.jspx"/>		
					</tr:panelGroupLayout>
		  		</f:facet>
			</tr:switcher>

And a menu model:

	<menu xmlns="http://myfaces.apache.org/trinidad/menu">
		<groupNode id="msgs" idref="message" label="Error Messages" defaultFocustPath="true">
			<itemNode id="message" label="Messages" action="goToMessages" 
				focusViewId="/index.jspx"/>
			<itemNode id="help" label="Help Text" action="goToHelp"
				focusViewId="/index.jspx"/> 
			<itemNode id="button" label="Buttons" action="goToButton"
				focusViewId="/index.jspx"/>
			<itemNode id="sound" label="Sounds" action="goToSound"
				focusViewId="/index.jspx"/>
		</groupNode>
		<groupNode id="allcodes" label="AllCodes" idref="cat">		
			<itemNode id="cat" label="Categories" action="goToCategory"
				focusViewId="/index.jspx" />
			<itemNode id="link" label="CodeLinks" action="goToLink"
				focusViewId="/index.jspx" />
		</groupNode>	
	</menu>

which is defined in faces-config.xml as a managed bean:

      <managed-bean>
        <managed-bean-name>root_menu</managed-bean-name>
        <managed-bean-class>com.dylt.bean.MenuModelBean</managed-bean-class>
        <managed-bean-scope>request</managed-bean-scope>
        <managed-property>
	      <property-name>source</property-name>
	      <property-class>java.lang.String</property-class>
	      <value>/WEB-INF/menu-metadata.xml</value>
       </managed-property>
      </managed-bean>  

Here, MenuModelBean just extends XMLMenuModel as follows (This is
similar to the example in the Trinidad Developer Guide):

 	public class MenuModelBean extends XMLMenuModel {
	
		public String getGroupLabel(){
			List list = getNodesFromFocusPath(false);
			return (String)list.get(list.size()-1);
		}
		public String getNavLabel(){
			List list = getNodesFromFocusPath(true);
			return (String)list.get(list.size()-1);
		}
    	public List getNodesFromFocusPath(boolean itemsOnly){
      	ArrayList focusPath = (ArrayList)this.getFocusRowKey();
      	return getNodesFromFocusPath(focusPath, itemsOnly);	      
    	} 
    
    	public List getNodesFromFocusPath(ArrayList focusPath, boolean itemsOnly){
	      
	      
	      if (focusPath == null || focusPath.size() == 0)
	        return null;

	      // Clone the focusPath cause we remove elements
	      ArrayList fp = (ArrayList) focusPath.clone();
	  
	      // List of nodes to return
	      List nodeList = new ArrayList<Object>();
	  
	      // Convert String rowkey to int and point to the
	      // node (row) corresponding to this index
	      int targetNodeIdx = (Integer)fp.get(0);
	      TreeModel tree = (TreeModel)this.getWrappedData();
	      
	      tree.setRowIndex(targetNodeIdx);

	      // Get the node
	      Object node = tree.getRowData();
	      String label = null;
	      if(node instanceof ItemNode){
	    	  label= ((ItemNode)node).getLabel();
	    	  if(itemsOnly)
	    		  nodeList.add(label);
	      }	  
	      else if (node instanceof GroupNode){
	    	  label= ((GroupNode)node).getLabel();
	    	  if(!itemsOnly)
	    		  nodeList.add(label);
	      }
	       
	      
	      // Remove the 0th rowkey from the focus path
	      // leaving the remaining focus path
	      fp.remove(0);
	  
	      // traverse into children 
	      if (   fp.size() > 0
	          && tree.isContainer() 
	          && !tree.isContainerEmpty()
	         )
	      {
	        tree.enterContainer();
	  
	        // get list of nodes in remaining focusPath
	        List childList = getNodesFromFocusPath(fp, itemsOnly);
	  
	        // Add this list to the nodeList
	        nodeList.addAll(childList);
	  
	        tree.exitContainer();
	      }
	  
	      return nodeList;
	    } 
      )

Here's the problem: If I'm on one of the facet pages other than the first one, clicking
on any command button or link always takes me back to the first facet. If I use
partialSubmit and partialTriggers to try to limit page refresh to a particular page
element, the behavior is even more bizarre. If I click on a tab to change facets, the
first command button or link click works as expected, but any subsequent clicks assume
I am on the first facet page and won't update the facet page I'm on at all. 

Here's an example page, the help.jspx in the second facet:

	jsp:root xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0"
		xmlns:f="http://java.sun.com/jsf/core"
		xmlns:tr="http://myfaces.apache.org/trinidad">
	<jsp:directive.page contentType="text/html;charset=utf-8" />
		<f:subview id="helpWrapperA">
			<tr:table id="helpTableA" var="hlp" value="#{helpBean.list}" partialTriggers="helpEditLink">
				<tr:column headerText="Id">
					<tr:outputText value="#{hlp.helpId}" />
				</tr:column>
				<tr:column headerText="Message">
					<tr:commandLink id="helpEditLink" text="#{hlp.text}"
						immediate="true" partialSubmit="true">
						<tr:setActionListener from="#{hlp}"
							to="#{pageFlowScope.helpDetail}" />
					</tr:commandLink>
				</tr:column>
			</tr:table>		
        </f:subview>
        <tr:separator/>
        <tr:showDetail undisclosedText="Show Detail" disclosedText="Hide Detail"> 
	        <f:subview id="helpWrapperB">
				<tr:panelFormLayout rows="2" 
					partialTriggers=":::helpWrapperA:helpTableA:helpEditLink">
					<tr:outputText value="ID:" />
					<tr:outputText value="Text:" />
					<tr:outputText value="#{pageFlowScope.helpDetail.helpId}" />
					<tr:inputText value="#{pageFlowScope.helpDetail.text}"/>	
				</tr:panelFormLayout>
		    </f:subview>
		</tr:showDetail>		
	</jsp:root>

Could this behavior be the result of the fact that the scope for the menu model must be "request"
? If so, then every subsequent
"request" will always go to, or assume I'm on,  the default tab.  How can I change this?

Glenn Silverman




Mime
View raw message