2

I'm trying to dynamically display the columns of a p:dataTable: the server dictates which columns are displayed and in which order. It doesn't look like I can set a dynamic order using the regular p:column tag so I'm stuck using the p:columns tag. The problems with the p:columns tag are:

1) The example in the showcase shows it working with String data, where you can map a column name to a field and then use an expression language map to retrieve the data (like a pseudo-getter)

http://www.primefaces.org/showcase/ui/data/datatable/columns.xhtml

If I have different data types though, then I'm probably stuck with a bunch of panels with render attributes based on the type of the data (display Strings one way, display User objects another way, etc).

Example:

<p:dataTable value="#{myBean.rows}" var="row">
    <p:columns value="#{myBean.columns}" var="column">

        <f:facet name="header">
             <h:outputText value="#{column.header}" />
         </f:facet>                

        <!-- The content of the cell is dynamic based on the type of the field -->

        <!-- display a String field -->
        <h:outputText rendered="#{myBean.isStringType(column.header)}"                      
                      value="#{row[column.property]}"/>

        <!-- display a Person field -->
        <h:outputText rendered="#{myBean.isPersonType(column.header)}" 
                      value="#{row[column.property].name}, #{row[column.property].email}"/>

    </p:columns>
</p:dataTable>

2) p:columns only supports a single sortFunction/filterFunction for all columns. Since these columns all have different types of data, they will require many different sorting and filtering methods

A p:column easily allows for the display of different data types as well as the sorting/filtering of the data. The only thing it can't do is have a dynamic order.

Unless I'm missing something? Is there a way to get this to work with p:column ? Or is there an elegant way to have p:columns handle all of this?

wsaxton
  • 1,030
  • 15
  • 34
  • Did you try? With what PF version? How is ordering related to dynamic columns? And you can use any type in a columns field... no problem. So for me your question is kind of unclear – Kukeltje Jun 06 '16 at 15:22
  • Yes, I tried. Using PF 6.0 RC3. p:column does not have an order attribute. – wsaxton Jun 06 '16 at 15:37
  • And as far as data types goes. If I have 10 different objects to display, in p:columns I would have to use 10 different panels with rendered attribute to display them in the single p:columns tag. That is ugly. Plus, they would all have to use a single sortFunction and filterFunction. Even worse. – wsaxton Jun 06 '16 at 15:39
  • @Kukeltje I rewrote the question to make it more clear. – wsaxton Jun 06 '16 at 17:12
  • If the `#{myBean.columns}` columns model is constant during at least the view scope, you'd theoretically better use `` instead of `` and `` instead of `rendered`. Does that in practice work out better as to sorting and all? Related: http://stackoverflow.com/q/3342984 and http://stackoverflow.com/q/13176842 – BalusC Jun 10 '16 at 14:54
  • @BalusC Unfortunately, it would still appear to have the same issue: namely that each would have to use the same column sorting value expression, the same filter expression, and I'd have to use a bunch of conditionals to display each column depending upon the type of data. This would work fine if I was displaying all String's, but I'm displaying Strings, objects, multiple objects, etc. – wsaxton Jun 10 '16 at 15:28
  • A possible alternative here would be to transform or rethink your backing data model of rows and columns, adapting or translating it so you can do exactly what you want. It will be helpful if you post your row and column data model if you need help about the adaption. – JMSilla Jun 11 '16 at 11:02
  • It seems you understood me as ``, but I actually meant ``. See the answer (where I used `` though, but point is the same). – BalusC Jun 13 '16 at 13:48

1 Answers1

4

It doesn't look like I can set a dynamic order using the regular p:column tag so I'm stuck using the p:columns tag.

If the #{myBean.columns} columns model is constant during at least the view scope, then you'd better use <c:forEach><p:column><c:choose>. It's faster than <p:columns>+rendered, and allows more dynamic freedom as you can declare every <p:column> individually depending on the type instead of having only one <p:columns> whose state changes every iteration round.

<p:dataTable value="#{myBean.rows}" var="row">
    <c:forEach items="#{myBean.columns}" var="column">
        <c:choose>
            <c:when test="#{column.type eq 'STRING'}">
                <p:column sortBy="#{row[column.property]}" filterBy="#{row[column.property]}">
                    #{row[column.property]}
                </p:column>
            </c:when>
            <c:when test="#{column.type eq 'PERSON'}">
                <p:column sortBy="#{row[column.property].name}" filterBy="#{row[column.property].name}">
                    #{row[column.property].name}, #{row[column.property].email}
                </p:column>
            </c:when>
            ...
        </c:choose>
    </c:forEach>
</p:dataTable>

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Thanks for the better performing answer than my original idea of the c:if. My concern is that this might be a nightmare to maintain, given there are up to 40 different columns which may require 20 different c:when statements. Will try this out and check out its performance when I get back from vacation! – wsaxton Jun 14 '16 at 12:31
  • The "nightmare to maintain" is in this context not related to JSF. You'd have had exactly the same problem in any other web based language/framework. – BalusC Jun 14 '16 at 12:33
  • Well, I'm currently using ICEfaces and the – wsaxton Jun 14 '16 at 13:40
  • Didn't realize bounties expire. I'll accept this one. Thanks @BalusC. – wsaxton Jun 16 '16 at 14:20