Change operator from or to and refine the result in Refinement List

Hi,
I am using RefinementList to filtering facets in algolia. Currently I am using algolia default “operator:or” for facets filtering in the RefinementList. There is a requirement to filter the same facets with the operator “and” and “or” with a toggle switch as below. When the toggle is on the facets need to filter with “and” operator and when it is off it should be filtering with “or” operator.
image

I need to achieve this without re initiating the search filter or without reloading the page. When the toggle is changing I am trying to update the operator parameter in refinement list widget according to the toggle changed value. However it is not updating when I use search.refresh(); I need to know is there a way to update or refresh the refinement list widget parameter operator.

My code is as below.

Widget parameter options as below

let widgets = [
                genreFilterWidget({ attribute: 'genres.name',
                                    sortBy: ["name:asc","count:desc"],  
                                    limit: 100, 
                                    operator: this.facetsOperator,
                                    afterAndOrButtonToggled: this.afterFilterAndOrButtonToggled.bind(this),

                }),];

After toggle switch changed it is passing the operator for widget parameters as below.

afterFilterAndOrButtonToggled(isChecked) {

            this.facetsOperator = (isChecked) ? 'and':'or';
            this.searchWidget.refresh();
        }

Rendering part as below

renderFilterWidgetFilterItemTemplate(refinementListRenderingOptions,isFirstRendering,) {
		const {items,refine,createURL,searchForItems,widgetParams,instantSearchInstance} = refinementListRenderingOptions;

		let {filterPlaceHolderText,showCountLabel,customLabels,tooltipOptions,switchTitle,afterAndOrButtonToggled,operator,} = widgetParams;

		if (isFirstRendering) {

			if (this.toggleEnabled) {
				const trigger_element = $(".filter_types").find(
					`.item .filter-btn[data-filter-id=${this.listContainer}]`,
				);
				this.loadToggleFilterTemplate(tooltipOptions, switchTitle);
				

				$(`#${this.listContainer}_popover .toggle_switch_wrapper .slide`)
					.off("click")
					.on("click", (e) => {
						const checkbox = $(
							`#${this.listContainer}_popover .toggle_switch_wrapper .toggle_filter_select`,
						);
						$(checkbox).trigger("click");
					});

				$(`#${this.listContainer}_popover #toggle_filter_select`)
					.off()
					.on("change", (e) => {
						if (typeof afterAndOrButtonToggled === "function") {
							const isToggleChecked = $(e.target).is(":checked");

							if (isToggleChecked) {
								operator = 'and';
							}else {
                                operator = 'or';
                            }
							afterAndOrButtonToggled(isToggleChecked);
						}
					});
			}
		}
}

I need to know how to refine the data as per the updated operator parameter. I very much appreciate if you can provide a solution in this regard.

Thanks.

Hi @adheesha, could you provide a codesandbox to demonstrate the issue? This will help with troubleshooting. We have a boilerplate here to help you get started.

Hi Cindy,

Thanks for your reply. I have updated the code here. Based on “And/Or” checkbox button change we need to update facets operator so then we will be able to change the facets operator dynamically.

Widget parameters are not evaluated constantly, but only on addition of the widget. However, what you can do is similar to how Vue InstantSearch deals with changes in widget parameters. In pseudo code:

let widget;
let lastOperator;
function onUpdate(operator) {
  if (operator === lastOperator) return;
  if (widget) search.removeWidgets([widget]);
  widget = refinementList({ operator, ...defaultArguments });
  search.addWidgets([widget]);
  lastOperator = operator;
}

onUpdate('and');

Hi @haroen ,

Thanks for the explanation. I have tried this and I am getting this error “The widget definition expects a dispose method.” while using removeWidgets function.

Can you please advise how to resolve this?

the custom widget you made isn’t following the specifications in that case @adheesha, please see instantsearch.js/connectRefinementList.ts at master · algolia/instantsearch.js · GitHub or Create Your Own Widgets | Building Search UI | Guide | Algolia Documentation

Hi @haroen ,
I was able to resolve this issue. Thanks for your help.

1 Like