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

        

Reply via email to