Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can <c:forEach> or <ui:repeat> not access <p:dataTable var>?

I am working with jsf Mojarra 2.2.7, Java 8, Primefaces 5.1 and netbeans 8.0.2

I have a class Event with a property List<GameRecord> gameRecordList. GameRecord includes List<Boolean> gamesEntered and other properties. The idea is I have a list of people in an event and am configuring if they are entered into bets or competitions.

In my .xhtml file I have

<p:dataTable value="#{events.gameRecordList}" var="item" rowIndexVar="rowIndex">

                <p:column>#{item.field1}</p:column>
                <p:column>#{item.field2}</p:column>

                <c:forEach items="#{events.gameRecordList.get(rowIndex).gamesEntered}" var="game">
                    <p:column>
                        <p:selectBooleanCheckbox value="#{game}"/>
                    </p:column>
                </c:forEach>


            </p:dataTable>

The <c:forEach> should work with value="#{item.gamesEntered}" rather than the full string but it does not. I have tried <ui:repeat> but either way the page comes up blank where this data should have appeared.

Does this make sense or is there a reason the full addressing is required to make it work?

like image 203
GolfAddict Avatar asked Feb 11 '23 16:02

GolfAddict


1 Answers

The <c:forEach> should work with value="#{item.gamesEntered}" rather than the full string but it does not.

JSTL tags run during view build time, building JSF component tree. JSF components run during view render time, producing HTML output. So at the moment <c:forEach> runs, <p:dataTable> hasn't run and its var is nowhere available and will evaluate as null. Note that the same applies to rowIndexVar, which will evaluate as 0 (the default value of an int).

See also

  • JSTL in JSF2 Facelets... makes sense?

I have tried <ui:repeat> but either way the page comes up blank where this data should have appeared.

UIData components can only accept UIColumn children. The <ui:repeat> isn't such one. The <c:forEach> works because it basically produces a bunch of physical <p:column> components for the datatable. You're lucky that each item has apparently the same amount of gamesEntered as the first item, this would otherwise have failed hard as well.

See also:

  • How to use ui:repeat in datatable to append columns?

By the way, you need <p:columns> which is basically an <ui:repeat> which extends from UIColumn class. But also here, its value cannot be set on a per-row basis, only on a per-table basis. The rowIndexVar isn't available in <p:columns value> and would evaluate as 0 anyway.

<p:dataTable value="#{events.gameRecordList}" var="item" rowIndexVar="rowIndex">
    <p:column>#{item.field1}</p:column>
    <p:column>#{item.field2}</p:column>
    <p:columns value="#{events.gameRecordList[0].gamesEntered}" columnIndexVar="columnIndex">
        <p:selectBooleanCheckbox value="#{events.gameRecordList[rowIndex].gamesEntered[columnIndex]}"/>
    </p:columns>
</p:dataTable>

See also:

  • Primefaces static and dynamic columns in datatable
  • Dynamic columns with List<List> in <p:dataTable><p:columns>
like image 99
BalusC Avatar answered Feb 19 '23 03:02

BalusC