0

I'm trying to show a 2D array as a table in a page. I know this sounds as if I was reinventing the wheel but the object I have to handle is a 2D array of a custom type that must also be rendered in a particular way (always the same).

The tricky part is that this 2D array can have null values in some of its indexes. In those cases, a particular "unavailable" cell must be rendered. The table structure (yes... <table> <tr> and <td>) was already defined by the Design Team and accepted by the client.


I've tried to use <c:forEach/> but got in trouble trying to make it work, because of the order in which JSTL and JSF tags are managed. When the JSF tags are handled there are some issues that include outdated values and missing components.

The array (attribute of a @ViewScoped bean) is always null when <c:forEach/> is invoked, even when I force the creation of the array:

public MyObject[][] getMatrix() {
    if(loadedMatrix == null)
        initializeMatrix();
    return loadedMatrix.getTable();
}

The initializeMatrix() method obtains the corresponding data from the database and invokes the logic that creates the 2D array, making loadedMatrix reference it once it's created (all of this works, no exceptions or errors). When initializeMatrix finishes, loadedMatrix is still null.

I went for the nested <c:forEach/> option because I need to manage the indexes of the table to know what to render (if the object is null, has an availability flag set to false or if it can be rendered normally), but as for now I think the safest solution is to create a custom component.


My question is: What alternatives do I have to render the content of a 2D array as a table while being aware of the indexes I'm rendering?.

Thanks in advance

Fritz
  • 9,987
  • 4
  • 30
  • 49

1 Answers1

3

You can use ui:repeat instead of c:forEach, I tried myself with a sample and it worked for me. c:foreach is a tag-handler and please take a look at the following post of @BalusC to learn more about why you should not use tag handlers with view-scoped beans.

JSTL in JSF2 Facelets... makes sense?

<table>
<ui:repeat value="#{sampleBean.twodarray}" var="firstLevel" varStatus=#{vs}>
    <tr>
    <ui:repeat value="#{firstLevel}" var="secondLevel" rendered="#{!empty  firstLevel}">
        <td>#{vs.index} - #{secondLevel}</td>
    </ui:repeat>
    <h:panelGroup rendered="#{empty firstLevel}">
        <td colspan="3">empty</td>
    </h:panelGroup>
    </tr>
</ui:repeat>
</table>
Community
  • 1
  • 1
cubbuk
  • 7,800
  • 4
  • 35
  • 62
  • I suspected as much about the ViewScope + JSTL combo, in particular after reading some articles about the differences between "what we think they do" and "what they actually do" in JSTL. I was missing the fact that I'm able to use the first level as the value of a nested ui:repeat! I'll try this one right away and see if I can get it to work... tough I still need to know a current index to label the table properly. – Fritz Jan 08 '13 at 16:00
  • I modified to answer to show you how you can get the current the index of the ui:repeat. varStatus attribute hold that information, but if you are meaning another index, just ignore this part =) – cubbuk Jan 08 '13 at 16:03
  • I was trying exactly that. +1 for speed and usefulness. – Fritz Jan 08 '13 at 16:05