How to iterate Map <String, Collection> into datatable in f

Using JSF 2.1 for Purposes

class FOO{
String name;
String value;
public void setName(String name){
this.name=name;
}
public String getName(){
return this.name;
}
public void setValue(String value){
this.value=value;
}
public String getValue(){
return this.value;
}

}

      

I have Map<String, List<FOO>>

The title name must be the Map Key. I need to create multiple columns (i.e. map size) and each column needs to have a FOO list in order to display FOO.Name in rows.

Example: if the map size is 4

Coulmns ----- Key1

1st column List<FOO>

ROWs versus Key1

Coulmns ----- Key2

1st column List<FOO>

ROWs versus Key2

Coulmns ----- Key3

1st column List<FOO>

ROWs versus Key3

Coulmns ----- Key4

1st column List<FOO>

ROWs versus Key4

Can anyone tell me which component to use to display this type of output in the xhtml page? I tried to use dynamic data creation but couldn't show it.

+3


source to share


2 answers


You have the wrong data structure. Change it to the correct data structure. The easiest way is to collect the data into List<Map<String, Object>>

which the property represents rows

. Map

represents columns keyed by column name. Collect the names of these columns in a separate List<String>

one that represents the property columns

. Finally, show it like this <p:columns>

:

<p:dataTable value="#{bean.rows}" var="row">
    <p:columns value="#{bean.columns}" var="column">
        #{row[column]}
    </p:columns>
</p:dataTable>

      



Here's how you can convert the weird data structure to the data structure you want, if necessary (and assuming that each List<FOO>

is the same size, the whole data structure makes it less understandable otherwise):

Map<String, List<FOO>> wrongDataStructure = createItSomehow();
List<String> columns = new ArrayList<String>(wrongDataStructure.keySet()); // Note I expect LinkedHashMap ordering here.
List<Map<String, Object>> rows = new ArrayList<Map<String, Object>>();
int size = wrongDataStructure.values().iterator().next().size();

for (int i = 0; i < size; i++) {
    Map<String, Object> row = new HashMap<String, Object>();

    for (String column : columns) {
        row.put(column, wrongDataStructure.get(column).get(i).getName());
    }

    rows.add(row);
}

// Now use "columns" and "rows".

      

+3


source


I couldn't figure out how to do this without using a trick: since the size of your lists on the map can be different for each set of keys, you need to know the size of the list with the largest set of items. Knowing that you can come up with this strange solution: the idea is to have a for loop in a for loop.

private Map<String, List<Foo>> fooMap = Maps.newHashMap();
private List<Foo> highestNumberOfFoos;

private init()
{
    highestNumberOfFoos = Lists.newArrayList(new Foo("a", "b"), new Foo("c", "d"), new Foo("e", "f")); // We know that there won't be any list who has more items than this item.
    fooMap.put("name1", highestNumberOfFoos);
    fooMap.put("name2", Lists.newArrayList(new Foo("g", "h"), new Foo("i", "j")));
}

      



... and in the view:

<table>
      <thead>
              <tr>
                  <ui:repeat value="#{bean.fooMap.keySet().toArray()}" var="key">
                         <td>#{key}</td>
                   </ui:repeat>
              </tr>
       </thead>
       <tbody>
             <ui:repeat value="#{bean.highestNumberOfFoos}" var="dummyFoo" varStatus="vs">
             <tr>
                 <ui:repeat value="#{bean.fooMap.entrySet().toArray()}" var="innerEntry">
                     <td>#{innerEntry.value[vs.index].name}</td>
                  </ui:repeat>
             </tr>
                  </ui:repeat>
       </tbody>
 </table>

      

0


source







All Articles