Vaadin 15 Grid日期列如何实现按输入日期筛选截至今日的数据范围
解决方案
你原有代码是针对字符串类型字段做模糊匹配的逻辑,完全不适用日期范围筛选场景。推荐优先使用Vaadin自带的DatePicker组件替代TextField,可以避免手动处理日期格式校验、解析的问题,实现逻辑如下:
// 替换原有TextField为DatePicker,指定日期显示格式 DatePicker casDatePicker = new DatePicker(); casDatePicker.setPlaceholder("请选择起始日期"); // 将DatePicker绑定到对应列的筛选区域,替换原有getFilters返回的TextField casColumn.setHeader(casDatePicker); LocalDate today = LocalDate.now(); // 添加值变化监听实现范围筛选 casDatePicker.addValueChangeListener(event -> { LocalDate inputStartDate = event.getValue(); // 先移除所有之前添加的cas相关筛选,避免重复叠加失效 data.removeFilter(filter -> filter.getClass().getName().contains("CasFilter")); if (inputStartDate != null) { data.addFilter(dataRecord -> { LocalDate recordDate = dataRecord.getCas(); // 筛选逻辑:记录日期 >= 输入起始日期 且 <= 今日 return !recordDate.isBefore(inputStartDate) && !recordDate.isAfter(today); }); } });
如果因业务要求必须使用TextField输入日期,需要额外加日期格式校验和解析逻辑,示例如下:
TextField cas = getFilters(casColumn, filter); cas.setPlaceholder("请输入yyyy-MM-dd格式的日期"); DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); LocalDate today = LocalDate.now(); cas.addValueChangeListener(event -> { String inputText = event.getValue(); data.removeFilter(filter -> filter.getClass().getName().contains("CasFilter")); if (StringUtils.isBlank(inputText)) { cas.setInvalid(false); return; } try { LocalDate inputStartDate = LocalDate.parse(inputText, dateFormatter); cas.setInvalid(false); data.addFilter(dataRecord -> { LocalDate recordDate = dataRecord.getCas(); return !recordDate.isBefore(inputStartDate) && !recordDate.isAfter(today); }); } catch (DateTimeParseException e) { // 格式错误时给用户提示 cas.setErrorMessage("日期格式错误,请输入yyyy-MM-dd格式"); cas.setInvalid(true); } });
注意事项
- 如果你的实体类中cas字段是
LocalDateTime或者Date类型,需要先统一转换为LocalDate类型再做比较,避免时区或者时间部分导致的判断误差 - 每次添加新筛选前必须先移除同规则的旧筛选,否则多次修改筛选值会导致筛选逻辑叠加失效
- 优先使用
DatePicker组件,无需额外处理格式校验和解析问题,用户体验更好
推荐学习资料
- Vaadin 15 官方文档中 DataProvider 筛选相关章节
- Java 8+ 日期时间API(LocalDate、DateTimeFormatter)官方教程
- Vaadin 组件库 DatePicker 组件使用说明
内容的提问来源于stack exchange,提问作者Mr Anderson
相关产品推荐
相关产品推荐

