cancel
Showing results for 
Search instead for 
Did you mean: 

UIComponent problems with rendered and actionListener

jmliege
Champ in-the-making
Champ in-the-making
Hi,

I'm currently modifying the browse jsp.

I want to list all nodes (content and folder) in one single UIRichList.

For this purpose i set some rendered tag in order to distinguish the rendering of folders, and the rendering of contents.

NB: I added my own NodePropertyResolver in order to get a new
nodeType value to test wether i have a node which is subclass of a folder (cm:folder) or not (cm:content).



<%– if folder, use this actionLink –%>
<a:actionLink id="col1-act2" value="#{r.name}" actionListener="#{BrowseBean.clickSpace}" rendered="#{r.nodeType=='folder'}">
   <f:param name="id" value="#{r.id}" />
</a:actionLink>
                              
<%– if not folder, use this actionLink –%>
<a:actionLink id="col9-act2" value="#{r.name}" href="#{r.url}" target="new" rendered="#{r.nodeType == 'content'}" />
<r:lockIcon id="col9-lock" value="#{r.nodeRef}"   align="absmiddle" rendered="#{r.nodeType == 'content'}"/>


My problem is that once I set a rendered tag, the actionListener seems to not working. (I click, and nothing's happen…)

Can you help me on this topic.
4 REPLIES 4

jmliege
Champ in-the-making
Champ in-the-making
Maybe I can provide exactly what I did.
In fact, I set up a new Backing bean, which uses the browsebean to get all nodes.

I'm creating a new list upon the BrowseBean.getNodes() and BrowseBean.getContent() functions.

for each node I get, I add a NodePropertyResolver which check if node is a subclass of folder, or content.

Here's the code…



package xxx.portal.web.bean;

import java.util.ArrayList;
import java.util.List;

import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.alfresco.model.ContentModel;

import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.web.app.context.IContextListener;
import org.alfresco.web.app.context.UIContextService;
import org.alfresco.web.bean.BrowseBean;
import org.alfresco.web.bean.repository.Node;
import org.alfresco.web.bean.repository.NodePropertyResolver;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
*
* LightBrowseBean is a simplified interface for external users.
*
* @author jmbailly - Sogeti Luxembourg SA
* @date Sep 5, 2006 3:16:52 PM
*
*/
public class LightBrowseBean implements IContextListener
{
   
   public static final String FOLDER_TYPE = "folder";
   public static final String CONTENT_TYPE = "content";
   
   public static final String NODE_TYPE = "nodeType";
   
   private Log logger = LogFactory.getLog(LightBrowseBean.class);
   
   private List<Node> items;
   
   protected BrowseBean browseBean;
   
   protected DictionaryService dictionaryService;
   
   /**
    * Constructor
    *
    *
    * @author jmbailly - Sogeti Luxembourg SA
    * @date Sep 5, 2006 5:19:58 PM
    */
   public LightBrowseBean()
   {
      UIContextService.getInstance(FacesContext.getCurrentInstance()).registerBean(this);
   }
   
   /**
    * @param browseBean The browseBean to set.
    *
    * @author jmbailly - Sogeti Luxembourg SA
    * @date Sep 5, 2006 5:16:52 PM
    */
   public void setBrowseBean(BrowseBean browseBean) {
      this.browseBean = browseBean;
   }
   
   /**
    * @param dictionaryService The dictionaryService to set.
    *
    * @author jmbailly - Sogeti Luxembourg SA
    * @date Sep 5, 2006 5:19:50 PM
    */
   public void setDictionaryService(DictionaryService dictionaryService) {
      this.dictionaryService = dictionaryService;
   }
   
   /* (non-Javadoc)
    * @see org.alfresco.web.app.context.IContextListener#contextUpdated()
    */
   public void contextUpdated()
   {
       items = null;
   }
   
   /**
    * @return Returns the items.
    *
    * @author jmbailly - Sogeti Luxembourg SA
    * @date Sep 5, 2006 4:21:48 PM
    */
   public List<Node> getItems()
   {
      if (logger.isDebugEnabled())
         logger.debug("LightBrowseBean.getItems()");
      
      int nodeSize = 0;
      if (browseBean.getNodes()!=null && !browseBean.getNodes().isEmpty())
         nodeSize = browseBean.getNodes().size();
      
      int contentSize = 0;
      if (browseBean.getContent()!=null && !browseBean.getContent().isEmpty())
         contentSize = browseBean.getContent().size();
      
      items = new ArrayList<Node>(nodeSize+contentSize);
      
      if (nodeSize > 0)
         for( Node node : browseBean.getNodes())
         {      node.addPropertyResolver(NODE_TYPE,this.resolverType);
            items.add(node);
         }
      
      if (contentSize > 0)
         for(Node node : browseBean.getContent())
         {
         node.addPropertyResolver(NODE_TYPE,this.resolverType);
            items.add(node);
         }
      
      return items;
   }
   
   
   /**
    * Resolver uses to determine if node is content or folder.
    */
   public NodePropertyResolver resolverType = new NodePropertyResolver()
   {
      public Object get(Node node)
      {
         String  strType = CONTENT_TYPE;
         if (dictionaryService.isSubClass(node.getType(),ContentModel.TYPE_FOLDER))
            strType = FOLDER_TYPE;
         return strType;
      }
   };
     
}

Here's the faces-config.


<managed-bean>
      <description>Back bean for external user browsing</description>
      <managed-bean-name>LightBrowseBean</managed-bean-name>
      <managed-bean-class>xxx.portal.web.bean.LightBrowseBean</managed-bean-class>
      <managed-bean-scope>session</managed-bean-scope>
      <managed-property>
         <property-name>dictionaryService</property-name>
         <value>#{DictionaryService}</value>
      </managed-property>
      <managed-property>
         <property-name>browseBean</property-name>
         <value>#{BrowseBean}</value>
      </managed-property>
   </managed-bean>

Hope it will help.

Tchao.
JM

kevinr
Star Contributor
Star Contributor
Your problem is due to a subtle issue with the way the JSF component framework is working.

The object 'r.nodeType' that you are testing is transient. What I mean by that is that the 'r' object is only available for the life of that row when it is rendered - this is fine generally and it can be used in value-binding expressions to set attribute values etc. The problem is that the 'rendered' attribute value is checked again later by JSF during the processing phase where it decides if the actionHandler related to the action can be processed. Unfortuntely at that time the 'r' value is gone and the value binding expression therefore always evaluaters to "false" always as 'r' isn't available, so it never processes the action click.

A way around this is to use the <a:booleanEvaluator> (see examples in browse.jsp) component to wrap your components.

Thanks,

Kevin

jmliege
Champ in-the-making
Champ in-the-making
I didn't test it right now, as I have to much workload, but still thank you very much.

Bye,
JM

clementus
Champ in-the-making
Champ in-the-making
Thanks for the solution…
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.