Here is a revised proposal of how we could do this:
<x:tree value="#{treeBacker.treeData}" var="node" varNodeToggler="t">
<f:facet name="foo-folder">
<h:panelGroup>
<h:commandLink immediate="true" action="#{t.toggleExpanded}">
<h:graphicImage value="folder-open.png"
rendered="#{t.expanded}" border="0"/>
<h:graphicImage
value="folder-closed.png"rendered="#{!t.expanded}" border="0"/>
</h:commandLink>
<h:outputText value="#{node.description}" styleClass="nodeFolder"/>
</h:panelGroup>
</f:facet>
<f:facet name="document">
<h:panelGroup>
<h:commandLink immediate="true" styleClass="document">
<h:graphicImage value="/images/document.png" border="0"/>
<h:outputText value="#{node.description}"/>
<f:param name="userId" value="#{node.identifier}"/>
</h:commandLink>
</h:panelGroup>
</f:facet>
</x:tree>
This is similar to earlier examples except the expand/collapse
information has been completely removed from the model. (It is not in
TreeNode interface or TreeModel classes.)
It makes use of a "varNdeToggler" variable. I was using
varNodeToggler in the WAR example I posted but I have taken it one
step further. It is now completely responsible for providing (and
updating) information regarding the expand/collapse state. So I have
changed #{node.expanded} to #{t.expanded}.
varNodeToggler is really just a variable that you can reference to
find out if something is expanded or collapsed. Behind the scenes its
up to HtmlTree (or subclass) to make a bean available in the request
with name you specify.
I think this solves every one of the scenarios we have discussed so
far. Its also still very simple and allows for the use of existing
"rendered" functionality which I still think is a logical way to do
this type of thing (if we can manage it.)
sean