我尝试为我的primefaces数据表实现自定义过滤器。我想用树组件过滤datetring。这是一个截图: Custom DataTable filter with Tree component
这是我的专栏定义。
<p:column filterBy="#{company.datum_wiedervorlage}" filterMatchMode="in" filterFunction="#{searchAndSelectView.filterByDatumWiedervorlage}">
<f:facet name="header">
<h:outputText style="width:150px" id="wiedervorlage_header" styleClass="single-ui-column-title" value="Datum Wiedervorlage" />
</f:facet>
<f:facet name="filter">
<p:overlayPanel for="wiedervorlage_header" hideEffect="fade" style="position: fixed" id="overlay_filter">
<p:tree value="#{searchAndSelectView.datumWiedervorlageTree}" var="entry" selectionMode="checkbox" animate="true" filterBy="#{entry}" selection="#{searchAndSelectView.selectedTreeNodeDates}">
<p:ajax event="select" update=":form" listener="#{searchAndSelectView.onTreeNodeDateSelect}"/>
<p:treeNode>
<h:outputText value="#{entry}" />
</p:treeNode>
</p:tree>
</p:overlayPanel>
</f:facet>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{company.datum_wiedervorlage}" />
</f:facet>
<f:facet name="input">
<p:inputText id="datum_wiedervorlage_input" value="#{company.datum_wiedervorlage}" style="width:100%" />
</f:facet>
</p:cellEditor>
</p:column>
问题是我每次想要过滤其他列时都会遇到以下异常。
18:11:04,288 SEVERE [javax.enterprise.resource.webcontainer.jsf.context] (default task-126) java.lang.ClassCastException: org.primefaces.component.overlaypanel.OverlayPanel cannot be cast to javax.faces.component.ValueHolder
at org.primefaces.component.datatable.feature.FilterFeature.populateFilterMetaDataWithoutColumnGroups(FilterFeature.java:396)
at org.primefaces.component.datatable.feature.FilterFeature.populateFilterMetaData(FilterFeature.java:293)
at org.primefaces.component.datatable.feature.FilterFeature.decode(FilterFeature.java:93)
at org.primefaces.component.datatable.DataTable.processValidators(DataTable.java:847)
at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:575)
at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
at org.primefaces.component.api.UIData.visitTree(UIData.java:827)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIForm.visitTree(UIForm.java:362)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at javax.faces.component.UIComponent.visitTree(UIComponent.java:1700)
at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:403)
at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:266)
at org.primefaces.context.PrimePartialViewContext.processPartial(PrimePartialViewContext.java:57)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1193)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:198)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:658)
at io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85)
at io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:62)
at io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36)
at org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131)
at io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:57)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:46)
at io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:64)
at io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:60)
at io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:77)
at io.undertow.security.handlers.NotificationReceiverHandler.handleRequest(NotificationReceiverHandler.java:50)
at io.undertow.security.handlers.AbstractSecurityContextAssociationHandler.handleRequest(AbstractSecurityContextAssociationHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43)
at io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:292)
at io.undertow.servlet.handlers.ServletInitialHandler.access$100(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:138)
at io.undertow.servlet.handlers.ServletInitialHandler$2.call(ServletInitialHandler.java:135)
at io.undertow.servlet.core.ServletRequestContextThreadSetupAction$1.call(ServletRequestContextThreadSetupAction.java:48)
at io.undertow.servlet.core.ContextClassLoaderSetupAction$1.call(ContextClassLoaderSetupAction.java:43)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.api.LegacyThreadSetupActionWrapper$1.call(LegacyThreadSetupActionWrapper.java:44)
at io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:272)
at io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:81)
at io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:104)
at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)
at io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:805)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
我没有胶水如何解决这个问题。我尝试使用InputHidden字段组件修复它,但没有任何运气。 Primefaces datatable date range filter with filterFunction
有人知道让这件事发挥作用的可能方法吗?
修改:根据要求提供。我正在使用primefaces 6.1和JSF 2.1
答案 0 :(得分:0)
我找到了解决方案。我已经自定义了OutputPanel,OverlayPanel和Tree,以允许创建我的自定义过滤器。对于我所有的新类,我都扩展了Primefaces类并实现了ValueHolder接口。我自定义的组件是:filterOutputPanel,overlayFilterPanel和TreeFilter。
代码如下:
<p:column id="dataDocColumn" filterBy="#{row.documentDate}"
headerText="Document date" filterMatchMode="equals" sortBy="#{row.documentDate}" >
<f:facet name="filter">
<cf:filterOutputPanel deferred="true">
<p:commandButton id="filterBtn" value="Filter" />
<cf:overlayFilterPanel for="filterBtn" hideEffect="fade" style="text-align:left;">
<cf:treeFilter id="dataDocTree"
value="#{myBean.rootDataDoc}" var="d"
filterBy="#{d}" style="width:150px;font-size:12px"
dynamic="true" filterMatchMode="contains"
selectionMode="checkbox"
selection="#{myBean.selectedDataDoc}">
<p:ajax event="select" oncomplete="PF('myTable').filter()" />
<p:ajax event="unselect" oncomplete="PF('myTable').filter()" />
<p:treeNode>
<h:outputText value="#{d}" />
</p:treeNode>
<p:treeNode type="month">
<h:outputText value="#{d}" />
</p:treeNode>
<p:treeNode type="date">
<h:outputText value="#{d}">
<f:convertDateTime pattern="dd-MM-yyyy" timeZone="CET" />
</h:outputText>
</p:treeNode>
</cf:treeFilter>
</cf:overlayFilterPanel>
</cf:filterOutputPanel>
</f:facet>
<h:outputText value="#{row.documentDate}" >
<f:convertDateTime pattern="dd-MM-yyyy" timeZone="CET"/>
</h:outputText>
</p:column>
FilterOutputPanel
@FacesComponent("view.components.FilterOutputPanel")
public class FilterOutputPanel extends OutputPanel implements ValueHolder{
public FilterOutputPanel() {
super();
}
/*
* This methods returns the local value of his child UIComponent
* that is a ValueHolder
*/
@Override
public Object getLocalValue() {
for(UIComponent c : this.getChildren()) {
if(c instanceof ValueHolder)
return ((ValueHolder) c).getLocalValue();
}
return null;
}
...
}
OverlayFilterPanel
@FacesComponent("view.components.OverlayFilterPanel")
public class OverlayFilterPanel extends OverlayPanel implements ValueHolder{
public OverlayFilterPanel() {
super();
}
/*
* This method returns the local value of his child UIComponent,
* assuming that the only child is a TreeFilter
*/
@Override
public Object getLocalValue() {
return ((ValueHolder) this.getChildren().get(0)).getLocalValue();
}
...
}
TreeFilter类
@FacesComponent("view.components.TreeFilter")
public class TreeFilter extends Tree implements ValueHolder{
public TreeFilter() {
super();
}
/*
* This method explores the Tree and returns the data selected on the leaf nodes
*/
@Override
public Object getLocalValue() {
TreeNode[] selectedDataDoc = (TreeNode[]) this.getSelection();
if(selectedDataDoc==null)
return null;
Date[] dateArray = new Date[selectedDataDoc.length];
int j=0;
for(int i=0; i<selectedDataDoc.length; i++) {
TreeNode n = selectedDataDoc[i];
if(n.isLeaf()) {
dateArray[j] = (Date)n.getData();
j++;
}
}
Date[] result = new Date[j];
for(int i=0; i<j; i++) {
result[i]=dateArray[i];
}
return result;
}
...
}
customtaglib.xml
...
<tag>
<tag-name>treeFilter</tag-name>
<component>
<description>Custom Tree filter</description>
<component-type>view.components.TreeFilter</component-type>
<renderer-type>org.primefaces.component.TreeRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>overlayFilterPanel</tag-name>
<component>
<description>Custom Overlay Filter Panel</description>
<component-type>view.components.OverlayFilterPanel</component-type>
<renderer-type>org.primefaces.component.OverlayPanelRenderer</renderer-type>
</component>
</tag>
<tag>
<tag-name>filterOutputPanel</tag-name>
<component>
<description>Custom Output Panel for filters</description>
<component-type>view.components.FilterOutputPanel</component-type>
<renderer-type>org.primefaces.component.OutputPanelRenderer</renderer-type>
</component>
</tag>
...
web.xml
<context-param>
<param-name>javax.faces.FACELETS_LIBRARIES</param-name>
<param-value>/WEB-INF/customtaglib.xml</param-value>
</context-param>