Tree2 renderer (HtmlTreeRenderer) prints invalid clientId when a button/link
with "immediate='true'" is fired
-------------------------------------------------------------------------------------------------------------
Key: TOMAHAWK-557
URL: http://issues.apache.org/jira/browse/TOMAHAWK-557
Project: MyFaces Tomahawk
Issue Type: Bug
Components: Tree2
Affects Versions: 1.1.1
Environment: Jetty 5.1.10
MyFaces Core 1.1.1, MyFaces Tomahawk 1.1.1, Facelets 1.1, AJAX4JSF 1.0
Reporter: Nicholas Hagen
I have a simple tree2 via:
<h:form id="form" ...>
...
<h:commandLink action="success" value="Test" immediate="true" />
<t:tree2 id="test" var="node" value="#{Bean.model}"
clientSideToggle="false">
<f:facet name="data">
<h:outputText value="${node.description}" />
</f:facet>
</t:tree2>
...
</h:form>
When first accessed, the page works correctly and the generated html shows:
<span id="form:test" ...>....</span>
However, if I click on the "Test" link that has "immediate" set to true, using
no navigation rules so that the page just gets redisplayed, then I end up with
an end result page with html:
<span id="form:test:0" ...>...</span>
Looking into the code it appears that the ":0" is appended during
UIDataTree.getClientId() because the nodeId is not null. Normally, the tree is
processed by calling the processDecodes, then processValidators,
processUpdates, etc. At the end of processValidators and processUpdates,
setNodeId(null) is called to reset the node id. Then, when encodeChidren is
called on the renderer, the nodeId is null so that the clientId is correct.
When "immediate" is set to true, then processValidators and processUpdates do
not get called. Thus, the last decoded child (from processDecodes) is set as
the node id, because processDecodes does not call setNodeId(null) nor does
encodeBegin(). I looked at the implementation of HtmlDataTable and it appears
that in its encodeBegin function that it calls setRowIndex(-1) to ensure the
row is reset prior to building the table. I am wondering if this same behavior
needs to be done in UIDataTree so that the node id is reset to null prior to
rendering the tree. Also, should processDecodes call
setNodeId(null) at the end of its processing similar to processValidators and
processUpdates?
This typically has no effect, unless you have JavaScript that expects that
field to be properly named. For example, I am using AJAX4JSF to re-render this
tree and A4J expects it to be called by the correct clientId, which initially
works, but after causing an immediate event, it no longer works as the field is
misnamed.
The workaround for this issue for me was to subclass the renderer, register it
in faces-config, and then call ((UITreeData) component).setNodeId(null) in the
encodeBegin(...) method of the renderer.
Further, I believe the last time I checked SVN, the sources still showed signs
of this issue (ie: nothing was calling setNodeId(null) after the decode phase
when processValidators/processUpdateValues was not called due to immediate
events. However, I have not actually attempted to use a newer version than
1.1.1. If in fact this issue appears fixed in a newer version, let me know.
Thanks.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira