AddSearch / search-ui

JavaScript library to develop Search UIs for the web
https://www.addsearch.com/
MIT License
24 stars 4 forks source link

Configurable filter logic #78

Closed Etroid closed 2 years ago

Etroid commented 2 years ago

When using checkbox filters, I've noticed that the logic defaults to "OR". Is there a way to change this to "AND" for specific use cases?

searchui.filters({
        containerId: 'checkbox-container',
        type: AddSearchUI.FILTER_TYPE.CHECKBOX_GROUP,
        options: {
          pricing: {
            label: 'Pricing',
            filter: {"category": "1xpricing"}
          },
          partners  : {
            label: 'Partners',
            filter: {"category": "1xpartners"}
          },
          customers: {
            label: 'Customers',
            filter: {"category": "1xcustomers"}
          }
        }
      });

In the above example I'd like each selection to filter the result list down. If I select pricing and partners I want to see content tagged with both.

anttiai commented 2 years ago

Hey. First of all, you should use custom fields for filtering. In your example, simple URL filters (like 1xpricing) mean that the first part (i.e. 1x) of the URL path equals pricing (e.g. domain.com/pricing). As documents can't have multiple URLs, the AND filter (1xpricing AND 1xpartners) wouldn't match anything.

Anyway, there are two ways to achieve what you asked:

1) The easiest way is to create a separate filter component for each filter. Filters in a single filter component share OR logic, but the default logic across different components is AND.

// Pricing
searchui.filters({
  containerId: 'checkbox-container-pricing',
  type: AddSearchUI.FILTER_TYPE.CHECKBOX_GROUP,
  options: {
    pricing: {
      label: 'Pricing',
      filter: {"category": "1xpricing"}
    }
  }
});

// Partners
searchui.filters({
  containerId: 'checkbox-container-partners',
  type: AddSearchUI.FILTER_TYPE.CHECKBOX_GROUP,
  options: {
    pricing: {
      label: 'Partners',
      filter: {"category": "1xpartners"}
    }
  }
});

// etc..

2) It's also possible to override the function that constructs the filtering object in the SearchUI library. The default createFilterObject can be copied, modified, and passed to AddSearchUI constructor in a setting named createFilterObjectFunction:

var conf = {
  createFilterObjectFunction: customCreateFilterObject
};

var searchui = new AddSearchUI(client, conf);

Basically, you would need to modify the OR operator to AND here.

By the way, Facets could be a valid option to achieve what you asked as well.