简体   繁体   中英

DataTable with dynamic columns

I am completely new to JSF, and just attempting a proof of concept to decide whether it will be useful for a project. My POC simply consists of a single page, with a table, containing some data.

The number of columns (as well as the number of rows) is dynamic, loaded from a database before the page is rendered.

With the following, I get two static columns with the appropriate number of rows, as I'd expect:

<h:dataTable id="data" value="#{viewDataBean.dataRows}" var="row">
    <h:column>
        <f:facet name="header">
            <h:outputText value="Col 1"/>
        </f:facet>
        <h:outputText value="#{row.values[0].value}"/>
    </h:column>
    <h:column>
        <f:facet name="header">
            <h:outputText value="Col 2"/>
        </f:facet>
        <h:outputText value="#{row.values[1].value}"/>
    </h:column>
</h:dataTable>

What I wanted to do was to add a <c:forEach...> around a single set of <h:column>...</h:column> tags, to iterate over the number of columns, but that didn't work - I tried a variety of combinations, but I was expecting something like this to work:

<h:dataTable id="data" value="#{viewDataBean.dataRows}" var="row">
    <c:forEach items="#{row.values}" var="val">
        <h:column>
            <f:facet name="header">
                <h:outputText value="Col 1"/>
            </f:facet>
            <h:outputText value="#{val.value}"/>
        </h:column>
    </c:forEach>
</h:dataTable>

From Googling, I've read various vague comments like 'that's not the way to do it', but I haven't been able to find any particularly compelling examples of the right way. Someone mentioned building the DataTable in the backing bean, but the only example of that I could find was http://forums.sun.com/thread.jspa?threadID=577589 . It worked, but felt kind of clumsy, especially since some of the methods used are deprecated.

At the moment, it's looking unlikely that I'll be able to use any libraries other than core JSF, but that might change if absolutely necessary. Can anyone shed any light on the right way to do this? It seems like it should be pretty simple, so I'm sure I'm just missing something obvious.

JSTL and JSF doesn't run in sync as you'd expect from the coding. It's more so that JSTL first processes the entire page from top to bottom first and then hands over the result to JSF for further processing. The #{row} is unavailable at the time JSTL is busy, so your attempt indeed won't work.

The linked topic indeed mentions deprecated methods, but the topic is also aged and discusses legacy JSF 1.0/1.1. If you explore the current Javadocs of the mentioned methods, you'll see that -as usual- the replacement methods are mentioned. For example, Application#createValueBinding() mentions the following:

Deprecated . This has been replaced by calling getExpressionFactory() then ExpressionFactory.createValueExpression(javax.el.ELContext, java.lang.String, java.lang.Class) .

You can find some concrete examples of dynamically populating a datatable this way in this article .

As to 3rd party component libraries, RichFaces has a rich:columns component which is designed for exactly this purpose.

第三方库PrimeFaces具有p:columns组件,用于从数据源动态生成列。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM