Sortable columns in embedded rich:dataTable - jsf

I have a jsp page containing a rich:dataTable with some data regarding my clients.
In each row I have another rich:dataTable containing some commission rates for the current customer.
The code is something like this:
<rich:dataTable id="clientList" value="#{clientsBean.model}" var="client" rows="15">
<rich:column id="nameColumn">
<f:facet name="header">
<h:outputText value="#{msg.manageclients_client_name}" />
</f:facet>
<h:outputText id="name" value="#{client.name}" />
</rich:column>
<rich:column id="clientRatesColumn">
<f:facet name="header">
<h:outputText value="#{msg.manageclients_client_rates}" />
</f:facet>
<rich:dataTable id="clientRates" value="#{client.clientRates}" var="clientRate">
<rich:column id="clientRateProduct" sortable="true" sortBy="#{clientRate.product.qualifiedName}">
<f:facet name="header">
<h:outputText value="#{msg.manageclients_rate_product}" />
</f:facet>
<h:outputText value="#{clientRate.product.qualifiedName}" />
</rich:column>
...
</rich:dataTable>
</rich:column>
...
</rich:dataTable>
As you can see the embedded rich:dataTable (id=clientRates) contains a sortable column (id=clientRateProduct).
My problem is that if I click on the sort icon in the clientRateProduct column for the current client all clientRates dataTables will be sorted (not just the one for the current client).
I want the sort action to be performed just on the current clientRates dataTable. Can anybody please suggest a solution ?
I use RichFaces 3.2.2.SR1. & Tomcat 6.0.29

you should encapsulate the inner data table with
<a4j:region renderRegionOnly="true" >
so only it will be updated from the ajax request

Related

Primefaces exporting only one expandable table

I am trying to export a view to xlsx using PrimeFaces extensions. I have a main table and an expandable row with 2 tables inside.
The exporter works fine for the first dataTable in the expandable row, but not for the other one. Any ideas?
<p:dataTable id="mainTable" var="mainObject" value="#{mainBean.mainList}">
<p:column exportable="false" width="5%">
<p:rowToggler />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="main column A"/>
</f:facet>
<h:outputText value="#{mainObject.columnA}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="main column B"/>
</f:facet>
<h:outputText value="#{mainObject.columnB}" />
</p:column>
<p:rowExpansion>
<p:datTable id="relatedTableA" var="relatedA" value="#{mainObject.relatedA}">
<f:facet name="header">
<h:outputText value="Related A"/>
</f:facet>
<p:column>
<f:facet name="header">
<h:outputText value="Related A column A"/>
</f:facet>
<h:outputText value="#{relatedA.columnA}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Related A column B"/>
</f:facet>
<h:outputText value="#{relatedA.columnB}" />
</p:column>
</p:dataTable>
<p:datTable id="relatedTableB" var="relatedB" value="#{mainObject.relatedB}">
<f:facet name="header">
<h:outputText value="Related B"/>
</f:facet>
<p:column>
<f:facet name="header">
<h:outputText value="Related B column A"/>
</f:facet>
<h:outputText value="#{relatedB.columnA}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Related B column B"/>
</f:facet>
<h:outputText value="#{relatedB.columnB}" />
</p:column>
</p:dataTable>
</p:rowExpansion>
</p:dataTable>
<h:commandLink>
<p:graphicImage url="/resources/images/Excel32.png" width="32"/>
<pe:exporter type="xlsx" target="mainTable" fileName="fileExport" facetBackground="#AAFFBB" datasetPadding="4" />
</h:commandLink>
I followed this guide: https://www.primefaces.org/showcase-ext/sections/exporter/expandableTable.jsf
In my app, the view works perfect. I use the toggle and then it shows the 2 tables. The only problem is that it exports only one of the expandables.
Thanks for your time.
Seemes this is simply not supported.
In the exporter component source code when it comes to exporting the row expensions they have hard coded to consider the first child for each rowExpansion only:
if (rowExpansion.getChildren().get(0) instanceof DataTable) {
final DataTable childTable = (DataTable) rowExpansion.getChildren().get(0);
// ...
}
This is why you only get the first sub table in your output.
Using the customExporter feature you have the chance to extend the ExcelExporter and override the method exportCells which seemes responsible for your problem. Then change the behavior to do a loop on rowExpansion.getChildren() instead of just getting the first element.
General steps to configure a custom exporter from the linked site:
Step 1: Create a folder named META-INF under resouces folder.Below
META-INF folder create another folder called services.
Step 2: Creae a
file with the name "ExporterFactory" as a service(Fully binary name of
the service).
Here it should be org.primefaces.extensions.component.exporter.ExporterFactory.
Step 3:
Provide your own implementaions/providers of Exporter factory anywhere
in your project.
And copy the absolute path of custom exporter factory implementation in the ExporterFactory file
How to do : Copy the file content of DefaultExporterFactory and rename the file as CustomExporterFactory.Copy the absolute path
org.primefaces.extensions.showcase.util.CustomExporterFactory in
ExporterFactory file.
Step 4: Copy the exporter implementations and
add your own changes.And call these custom implementations(Ex
PDFCustomExporter,ExcelCustomExporter) instead built-in
implmentations(Ex PDFExporter,ExcelExporter)

Insert textbox in datatable but having difficulty to save all the records

Hi i am adding a textbox in a datatable where the user will input data in each row. I need help on how to save the data...because right now it's saving only the last row. Please see code below, can someone help on this? I think there should be some sort of array but i dont know if it is possible to store value in array using el expression. I implemented a nested datatable since i want the data to be side by side. If you have a better idea other than using datatable , I would be glad if you could share it and give proper instruction on how to proceed. ( but it should be side by side)
Thanks in advance
<p:dataTable id="dta" value="#{MyCarComponent.model}" var="cur" rows="15" >
<p:column>
<f:facet name="header">
<h:outputText value="Model:" />
</f:facet>
<h:outputText value="#{current.cptModel}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Type:" />
</f:facet>
<p:dataTable id="dta1" value="#{cur.type}" var="curType" rows="15" >
<p:column>
<h:outputText value="#{curType.cptType}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Origin:" />
</f:facet>
<h:form>
<p:dataTable id="dta3" value="#{curType.origins}" var="curOrigin" rows="15" >
<p:column>
<h:outputText value="#{curOrigin.origin}" />
</p:column>
<p:column>
<h:inputText
value="#{MyCarComponent.origindetails.country}"/>
</p:column>
</p:dataTable>
</h:form>
</p:column>
</p:dataTable>
</p:column>
<f:facet name="footer">
<p:commandButton image="save" ajax="false" value="Save" action=" #. {Mycar.saveMyCar(curOrigin.origin,MyCarComponent.origindetails)}" />
</f:facet>
You're currently binding the input field of all rows to one and same bean property. So when JSF processes the form submit in the same sequence as the component tree, the value of each input field will be set in this one and same property. Of course the property will end up being the one of the last row.
You just need to bind the value of the input field to the currently iterated row, the #{curOrigin}. E.g.
<h:inputText value="#{curOrigin.country}" />
Just create the property of there if it doesn't exist yet.

Datatable not displaying any data but its fine using a pannel grid

i am currently using a pannel grid to display some data retrived from a database, this is working fine, the layout is not perfect but it displays all of the correct data, however i am wanting to use a datatable for looks more than anything, i have tried to use the outputText from the pannel grid but when i run the page it just says no data found, but on the same page the same code displays the data in the pannel grid
what am i doing wrong ?
this is the code for the working pannel grid
<!-- heading -->
<f:facet name="header">
User Details
</f:facet>
<h:outputText value="#{bundle.ViewUserdetailsLabel_id}"/>
<!-- adding in a small effect here that will fade a message when a user hovers over the id number or username -->
<h:outputLink id="id1" value="#">
<h:outputText id="id" value="#{userdetailsController.selected.id}" title="#{bundle.ViewUserdetailsTitle_id}"/>
</h:outputLink>
<p:tooltip for="id" value="This is your I.D. Number" showEffect="fade" hideEffect="fade" />
<h:outputText value="#{bundle.ViewUserdetailsLabel_username}"/>
<h:outputLink id="username1" value="#">
<h:outputText id="username" value="#{userdetailsController.selected.username}" title="#{bundle.ViewUserdetailsTitle_username}"/>
</h:outputLink>
<p:tooltip for="username" value="Your registered username, this can be changed" showEffect="fade" hideEffect="fade" />
</p:panelGrid>
and here is the not working datatable
<p:dataTable>
<p:column >
<f:facet name="header">
<h:outputText value="{bundle.ViewUserdetailsLabel_id}"/>
</f:facet>
<h:outputText value="{userdetailsController.selected.id}" />
</p:column>
<p:column headerText="username" >
<f:facet name="header">
<h:outputText value="{bundle.ListUserdetailsTitle_username}"/>
</f:facet>
<h:outputText value="{userdetailsController.selected.username}" />
</p:column>
</p:dataTable>
as you can see the outputText values are the same so it should work right ?
thanks
If you happen to have only few hardcoded values to display in a form of a table, then you are better off using <h:panelGrid>. If you however have a list of objects that you want to iterate over and display them quickly then use <p:dataTable>.
Let's say we have a List of employees
<p:dataTable var="employee" value="#{tableBean.employees}">
<p:column headerText="Name">
<h:outputText value="#{employee.name}" />
</p:column>
<p:column headerText="Age">
<h:outputText value="#{employee.age}" />
</p:column>
<p:column headerText="Sex">
<h:outputText value="#{employee.sex}" />
</p:column>
</p:dataTable>
then your table would look like this. var in this case is completely arbitrary, you could for instance call it 'fluffy' if you wanted. There are a lot of settings you can use with dataTable like pagination, export, sorting etc. But I suggest you familiarize yourself with Primefaces showcase

outputText and inputText in f:facet of rich:column doesn't work - JSF

I'm trying to achieve external filtering using rich:dataTable which has sorting ability.
Here's what I have tried:
<rich:column sortBy="#{data.name}" id="name" filterMethod="#myBean.filter}">
<f:facet name="header">
<h:outputText value="Name" />
<h:inputText value="#{myBean.currentName}"
id="nameFilterInput" onclick="Event.stop(event)" onkeypress="searchNameOnEnter(event, this);">
<a4j:support event="onkeyup" reRender="dataTable , ds"
ignoreDupResponses="true" requestDelay="700" />
</h:inputText>
</f:facet>
<h:outputText value="#{data.name}" />
</rich:column>
Problem: The input text field is overwriting the output text (the header name)
I've tried using h:panelGroup inside the f:facet, but the problem is the sort icon is rendered in the third row seperately.
What am I missing here?
Any help would be great.
Updated: #Christophe Roussy, here's the screenshot
As seen the inputText is overwriting the outputText.
Update 2: I saw a post here: https://community.jboss.org/thread/13046 which explains to use <f:facet name="filter"> for inputText, but that seems to work only for rich:extendedDataTable.
Any way to make it work with rich:dataTable?
The <f:facet> can have only one child. Wrap them in a <h:panelGroup>.
<f:facet name="header">
<h:panelGroup>
<h:outputText ... />
<h:inputText ... />
</h:panelGroup>
</f:facet>

JSF - Pagination implementation using Tomahawk

I am trying to implement Pagination in JSF using Tomahawk. When the page is loaded, the table in the first page is populated with data. But, when I click on Next or Prev the table is empty. I don't see any javascript error in the browser. Following is the code from the jsp. Please let me know if I am missing something:
<t:dataTable id="tableid" value="#{SiteSearchCriteria.siteList}"
var="item" border="1" rows="5" rowIndexVar="rowIndex"
rowClasses="trobg1,trobg2">
<h:column>
<f:facet name="header">
<h:outputText value="siteName"></h:outputText>
</f:facet>
<h:outputLabel value="#{item.siteName}"></h:outputLabel>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="siteCLLI"></h:outputText>
</f:facet>
<h:outputLabel value="#{item.siteCLLI}"></h:outputLabel>
</h:column>
</t:dataTable>
<t:dataScroller id="dataScrollerId" for="tableid" fastStep="10"
pageIndexVar="pageIndex" renderFacetsIfSinglePage="true"
pageCountVar="pageCount" paginator="true" paginatorMaxPages="9"
immediate="true">
<f:facet name="first">
<t:outputText value="First"></t:outputText>
</f:facet>
<f:facet name="last">
<t:outputText value="Last"></t:outputText>
</f:facet>
<f:facet name="previous">
<t:outputText value="Previous"></t:outputText>
</f:facet>
<f:facet name="next">
<t:outputText value="Next"></t:outputText>
</f:facet>
</t:dataScroller>
The backing bean that I was using was in "request" scope. Hence, the data was not visible when I clicked on "Next". Changed the scope of backing bean to "Session" and things started to work.

Resources