2

What I'm trying to do is do something to the first row, second row, etc. of the table.

<p:panel header="#{mat.description}">
    <p:dataTable var="datarow" value="#{myBean.getDatarows(mat.itemId)}" emptyMessage="No materials" rowIndexVar="row">
        <c:choose>
            <c:when test="${row eq 0}">
                <p:column headerText=""><h:outputText value="#{datarow.get(1)}" /></p:column>
            </c:when>
            <c:when test="${row eq 1}">
                <p:column headerText=""><h:outputText value="#{datarow.get(1)}" /></p:column>
            </c:when>
        </c:choose>
        <p:column headerText=""><h:outputText value="#{datarow.get(6)}" /></p:column>
        <p:column headerText="Month 1"><h:outputText value="#{datarow.get(1)}" /></p:column>
        <p:column headerText="Month 3"><h:outputText value="#{datarow.get(2)}" /></p:column>
        <p:column headerText="Month4"><h:outputText value="#{datarow.get(3)}" /></p:column>
        <p:column headerText="Month 5"><h:outputText value="#{datarow.get(4)}" /></p:column>
        <p:column headerText="Month6"><h:outputText value="#{datarow.get(5)}" /></p:column>
    </p:dataTable>
</p:panel>

But the c:choose and c:when is not displaying anything. Am I doing the test for row number wrongly?

octopish
  • 59
  • 2
  • 8

2 Answers2

4

This is bad design and will not work that way. You are mixing up JSTL and JSF tags in a wrong way.

The JSTL tags c:choose and c:when are evaluated during tree built, but the p:dataTable tag when the UI tree is rendered.

Just use the rendered-attribute on p:column instead, if you want to include/exclude complete columns of your datatable. If you want to achieve different behavior of what is beeing displayed inside the columns, you could for example use the ?-operator to decide what is beeing rendered:

<p:dataTable var="datarow" ... rowIndexVar="row">
    <p:column>
        <h:outputText value="#{row eq 0 ? datarow.get(1) : 'some other stuff'}"/>
    </p:column>
</p:dataTable>

To render different kind of elements inside your column, just put both of them inside the column, but with different rendered-attribute:

<p:column>
        <h:outputText rendered="#{row != 4}"/>
        <p:inputText rendered="#{row eq 4}"/>
</p:column>

This will render an input-element in the 5th row (rowIndexVar is 0-based), and an output-element in all other rows.

stg
  • 2,757
  • 2
  • 28
  • 55
  • Thank you. I see that I wasnt doing it right, but my actual intention was to let it be an editable textbox on only one row, and an output text on the others. How can I do that? – octopish Sep 09 '14 at 14:08
  • @pern I edited my answer according to your additional question in your comment. – stg Sep 09 '14 at 14:16
0

I believe you always need the same number of columns.

Change your code to:

<c:when test="${row eq 0}">
    <p:column headerText=""><h:outputText value="#{datarow.get(1)}" /></p:column>
</c:when>
<c:when test="${row ne 0}">
    <p:column headerText=""><h:outputText value="#{datarow.get(1)}" /></p:column>
</c:when>

This way you still have the column when not in the first or second row.

Yamada
  • 723
  • 6
  • 23
  • Then you should add more when test cases ... but you should always have a match. – Yamada Sep 09 '14 at 14:00
  • 1
    This is conceptually wrong and will not work, you just do not notice it, because you are rendering the same content in each case. See my answer below for more details. – stg Sep 09 '14 at 14:01