Cannot use Datatable "var" bound variable in columns "value" EL expression
--------------------------------------------------------------------------

         Key: TOMAHAWK-492
         URL: http://issues.apache.org/jira/browse/TOMAHAWK-492
     Project: MyFaces Tomahawk
        Type: Bug

  Components: Extended Datatable  
    Versions: 1.1.1, 1.1.2, 1.1.4-SNAPSHOT, 1.1.3    
    Reporter: Tim
    Priority: Minor


Assuming a backing bean that contains an attribute of ArrayList of ArrayList's 
(basically a 2d array) you can not use the variable defined in "var" of 
datatable, in the following example its "array'. 


                                <t:dataTable value="#{Test.array2d}" 
var="array">
                                        <t:column>Static Stuff</t:column>
                                        <t:columns value="#{array}" 
var="column">
                                                <h:outputText 
value="T#{column}T" />
                                        </t:columns>
                                </t:dataTable>

I tracked the problem down to the HtmlTableRendererBase:encodeChildren(). Where 
it first calls beforeBody() and then encodeInnerHtml(). 
BeforeBody() enquires the rowcount() from the columns child which since its 
value is bound to #{array} resolves the variable. This looks harmless, until 
you realise that dataTable does not bind the variable "array" until 
encodeInnerHtml() is called, hence columns.getRowCount() resolves the variable 
"array" to null and does not define any columns, making them never render.

Im not sure what the "correct" fix should be, but to work around this problem I 
extended HtmlTableRenderer and overroad encodeChildren():

    /**
     * Force the table's data model to be loaded before encoding the body,
     * otherwise the variable bindings for var and varIndex are not done before
     * the children columns getRowCount() in beforeBody()
     * 
     * @see javax.faces.render.Renderer#encodeChildren(FacesContext, 
UIComponent)
     */
    public void encodeChildren(FacesContext facesContext, UIComponent 
component) throws IOException
    {
        // Force the datamodel and bindings to be loaded
        UIData uiData = (UIData) component;
        uiData.setRowIndex(0);
        if (!uiData.isRowAvailable()) {
            uiData.setRowIndex(-1);
        }
        
        super.encodeChildren(facesContext, component);
    } 

This ensures that the model and loop variable are bound before talking to 
children.

Occurs in all version (inluding nightly 1.1.4 14/6/2006)

-- 
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