I want to create a table which display a list of values in several rows, each row should contains only 3 columns.
I can create this by using JSTL but not using JSF. I am suspecting that it is xhtml related issue, not a problem in JSP, xhtml is very strict about the elements formation. Is there a way to achieve this?
Using JSTL:
<c:forEach var="book" value="${bookBean.bookList}" varStatus="bookStatus">
<c:if test="${bookStatus.index eq 0 or bookStatus.index mod 3 eq 0}">
<tr>
</c:if>
<td>
<table>
<tr>
<td>#{book.bookId}</td>
<td>#{book.bookName}</td>
<td>#{book.price}</td>
<td>#{book.author}</td>
</tr>
</table>
</td>
<c:if test="${bookStatus.count mod 3 eq 0}">
</tr>
</c:if>
</c:forEach>
Using JSF:
<ui:repeat var="book" value="#{bookBean.bookList}" varStatus="bookStatus">
<ui:fragment rendered="#{bookStatus.first or bookStatus.index mod 3 eq 0}">
<tr> <!-- Here i am getting an error saying closing tr missed.--->
</ui:fragment>
<td>
<table>
<tr>
<td>#{book.bookId}</td>
<td>#{book.bookName}</td>
<td>#{book.price}</td>
<td>#{book.author}</td>
</tr>
</table>
</td>
<ui:fragment rendered="#{(bookStatus.index+1) mod 3 eq 0}">
</tr>
</ui:fragment>
</ui:repeat>
This is actually not easy to do without using some component library (richfaces I know for a fact that has a component that does this.. rich:dataGrid..)
Here's a solution I found a while back to solve this issue... (I'm not a big fan of component libraries myself... ).. it's not the most elegant solution.. but it does the trick..
<table>
<tr>
<ui:repeat var="book" value="#{bookBean.bookList}" varStatus="bookStatus">
<td>
<table>
<tr>
<td>#{book.bookId}</td>
<td>#{book.bookName}</td>
<td>#{book.price}</td>
<td>#{book.author}</td>
</tr>
</table>
</td>
<h:outputText value="</tr><tr>" escape="false" rendered="#{(bookStatus.index + 1 ) mod 3 eq 0}"/>
</ui:repeat>
</tr>
</table>
As #FMQ has mentioned, try to use a JSF component library. Primefaces could be a good option, checkout the Demo page.
Related
Methods in xhtml are supposed to run in hierarchical order.
cursoAlumnoView.listarEntrega() runs first, then all methods listed above it.
<c:forEach items="#{cursoAlumnoView.listaCursoAlumno()}" var="cur">
#{cursoAlumnoView.setIdusu(cur.idUsuario)}
<tr class="text-center">
<td>#{cur.idUsuario.idUsuario}</td>
<td>#{cur.idUsuario.nombres} #{cur.idUsuario.apellidos}</td>
<td>
#{cursoAlumnoView.devolverPromedioLista()}
</td>
<c:forEach items="#{cursoAlumnoView.listarEntrega()}" var="c">
<c:if test="#{c.nota lt 6}">
<td class="table-danger">
#{c.nota}
</td>
</c:if>
<c:if test="#{c.nota ge 6}">
<td class="table-success">
#{c.nota}
</td>
</c:if>
</c:forEach>
<c:if test="#{actividadView.listaCursoAsignatura().size() gt cur.idUsuario.entregaActividadCollection.size()}">
<c:forEach begin="1" end="#{actividadView.listaCursoAsignatura().size() - cur.idUsuario.entregaActividadCollection.size()}">
<td class="table-danger">0.0</td>
</c:forEach>
</c:if>
</tr>
</c:forEach>
I am working with JSF 2.2 and Primefaces 6.0. I have a p:dataTable with different p:columns, and each column has many rows. I would like that, whenever column1 input changes, column2 input, in the same row, updates, however, it is not working; it doesn't render.
This is my xhtml code:
<p:dataTable value="#{myBean.objectsList}" var="object">
<p:column headerText="column1">
<table>
<tbody>
<ui:repeat value="#{object.subObjects}" var="object2">
<tr>
<td>
<c:set var="object3" value="#{object2.subObjects}"/>
<h:inputText id="value1#{myBean.toString(object3)}" value="#{object3.value1}">
<f:ajax event="change" listener="#{myBean.doSomething}"
execute="#this" render="#this"/>
</h:inputText>
</td>
</tr>
</ui:repeat>
</tbody>
</table>
</p:column>
<p:column headerText="column2">
<table>
<tbody>
<ui:repeat value="#{object.subObjects}" var="object2">
<tr>
<td>
<c:set var="object3" value="#{object2.subObjects}"/>
<h:inputText value="#{object3.value2}" disabled="disabled">
<f:ajax event="change" listener="#{myBean.doSomething2}"
execute="#this" render="value1#{myBean.toString(object3)}"/>
</h:inputText>
</td>
</tr>
</ui:repeat>
</tbody>
</table>
</p:column>
</p:dataTable>
Each object has many objects as a List.
In f:ajax tag of the first column (column1), you have given #this as value for the attribute render.
Instead, please try giving id of the component column2 or id of the p:dataTableitself.
I have a condition where i need to have two radio buttond with related data in the below the buttons.
i did something like below but the selected radio button value is not getting in the backed been. Please correct where i am going wrong
<table>
<tr>
<td>
<h:selectOneRadio value="#{beenObject.adressSelection}">
<f:selectItem itemValue="Employer" itemLabel="Employer" />
</h:selectOneRadio>.
</td>
<td>
<h:selectOneRadio value="#{beenObject.adressSelection}">
<f:selectItem itemValue="Consultant" itemLabel="Consultant" />
</h:selectOneRadio>.
</td>
</tr>
<tr>
<td>
<h:outputText value="#{beenObject.consultentDetailsString}">
</h:outputText>
</td>
</tr>
<tr>
<td>
<h:outputText value="#{beenObject.employerDetailsString}">
</h:outputText>
</td>
</tr>
</table>
I'm facing an issue similar as yours however I tried to replicate my situation at your code. While I was simplifying the lines I just end-up fixing your bug.
Below the code wich will work for you.
<table>
<tr>
<td>
<h:selectOneRadio value="#{beenObject.adressSelection}">
<f:selectItem itemValue="Employer" itemLabel="Employer" />
<f:selectItem itemValue="Consultant" itemLabel="Consultant" />
</h:selectOneRadio>
</td>
</tr>
<tr>
<td>
<h:outputText value="#{beenObject.consultentDetailsString}">
</h:outputText>
<h:outputText value="#{beenObject.employerDetailsString}">
</h:outputText>
</td>
</tr>
</table>
Explaining what I did:
I grouped the elements f:selectItem underneath f:selectItems like is shown in the sample at primeface showcase and it starts to work.
Hope it work as you want.
Cheers.
I have been working on this problem from last two days. I went through the apis possibly I could refer to but no luck.
I have been using ui:repeat as jsf facelet to render data with rows and columns
Code for reference
<ui:repeat var="pendingRequestItem" value="#{oqHomeController.allRequests}" > --JSF
<p:row rendered="#{oqHomeController.renderPendingRequest}> -- PRIMEFACES FOR ROW
<td><h:outputText value="#{pendingRequestItem.title}" /></td>
<td><h:outputText value="#{oqHomeController.pendingCount}" /></td>
</p:row>
</ui:repeat>
And the above code is resulting in the following which is very strange.
<tbody>
<td>Request for Quote 1</td>
<td>1</td>
<td>DTHEME1</td>
<td>4</td>
</tbody>
I hope it should be
<tbody>
<tr>
<td>Request for Quote 1</td>
<td>1</td>
</tr>
<tr>
<td>DTHEME1</td>
<td>4</td>
</tr>
</tbody>
Please help thanks.
Have you tried <p:dataTable> it seems that is what you are looking for:
<p:dataTable var="pendingRequestItem" value="#{oqHomeController.allRequests}">
<p:column>
<h:outputText value="#{pendingRequestItem.title}"/>
</p:column>
<p:column>
<h:outputText value="#{oqHomeController.pendingCount}"/>
</p:column>
</p:dataTable>
I have a Java object with 30 attributes. I populate the object from database. I want to display only values which are not empty.
<table>
<col width="280"/><col width="130"/>
<ui:repeat var="ud" value="#{TreeViewController.componentData}">
<tr>
<td>
<h:outputText value="componentStatsId" rendered="#{ud.componentStatsId != 0}"/>
</td>
<td>
<h:outputText value="#{ud.componentStatsId}" rendered="#{ud.componentStatsId != 0}"/>
</td>
</tr>
.......... and 40 more table rows
</ui:repeat>
</table>
I tested to create simple JSF table with rows which are not rendered if the values are empty. But I noticed that if the values are empty I get tiny spaces:
How I can solve this problem?
Yes, that would be the expected behavior from your code since is just preventing the rendering of the <<h:outputText> but not the <tr> nor <td> components.
To solve this, you should use <ui:fragment> and control the <tr> and <td> renderization using the rendered attribute:
<ui:repeat var="ud" value="#{TreeViewController.componentData}">
<ui:fragment rendered="#{ud.componentStatsId != 0}">
<tr>
<td>
componentStatsId
</td>
<td>
#{ud.componentStatsId}
</td>
</tr>
</ui:fragment>
<!-- .......... and 40 more table rows -->
<ui:fragment rendered="#{ud.componentTypeId != 0}">
<tr>
<td>
...
</td>
<td>
...
</td>
</tr>
</ui:fragment>
</ui:repeat>