Primefaces datatable row expansion exporting - jsf

I need to export datatable row expansion in primefaces but i cannot figure it out. Is there anyway to do that ?
Thanks in advance.

You can export PrimeFaces DataTable with rowExpansion data without an other Java API or you can use custom export method on ManagedBean class with Apache POI API help.
Here trick is, add the columns which to be exporting to the file and append the visible=”false” attribute to the these columns.
Then append the exportable=”false” attribute to the p:rowToggler column.
Thus, you won’t see datatable columns but you will see these columns on the exported file.
Obtained from here
<h:form id="myDtTblFrm">
<h:commandLink>
<img src="../ims/excel.png"/>
<p:dataExporter type="xlsx" target="myTbl" fileName="myExcelFile"/>
</h:commandLink>
<p:dataTable id="myTbl" var="item" value="#{myBean.list}">
<p:rowExpansion>
<p:panelGrid columns="2" columnClasses="label, value" style="width: 50%">
<h:outputText value="Column Header 04" />
<h:outputText value="#{item.property04}" />
<h:outputText value="Column Header 05" />
<h:outputText value="#{item.property05}" />
</p:panelGrid>
</p:rowExpansion>
<p:column exportable="false">
<p:rowToggler />
</p:column>
<p:column headerText="Colum01">
<p:outputLabel value="#{item.property01}" />
</p:column>
<p:column headerText="Column02" visible="false" >
<p:outputLabel value="#{item.property02}" />
</p:column>
<p:column headerText="colum03" >
<p:outputLabel value="#{item.property03}" />
</p:column>
<p:column headerText="colum04" style="display: none">
<p:outputLabel value="#{item.property04}" />
</p:column>
<p:column headerText="colum05" style="display: none">
<p:outputLabel value="#{item.property05}" />
</p:column>
</p:dataTable>

Related

Tooltip in the Column Header of a Primefaces Datatable

In an application based on JSF 2.1 and Primefaces 6.0, I am trying to add a tooltip to the header of a datatable.
In my current solution, the tooltip appears only when pointing the mouse precisely on the text title ("Projekttyp"). I need the tooltip to appear whenever the mouse pointer is in the column header. Unfortunately, it is not possible to assign an id to the facet header.
I understand that the global tooltip as described here Primefaces Showcase Tooltip can only be used in higher Versions of JSF (JSF 2.2).
Here is my code:
<p:column sortBy="#{d.auftraggeber.typ}" filterBy="#{d.auftraggeber.typ}" field="auftraggeber.typ"
filterFunction="#{filterController.filterByString}" filterable="true" sortable="true"
width="6%" styleClass="#{Constants.STRING_COL_STYLE_CLASS}">
<f:facet name="filter">
<p:inputText onkeyup="clearTimeout(window.customFilterDelay);window.customFilterDelay=setTimeout(function() {PrimeFaces.getWidgetById('#{component.parent.parent.clientId}').filter();},1500)"
value="#{sucheForm.filter.typFilter}"
tabindex="1"
styleClass="input-filter #{Constants.NO_DIRTY_CHECK_STYLE_CLASS}">
<p:ajax event="keyup" update="#(.updateableFromTableFilter)" delay="1500" />
</p:inputText>
</f:facet>
<f:facet name="header">
<h:outputText id="typColumntitle" title="Projekttyp" value="Projekttyp"/>
<p:tooltip id="typTooltip"
for="typColumntitle"
rendered="true"
myPosition="left bottom" atPosition="right bottom"
hideDelay="500">
<p:scrollPanel style="width: 300px;height:200px">
<p:dataTable id="projektTypTable" var="typ" value="#{projekttypListProducer.typAndDescList}">
<p:column headerText="Projekttyp" width="30%">
<h:outputText value="#{typ.inhalt}"/>
</p:column>
<p:column headerText="Bemerkung" width="70%">
<h:outputText value="#{typ.bemerkung}"/>
</p:column>
</p:dataTable>
</p:scrollPanel>
</p:tooltip>
</f:facet>
<h:outputText value="#{d.auftraggeber.typ}"/>
</p:column>
Add the f:facet tag like the above and it will work fine (I mean tooltip value will be displayed); if you hover your mouse anywhere inside the column header.
Even outside the text in the column header.
<p:column id= "keyColumnId">
<f:facet name="header">
<h:outputText value="YOUR COLUMN HEADER" />
<p:tooltip value="TOOLTIP VALUE TO SHOW" for="keyColumnId" />
</f:facet>
</p:column>
PrimeFaces supports 'jquery' selectors in the for attribute of the p:tooltip. You effectively need to select the 'parent' of the element with id typColumntitle, so this will (most likely) work.
<p:tooltip id="typTooltip"
for="#(#typColumntitle:parent)"
rendered="true"
myPosition="left bottom" atPosition="right bottom"
hideDelay="500">
Solving this problem turned out to be easy in the end. I just had to assign an id to the column <p:column id="columnwithtooltip" and adjust the for="columnwithtooltip" in the tooltip accordingly:
<p:column id="projekttypColumn" sortBy="#{d.auftraggeber.typ}" filterBy="#{d.auftraggeber.typ}" field="auftraggeber.typ"
filterFunction="#{filterController.filterByString}" filterable="true" sortable="true"
width="6%" styleClass="#{Constants.STRING_COL_STYLE_CLASS}">
<f:facet name="filter">
<p:inputText onkeyup="clearTimeout(window.customFilterDelay);window.customFilterDelay=setTimeout(function() {PrimeFaces.getWidgetById('#{component.parent.parent.clientId}').filter();},1500)"
value="#{sucheForm.filter.typFilter}"
tabindex="1"
styleClass="input-filter #{Constants.NO_DIRTY_CHECK_STYLE_CLASS}">
<p:ajax event="keyup" update="#(.updateableFromTableFilter)" delay="1500" />
</p:inputText>
</f:facet>
<f:facet name="header">
<h:outputText id="typColumntitle" title="Projekttyp" value="Projekttyp"/>
<p:tooltip id="typTooltip"
for="projekttypColumn"
rendered="true"
myPosition="left bottom" atPosition="right bottom"
hideDelay="500">
<p:scrollPanel style="width: 300px;height:200px">
<p:dataTable id="projektTypTable" var="typ" value="#{projekttypListProducer.typAndDescList}">
<p:column headerText="Projekttyp" width="30%">
<h:outputText value="#{typ.inhalt}"/>
</p:column>
<p:column headerText="Bemerkung" width="70%">
<h:outputText value="#{typ.bemerkung}"/>
</p:column>
</p:dataTable>
</p:scrollPanel>
</p:tooltip>
</f:facet>
<h:outputText value="#{d.auftraggeber.typ}"/>
</p:column>

selectManyCheckbox into p:dataTable column

I can not correctly view the contents of a column with selectManyCheckbox in p:dataTable.
Here my .xhtml:
<h:form id="projAccess" enctype="multipart/form-data">
<p:dataTable tableStyle="width:auto" id="i_dtb2" var="p" value="#{comBean.l_uSrcRes}" paginator="true" rows="5" rowsPerPageTemplate="5,10"
paginatorPosition="bottom">
<p:columnGroup type="header">
<p:row>
<p:column rowspan="2" headerText="User" />
<p:column rowspan="2" headerText="Asset" />
<p:column colspan="6" headerText="Roles" />
<p:column rowspan="2" colspan="2" headerText="Action" />
</p:row>
<p:row>
<p:column headerText="Project Manager"></p:column>
<p:column headerText="Project Manager Deputy"></p:column>
<p:column headerText="Business Analyst"></p:column>
<p:column headerText="Functional Analyst"></p:column>
<p:column headerText="Technical Analyst"></p:column>
<p:column headerText="Developer"></p:column>
</p:row>
</p:columnGroup>
<p:column>
<h:outputText value="#{p.usercd}" />
</p:column>
<p:column>
<h:outputText value="#{p.asset}" />
</p:column>
<p:column colspan="6">
<h:panelGroup layout="block" >
<p:selectManyCheckbox columns="6" value="#{p.rolesList}">
<f:selectItems value="#{comBean.l_roles}" var="role" itemLabel="#{role}" itemValue="#{role}" />
</p:selectManyCheckbox>
</h:panelGroup>
</p:column>
<p:column>
<p:commandButton action="#{comBean.m_updateAccess}" ajax="false" icon="ui-icon-pencil">
<f:setPropertyActionListener value="#{p}" target="#{comBean.f_selectedUser}" />
<f:param name="area" value="project" />
</p:commandButton>
</p:column>
<p:column>
<p:commandButton action="#{ubean.m_deleteUser}" ajax="false" icon="ui-icon-trash">
<f:setPropertyActionListener value="#{p}" target="#{comBean.f_selectedUser}" />
<f:param name="area" value="project" />
</p:commandButton>
</p:column>
</p:dataTable>
</h:form>
Here the result:
How can I adapt content to header columns?
You are using tableStyle="width:auto" in your p:dataTable.
Removing this will align the checkboxes to its respective columns but you can notice that the columns are still a little bit misaligned.
To solve this, you can add style="padding:0px;" on your checkbox p:column.
Your code will look something like this.
<p:dataTable id="i_dtb2" var="p" value="#{comBean.l_uSrcRes}" paginator="true" rows="5" rowsPerPageTemplate="5,10"
paginatorPosition="bottom">
// other codes
<p:column colspan="6" style="padding:0px;">
// other codes
</p:column>
// other codes
</p:dataTable>
On another note, if your functional specification allows it, you can remove [Project Manager, Project Manager Deputy, etc] headers, since your are displaying them right next to the checkboxes.
You will have to remove p:columnGroup and set the headerText to their respective columns with "Roles" as headerText for your checkBox column.
Hope this helps.

JSF commandButton issue

I am providing a search function using JSF. I get the list and display it correctly in a datatable :
<p:dataTable id="props" var="prop" value="#{propController.propSearch}" editable="true" style="margin-bottom:20px">
<p:column headerText="Id" width="20">
<h:outputText value="#{prop.id}" />
</p:column>
<p:column headerText="Name" width="300">
<h:outputText value="#{prop.name}"/>
</p:column>
<p:column headerText="Description">
<h:outputText value="#{prop.shortDescription}" />
</p:column>
<p:column headerText="Price" width="120">
<h:outputText value="#{prop.price}" />
</p:column>
<p:column width="120">
<h:commandButton value="View Prop" immediate="true" action="#{propController.viewSingleProp(prop)}" />
</p:column>
<p:column width="120">
<h:commandButton value="Delete" immediate="true" onclick="return confirm('Are you sure you want to delete this prop?')" actionListener="#{propController.deleteProp(prop)}" />
</p:column>
</p:dataTable>
</h:form>
However the commandButton to view each individual item does not get called. Instead the search page just refreshes with no data.
Why is this happening?
(I hope your opening tag of <h:form> is just missing in your code posted in your question, not in your actual code!)
You need to remove the attribute immediate="true" from the h:commandButton.
See:
Immediate=true VS immediate=false in JSF Component

Primefaces filter datatable

Hello guys I have a problem with my datatable I want to filter it, but if i put something into the text field nothing is shown and also if i clear the input also nothing.
It is possible if i have more than one statment in a column?
So I use primefaces 3.5 and jsf 2.1
Here is the code and if you need more code post an comment. thx
<p:dataTable id="inboxTable" var="task" value="#{taskboxBean.taskboxInboxList}" paginator="true"
widgetVar="inboxTable" rows="10" selection="#{taskboxBean.selectedTaskbox}"
selectionMode="single" rowKey="#{task.ID}" emptyMessage="" paginatorPosition="bottom"
filteredValue="#{taskboxBean.inboxList}">
<p:ajax event="rowSelect" update=":contentForm, :postForm:tabViewPosts:inboxTable"
listener="#{taskboxBean.onTaskboxRowSelect}" />
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Suchen:" />
<p:inputText id="globalFilter" onkeyup="inboxTable.filter()"
style="margin-left:5px;width:150px" />
</p:outputPanel>
</f:facet>
<p:column headerText="Post">
<h:outputText
value="#{task.FROM_USER.FIRST_NAME} #{task.FROM_USER.LAST_NAME} (#{task.FROM_USER.EMAIL})" />
<div align="right">
<h:panelGroup rendered="#{!task.IS_SEEN}" class="fa fa-envelope fa-2x" />
<h:panelGroup rendered="#{task.IS_SEEN}" class="fa fa-envelope-o fa-2x" />
</div>
<h:outputText value="#{task.TASKTYPE.NAME}" />
<br />
<h:outputText value="#{task.CREATE_TIMESTAMP}" />
</p:column>
</p:dataTable>
It is not explicitely written in documentation, but as mentioned on PrimeFaces forum, you need to declare filterBy attribute on columns you want to make searchable via global filter.
It is also suggested here to add filterStyle="display:none" to columns if you don't want a filter to be visible on individual columns.
The example from documentation has filterBy:
<p:dataTable var="car" value="#{carBean.cars}"
filteredValue="#{carBean.filteredCars}" widgetVar="carsTable">
<f:facet name="header">
<p:outputPanel>
<h:outputText value="Search all fields:" />
<h:inputText id="globalFilter" onkeyup="carsTable.filter()" />
</p:outputPanel>
</f:facet>
<p:column filterBy="#{car.model}" headerText="Model" filterMatchMode="contains">
<h:outputText value="#{car.model}" />
</p:column>
</p:dataTable>
however, as typical for PrimeFaces documentation, it's not written that it won't work without filterBy.
You must add getter and setter of your taskboxInboxList in the taskboxBean class. But it filters just the first statement placed in the column.

datatable row remains selected/highlighted where selectionMode="single"

I've been running Primefaces 3.0, no issues, and now am trying an upgrade to 3.4.x - I've tried 3.4, 3.4.1, and 3.4.2 and this problem occurs in all 3 - basically for the datatable with the selectionMode="single" option when I click on a row it remains selected no matter how many other rows I select. At the same time I'm quite sure the selection="#{databrowser.selectedData}" variable is not being set when I'm clicking on the rows. The table is fully populated and no 2 rows have the exact same data in all columns. Tested and this occurs in both Chrome and Firefox. I can't find any similar problem posted - wondering if anyone else has had this issue?
Apart from the element referencing this is the 3.0 code I've used:
<p:layoutUnit position="center" resizable="true" header="Data Set Details" styleClass="east_panel_header" >
<h:form id="tblbrowser">
<p:dataTable id="dataTable" emptyMessage="No data sets found." style="width: 100%" var="datlis" resizableColumns="true" value="#{databrowser.selectedDataModel}" widgetVar="dataTable" selection="#{databrowser.selectedData}" selectionMode="single" >
<p:ajax event="rowSelect" update=":usercomments:commentsTable, :tblbrowser:dataTable" />
<f:facet name="header" >
<p:outputPanel>
<h:outputText value="Search all fields " />
<p:inputText id="globalFilter" onkeyup="dataTable.filter()"/>
</p:outputPanel>
</f:facet>
<p:column id="owner" filterBy="#{datlis.uname}" headerText="Added By" filterMatchMode="contains" >
<h:outputText value="#{datlis.uname}" />
</p:column>
<p:column id="name" filterBy="#{datlis.name}" headerText="Name" >
<h:outputText value="#{datlis.name}" />
</p:column>
<p:column id="description" filterBy="#{datlis.description}" headerText="Description" filterMatchMode="endsWith" >
<h:outputText value="#{datlis.description}" />
</p:column>
<p:column id="datatype" filterBy="#{datlis.data_type}" headerText="Data Type"
filterOptions="#{databrowser.dataTypeOptions}" filterMatchMode="exact" >
<h:outputText value="#{datlis.data_type}" />
</p:column>
<p:column id="quality" filterBy="#{datlis.quality}" headerText="Source Type"
filterOptions="#{databrowser.qualityOptions}" filterMatchMode="exact" >
<h:outputText value="#{datlis.quality}" />
</p:column>
<p:column id="added" headerText="Date Added" filterMatchMode="endsWith" >
<h:outputText value="#{datlis.added}" />
</p:column>
<p:column headerText="Metadata" style="width:40px" >
<p:commandButton id="selectButton" rendered="#{datlis.has_metadata}" icon="ui-icon-circle-arrow-s" title="View" ajax="false" >
<f:param name="filepath" value="#{datlis.filepath}" />
<p:fileDownload value="#{filedownloader.mfile}" />
</p:commandButton>
</p:column>
<p:column headerText="Data File(s)" style="width:90px" >
<p:commandButton id="selectButton2" rendered="#{datlis.has_datafiles}" icon="ui-icon-circle-arrow-s" title="View" ajax="false" >
<f:param name="datafiles" value="#{datlis.datafiles}" />
<p:fileDownload value="#{filedownloader2.dfile}" />
</p:commandButton>
<h:outputText value=" " />
<h:outputText value="#{datlis.zipsize}" />
</p:column>
</p:dataTable>
</h:form>
</p:layoutUnit>
You are missing the rowKey attribute which should be the unique identifier of each row.
Example, if your selectedData object has a unique field id, your dataTable component should look like:
<p:dataTable id="dataTable" rowKey=#{datlis.id}
value="#{databrowser.selectedDataModel}" var="datlis"
selection="#{databrowser.selectedData}" selectionMode="single" >
No need to update the same table within p:ajax to see the selection, so you can probably remove the :tblbrowser:dataTable from the update target and have only:
<p:ajax event="rowSelect" update=":usercomments:commentsTable" />

Resources