Vaadin:过滤器的菊花链?
Vaadin: Daisy chain of filters?
我现在有这个特殊问题 - 我有一个网格,我试图通过多个过滤器过滤数据。为此,我使用文本框作为过滤条件的输入字段。
我的网格有三列(名字、姓氏、地址),我希望能够一个接一个地链接过滤操作。所有值均取自 MySQL 数据库。
基本上过滤过程应该是这样的:
FirstName ^ LastName ^ Address
例如,三列网格:
在 First Name 列的过滤器中,我输入了变量 Aa
,这将导致 table 看起来像这样:
但是,如果我决定将 D
输入到姓氏过滤器中,它 returns 结果如下(忽略第一个过滤器的修改):
而不是像这样的预期结果:
我通过网格过滤的方式是这样的:
firstNameFilter.addValueChangeListener( e->
{
Notification.show(e.getValue());
ldp.setFilter(desc ->
{
return StringUtils.containsIgnoreCase(desc.getFName(), firstNameFilter.getValue());
});
});
firstNameFilter.setValueChangeMode(ValueChangeMode.EAGER);
在考虑以前的过滤操作的同时过滤多列的最佳方法是什么?
listDataProvider.setFilter(...)
将覆盖任何现有过滤器。
我已经编写了 an answer about this very topic,其中包含可供复制粘贴的完整示例代码,以及显示多个过滤器按预期工作的屏幕截图。
它最重要的收获是:
Every time that any filter value changes, I reset the current filter using setFilter. But within that new Filter, I will check the values of ALL filter fields, and not only the value of the field whose value just changed. In other words, I always have only one single filter active, but that filter accounts for all defined filter-values.
这是您的代码的样子:
firstNameFilter.addValueChangeListener( e-> this.onFilterChange());
lastNameFilter.addValueChangeListener( e-> this.onFilterChange());
addressFilter.addValueChangeListener( e-> this.onFilterChange());
// sidenote: all filter fields need ValueChangeMode.EAGER to work this way
private void onFilterChange(){
ldp.setFilter(desc -> {
boolean fNameMatch = true;
boolean lNameMatch = true;
boolean addressMatch = true;
if(!firstNameFilter.isEmpty()){
fNameMatch = StringUtils.containsIgnoreCase(desc.getFName(), firstNameFilter.getValue());
}
if(!lastNameFilter.isEmpty()){
lNameMatch = StringUtils.containsIgnoreCase(desc.getLName(), lastNameFilter.getValue());
}
if(!addressFilter.isEmpty()){
addressMatch = StringUtils.containsIgnoreCase(desc.getAddress(), addressFilter.getValue());
}
return fNameMatch && lNameMatch && addressMatch;
});
});
我现在有这个特殊问题 - 我有一个网格,我试图通过多个过滤器过滤数据。为此,我使用文本框作为过滤条件的输入字段。
我的网格有三列(名字、姓氏、地址),我希望能够一个接一个地链接过滤操作。所有值均取自 MySQL 数据库。
基本上过滤过程应该是这样的:
FirstName ^ LastName ^ Address
例如,三列网格:
在 First Name 列的过滤器中,我输入了变量 Aa
,这将导致 table 看起来像这样:
但是,如果我决定将 D
输入到姓氏过滤器中,它 returns 结果如下(忽略第一个过滤器的修改):
而不是像这样的预期结果:
我通过网格过滤的方式是这样的:
firstNameFilter.addValueChangeListener( e->
{
Notification.show(e.getValue());
ldp.setFilter(desc ->
{
return StringUtils.containsIgnoreCase(desc.getFName(), firstNameFilter.getValue());
});
});
firstNameFilter.setValueChangeMode(ValueChangeMode.EAGER);
在考虑以前的过滤操作的同时过滤多列的最佳方法是什么?
listDataProvider.setFilter(...)
将覆盖任何现有过滤器。
我已经编写了 an answer about this very topic,其中包含可供复制粘贴的完整示例代码,以及显示多个过滤器按预期工作的屏幕截图。
它最重要的收获是:
Every time that any filter value changes, I reset the current filter using setFilter. But within that new Filter, I will check the values of ALL filter fields, and not only the value of the field whose value just changed. In other words, I always have only one single filter active, but that filter accounts for all defined filter-values.
这是您的代码的样子:
firstNameFilter.addValueChangeListener( e-> this.onFilterChange());
lastNameFilter.addValueChangeListener( e-> this.onFilterChange());
addressFilter.addValueChangeListener( e-> this.onFilterChange());
// sidenote: all filter fields need ValueChangeMode.EAGER to work this way
private void onFilterChange(){
ldp.setFilter(desc -> {
boolean fNameMatch = true;
boolean lNameMatch = true;
boolean addressMatch = true;
if(!firstNameFilter.isEmpty()){
fNameMatch = StringUtils.containsIgnoreCase(desc.getFName(), firstNameFilter.getValue());
}
if(!lastNameFilter.isEmpty()){
lNameMatch = StringUtils.containsIgnoreCase(desc.getLName(), lastNameFilter.getValue());
}
if(!addressFilter.isEmpty()){
addressMatch = StringUtils.containsIgnoreCase(desc.getAddress(), addressFilter.getValue());
}
return fNameMatch && lNameMatch && addressMatch;
});
});