I'm using a normal datatable with lazyloading and rowexpansion with a nested table and I have problems by opening the rowexpansion after lazyloading. ScrollRows is setted to 150.
<ui:composition template="/ressources/basic.xhtml" xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui">
<ui:define name="title">#{label['template.tab1']}</ui:define>
<ui:define name="content">
<h:form id="crateTbl">
<p:dataTable rowExpandMode="single" id="cTbl" var="crate" value="#{cratesView.lazyModel}" selectionMode="single"
filteredValue="#{cratesView.filteredCrates}" selection="#{cratesView.selectedCrate}"
lazy="true" liveScroll="true" scrollRows="150"
widgetVar="cratesTbl" rowKey="#{crate.id}" scrollable="true" scrollHeight="550">
<p:column style="width:16px" exportable="false">
<p:rowToggler />
</p:column>
<p:column headerText="#{label['crate.col.grp']}" filterStyle="width:60px;" filterBy="#{crate.grp}" filterMatchMode="contains" width="60">
<h:outputText value="#{crate.grp}"/>
</p:column>
...additional columns of crate.
<p:rowExpansion >
<p:panelGrid columnClasses="label,value" >
<div class="remark-label"><b>#{label['crateview.toggle.remark']}</b>: <h:outputLabel value="#{crate.remark}"/></div>
<p:dataTable id='bTbl' var="bottle" value="#{cratesView.getBottles2Crate(crate)}"
widgetVar="bottleTbl" rowKey="#{bottle.id}" scrollable="true" scrollHeight="300">
<p:column headerText="#{label['bottle.col.grp']}" width="50">
<h:outputText value="#{bottle.grp}"/>
</p:column>
...additional columns of bottle
</p:dataTable>
</p:column>
</p:row>
</p:panelGrid>
</p:rowExpansion>
</p:dataTable>
</h:form>
</ui:define>
and Bean:
@ManagedBean(name = "cratesView")
@ViewScoped
public class CrateView implements Serializable {
//object definitions
@PostConstruct
public void init() {
//init some objects
lazyModel = new LazyCrateDatamodel(cratesList);
}
public LazyDataModel<Crate> getLazyModel() {
return lazyModel;
}
public void setLazyModel(LazyCrateDatamodel lazyModel){
this.lazyModel = lazyModel;
}
public void setSelectedCrate(final Crate c){
this.selectedCrate = c;
}
public Crate getSelectedCrate() {
return this.selectedCrate;
}
public List<Crate> getFilteredCrates() {
return filteredCrates;
}
public void setFilteredCrates(List<Crate> filteredCrates) {
this.filteredCrates = filteredCrates;
}
public List<Bottle> getBottles2Crate(final Crate c)
{
int grp = c.getGrp(); //
return gProvider.getBottlesByCrate(calculated.getGrp(), 0);
}
}
Everything runs fine on the firstpage, opening the expansion shows correct data in the table. After loading the next 150 rows and scrolling back to e.g. the first row and opening the expansion the data of a wrong crate is loaded. cratesView.getBottles2Crate(crate) is called with a crate-object shifted by n*150(n - numbers of loadings). The object of the rowtoggling-event is not the same of the datamodel. On the other side setSelectedCrate gets the right object. Do I have something misconfigurated or is there a hint in the docs using rowexpansion and lazyloading...
Thanks for some hints.
Edit: Correct some syntax.
Sorry for the missing information:
Mojarra JSF Implementation 2.3.0 (20170310-1214)
Primeface 6.2
I tested it parallel with a minimal version:
Classes: Testdata provider:
Entities Crate:
next Bottle:
next Entity:
next LazyView:
next LazyDatamodel:
It's the same behavior: After one loading scrolling to the beginning, the given crate is the 150 shifted crate, not crate[0]. Hope someone can verify this behavior.