我使用JSF 2.2,Primefaces 6.0和CDI。我有一个实现了延迟加载的datatable
(datatable
从数据库下载数据)。每列都有一个筛选器字段。
其中一列必须具有readonly
过滤器字段(在显示datatable
之前,我在某个变量中保存了此过滤器的值)。因此,正如我所写,此筛选器字段应readonly
(不可编辑),并且筛选器应将此字段中的值用于筛选。 如何实现此功能?
我尝试添加inputtext
组件并设置 readonly
属性:
<p:dataTable id="dataTableOfDataStore" var="obj" widgetVar="dataTableOfDataStoreVar"
value="#{formVisualizationController.dataTableLazy}"
lazy="true"
filteredValue="#{formVisualizationController.filteredDataTable}"
filterDelay="2000"
<!-- other attributes -->
>
<!-- other columns -->
<p:column headerText="Source IP" sortBy="#{obj.sip}"
filterBy="#{obj.sip}" filterMatchMode="contains">
<f:facet name="filter">
<p:inputText readonly="true" onchange="PF('dataTableOfDataStoreVar').filter()"
value="#{formVisualizationController.selectedSourceIPFieldOfFiltr.ip}"
style="width: 100%; background-color: #0088cc; color: #ffffff;"/>
</f:facet>
<h:outputText value="#{obj.sip}" />
</p:column>
<!-- other columns -->
</p:dataTable>
不幸的是,它不起作用。当我删除 readonly
属性时,它可以工作,但过滤器字段也是可编辑的。
当然,我可以通过手动将此值传递给数据库查询,然后从列中删除过滤器并保留具有值(以及readonly
属性)的inputtext
组件来实现此目的,但也许您知道一些不同的方法来实现这一目标。
此答案解释了为什么只读字段不包含在请求中。因此,Primefaces不使用它来过滤。
在我看来,如果您想确保它没有被篡改,您无论如何都必须在服务器端覆盖/检查它。因此,以编程方式设置它似乎是最好的解决方案。
可以在查询中执行此操作,也可以通过以编程方式添加筛选器值来执行此操作。例如,您可以重写 load 方法以使用 bean 中的值(如果它是必需的)。
dataTableLazy = new LazyDataModel<?>(){
public List<Site> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
//set your filter here
super.load(first, pageSize, sortField, sortorder, filters);
}
}
答案的实现
修改 JSF 视图。我保留了包含我的常量值的
inputtext
组件(带有readonly
属性),并且删除了此列的过滤器功能(在客户端)。筛选器属性必须保留在<p:column>
组件中,否则您将不会在列的标题行中看到inputtext
组件。<p:column headerText="Source IP" sortBy="#{obj.sip}" filterBy="#{obj.sip}" filterMatchMode="contains"> <f:facet name="filter"> <p:inputText readonly="true" value="#{formVisualizationController.selectedSourceIPFieldOfFiltr.ip}" style="width: 100%; background-color: #0088cc; color: #ffffff;"/> </f:facet> <h:outputText value="#{obj.sip}" /> </p:column>
在
load
方法中,我将值放入filters
参数中,该参数存储过滤所需的所有值。dataTableLazy=new LazyDataModel<Data>() { @Override public List<Data> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) { //here I put my value filters.put("sip", selectedSourceIP.getIp()); List<Data> result=dataService.getLazyDataStoreTable(idSeletedUserTable, first, pageSize, multiSortMeta, filters); //other code return result; } };
我的想法是使用"选择一"按钮来模拟只读过滤器字段,如下所示:
<p:column headerText="Source IP" sortBy="#{obj.sip}"
filterBy="#{obj.sip}" filterMatchMode="contains">
<f:facet name="filter">
<p:selectOneButton onchange="PF('dataTableOfDataStoreVar').filter()">
<f:selectItem itemLabel="#{formVisualizationController.selectedSourceIPFieldOfFiltr.ip}"
itemValue="#{formVisualizationController.selectedSourceIPFieldOfFiltr.ip}" />
</p:selectOneButton>
</f:facet>
<h:outputText value="#{obj.sip}" />
</p:column>