Iterate through List<String> using JSF 2 - jsf

I have this java code.
List<String> myList = new ArrayList<String>();
myList.add("Hello");
myList.add("World");
I need to loop through the list to display those values in a webpage. I thought of using a dataTable but I don't know how to retrieve each entry on the list.
Ideas? Thanks!

You can use <ui:repeat>:
<ui:repeat value="#{bean.myList}" var="value">
#{value} <br />
</ui:repeat>
If you're not sure if you should use <h:dataTable> or <ui:repeat>, you can check an example that mkyong provides here: JSF 2 repeat tag example
In short: <h:dataTable> renders a <table> HTML component, while <ui:repeat> gives you the flexibility to choose how to display the data.

Related

Netbeans doesn't autocomplete properties of var of nested <ui:repeat>

Let me say I have a Book Library with a list of Book. A Book has a List of Page. Page has a list of Line.
In JSF, i'm trying to display all the lines, now I'm using <h:dataTable> or <ui:repeat> to iterate through the lists. When I'm on second level of hierarchy which is page, instead of showing the properties of page as lines, netbeans only show the properties of book again as available properties
<ui:repeat value="#{bookLibrary.books}" var="book">
<ui:repeat value="#{book.pages}" var="page">
<ui:repeat value="#{page.???}" var="line">
</ui:repeat>
</ui:repeat> </ui:repeat>
Yes, I now found out that it works if I add the field manually. Its the code completion that's leading me to believe my code is wrong

I can't use varStatus value to get index in p:repeat [duplicate]

I'm trying to assign an id to a component inside a <ui:repeat> like that:
<ui:repeat value="#{bean.columns}" var="column">
<h:panelGroup layout="block" id="column_#{column.id}"
styleClass="#{column.id} dashboard_column">
The thing is that #{column.id} value is being placed properly inside the styleClass value but its not being set inside the id attribute. All that is being set inside the id attribute is the automatically generated id by the JSF + my hard coded value column_.
If I remove the hard coded column_ I get an exception:
java.lang.IllegalArgumentException: component identifier must not be a zero-length String
at
Any Ideas?
This is not possible with a render-time tag such as <ui:repeat>. The <ui:repeat> will however by itself already ensure the uniqueness of the generated client ID by prepending it with the row index. So just remove the EL part from the ID attribute of the component.
<ui:repeat value="#{bean.columns}" var="column">
<h:panelGroup layout="block" id="column">
With a view build time tag such as <c:forEach> (which will basically generate multiple <h:panelGroup> components instead of only one which is rendered multiple times), it is possible to specify a dynamic ID like that.
<c:forEach items="#{bean.columns}" var="column">
<h:panelGroup layout="block" id="column_#{column.id}">
(you should only be well aware of how JSTL works in Facelets)
An alternative is to use a static <div> element instead of a JSF <h:panelGroup layout="block"> component.
<ui:repeat value="#{bean.columns}" var="column">
<div id="column_#{column.id}">
See also:
JSTL in JSF2 Facelets... makes sense?
JSF prefixes the id automatically. If you simply write id="column" the generated HTML will contain such identifiers:
myForm:0:column
myForm:1:column
myForm:2:column
and so on.
Anyway: Do never use JSTL tags (like c:foreach and c:if) in JSF templates. They cause random behaviour, very difficult to debug. And if they work, the slow down the application a lot.
Use ui:repeat for loops, and ui:fragment for conditional blocks. Note that there is no replacement for c:set, such a construct does not exist anymore in JSF 2.

Dynamic id for primefaces datatable [duplicate]

I'm trying to assign an id to a component inside a <ui:repeat> like that:
<ui:repeat value="#{bean.columns}" var="column">
<h:panelGroup layout="block" id="column_#{column.id}"
styleClass="#{column.id} dashboard_column">
The thing is that #{column.id} value is being placed properly inside the styleClass value but its not being set inside the id attribute. All that is being set inside the id attribute is the automatically generated id by the JSF + my hard coded value column_.
If I remove the hard coded column_ I get an exception:
java.lang.IllegalArgumentException: component identifier must not be a zero-length String
at
Any Ideas?
This is not possible with a render-time tag such as <ui:repeat>. The <ui:repeat> will however by itself already ensure the uniqueness of the generated client ID by prepending it with the row index. So just remove the EL part from the ID attribute of the component.
<ui:repeat value="#{bean.columns}" var="column">
<h:panelGroup layout="block" id="column">
With a view build time tag such as <c:forEach> (which will basically generate multiple <h:panelGroup> components instead of only one which is rendered multiple times), it is possible to specify a dynamic ID like that.
<c:forEach items="#{bean.columns}" var="column">
<h:panelGroup layout="block" id="column_#{column.id}">
(you should only be well aware of how JSTL works in Facelets)
An alternative is to use a static <div> element instead of a JSF <h:panelGroup layout="block"> component.
<ui:repeat value="#{bean.columns}" var="column">
<div id="column_#{column.id}">
See also:
JSTL in JSF2 Facelets... makes sense?
JSF prefixes the id automatically. If you simply write id="column" the generated HTML will contain such identifiers:
myForm:0:column
myForm:1:column
myForm:2:column
and so on.
Anyway: Do never use JSTL tags (like c:foreach and c:if) in JSF templates. They cause random behaviour, very difficult to debug. And if they work, the slow down the application a lot.
Use ui:repeat for loops, and ui:fragment for conditional blocks. Note that there is no replacement for c:set, such a construct does not exist anymore in JSF 2.

Displaying the values of a nested array list in JSF data table

Its been quite some time since i have started developing web pages using JSF but i am still learning most of the stuff. Now I have an interesting question
When I have the values those to be displayed in a data table in the ArrayList and I am adding those ArrayList objects in another array list , so now how will i be able to display them in a data table.
I am doing this since , i need my table to be so dynamic so that i dont know how many columns will i be getting in the result set to be displayed in the page, hece i cannot have a Bean obj for storing my variable values. So i have decided to have something like
ArrayList<ArrayList<String>>
ArrayList<String> - Values for Each row
Does this have a solution that can be provided int he jsf page
Use either plain HTML with a nested <ui:repeat>
<table>
<ui:repeat value="#{bean.rows}" var="row">
<tr>
<ui:repeat value="#{row}" var="column">
<td>#{column}</td>
</ui:repeat>
</tr>
</ui:repeat>
</table>
or grab a 3rd party component library which has sort of a <x:columns> tag like PrimeFaces with <p:columns> and Tomahawk with <t:columns>.
<p:dataTable value="#{bean.rows}" var="row">
<p:columns value="#{row}" var="column">
#{column}
</p:columns>
</p:dataTable>
Either way, you can even keep the columns in a separate list.

JSF <h:outputFormat>: use array values as parameters

On my JSF2 page, i'm using internationalized error messages.
In my backing bean, i'm putting the messages into the flash Scope:
flash.put("error", exception.getType());
On the page, this string gets translated this way:
<h:outputText value="#{bundle[flash.error]}"/>
Works fine.
NOW i want to be also able to put (an arbitrary number of) parameters into the message text, that get inserted into the placeholders in the i18n-property in my message.properties. Therefore, i'm putting the parameters as a String array into the Flash Scope, like this:
//exception.getParameters returns String[]
flash.put("errorParams", exception.getParameters())
Now i also want to be able to use this String array as parameters for an outputFormat element, to insert them into a property like Welcome, {0} {1}.
So i tried to achieve this by using ui:repeat:
<h:outputFormat value="#{bundle[flash.error]}" rendered="#{! empty flash.error}" class="invalid">
<ui:repeat value="#{flash.errorParams}" var="_param">
<f:param value="#{bundle[_param]}"/>
<!-- also doesn't work: <f:param value="#{_param}"/>-->
</ui:repeat>
</h:outputFormat>
Unfortunately, the param value is ignored and the placeholders of the i18n-property aren't replaced, so the rendered output is Welcome, {0} {1}. When using a "regular" repeater, displaying the array elements just as an outputtext, it works. So the outputFormat tag doesn't seem to support the use of a repeat as a child.
Damn, so close ;) Anyone knows a good way to do what i want, or is there any component library supporting something like that?
The problem here is that ui:repeat is a render-time child of h:outputFormat which it indeed doesn't support at all. You'd like to put multiple f:param elements directly as children of h:outputFormat during build time.
The c:forEach is suitable for this task. The JSTL core tags (which are already included in Facelets, so you don't need to install any extra JARs) do their job during building the view tree, right before it's JSF turn to process/render the view tree.
<html xmlns:c="http://java.sun.com/jsp/jstl/core">
...
<h:outputFormat value="#{bundle[flash.error]}" rendered="#{! empty flash.error}" class="invalid">
<c:forEach items="#{flash.errorParams}" var="_param">
<f:param value="#{bundle[_param]}"/>
</c:forEach>
</h:outputFormat>

Resources