How to visualize PanelGrid components inside DataTable - jsf

I am trying to create a DataTable (because of pagination) with PanelGrid like this.
My code for the grid is taken from PrimeFaces website:
<p:panelGrid style="margin-top:20px">
<f:facet name="header">
<p:row>
<p:column colspan="7">1995-96 NBA Playoffs</p:column>
</p:row>
<p:row>
<p:column colspan="2">Conf. Semifinals</p:column>
<p:column colspan="2">Conf. Finals</p:column>
<p:column colspan="2">NBA Finals</p:column>
<p:column>Champion</p:column>
</p:row>
</f:facet>
<p:row>
<p:column style="font-weight: bold;">Seattle</p:column>
<p:column style="font-weight: bold;">4</p:column>
<p:column rowspan="2" style="font-weight: bold;">Seattle</p:column>
<p:column rowspan="2" style="font-weight: bold;">4</p:column>
<p:column rowspan="5">Seattle</p:column>
<p:column rowspan="5">2</p:column>
<p:column rowspan="11" style="font-weight: bold;">Chicago</p:column>
</p:row>
<p:row>
<p:column>Houston</p:column>
<p:column>0</p:column>
</p:row>
</p:panelGrid>
When i put the code for the grid between DataTable tags, it just show the header and pagination line. Some idea how to make such PanelGrids with pagination?

You don't need p:panelGrid for that. You can use p:dataTable and p:row with p:column rowspan="2" and p:column colspan="2" like you have in your code. In case if table is more complicated use p:subTable. Example of subtable is here.

Related

How to make a grouping datatable with selection in primefaces?

I've tried with primefaces showcase examples, but I don't know how to make a grouping datatable with checkbox selection like this:
I've tried with subtable, p:column and p:row, but still I don't have an idea how to get same results such as if I use panelGrid.
If you want to check multiple rows with one checkbox in the 'grouped' column, that is not supported in PrimeFaces up to the 6.3-SNAPSHOT. If it is/will be supported in future releases depends on an issue being created and it getting enough support or sponsor this via paid consultancy.
Row grouping is what comes closest
<h3>Rowspan</h3>
<h:form>
<p:dataTable var="car" value="#{dtRowGroupView.cars}" sortBy="#{car.brand}">
<p:column headerText="Brand" groupRow="true">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
</p:dataTable>
</h:form>
But I've not seen this work with selection or an additional 2nd grouped row
The idea of this table was to compare the different values of each field to decide if the assumed id and name are taken as good. Here is an example:
I used ui:repeat, p:row and p:column to get this customized table:
<h:form id="stocktakingTable">
<h:panelGroup layout="block" class="col-lg-10 col-md-10 col-lg-offset-1">
<p:panelGrid>
<f:facet name="header">
<p:row>
<p:column>Ok</p:column>
<p:column>Assumed id</p:column>
<p:column>Assumed name</p:column>
<p:column>Place</p:column>
<p:column>Id</p:column>
<p:column>Name</p:column>
<p:column>Main color</p:column>
<p:column>Size</p:column>
</p:row>
</f:facet>
<ui:repeat value="#{oneCtrl.stocktakingList}" var="stocktaking">
<p:row>
<p:column rowspan="4">
<p:selectBooleanCheckbox value="#{stocktaking.ok}" disabled="#{stocktaking.ok}" valueChangeListener="#{oneCtrl.updateStocktaking(stocktaking)}">
<p:ajax update=":#{p:component('stocktakingTable')}"/>
</p:selectBooleanCheckbox>
</p:column>
<p:column rowspan="4" style="font-weight: #{stocktaking.ok ? 'normal' : 'bold'}">#{stocktaking.assumedId}</p:column>
<p:column rowspan="4" style="font-weight: #{stocktaking.ok ? 'normal' : 'bold'}">#{stocktaking.assumedName}</p:column>
<p:column style="font-style: italic">Real Stocktaking</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.realId)}">#{stocktaking.realId}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.realName)}">#{stocktaking.realName}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.realColor)}">#{stocktaking.realColor}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.realSize)}">#{stocktaking.realSize}</p:column>
</p:row>
<p:row>
<p:column style="font-style: italic">Calculated stocktaking</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.calculatedId)}">#{stocktaking.calculatedId}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.calculatedName)}">#{stocktaking.calculatedName}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.calculatedColor)}">#{stocktaking.calculatedColor}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.calculatedSize)}">#{baseCtrl.calculatedSize}</p:column>
</p:row>
<p:row>
<p:column style="font-style: italic">Shop web page</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.shopId)}">#{stocktaking.shopId}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.shopName)}">#{stocktaking.shopName}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.shopColor)}">#{stocktaking.shopColor}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.shopSize)}">#{stocktaking.shopSize}</p:column>
</p:row>
<p:row>
<p:column style="font-style: italic">Online shop web page</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.onlineId)}">#{stocktaking.onlineId}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.onlineName)}">#{stocktaking.onlineName}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.onlineColor)}">#{stocktaking.onlineColor}</p:column>
<p:column style="color: #{oneCtrl.AssignedColors.get(stocktaking.onlineSize)}">#{stocktaking.onlineSize}</p:column>
</p:row>
<p:row>
<p:column colspan="8" styleClass="ui-widget-header"/>
</p:row>
</ui:repeat>
</p:panelGrid>
</h:panelGroup>
</h:form>
I’m sorry if I wasn’t clear enough at first :'(

p:treeTable with ui:repeat in header

I'm using ui:repeat regularly in p:dataTable in a <p:columnGroup type="header">, mostly to set the colspan attribute which works fine. Examples below are simplified to concentrate on the issue.
<p:dataTable var="i" value="#{bean.data}">
<f:facet name="header">Works fine</f:facet>
<p:columnGroup type="header">
<p:row>
<ui:repeat var="c" value="#{bean.columns}">
<p:column colspan="1" headerText="#{c.name}" />
</ui:repeat>
</p:row>
</p:columnGroup>
<p:column><h:outputText value="#{i.value}"/></p:column>
</p:dataTable>
Now let's come to p:treeTable and issue. A example with p:columnGroup is also working fine:
<p:treeTable var="i" value="#{reportPlanningMtefBean.tree}">
<f:facet name="header">columnGroup fine in tree</f:facet>
<p:columnGroup type="header">
<p:row>
<p:column colspan="1" headerText="a" />
<p:column colspan="1" headerText="b" />
</p:row>
</p:columnGroup>
<p:column><h:outputText value="#{i.value1}"/></p:column>
<p:column><h:outputText value="#{i.value2}"/></p:column>
</p:treeTable>
But I have no success with a ui:repeat in p:treeTable. The headers are simply not shown!
<p:treeTable var="i" value="#{reportPlanningMtefBean.tree}">
<f:facet name="header">columnGroup fine in tree</f:facet>
<p:columnGroup type="header">
<p:row>
<ui:repeat var="c" value="#{bean.columns}">
<p:column colspan="1" headerText="#{c.name}"/>
</ui:repeat>
</p:row>
</p:columnGroup>
<p:column><h:outputText value="#{i.value1}"/></p:column>
<p:column><h:outputText value="#{i.value2}"/></p:column>
</p:treeTable>
Above examples are tested with PrimeFaces 5.2 (changed this to 6.0, too) and Mojarra 2.1.28-jbossorg-5.

SummaryRow in p:dataTable not working

I am trying to show a total value on my dataTable, my code is similar to the primefaces showcase DataTable - SummaryRow and still not working.
<p:dataTable id="dtCaixa" var="list" value="#{caixaMB.list}" paginator="true" rows="7"
paginatorPosition="bottom" rowsPerPageTemplate="10,15,20" liveScroll="true"
paginatorAlwaysVisible="false" emptyMessage="Nenhuma entrada!" liveResize="true">
<p:column headerText="Nome" sortBy="#{list.produtoFK.nome}" style="width:15%;">
<h:outputText value="#{list.produtoFK.nome}" />
</p:column>
<p:column headerText="Funcionário" sortBy="#{list.funcionarioFK.nome}">
<h:outputText value="#{list.funcionarioFK.nome}" />
</p:column>
<p:column headerText="Quantidade" sortBy="#{list.quantidade}">
<h:outputText value="#{list.quantidade}" />
</p:column>
<p:column headerText="Preço" >
<h:outputText value="#{list.produtoFK.preco}" rendered="#{not empty list.produtoFK}">
<f:convertNumber pattern="R$ #0.00" locale="pt_BR"/>
</h:outputText>
</p:column>
<p:column headerText="Total" sortBy="#{list.total}" >
<h:outputText value="#{list.total}" >
<f:convertNumber pattern="R$ #0.00" locale="pt_BR"/>
</h:outputText>
</p:column>
<p:column headerText="Remover" class="centered">
<p:commandButton icon="ui-icon-trash" title="excluir" onclick="PF('confirmaExclusao').show();">
<f:setPropertyActionListener target="#{caixaMB.itemSelecionado}" value="#{list}" />
</p:commandButton>
</p:column>
<p:summaryRow>
<p:column colspan="3" style="text-align:right">
<h:outputText value="Total:" />
</p:column>
<p:column>
<h:outputText value="#{caixaMB.total}">
</h:outputText>
</p:column>
</p:summaryRow>
</p:dataTable>
Does anybody have any idea why is this happening?
You need to sort the dataTable using at least one column if you want to use summaryRow. Check the Primefaces documentation.
E.g. put the attribute sortBy="#{myList.myOrderValue}" on the <p:datatable> tag.
I think what you're trying to achieve is the overall total of the column showing up at the bottom. I was caught out by the summaryRow function too, until I realised it was a grouping function and not a totalling summary. What I did you get around this was for the last column I added some footerText. You will have to calculate your totals manually (iterate over your dataset etc), then you can use something like:
<p:column style="text-align: right" footerText="$ #{invoicesbean.total}">
<f:facet name="header">
<h:outputText value="Amount" />
</f:facet>
........ etc
This worked well for me but YMMV!

Primefaces duplicate header when i add a css rule

I use primefaces in order to build a datatable. The problem is that when i try to align the header whith the columns using a css rule (float: left) then the header row is duplicated.
The question is why this happens and how it can be solved.
Below i have the code and a snapshoot of the duplicated table header.
<h:form id="jobsForm" styleClass="jobsForm">
<p:dataTable id="jobsDataTable" var="jobs" scrollable="true"
value="#{jobsBean.getJobList()}" selectionMode="single"
widgetVar="jobs" rowKey="#{jobs.id}" styleClass="jobsTable">
<p:column id="jobId" styleClass="jobColumn" sortBy="#{jobs.id}">
<f:facet id="idFacet" name="header">
<h:outputText styleClass="jobText" id="idLabel" value="#{msg.JOB_ID}"/>
</f:facet>
<h:outputText id="id" value="#{jobs.id}" />
</p:column>
<p:column id="jobTitle" styleClass="jobColumn" sortBy="#{jobs.id}">
<f:facet id="titleFacet" name="header">
<h:outputText styleClass="jobText" id="titleLabel" value="#{msg.JOB_TITLE}"/>
</f:facet>
<h:outputText id="title" value="#{jobs.title}"/>
</p:column>
<p:column id="jobState" styleClass="jobColumn" sortBy="#{jobs.status}">
<f:facet id="titleFacet" name="header">
<h:outputText styleClass="jobText" id="statusLabel" value="#{msg.JOB_STATUS}"/>
</f:facet>
<h:outputText id="status" value="#{jobs.status}"/>
</p:column>
<p:column id="jobStartDate" styleClass="jobColumn" sortBy="#{jobs.start_date}">
<f:facet id="startFacet" name="header">
<h:outputText styleClass="jobText" id="startLabel" value="#{msg.JOB_START}"/>
</f:facet>
<h:outputText id="start" value="#{jobs.start_date}"/>
</p:column>
<p:column id="jobEndDate" styleClass="jobColumn" sortBy="#{jobs.start_date}">
<f:facet id="endFacet" name="header">
<h:outputText styleClass="jobText" id="endLabel" value="#{msg.JOB_END}"/>
</f:facet>
<h:outputText id="end" value="#{jobs.end_date}"/>
</p:column>
</p:dataTable>
</h:form>
Usually I don't get good results applying CSS classes directly on PrimeFaces components without using some selectors.
In this case you can write some CSS classes using selectors to override the default PrimeFaces behavior. Here's a example:
.ui-datatable thead tr th.align-left,
.ui-datatable tbody tr td.align-left {
text-align: left;
}
Now you can apply the align behavior directly on the wanted column (in this case, including 'align-left' on the job column styleClass):
<p:dataTable id="jobsDataTable"
var="jobs"
scrollable="true"
value="#{jobsBean.getJobList()}"
selectionMode="single"
widgetVar="jobs"
rowKey="#{jobs.id}"
styleClass="jobsTable">
<p:column id="jobId"
styleClass="jobColumn align-left"
sortBy="#{jobs.id}">
<f:facet id="idFacet" name="header">
<h:outputText styleClass="jobText" id="idLabel" value="#{msg.JOB_ID}"/>
</f:facet>
<h:outputText id="id" value="#{jobs.id}" />
</p:column>
</p:dataTable>
Lastly, make sure to remove the jobsForm class from the styleClass.

Primefaces Filterby/Sort on a datatable with a subtable

So lets say I have the following table:
<p:dataTable id="genaricTable" var="item" value="#{genaricBean.currentValue}" >
<p:columnGroup type="header">
<p:row>
<p:column rowspan="" headerText="value1"/>
<p:column rowspan="" headerText="value2"/>
<p:column rowspan="" headerText="value3"/>
</p:row>
</p:columnGroup>
<p:subTable var="subItem" value="#{item.subItemList}" >
<f:facet name="header">
#{item.header}
</f:facet>
<p:column>
<h:outputText value="#{subItem.value1}"/>
</p:column>
<p:column>
<h:outputText value="#{subItem.value1}"/>
</p:column>
<p:column>
<h:outputText value="#{subItem.value1}"/>
</p:column>
</p:subTable>
</p:dataTable>
Is there a way I can filter/sort by the subcolumn tables with the built in primefaces components? The only thing I can think of is putting in a custom command link to do it.
You're right. It doesn't work when you add the sortBy attribute to the column definition inside of the subTable.
There is however a very easy solution. Add it to the column definition inside of your header columnGroup. PrimeFaces DO process this attribute if defined there.
I suppose this approach could maybe work for the filterBy as well, I didn't try it out though.
<p:columnGroup type="header">
<p:row>
<p:column rowspan="" headerText="value1" sortBy="#{subItem.value1}"/>
<p:column rowspan="" headerText="value2"/>
<p:column rowspan="" headerText="value3"/>
</p:row>
</p:columnGroup>
EDIT : You do of course need to take your underlying dataset into consideration and maybe use something different as sort Expression or maybe also write a little workaround in your Managed Bean, because it's never that simple with hierarchical data. I used that Expression simply to illustrate the solution.
for sorting the subcolumn table, you can add in sortBy in the subcolumn..something similar like this..
<p:column sortBy="#{subItem.value1}">
<h:outputText value="#{subItem.value1}"/>
</p:column>
have a try..

Resources