How to clear selected refinements for a specific attribute?

Hi,

I’m using a custom refinement list for a specific attribute.
What I want is add a “clear” button just below values.
This way user can clear his current selection for this specific attribute.
I’m not using the “currentRefinements” widget.
I’ve tried refine(null)and refinde('') but it’s doesn’t work.

Thanks.

import instantsearch from 'instantsearch.js';
import { connectRefinementList } from 'instantsearch.js/es/connectors';

// 1. Create a render function
const renderRefinementList = (renderOptions, isFirstRender) => {
  const {
    items,
    isFromSearch,
    refine,
    createURL,
    isShowingMore,
    canToggleShowMore,
    searchForItems,
    toggleShowMore,
    widgetParams,
  } = renderOptions;

  const container = document.querySelector(widgetParams.container);

  if (isFirstRender) {
    const ul = document.createElement('ul');
    const btnClose = container.querySelector('button.save').addEventListener('click', function() {
      if(!container.classList.contains('active')) {
        container.classList.add('active');
      }
    });
    const btnClear = container.querySelector('button.clear').addEventListener('click', function() {
      refine(null);
    });


    // input.addEventListener('input', event => {
    //   searchForItems(event.currentTarget.value);
    // });

    console.log('rendering...');
  }

  container.querySelector('ul').innerHTML = items
    .map(
      item => `
        <li>
          <a
            href="${createURL(item.value)}"
            data-value="${item.value}"
            class="${item.isRefined ? 'selected' : ''}"
          >
            ${item.label} <span class="${item.isRefined ? 'text-white' : 'text-red'} font-semibold">${item.count}</span>
          </a>
        </li>
      `
    )
    .join('');

  let countActiveFilters = 0;
  items.forEach(function(item) {
    if(item.isRefined) {
      countActiveFilters++;
    }
  });

  if(countActiveFilters === 0) {
    container.classList.remove('active--filters');
    container.querySelector('.btn-filter').innerHTML = `${container.dataset.title}`;
  } else if (countActiveFilters >= 1) {
    container.classList.add('active--filters');
    container.querySelector('.btn-filter').innerHTML = `${container.dataset.title} • ${countActiveFilters}`;
  }


  [...container.querySelectorAll('a')].forEach(element => {
    element.addEventListener('click', event => {
      event.preventDefault();
      refine(event.currentTarget.dataset.value);
    });
  });
};

const customRefinementList = connectRefinementList(
  renderRefinementList
);

export {renderRefinementList, customRefinementList};

Hi there,

Thank you for reaching out!

You can clear the refinements currently set by using the clearRefinements widget. If you want to limit this widget to only one refinement, you can use the includeAttributes parameter for this widget. If you want to have this functionality for multiple refinements, you can create multiple instances of this widget.

Hope this helps!

Cheers,

Hi,
Thanks for your anwser.
Does it mean if I have 10 attributes, I need to declare 10 custom refinements widgets + 10 clear refinements widgets ?
I can’t do it directly in my custom refinements widget ?
Because basically, clearing user selection is like clicking on each selected item…

Hi,

Indeed, you can’t do this directly from the refinement widgets. If you want to clear all the refinements at once, a single widget will do. If you want a button like this for each refinement, you would have to create 10 widgets indeed.

Hope this helps!

Hi @hjerem and @devin.beeuwkes, I’ve been banging my head against this for the last few days, @maria.schreiber helped me come up with a pretty great idea. It’s using the functionality of the customRefinementLists and different logic for desktop vs mobile but the desktop stuff @maria.schreiber worked out is exactly what you’d need @hjerem.

1 Like