我正在使用 Primefaces 8.0。一个表格,其中包含冻结列和冻结部分和滚动部分中列的过滤器。启用行虚拟化。
按钮代码:
<p:commandLink partialSubmit="true" process="@this" action="#{controller.loadCars}" update=":form:tab1">
<h:outputText value="Submit"/>
</p:commandLink>
表代码:
<h:form id="form">
<p:dataTable
id="tab1"
scrollable="true"
scrollHeight="350"
scrollWidth="900"
frozenColumns="2"
var="car"
scrollRows="5"
virtualScroll="true"
lazy="true"
rows="5"
rowIndexVar="#"
value="#{model.cars}"
widgetVar="carsTable"
emptyMessage="No cars found with given criteria"
filteredValue="#{model.filteredCars}">
<p:ajax event="filter" />
<p:columnGroup groupRow="true" type="frozenHeader" >
<p:row>
<p:column field="1" headerText="Id" filterBy="#{car.id}" filterMatchMode="contains" >
<p:inputText style="width:90%;"
onchange="PF('carsTable').filter()"
onkeyup="PF('carsTable').filter()"
onkeypress="if (event.keyCode == 13) { return false; }">
</p:inputText>
</p:column>
<p:column field="2" headerText="Color" filterBy="#{car.color}" filterMatchMode="contains" >
<p:inputText style="width:90%;"
onchange="PF('carsTable').filter()"
onkeyup="PF('carsTable').filter()"
onkeypress="if (event.keyCode == 13) { return false; }">
</p:inputText>
</p:column>
</p:row>
</p:columnGroup>
<p:columnGroup groupRow="true" type="scrollableHeader">
<p:row>
<p:column headerText="Id" width="100"/>
<p:column field="4" headerText="Year" filterBy="#{car.year}" filterable="true" filterMatchMode="contains" width="100">
<p:inputText style="width:90%;"
onchange="PF('carsTable').filter()"
onkeyup="PF('carsTable').filter()"
onkeypress="if (event.keyCode == 13) { return false; }">
</p:inputText>
</p:column>
<p:column headerText="Brand" width="100"/>
<p:column headerText="Color" width="100"/>
<p:column headerText="Id" width="100"/>
<p:column headerText="Year" width="100"/>
<p:column headerText="Brand" width="100"/>
<p:column headerText="Color" width="100"/>
<p:column headerText="Id" width="100"/>
<p:column headerText="Year" width="100"/>
<p:column headerText="Brand" width="100"/>
<p:column field="3" sortBy="#{car.color}" filterBy="#{car.color}" headerText="Color2" filterMatchMode="contains" width="100" >
<p:inputText style="width:90%;"
onchange="PF('carsTable').filter()"
onkeyup="PF('carsTable').filter()"
onkeypress="if (event.keyCode == 13) { return false; }">
</p:inputText>
</p:column>
</p:row>
</p:columnGroup>
<p:column headerText="Id" >
<h:outputText value="#{car.id}"/>
</p:column>
<p:column headerText="Color" >
<h:outputText value="#{car.color}" />
</p:column>
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
<p:column groupRow="true" headerText="Color2" >
<h:outputText value="#{car.color}" />
</p:column>
</p:dataTable>
</h:form>
控制器
import javax.enterprise.context.RequestScoped;
import javax.inject.Named;
@Named
@RequestScoped
public class Controller implements Serializable {
@Inject
private Model model;
public void loadCars(){
model.getCars().clear();
List<Car> tempCars = new ArrayList<>();
for(int i = 0 ; i < 100 ; i++) {
tempCars.add(new Car( UUID.randomUUID().toString().substring(0, 8), model.getBrands().get((int)(Math.random() * 10)), String.valueOf((int)(Math.random() * 50 + 1960)), model.getColors().get((int) (Math.random() * 10)), (int) (Math.random() * 100000), (Math.random() > 0.5) ? true: false ));
}
model.getCars().addAll(tempCars);
}
}
模型
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import lombok.Data;
@Named
@SessionScoped
@Data
public class Model implements Serializable {
Model(){
colors = new ArrayList<>();
colors.add("Black");
colors.add("White");
colors.add("Green");
colors.add("Red");
colors.add("Blue");
colors.add("Orange");
colors.add("Silver");
colors.add("Yellow");
colors.add("Brown");
colors.add("Maroon");
brands = new ArrayList<>();
brands.add("BMW");
brands.add("Mercedes");
brands.add("Volvo");
brands.add("Audi");
brands.add("Renault");
brands.add("Fiat");
brands.add("Volkswagen");
brands.add("Honda");
brands.add("Jaguar");
brands.add("Ford");
}
private List<Car> cars = new ArrayList<>();
private List<Car> filteredCars;
private List<String> colors;
private List<String> brands;
}
目的
public class Car implements Serializable {
public String id;
public String brand;
public String year;
public String color;
public int price;
public boolean sold;
public Car() {}
public Car(String id, String brand, String year, String color) {
this.id = id;
this.brand = brand;
this.year = year;
this.color = color;
}
public Car(String id, String brand, String year, String color, int price, boolean sold) {
this.id = id;
this.brand = brand;
this.year = year;
this.color = color;
this.price = price;
this.sold = sold;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getYear() {
return year;
}
public void setYear(String year) {
this.year = year;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public boolean isSold() {
return sold;
}
public void setSold(boolean sold) {
this.sold = sold;
}
@Override
public int hashCode() {
int hash = 7;
hash = 59 * hash + (this.id != null ? this.id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final Car other = (Car) obj;
if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
return false;
}
return true;
}
}
如果关闭行虚拟化,然后在表中过滤,那么一切正常。
将数据过滤到表中时,会出现来自 primefaces 库的 JS 错误。
Uncaught TypeError: can't access property "children", b.bodyTable is undefined
oncomplete http://localhost:8080/jsf_html4+PR8/javax.faces.resource/components.js.xhtml?ln=primefaces&v=8.0:12
v http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:18
jQuery 6
send http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:18
offer http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:18
handle http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:18
ab http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:18
filter http://localhost:8080/jsf_html4+PR8/ line 2 > injectedScript:1
callBehavior http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:22
filter http://localhost:8080/jsf_html4+PR8/javax.faces.resource/components.js.xhtml?ln=primefaces&v=8.0:12
filterTimeout http://localhost:8080/jsf_html4+PR8/javax.faces.resource/components.js.xhtml?ln=primefaces&v=8.0:12
setTimeout handler*bindFilterEvent/< http://localhost:8080/jsf_html4+PR8/javax.faces.resource/components.js.xhtml?ln=primefaces&v=8.0:12
jQuery 2
components.js.xhtml:12:31834
oncomplete http://localhost:8080/jsf_html4+PR8/javax.faces.resource/components.js.xhtml?ln=primefaces&v=8.0:12
v http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:18
jQuery 6
send http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:18
offer http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:18
handle http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:18
ab http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:18
filter http://localhost:8080/jsf_html4+PR8/ line 2 > injectedScript:1
callBehavior http://localhost:8080/jsf_html4+PR8/javax.faces.resource/core.js.xhtml?ln=primefaces&v=8.0:22
filter http://localhost:8080/jsf_html4+PR8/javax.faces.resource/components.js.xhtml?ln=primefaces&v=8.0:12
filterTimeout http://localhost:8080/jsf_html4+PR8/javax.faces.resource/components.js.xhtml?ln=primefaces&v=8.0:12
(Асинхронный: setTimeout handler)
bindFilterEvent http://localhost:8080/jsf_html4+PR8/javax.faces.resource/components.js.xhtml?ln=primefaces&v=8.0:12
jQuery 2