我有一个动态列的数据表:
<p:dataTable id="bookings" var="booking" value="#{tableBean.dataModel}"
widgetVar="bookingTable" filteredValue="#{tableBean.filteredFields}"
paginator="true" rows="15"
lazy="true" rowsPerPageTemplate="15,30,50" type="none" draggableColumns="true">
[...]
<p:columns value="#{tableBean.columns}" var="column" columnIndexVar="colIndex"
sortBy="#{booking.properties[column.property]}"
filterBy="#{booking.properties[column.property]}"
filterMatchMode="in"
styleClass="telegrotesk">
<f:facet name="header">
<h:outputText value="#{column.header}"/>
</f:facet>
<f:facet name="filter">
<p:selectCheckboxMenu label="#{column.header}" onchange="PF('bookingTable').filter()">
<f:selectItems value="#{column.possibilities}" />
</p:selectCheckboxMenu>
</f:facet>
<h:outputText value="#{booking.properties[column.property]}"/>
</p:columns>
列类似于primefaces示例(http://www.primefaces.org/showcase/ui/data/datatable/filter.xhtml)中的类:
static public class ColumnModel implements Serializable {
private String header;
private String property;
private List<SelectItem> possibilities;
public ColumnModel(Field property) {
this.header = property.getName();
this.property = property.getSqlName();
}
public String getHeader() {
return header;
}
public String getProperty() {
return property;
}
public List getPossibilities() {
return possibilities;
}
public void setPossibilities(List<SelectItem> possibilities) {
this.possibilities = possibilities;
}
}
在我的示例中,只有一个动态列用于测试,该列显示创建预订的User。它工作,在复选框下拉框中显示所有用户。当我选择一个或多个用户时,函数load
public List<Booking> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
[...]
}
被执行,但是过滤器总是空的!
ColumnModel
中的可能性列表是SelectItems
的集合。标签总是用户名,值是User对象。对于用户类,我定义了一个Converter类,用@FacesConverter(forClass = User.class)
javax.faces.convert.Converter
我做错了什么,过滤器映射总是空的?
编辑
当我这样做的时候
<p:columns value="#{tableBean.columns}" var="column" columnIndexVar="colIndex"
sortBy="#{booking.properties[column.property]}"
filterBy="#{booking.properties[column.property]}"
filterMatchMode="in"
filterOptions="#{column.possibilities}"
styleClass="telegrotesk">
和没有facet,它工作正确,但我只能选择一个用户。
我使用的是primefaces 5.0, jsf 2.2.1和glassfish v4
你没有做错什么,这是Primefaces的错误。
请给它打上星号,让我们试着把它修好。
新的PF5增强过滤不适用于动态列:https://code.google.com/p/primefaces/issues/detail?id=6912
处理:
步骤1:在Primefaces源代码(https://code.google.com/p/primefaces/source/checkout)中打开FilterFeature.java.
在populateFilterMetaData(FacesContext context, DataTable table)
方法中,第300行左右,替换为:
filterId = dynamicColumn.getContainerClientId(context) + separator + "filter";
dynamicColumn.cleanStatelessModel();
与这个:filterId = dynamicColumn.getContainerClientId(context) + separator + "filter";
filterFacet = null;
dynamicColumn.cleanStatelessModel();
所以你只要加上filterFacet = null;
构建PF的技巧:https://code.google.com/p/primefaces/wiki/BuildingFromSource
步骤2:在您的项目中,确保您的过滤器facet中的输入组件具有filter
的id的例子:
<f:facet name="filter">
<p:selectOneButton id="filter" onchange="PF('recordTable').filter()" >
<f:converter converterId="javax.faces.Boolean" />
<f:selectItem itemLabel="All" itemValue="" />
<f:selectItem itemLabel="True" itemValue="true" />
<f:selectItem itemLabel="False" itemValue="false" />
</p:selectOneButton>
</f:facet>
是在primefaces 4.0版本中可以在动态列中添加过滤器选项
<p:columns value="#{pc_searchJobBean.columns}" var="column"
id="searchJobColumns" columnIndexVar="colIndex"
rendered="#{column.property eq 'minWorkExp' or column.property eq 'maxWorkExp' or column.property eq 'minSalary'
or column.property eq 'maxSalary'}"
filterBy="#{tbl[column.property]}" filterOptions="#{column.items}">
<f:facet name="header">
<h:outputText value="#{column.header}" escape="false">
</h:outputText>
</f:facet>
<h:outputText value="#{tbl[column.property]}" escape="false"
rendered="#{column.header!='Priority'}">
<f:convertDateTime
pattern="#{userSettingBean.userSettingVO.dateFormat}" />
</h:outputText>
</p:columns>
Java代码…
public static class ColumnModel {
private String header;
private String property;
private SelectItem[] items;
public ColumnModel(String header, String property, SelectItem[] items) {
super();
this.header = header;
this.property = property;
this.setItems(items);
}
public ColumnModel(String header, String property) {
this.header = header;
this.property = property;
}
public String getHeader() {
return header;
}
public void setHeader(String header) {
this.header = header;
}
public String getProperty() {
return property;
}
public void setProperty(String property) {
this.property = property;
}
public SelectItem[] getItems() {
return items;
}
public void setItems(SelectItem[] items) {
this.items = items;
}
}
设置列中的selectItems
if(model.getProperty().equals("country")){
model.setItems(countryOptions);
}if(model.getProperty().equals("jobType")){
model.setItems(jobTypeOptions);
}