I have this problem, and I don't understand why...I used it all the time in this way
<p:dataTable id="datatable" var="ligne" value="#{ficheMB.lignes}"
selection="#{ficheMB.selectedLignes}" rowKey="#{ligne.id}" >
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column headerText="Article">
<h:outputText value="#{ligne.article.nom}" />
</p:column>
<p:column headerText="Tarif">
<h:outputText value="#{ligne.article.tarif}" />
</p:column>
this is the error
javax.faces.FacesException: DataModel must implement org.primefaces.model.SelectableDataModel when selection is enabled.
at org.primefaces.component.datatable.DataTable.getRowKeyFromModel(DataTable.java:1409)
at org.primefaces.component.datatable.DataTableRenderer.encodeRow(DataTableRenderer.java:1244)
at org.primefaces.component.datatable.DataTableRenderer.encodeRows(DataTableRenderer.java:1184)
thank you for your help
Passed on the demo example of:
https://www.primefaces.org/showcase/ui/data/datatable/basic.xhtml
and I can show the complete example as primefaces-test-master and run as mvn clean jetty:run-exploded
I've created a displays using 'p:selectManyCheckbox ' to show all my Year, Brand, Colour, Price & Sold' as:
<p:selectManyCheckbox id="carColumns" value="#{carService.selectedItems}">
<f:selectItem itemLabel="Year" itemValue="Year"/>
<f:selectItem itemLabel="Brand" itemValue="Brand"/>
<f:selectItem itemLabel="Colour" itemValue="Colour"/>
<f:selectItem itemLabel="Price" itemValue="Price"/>
<f:selectItem itemLabel="Sold" itemValue="Sold"/>
<p:ajax listener="#{carService.selectedItemsChanged}" update="formCars:tblCars"/>
</p:selectManyCheckbox>
It then displays the p:dataTable and each p:column of the 'car' plus the others:
<p:dataTable id="tblCars" var="car" value="#{dtBasicView.cars}" paginator="true"
rows="100"
multiViewState="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100"
resizableColumns="true"
draggableColumns="true"
scrollWidth="100%">
<f:facet name="header">
<p:commandButton id="columnTogglerCars" type="button" value="Columns" style="float:right"
icon="pi pi-align-justify"/>
<p:columnToggler datasource="tblCars" trigger="columnTogglerCars"/>
</f:facet>
<p:column headerText="Id" rendered="true">
<h:outputText value="#{car.id}"/>
</p:column>
<p:column headerText="Year" sortBy="#{car.year}" rendered="#{carService.yearColumnRendered}">
<h:outputText value="#{car.year}"/>
</p:column>
<p:column headerText="Brand" sortBy="#{car.brand}" rendered="#{carService.brandColumnRendered}">
<h:outputText value="#{car.brand}"/>
</p:column>
<p:column headerText="Colour" sortBy="#{car.colour}" rendered="#{carService.colourColumnRendered}">
<h:outputText value="#{car.colour}"/>
</p:column>
<p:column headerText="Price" sortBy="#{car.price}" rendered="#{carService.priceColumnRendered}">
<h:outputText value="#{car.price}"/>
</p:column>
<p:column headerText="Sold" sortBy="#{car.sold}" rendered="#{carService.soldColumnRendered}">
<h:outputText value="#{car.sold}"/>
</p:column>
</p:dataTable>
If I then alter the orders (up or down) displayed of p:column headerText on the selected items of p:selectManyCheckbox then sometimes will not actually displayed each of the 'Year, Brand, Colour, Price & Sold' in dataTable.
Am I doing something wrong with p:selectManyCheckbox and p:dataTable ?
(1) Hows all five images 'Year, Brand, Colour, Price & Sold'.
(2) Show two pages 'Year, Brand'
(3) Selects "Year, Brand, Colour but it only shows '"Year, Brand', though selected (Colour)!
See the code at: https://www.dropbox.com/s/vfugj0fppejtti7/primefaces-test-master.zip?dl=0
I had the same problem with ajax and p:dataTable, I solve it insert the p:dataTable inside the p:panel and with ajax I have update the panel, an example
<p:panel id="panel-update">
<p:dataTable id="tblCars" var="car" value="#{dtBasicView.cars}" paginator="true"
rows="100"
multiViewState="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100"
resizableColumns="true"
draggableColumns="true"
scrollWidth="100%">
<f:facet name="header">
<p:commandButton id="columnTogglerCars" type="button" value="Columns" style="float:right"
icon="pi pi-align-justify"/>
<p:columnToggler datasource="tblCars" trigger="columnTogglerCars"/>
</f:facet>
<p:column headerText="Id" rendered="true">
<h:outputText value="#{car.id}"/>
</p:column>
<p:column headerText="Year" sortBy="#{car.year}" rendered="#{carService.yearColumnRendered}">
<h:outputText value="#{car.year}"/>
</p:column>
<p:column headerText="Brand" sortBy="#{car.brand}" rendered="#{carService.brandColumnRendered}">
<h:outputText value="#{car.brand}"/>
</p:column>
<p:column headerText="Colour" sortBy="#{car.colour}" rendered="#{carService.colourColumnRendered}">
<h:outputText value="#{car.colour}"/>
</p:column>
<p:column headerText="Price" sortBy="#{car.price}" rendered="#{carService.priceColumnRendered}">
<h:outputText value="#{car.price}"/>
</p:column>
<p:column headerText="Sold" sortBy="#{car.sold}" rendered="#{carService.soldColumnRendered}">
<h:outputText value="#{car.sold}"/>
</p:column>
</p:dataTable>
</p:panel>
Now with ajax can update the panel
<p:selectManyCheckbox id="carColumns" value="#{carService.selectedItems}">
<f:selectItem itemLabel="Year" itemValue="Year"/>
<f:selectItem itemLabel="Brand" itemValue="Brand"/>
<f:selectItem itemLabel="Colour" itemValue="Colour"/>
<f:selectItem itemLabel="Price" itemValue="Price"/>
<f:selectItem itemLabel="Sold" itemValue="Sold"/>
<p:ajax listener="#{carService.selectedItemsChanged}" update="formCars:panel-update"/>
</p:selectManyCheckbox>
you're doing something that's not consistent, the p:columnToggler uses javascript to show and hide those dataTable columns, but using your selectManyCheckbox you're using the jsf some managed bean to not render some column, first of all stick to one of those, as the selectManyCheckbox and it's managed bean carService.selectedItems have no idea what you have hidden or displayed using the p:columnToggler.
anyway if you're trying to create a p:dataTable that has dynamic columns then you should do it as in this example.
Edit 1:
As described in Kukeltje comment, using visible attribute of p:column is the way to go instead of using rendered if you really nead to manage showing and hiding columns in the backing bean and still be able to use the columnToggler
I am using PF 5.3, on (weblogic 11g/jsf2.0/java 1.6).
I thought the issue of not shown emptyMessage in Datatable is fixed in 5.3, but inspite of using the latest version, i still dont see the message. Below is my sample code.
<p:dataTable id="attaDt" var="fileRow" value="#{pendpaybean.selectedPayDetailsFiles}"
rowIndexVar="rowIndex"
emptyMessage="No Files Uploaded"
>
<p:column headerText="Uploaded Date"
width="15px;" style="text-align:center"
>
<h:outputText value="#{fileRow.columns[0]}" />
</p:column>
<p:column headerText="Uploaded By"
width="30px;" style="text-align:center"
>
<h:outputText value="#{fileRow.columns[3]}" />
</p:column>
</p:datatable>
Any help ?
Your code works well. NOTE I put attribute value to null for showing emptyMessage.
Your adapted code:
<h:body>
<h:form>
<p:dataTable id="attaDt" value="#{null}" var="fileRow" rowIndexVar="rowIndex" emptyMessage="No Files Uploaded">
<p:column headerText="Uploaded Date" width="15px;" style="text-align:center">
<h:outputText value="#{fileRow.columns[0]}" />
</p:column>
<p:column headerText="Uploaded By" width="30px;" style="text-align:center">
<h:outputText value="#{fileRow.columns[3]}" />
</p:column>
</p:dataTable>
</h:form>
</h:body>
Basically, I have 2 collections of objects: List and List. Each person has a value in each criteria, which builds the matrix to be displayed:
criteria1 criteria2 criteria3 ...
person1 2 5 8
person2 4 3 1
person3 6 9 0
...
The number of elements in each collection is unknown since they are coming from query results. My model has 3 tables: criteria, person and criteria_person (which has the personId, criteriaId and qualification).
I have been able to display the datatable with these collections but I have no clue about how to relate them to the qualification associated to them, and then make them persist. So, any guidance would be much appreciated.
You just asked such a wide question. For this you can use row expansion see more
You can simple add a table with person name and criteria would be it's inner table like in the example on the showcase.
here is sample example:
<p:dataTable var="person" value="#{dtBasicView.peronsViewList}">
<f:facet name="header">
Person with criteria
</f:facet>
<p:column style="width:16px">
<p:rowToggler />
</p:column>
<p:column headerText="Person Name">
<h:outputText value="#{person.personName}" />
</p:column>
<p:column headerText="Reg. Date">
<h:outputText value="#{person.regDate}" />
</p:column>
<p:rowExpansion>
<p:panelGrid columns="2" columnClasses="label,value" style="width:300px">
<p:dataTable var="cri" value="#{person.criteria}">
<p:column headerText="Id">
<h:outputText value="#{cri.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{cri.year}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{cri.brand}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{cri.color}" />
</p:column>
</p:dataTable>
</p:panelGrid>
</p:rowExpansion>
</p:dataTable>
I am not sure if I understood the question 100%, but I solved something similar with p:columns and a backing bean method which resolves the value for the current cell:
<p:dataTable value="#{curSearch.getSearchResults()}" var="curSearchResult">
<p:columns value="#{curSearch.determineItems()}" var="curSearchItem">
<f:facet name="header">
<h:outputText value="#{curSearchItem}" />
</f:facet>
<h:outputText value="#{someUiBusinessLogicBean.generatePropertyValue(curSearchResult, curSearchItem)}" />
</p:columns>
</p:dataTable>
Hope this shows the idea. But I would recommend to build a handy UI model.
I'm using a datatable with filtering. This is the table declaration:
<p:dataTable id="#{tblId}" var="p" editable="true" editMode="cell"
resizableColumns="true" rowIndexVar="rowIndex" selectionMode="multiple"
rowKey="#{p.id}" selection="#{ppselection}"
emptyMessage="No Params in table" value="#{tblValue}" scrollable="true"
style="height:100%" sortMode="multiple" styleClass="#{styleClass}"
filteredValue="#{filteredParams}">
When adding a new row to the table, I want it to already be displayed according to the current filter. i.e. if the filter is "aa" and the row name is "aabbcc" then I want it displayed, but if the row name is "bbcc" then I don't want it displayed. Right now, all I came up with is decidng whether I want to manually add it to the filteredParams list or not.
This is an example of one of the columns in the table, although all the coulmns are filterable:
<p:column width="15%" id="ParameterColumn" headerText="Parameter" sortBy="#{p.name}"
filterBy="#{p.name}" filterMatchMode="contains">
<p:cellEditor id="Parameter">
<f:facet name="output">
<h:outputText id="param_name" value="#{p.name}" />
</f:facet>
<f:facet name="input">
<p:inputText id="nameInput" value="#{p.name}" style="width:99%"
validator="#{p.validateParamName}">
<p:ajax event="change"
update=":main_tabs:paramForm:ParamTbl, :main_tabs:paramForm:SplitedParamTbl" />
</p:inputText>
<p:messages for="nameInput" display="tooltip" />
</f:facet>
</p:cellEditor>
</p:column>
Thanks!!
You can trigger filtering in oncomplete method of ajax/button that adds new row:
oncomplete='tableWidgetVar.filter();'