Dynamically generate h: column based on hashmaps list

In my application, I want to display <h:dataTable> with managed beans. This table is currently being created using List<Folder> . Now I want to change Folder to something more dynamic. This is because I do not want to change the Folder class if I later want to add another field. I just need to add another entry to Map<String, Object> instead of introducing a new field in Folder .

So, is it possible to bind List<Map<String, Object>> to <h:dataTable> ?

+4
source share
1 answer

Is it possible to associate a HashMaps list with a jsf h: dataTable component?

This is possible only when generating the necessary <h:column> tags with a view time tag, for example, JSTL <c:forEach> .

Here is a specific startup example assuming your environment supports EL 2.2:

 <h:dataTable value="#{bean.listOfMaps}" var="map"> <c:forEach items="#{bean.listOfMaps[0].keySet().toArray()}" var="key"> <h:column> #{map[key]} </h:column> </c:forEach> </h:dataTable> 

(if your environment does not support EL 2.2, you will need to provide another getter that returns the map key set to String[] or List<String> ; you should also keep in mind that HashMap is inherently unordered, you can use LinkedHashMap instead, to maintain insertion order)

When you use a version of Mojarra older than 2.1.18, the disadvantage is that #{bean} must have the scope of the request (without looking at the scope). Or at least <c:forEach items> should reference the bean request area. An object with a visible bean would otherwise be recreated on every HTTP request, since <c:forEach> triggered when the view time is created when the viewport is not yet available. If for <h:dataTable> you absolutely need a bean view, then you can always create a separate object with a limited bean request exclusively for <c:forEach items> . The solution is to upgrade to Mojarra 2.1.18 or later. For some reference see also JSTL in JSF2 Facelets ... does it make sense?

JSF component libraries, such as PrimeFaces , can offer a <x:columns> that makes this simpler, like <p:dataTable> with <p:columns> .

 <p:dataTable value="#{bean.listOfMaps}" var="map"> <p:columns value="#{bean.listOfMaps[0].keySet().toArray()}" var="key"> #{map[key]} </p:columns> </p:dataTable> 
+5
source

Source: https://habr.com/ru/post/1443431/


All Articles