PrimeFaces 10 datePicker范围过滤结束日期包含匹配失效问题
问题根因
你之前修改前端日期时分秒的方案不生效,核心原因是<p:datePicker>绑定的<f:convertDateTime>仅保留年月日维度,提交过滤请求时会自动抹除你修改的时分秒信息,后端收到的结束日期仍为当天00:00:00。PrimeFaces 10默认的range匹配逻辑为字段值 >= 起始日期 and 字段值 < 结束日期,自然过滤不到结束日期当天带时间的记录。
解决方案
推荐优先选择自定义服务端过滤逻辑的方案,兼容性最高:
方案1:自定义后端过滤函数
- 修改XHTML中列的配置,添加
filterFunction属性绑定自定义过滤方法:
<p:column field="dateCreated" headerText="Request Date" filterMatchMode="range" filterFunction="#{requestBean.filterDateRange}"> <f:facet name="filter"> <p:datePicker widgetVar="dateFilterWidget" pattern="yyyy/MM/dd" selectionMode="range" onchange="PF('inboxTableWidget').filter();"> <f:convertDateTime type="date" dateStyle="short" pattern="yyyy/MM/dd" /> </p:datePicker> </f:facet> <h:outputText value="#{requestItem.dateCreated}"> <f:convertDateTime pattern="yyyy/MM/dd hh:mm aa" locale="ar"/> </h:outputText> </p:column>
- 在对应的后端Bean中添加自定义过滤方法:
import java.util.Calendar; import java.util.Date; import java.util.List; import java.util.Locale; // 你的Bean类 public class RequestBean { // 其他原有逻辑 public boolean filterDateRange(Object rowValue, Object filterValue, Locale locale) { // 过滤值为空直接返回匹配 if (filterValue == null) { return true; } Date rowDate = (Date) rowValue; List<Date> dateRange = (List<Date>) filterValue; if (dateRange.size() != 2 || dateRange.get(0) == null || dateRange.get(1) == null) { return true; } Date startDate = dateRange.get(0); Date endDate = dateRange.get(1); // 调整结束日期为当天23:59:59.999 Calendar cal = Calendar.getInstance(); cal.setTime(endDate); cal.add(Calendar.DAY_OF_MONTH, 1); cal.add(Calendar.MILLISECOND, -1); Date adjustedEnd = cal.getTime(); return rowDate.compareTo(startDate) >= 0 && rowDate.compareTo(adjustedEnd) <= 0; } }
方案2:前端调整参数(无需改后端)
如果不方便修改后端代码,可以在过滤请求提交前修改结束日期参数,给结束日期加1天,利用默认的小于逻辑实现小于等于原结束日期的效果:
- 首先在浏览器F12网络面板中触发一次过滤,查看提交的结束日期参数名,一般格式为
[表组件id]:[列field]_filter_end,示例中假设为inboxTable:dateCreated_filter_end - 替换原有JS逻辑:
function dateFilterChange(){ PF('inboxTableWidget').filter(); } // 监听过滤请求提交前事件,修改结束日期参数 $(document).on('pfAjaxBeforeSend', function(e, xhr, settings) { // 只处理你的表格过滤请求 if (!settings.data.includes('inboxTable:filter')) return; const params = new URLSearchParams(settings.data); const endDateParam = 'inboxTable:dateCreated_filter_end'; const originEnd = params.get(endDateParam); if (!originEnd) return; // 日期加1天 const endDate = new Date(originEnd); endDate.setDate(endDate.getDate() + 1); // 按组件配置的格式拼接新日期字符串 const newEnd = `${endDate.getFullYear()}/${String(endDate.getMonth() + 1).padStart(2, '0')}/${String(endDate.getDate()).padStart(2, '0')}`; // 替换参数 params.set(endDateParam, newEnd); settings.data = params.toString(); });
内容的提问来源于stack exchange,提问作者Mahmoud Saleh
相关产品推荐
相关产品推荐

