I have the CommandLink/CommandButton which is an element of the column in the dataTable. The dataTable is integrated with the lazy model. My code (not exactly my, because this is the primefaces showcase example) works perfect when the number of records in the table is divisible by the page size. For example the page size is 5 and the number of records is 60. But, when the number of records is 61, then when I reach the last record in the table, the action listener for every button is not called. I've tried to change p:commandlink to h:commandbutton/p:commandbuton. I've tried all the stackoverflow tips related to use update="@form" or immediate="true" or disable ajax requests by ajax="false", but the result is the same. For me it looks like a problem with dataTable rendering. Please look at the source code. This example is based on the primefaces showcase, I've added only a new column (this one with the commandlink).
xhtml page:
<h:form id="form">
<p:dataTable styleClass="test-class" id="data" var="car" value="#{tableBean.lazyModel}" scrollable="true" liveScroll="true" scrollRows="5" scrollHeight="200" lazy="true" >
<p:column headerText="Model">
<h:outputText value="#{car.model}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Manufacturer">
<h:outputText value="#{car.manufacturer}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
<p:column headerText="Color">
<p:commandLink value="Test"
actionListener="#{tableBean.buttonListener()}" />
</p:column>
</p:dataTable>
</h:form>
datatable lazy model:
public class MyLazyModel extends LazyDataModel<Car> {
private List<Car> datasource;
public MyLazyModel(List<Car> datasource) {
this.datasource = datasource;
}
@Override
public Car getRowData(String rowKey) {
for(Car car : datasource) {
if(car.getModel().equals(rowKey))
return car;
}
return null;
}
@Override
public Object getRowKey(Car car) {
return car.getModel();
}
@Override
public List<Car> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,String> filters) {
//rowCount
int dataSize = datasource.size();
this.setRowCount(dataSize);
//paginate
if(dataSize > pageSize) {
try {
return datasource.subList(first, first + pageSize);
}
catch(IndexOutOfBoundsException e) {
return datasource.subList(first, first + (dataSize % pageSize));
}
}
else {
return datasource;
}
}
}
DataTable bean:
@ManagedBean
@ViewScoped
public class TableBean {
private LazyDataModel<Car> lazyModel;
private Car selectedCar;
private List<Car> cars;
public TableBean() {
populateRandomCars(cars, 60);
lazyModel = new MyLazyModel(cars);
}
public void setSelectedCar(Car selectedCar) {
this.selectedCar = selectedCar;
}
public LazyDataModel<Car> getLazyModel() {
return lazyModel;
}