how to iterate Map<String,Collection> in datatable in primefaces

回眸只為那壹抹淺笑 提交于 2021-02-07 19:14:20

问题


Using JSF 2.1 with primefaces

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 an Map<String, List<FOO>>

Header name should be Key of the Map. I need to create multiple columns (i.e. size of Map) and each column should have the list of FOO to display FOO.Name in rows.

For Example : if size of map is 4

Coulmns-----Key1

ROWs of 1st column - List<FOO> against Key1

Coulmns-----Key2

ROWs of 1st column - List<FOO> against Key2

Coulmns-----Key3

ROWs of 1st column - List<FOO> against Key3

Coulmns-----Key4

ROWs of 1st column - List<FOO> against Key4

Can someone tell me what component to use for displaying this type of output in xhtml page ? I have tried using dynamic datatable creation but not able to show this.


回答1:


You've there a wrong data structure. Change it to the right data structure. Easiest is to collect the data in a List<Map<String, Object>> which represents the rows property. The Map represents the columns, keyed by a column name. Collect those column names in a separate List<String> which represents the columns property. Finally show it as follows by <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 could convert the strange data structure to the right data structure, if necessary (and assuming that each List<FOO> is of the same size; the whole data structure makes otherwise less sense):

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".



回答2:


I couldn't figure out a way to do this without using a trick: Since the size of your lists in the map may differ for each key set, you need to know the size of the list with largest item set. By knowing that you can come up with this bizarre 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>


来源:https://stackoverflow.com/questions/14612034/how-to-iterate-mapstring-collection-in-datatable-in-primefaces

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!