Dynamically generate a table within a row of a table - jsf

I have a SEAM 2, JSF 1.2 web application with a Java back end. Currently I have table that displays books (see below). What I need to add to this is a collapse-able table to each of these rows that would show previous versions of this book (#{_item.relatedVersions}). Each of these version are a book themselves (but don't have an expandable sub-version table, i.e only 1 level deep on a nested table). So what I am wondering is what is the cleanest way to display a list of books (#{bean.items}) in "Table A", and then foreach book dynamically generate another Table within a row in "Table A"?
...
<a:form id="bookList_results_form">
<rich:dataTable id="bookList_dt"
rendered="#{bean.itemCount gt 0}"
var="_item"
width="100%"
value="#{bean.items}">
<rich:column>
<f:facet name="header">ID</f:facet>
<h:outputText value="#{_item.bookId}"/>
</rich:column>
<rich:column>
<a:commandButton image="#{plusIcon}" size="15"
title="Expand version info."
action="#{bean. ???}"
ajaxSingle="true" bypassUpdates="true" immediate="true"/>
<f:facet name="header">Book Name</f:facet>
<h:outputText value="#{_item.bookName}" escape="true"/>
</rich:column>
<rich:column>
<f:facet name="header">Comments</f:facet>
<h:outputText value="#{_item.comments}"/>
</rich:column>
<rich:column>
<f:facet name="header">Actions</f:facet>
<a:commandLink
value="Edit"
title="View or Edit metadata for this book"
action="#{bean.edit(_item.bookId)}"/>
</rich:column>
</rich:dataTable>
</a:form>
...

Check out the
http://showcase.richfaces.org/richfaces/component-sample.jsf?demo=subTableToggleControl&skin=blueSky
<h:form>
<rich:dataTable value="#{carsBean.inventoryVendorLists}" var="list">
<f:facet name="header">
<rich:columnGroup>
<rich:column colspan="6">
<h:outputText value="Cars marketplace" />
</rich:column>
<rich:column breakRowBefore="true">
<h:outputText value="Model" />
</rich:column>
<rich:column>
<h:outputText value="Price" />
</rich:column>
<rich:column>
<h:outputText value="Mileage" />
</rich:column>
<rich:column>
<h:outputText value="VIN Code" />
</rich:column>
<rich:column>
<h:outputText value="Items stock" />
</rich:column>
<rich:column>
<h:outputText value="Days Live" />
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column colspan="6">
<rich:collapsibleSubTableToggler for="sbtbl" />
<h:outputText value="#{list.vendor}" />
</rich:column>
<rich:collapsibleSubTable value="#{list.vendorItems}" var="item" id="sbtbl" expandMode="client">
<rich:column>
<h:outputText value="#{item.model}" />
</rich:column>
<rich:column>
<h:outputText value="#{item.price}" />
</rich:column>
<rich:column>
<h:outputText value="#{item.mileage}" />
</rich:column>
<rich:column>
<h:outputText value="#{item.vin}" />
</rich:column>
<rich:column>
<h:outputText value="#{item.stock}" />
</rich:column>
<rich:column>
<h:outputText value="#{item.daysLive}" />
</rich:column>
<f:facet name="footer">
<h:outputText value="Total of #{list.vendor} Cars: #{list.count}" />
</f:facet>
</rich:collapsibleSubTable>
</rich:dataTable>
</h:form>

Have you already tried to use the <rich:subTable>?
Edit: I've updated main parts of my answer to show a more detailed example:
<rich:dataTable id="bookList_dt" [...] var="_item" value="#{bean.items}" >
<f:facet name="header">
<rich:column>
Header1
</rich:column>
<rich:column>
Header2
</rich:column>
</f:facet>
<rich:column>
<a4j:commandLink id="toggleIcon" action="#{bean.toggleRelatedVisible(_item)}" reRender="bookList_dt">
<h:graphicImage value="/img/plusIcon.gif" rendered="#{not bean.isRelatedVisible(_item)}" style="margin-right:4px;" />
<h:graphicImage value="/img/minusIcon.gif" rendered="#{bean.isRelatedVisible(_item)}" style="margin-right:4px;" />
</a4j:commandLink>
<h:outputText value="#{_item.bookId}"/>
</rich:column>
[...]
<rich:subTable value="#{_item.relatedVersions}"
var="_relatedItem"
rendered="#{bean.isRelatedVisible(_item)}">
<rich:column>
<h:outputText value="#{_relatedItem.bookId}"/>
</rich:column>
[...]
</rich:subTable>
</rich:dataTable>
In this solution I'm rerendering the whole table on collapse/expand of the subtable. Maybe you can find a more effective way.
Of course, the bean must have some collection of boolean-values containing the state (collapsed/expended) of the subtables.

Related

richfaces DataScroller not working

I am trying to implement datascroller in richfaces 3.1.4 with JSF 1.2 but the datascroller is not working properly though it is showing the no of pages.Here is the code :
<rich:dataTable width="150 px" id="listOfServiceId" rows="#{posManageOrderBean.count}" columnClasses="col"
value="#{posManageOrderBean.customerProjectServiceIds}" var="serviceIDs"
headerClass="dr-stglpnl-h" rowClasses="evenrow,oddrow">
<h:column>
<f:facet name="header">
<h:outputText value="Service Id" rendered="true" />
</f:facet>
<h:commandLink value="#{serviceIDs.serviceID}" action="#{posManageOrderBean.showAllServiceIdAttr}" >
<f:param name="serviceId" value="#{serviceIDs.serviceID}"> </f:param>
</h:commandLink>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Copf Id" rendered="true" />
</f:facet>
<h:outputText value="#{serviceIDs.copfID}" rendered="true" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Service Id" rendered="true" />
</f:facet>
<h:outputText value="#{serviceIDs.customerProjectName}" rendered="true" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Service Id" rendered="true" />
</f:facet>
<h:outputText value="#{serviceIDs.customerName}" rendered="true" />
</h:column>
<f:facet name="footer">
<h:panelGrid>
<rich:datascroller maxPages="20" id="sc1" for="listOfServiceId" reRender="listOfServiceId"></rich:datascroller>
</h:panelGrid>
</f:facet>
</rich:dataTable>

JSF RichTable merging rows / columns in a header

What I want to do is do this layout with RichTable in its header to have 3 columns:
+---+---+-------+
| | | 3 5 |
| 1 | 2 |-------+
| | | 4 6 |
+---+---+-------+
I got used this (8.2) resource to get it done. Rich-faces 4.0.0
But instead I end up having plain table-row with no any merging.
Could you please shed a light on this?
Update:
About the answer from Vasil Lukach. In my case (if I do copy paste of those code), I have this result (I use hard coded values to keep it simple):
My code looks like this:
<rich:dataTable id="mydatatable"
value="#{applicationListBean.data}" >
<f:facet name="header">
<h:outputText value="msg.txnLineItems" />
<rich:columnGroup>
<rich:column rowspan="2">
<h:outputText value="msg.item" />
</rich:column>
<rich:column rowspan="2">
<h:outputText value="msg.department" />
</rich:column>
<rich:column rowspan="2">
<h:outputText value="msg.purchaseAmount}" />
</rich:column>
<rich:column rowspan="2">
<h:outputText value="msg.quantity" />
</rich:column>
<rich:column colspan="5">
<h:outputText value="msg.promotions" />
</rich:column>
<rich:column breakRowBefore="true">
<h:outputText value="msg.promoName" />
</rich:column>
<rich:column>
<h:outputText value="msg.promoCode" />
</rich:column>
<rich:column>
<h:outputText value="msg.promoCategory" />
</rich:column>
<rich:column>
<h:outputText value="msg.discount" />
</rich:column>
<rich:column>
<h:outputText value="msg.points" />
</rich:column>
</rich:columnGroup>
</f:facet>
</rich:dataTable>
I use <rich:column rowspan="2"> and <rich:column breakRowBefore="true"> for similar table:
Code
<f:facet name="header">
<h:outputText value="#{msg.txnLineItems}" />
<rich:columnGroup>
<rich:column rowspan="2">
<h:outputText value="#{msg.item}" />
</rich:column>
<rich:column rowspan="2">
<h:outputText value="#{msg.department}" />
</rich:column>
<rich:column rowspan="2">
<h:outputText value="#{msg.purchaseAmount}" />
</rich:column>
<rich:column rowspan="2">
<h:outputText value="#{msg.quantity}" />
</rich:column>
<rich:column colspan="5">
<h:outputText value="#{msg.promotions}" />
</rich:column>
<rich:column breakRowBefore="true">
<h:outputText value="#{msg.promoName}" />
</rich:column>
<rich:column>
<h:outputText value="#{msg.promoCode}" />
</rich:column>
<rich:column>
<h:outputText value="#{msg.promoCategory}" />
</rich:column>
<rich:column>
<h:outputText value="#{msg.discount}" />
</rich:column>
<rich:column>
<h:outputText value="#{msg.points}" />
</rich:column>
</rich:columnGroup>
</f:facet>

rich:extendedDataTable with dynamic columns

I want to fill a rich:extendedDataTable with a static columns and dynamic columns in RichFaces 4.2
I tried following code,but it's not working for me :
<rich:extendedDataTable id="listDipRec"
iterationStatusVar="itDipRec" rows="200"
value="#{declarationReglementaireModel.detailCurrentDecReg.decReg.listLigneDipRecsDTO}"
var="ligneDipRec" frozenColumns="1"
style="height:300px; width:800px;" selectionMode="none">
<rich:column width="35px">
<h:panelGrid columns="1" cellpadding="2">
<a4j:commandLink render="editGridDipRec" execute="#this"
oncomplete="#{rich:component('modifDipRec')}.show()">
<span class="icone icone-edit icone-align-center" />
<a4j:param value="#{itDipRec.index}"
assignTo="#{declarationReglementaireModel.currentLigneDipRecIndex}" />
<f:setPropertyActionListener
target="#{declarationReglementaireModel.currentLigneDipRec}"
value="#{ligneDipRec}" />
</a4j:commandLink>
</h:panelGrid>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Date ligne fichier Dip" />
</f:facet>
<h:outputText value="#{ligneDipRec.dtLigneDipRec}">
<f:convertDateTime pattern="dd/MM/yyyy" timeZone="Europe/Paris" />
</h:outputText>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Référence titre" />
</f:facet>
<h:outputText value="#{ligneDipRec.rfTitre}">
</h:outputText>
</rich:column>
<rich:column>
<f:facet name="header">
<h:outputText value="Origine titre" />
</f:facet>
<h:outputText value="#{ligneDipRec.lbOrigineLigne}">
</h:outputText>
</rich:column>
<c:forEach items="#{ligneDipRec.listDonneeDipRecDTO}" var="column"
varStatus="status">
<rich:column>
<f:facet name="header">
<h:outputText value="Valeur rubrique" />
</f:facet>
<h:outputText value="#{declarationReglementaireModel.getColumnData(ligneDipRec,column).lbValeurRubrique}" />
</rich:column>
</c:forEach>
</rich:extendedDataTable>
<c:forEach> doesn't have access to the table's variables (i.e. ligneDipRec), and unfortunately you can't do anything about it.
The good news is that whatever you put inside the forEach will have access to those variables. The only thing you need to do is to save the size of the list somewhere in the bean and then loop over it, rather than over the variable:
<c:forEach var="columnNumber" begin="0"
end="{declarationReglementaireModel.detailCurrentDecReg.decReg.listSize - 1}">

Where to keep h:messages in a h:datatable while validating two h:columns

I am using one h:selectbooleancheckbox in each row to make 2 columns editable.
Have a look at my JSF page
<h:dataTable id="editTable" styleClass = "listtable" value="#{bean.GroupList}" var="group" border="1" first="0" rows="8" width="75%" frame="hsides" rules="all" cellpadding="5" headerClass="tableheading" rowClasses="firstrow, secondrow">
<f:facet name="header">
<h:outputText value="Groups"></h:outputText>
</f:facet>
<h:column>
<f:facet name="header">
<h:outputText value="GroupId"></h:outputText>
</f:facet>
<h:outputText value="#{group.Id}" rendered="#{not bean.checked[group.Id]}"></h:outputText>
<h:inputText value="#{group.Id}" rendered="#{bean.checked[group.Id]}" required="true"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="GroupName"></h:outputText>
</f:facet>
<h:outputText value="#{group.Name}" rendered="#{not bean.checked[group.Id]}"></h:outputText>
<h:inputText value="#{group.Name}" rendered="#{bean.checked[group.Id]}" required="true"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Check to Enable/Disable"></h:outputText>
</f:facet>
<h:selectBooleanCheckbox value="#{bean.checked[group.Id]}" />
</h:column>
</h:dataTable>
I have required="true" for GroupId and GroupName columns.
I am not getting where to keep h:messages for each column to display requiredmessage
Please help.
You need to use <h:message> instead to display errors specific to an input element. The <h:messages> will display all messages which are not covered by any <h:message>.
<h:column>
<f:facet name="header">
<h:outputText value="GroupId"></h:outputText>
</f:facet>
<h:outputText value="#{group.Id}" rendered="#{not bean.checked[group.Id]}"></h:outputText>
<h:inputText id="groupId" value="#{group.Id}" rendered="#{bean.checked[group.Id]}" required="true"/>
<h:message for="groupId" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="GroupName"></h:outputText>
</f:facet>
<h:outputText value="#{group.Name}" rendered="#{not bean.checked[group.Id]}"></h:outputText>
<h:inputText id="groupName" value="#{group.Name}" rendered="#{bean.checked[group.Id]}" required="true"/>
<h:message for="groupName" />
</h:column>

How do i edit a Data Table-->columnGroup to have multiple column groups with complex header?

This is a base sample with 3 rows of data displayed under 1 columnGroup heading and 3 column headings and then the 3 columns of data:
<rich:dataTable value="Some Table">
<f:facet name="header">
<rich:columnGroup>
<rich:column colspan="3">
<h:outputText value="ColumnGroupHead"/>
</rich:column>
<rich:column breakBefore="true">
<h:outputText value="Col 1 head"/>
</rich:column>
<rich:column>
<h:outputText value="Col 2 head"/>
</rich:column>
<rich:column>
<h:outputText value="Col 3 Head"/>
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column>
<h:outputText value="Col1 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col2 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col3 Data"/>
</rich:column> <rich:column>
<h:outputText value="Col4 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col5 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col6 Data"/>
</rich:column>
</rich:dataTable>
Now in relaity, my dataTable contains 6 columns, and i want the same complex header as in example above for columns 4,5,6. I have tried the follwoing code, but what I am trying to apply as the next (visual) column group with a specific colspan in the table is starting on the broken line of the col1,2,3 Headers.
<rich:dataTable value="Some Table">
<f:facet name="header">
<rich:columnGroup>
<rich:column colspan="3">
<h:outputText value="ColumnGroupHead1"/>
</rich:column>
<rich:column breakBefore="true">
<h:outputText value="Col 1 head"/>
</rich:column>
<rich:column>
<h:outputText value="Col 2 head"/>
</rich:column>
<rich:column>
<h:outputText value="Col 3 Head"/>
</rich:column>
<rich:column colspan="3">
<h:outputText value="ColumnGroupHead2"/>
</rich:column>
<rich:column breakBefore="true">
<h:outputText value="Col 3 head"/>
</rich:column>
<rich:column>
<h:outputText value="Col 4 head"/>
</rich:column>
<rich:column>
<h:outputText value="Col 5 Head"/>
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column>
<h:outputText value="Col1 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col2 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col3 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col4 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col5 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col6 Data"/>
</rich:column>
Is it psossible to have maultiple column groups in a dataTable?
When I try and close the first columnGroup and then open a new columnGroup, the iital columnGroup is not applied to the dat table.
any assistance would be appreicated.
Rory
I got this figured out. Would delete if knew how.
I had my colspan ColumnGroupHEading sets out fo sequence.
<rich:dataTable value="Some Table">
<f:facet name="header">
<rich:columnGroup>
<rich:column colspan="3">
<h:outputText value="ColumnGroupHead"/>
</rich:column>
<rich:columnGroup>
iT IS THEN THAT I SHOULD HAVE ENTERED THE NEXT COLSPAN , ColumnGroupHeading Header.
<rich:column colspan="3">
<h:outputText value="ColumnGroupHead2"/>
</rich:column>
<rich:column breakBefore="true">
<h:outputText value="Col 1 head"/>
</rich:column>
aND THEN THE COLUMN HEADINGS
<rich:column breakBefore="true">
<h:outputText value="Col 1 head"/>
</rich:column>
<rich:column>
<h:outputText value="Col 2 head"/>
</rich:column>
<rich:column>
<h:outputText value="Col 3 Head"/>
</rich:column>
<h:outputText value="Col 4 head"/>
</rich:column>
<rich:column>
<h:outputText value="Col 5 head"/>
</rich:column>
<rich:column>
<h:outputText value="Col 6 Head"/>
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:column>
<h:outputText value="Col1 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col2 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col3 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col4 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col5 Data"/>
</rich:column>
<rich:column>
<h:outputText value="Col6 Data"/>
</rich:column>
</rich:dataTable>

Resources