Filter refinementLists by 'All'

I’ve been trying to work out a way to show all options available by adding an ‘All’ filter to my template. Essentially all I need to do is have a listener on my ‘All’ checkbox that calls a function to clear my currentRefinements, search based on that state then provide a UI indicator to show that ‘All’ is selected.

Below is the code I’m using but for the life of me I can’t figure out where to add my UI update. I’ve tried adding a class after doing helper.search(), adding a setTimeout that runs 2 seconds after helper.search() is run but I’m never able to add a class to my checkbox element.

// Clears any refined values.
function clearAllValues(event){
	// Clears Refinements
	helper.clearRefinements()
	// Searches based on new state and no refinements. Showing all options. BUT is also redrawing DOM.
	helper.search()
	// ISSUE is that I'm unable to simply add a UI state to the 'All' checkbox below.
	this.classList.add('checked')			
}

To reiterate, I know it has something to do with helper.search() redrawing or reloading the widgets but I’m not sure how to get round it, if I even can.

Hi there,
Thanks for reaching out to us.

I don’t know which flavor you’re using, so I’ve made an example in InstantSearch.js.

If you look at the source code,
All item is added by transformItems.

And there is searchFunction at instantsearch widget to intercept the search.
Inside it, it checks if there is ‘All’ refined, then it clears the refinements and keep searching.

Let me know how it goes and if you have more questions.

1 Like

Hi @eunjae.lee

Thank you for your suggestion. I am using vanilla js to build the widgets and logic. I’ve built the widget as a customised to handle different logic on mobile and desktop respectively.

Here is a small mockup of my code. So I’m checking the width then if it’s desktop filters will apply when they are selected. If the user is on mobile then the filters that are selected will be pushed into an array and then be refined when ‘apply’ is clicked.

My issue is that when I refine using ‘All’ the filters are cleared by my checkbox doesn’t have a class added due to the redraw. I can see how using transform items wil work if I use the widget but I’m not sure how to apply it to the custom UI method.

Hi @brendan.betheldo, I’m not sure I completely understand the issue at hand, but if you’re looking to create a custom UI for a widget the best way to do that by using a connector. For example connectRefinementlist will allow you to create your own RefinementList widget including all the HTML / classes involved but lying a top of the logic of a regular refinement list. Would that solve the need here?

Hi @maria.schreiber, I’m currently using connectRefinementlist to build my own refinementList. My issue is that when I click ‘All’ in my list and clear my refinements then research I’m unable to add a class or checked state to the ‘All’ checkbox to show that the checkbox is checked. Does that make sense?

Ah, sorry for being obtuse. I see what you mean now. I think what could be missing is the use of the isFirstRender parameter used to “do some initial rendering and bind events” as shown in this example: https://www.algolia.com/doc/api-reference/widgets/refinement-list/js/#full-example

Don’t hesitate to reach out if that’s still not doing the trick.

I completely forgot about that method. Honestly though, I’m not too sure what I should be binding inside that event to stop the redraw of my list widgets on search.

EDIT : After taking a walk and thinking about it: Do you mean I should render my ‘All’ boxes inside the isFirstRender check, and add the listeners there? If I did that would it mean I’d need to make one for every refinementList I had?

Hey @brendan.betheldo, sorry to leave you hanging there.

Upon further consideration, I think this can be done outside of isFirstRender.

What I did was just make the “checked” status dependent on whether or not

helper && helper.getRefinements(attribute).length ?

on line 57. This way the check is dynamically rendered based on whether there are currently refinements.

Does that accomplish what you’re looking for?

1 Like

Hi @maria.schreiber, that’s all good. That solution does help actually! Is there a way to have the checkboxes reset their sibling lists? For example if I check ‘All’ in brand have it not effect categories? Thanks so much for your help.

I’ve tried passing the attribute to a function that uses clearRefinements(attribute).search() but that still seems to reset all refinementLists.

Good catch! That’s happening since the event listener is listening and acting on any time an input.filter-all is clicked.

I’ve added an additional className (line 61) and a way to use that class name to extract the attribute to clear (38 - 41) to handle that.

1 Like

That’s awesome. Then on mobile I can just pass that same element into the clearAll function to do them in bulk. The only question I have is; Why when I passed clearRefinements(attribute)were all the values being cleared? I get that I was watching all ‘All’ checkboxes but I thought passing the attribute I want to clear would be specific enough?

1 Like

Hi @brendan.betheldo - it’s possible that there is a syntax issue.

The clearRefinements() option in InstantSearch.js takes an object with keys, for example:

clearRefinements({
  // ...
  includedAttributes: ['myAttribute'],
});

Can you share with us what syntax you are using, and the documentation that you are following? Thanks!

Hi @ajay.david and @maria.schreiber, I think I was just working too fast and not saving properly. Essentially I added a shorthand variable var widgetAttrs = widgetParams.attribute; which was the correct value I needed but I think I kept trying to use widgetParams where it wasn’t available which threw the error.

Huh, when I do put (attribute) in on line 43, it actually works as expected: https://codesandbox.io/s/instantsearchjs-app-qd4zz

Should’ve tried that before adding in the additional class. :wink:

Could you share an example when it was not working @brendan.betheldo ?

@maria.schreiber check my post above yours. :slight_smile:
Just working too quickly and not waiting for compiler to finish.

1 Like

:+1:, my bad for not even checking!