I have been searching for a solution of how to display an h:dataTable view where the number of columns is only known at runtime. I found normal tables (plain html) supported by JSF which works but which escapes the concept. I saw extremely complex things which I never understood. So - I have no idea how I came to it - I found this solution which looks quite simple to me and - more surprisingly - works quite good:
The table in the xhtml file looks like this:
And this is the relevant part of the backing bean (modelExtractor):
Now I am not particularly in love with the getColIdxs() and getRowIdxs() functions as these are simply crutches to make JSF what I want but their potential scope of disturbance is quite limited.
So, question behind - as I found it already working - is solely how you find this and maybe someone can even improve it further. Besides that obviously I felt like sharing this with anyone so maybe someone can use it some time.
Actually, I'm surprised that anything displays, since you aren't fetching row columns values, just column headers. I was thinking that unless there's at least one displayable row of data, the column headers didn't display.
I'm conflicted about your solution. One the one hand:
A) It works.
B) Oracle does have samples of JSF on their official website mixing JSF and JSTL tags, so presumably there's at least some support (in other words, not a kludge that could break randomly when new versions of JSF are released).
On the other:
A) Mixing JSF and JSTL is not somethng I recommend, since despite Oracle's examples, in real life JSTL on JSF pages hasn't proven reliable. JSF View Templates are NOT JSPs, and JSTL was designed for JSPs.
B) Putting any sort of logical construct on a JSF View Template is not something I recommend either. People tend to blur the line between business logic (which should be on the backing bean) and display logic. And in cases where the logic is purely for the display (show/hide stuff etc., I do recommend only simple EL expressions on the view template - no fancy function calls or complex conditionals. EL is a to debug, so for a peaceful night's sleep, put the complex logic on the backing bean and have it return a simple boolean value for the EL to reference. A debugger can easily step through Java logic on a backing bean. Stepping through logic on a View Template is much harder.
C) Core JSF does require such measures -as yours although as an alternative, you can dynamically build dataTable column definitions in Java logic in a backing bean using the UIComponent binding mechanism (it's not as arcane as it sounds). However, many of the third-party extension libraries such as PrimeFaces do have extended dataTable controls that support a variable list of columns without the need for JSTL or complex coding.
So, in short, I endorse your solution with reservations. If possible, use one of the native JSF solutions that the extension libraries offer. If that's not an option, then jSTL or UIComponent binding solutions are a reasonable alternative.
Not content with having passed a rain cloud over your parade, there's a couple of Best Practices, I should point out.
First, don't fetch or generate data within JSF backing bean "get" methods. A getter may be invoked 5 or 6 times in the process of rendering a JSF page, which multiplies the amount of work to be done and the time to do it. It's OK to generate the data on the first get, but cache it so that the 2nd-through 6th gets don't have to repeat all that effort. I know that this was just a simple sample, but it's always worth keeping in mind. Oh, and the other reason for caching is that "get" methods MUST be idempotent - returning exactly the same results for each call. That won't happen if you're generating random numbers or querying a changing database on each call.
Secondly, I strongly recommend conservative bracketing. Only one late-night desperate attempt to debug something this way:
Will make you a confirmed believer in this style of coding:
"privilege" comes from the Latin words for "private" and "law" (legal) and dates to feudal times. To "claim privilege" meant that you were above the laws that applied to the common people.
posted 3 years ago
Happy new year to you; sorry for my late reply, I saw your comments in mid-december but at least my mind was already practicing skiing, so it took me until now before I was really getting back into the details.
Well, I must admit I am not expert enough to understand everything you wrote. I suppose the extended tooling (you named PrimeFaces) could be well worth looking at. I am still having a hard time to figure out the connections is JSF and JSTL by now, so it wasn't my first goal to import other packages which improve complexity. Besides all the "this is working" I would need some "this has prooved to be good practice". But whenever I try to find these, I hit into walls of "this doesn't work together with something else". So building a fully dynamic web application without any "phone joker" for someone who has done it before seems quite tedious...
I will try to incorporate some of your suggestions - at least the ones I could follow. I have actually implemented the caching now. Done paging as well, works surprisingly smoothly. If it fits best practice - don't know at all...
Thanks & CU,
Please enjoy this holographic presentation of our apocalyptic dilemma right after this tiny ad: