Vaadin 8 Grid Filtering across columns

I have a grid with a textfield, combo box and button that depending on the selection in the combo it applies the correct filter to the grid that matches the column selected in the combobox. However if I want to search across all columns for the phrase in the textfield, I dont know exaclt how to do this. I tried using a bunch of addFilter calls, and while one will return true, the others will return false and the row will be filtered out.

How can I filter across all columns where if any of the filters match it keeps the row?

Below is my code:

//query text field
        TextField queryBar = new TextField("Search Terms");
        queryBar.setPlaceholder("Enter search terms");
        queryBar.setWidth(100, Unit.PERCENTAGE);
        searchWrapper.addComponent(queryBar);

        //category drop down
        //XXX:This is for debug only
        List<String> values = new ArrayList<>();
        values.add("First Name");
        values.add("Last Name");
        values.add("Tech Topic");
        values.add("Organization");
        values.add("Email");

        ComboBox categorySelect = new ComboBox("Category");
        categorySelect.setPlaceholder("All Categories");
        //categorySelect.setReadOnly(true);
        categorySelect.setItems(values);
        searchWrapper.addComponent(categorySelect);

        //search button
        Button searchButton = new Button("Search");
        searchWrapper.addComponent(searchButton);
        searchButton.addClickListener((event) -> {
            ListDataProvider<Person> dataProvider = (ListDataProvider<Person>) grid.getDataProvider();

            //build and apply the correct filter
            if (categorySelect.getValue() == null || categorySelect.getValue().toString().isEmpty()) {
                //add all filters    
                dataProvider.addFilter(Person::getFirstName, s -> caseInsensitiveContains(s, queryBar.getValue()));
                dataProvider.addFilter(Person::getLastName, s -> caseInsensitiveContains(s, queryBar.getValue()));
                dataProvider.addFilter(Person::getTechnicalTopics, s -> caseInsensitiveListContains(s, queryBar.getValue()));
                dataProvider.addFilter(Person::getEmail, s -> caseInsensitiveContains(s, queryBar.getValue()));
            } else {
                //More will need to go here eventually
                if ("First Name".equals(categorySelect.getValue().toString())) {
                    dataProvider.setFilter(Person::getFirstName, s -> caseInsensitiveContains(s, queryBar.getValue()));
                } else if ("Last Name".equals(categorySelect.getValue().toString())) {
                    dataProvider.setFilter(Person::getLastName, s -> caseInsensitiveContains(s, queryBar.getValue()));
                } else if ("Tech Topic".equals(categorySelect.getValue().toString())) {
                    dataProvider.setFilter(Person::getTechnicalTopics, s -> caseInsensitiveListContains(s, queryBar.getValue()));
                } else if ("Email".equals(categorySelect.getValue().toString())) {
                    dataProvider.setFilter(Person::getEmail, s -> caseInsensitiveContains(s, queryBar.getValue()));
                }
            }
            dataProvider.refreshAll();
        });

//******************CONTAINS METHODS*************************/

/**
     * Checks to see if one string contains the other regarless of case
     *
     * @param where
     * @param what
     * @return
     */
    private Boolean caseInsensitiveContains(String where, String what) {
        return where.toLowerCase().contains(what.toLowerCase());
    }

    /**
     * Checks to see if the string array contains the target regardless of case
     *
     * @param where
     * @param what
     * @return
     */
    private Boolean caseInsensitiveListContains(String[] where, String what) {
        boolean flag = false;
        for (int i = 0; i < where.length; i++) {
            if (where[i]
.toLowerCase().contains(what.toLowerCase())) {
                flag = true;
                break;
            }
        }
        return flag;
    }

Hi Gary,

Instead of using multiple
addFilter(ValueProvider, Predicate)
you should use
addFilter(Predicate)
and extract and compare the values inside the predicate itself. That way you have control over what does it mean to check multiple fields at the same time. By default multiple filters are chained together with an "
AND
" and not "
OR
" so any filter not matching will remove the row from the filtered result set.

//Teemu