Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create a select dropdown with Algolia InstantSearch.JS

After a few days of creating an Algolia search form, now struggling with trying to create a simple select field with a list of colours. The colour list itself is approx 50 colours long so typing this as options is not really an option, plus these change daily.

I've managed to get a price range slider on there and pull through the options of the colour but I now need to loop through the colours and either return '...' and put within '' or create the select field itself.

So far, I've got:

search.addWidget(
  instantsearch.widgets.menu({
    container: '#colour',
    attributeName: 'colour',
    limit: 10,
    indices: {
      header: 'Colour'
    }
  })
);

Is there anyway to reformat this into a select field? Also, the colour ranges still need to be selectable after one has already been selected so the end user can just change.

Any guidance or help would be hugely appreciated.

Thanks!

like image 876
JonnyT Avatar asked Mar 12 '23 10:03

JonnyT


1 Answers

That's possible with InstantSearch.js' connectors. What you do is in the first render make a select, and on subsequent renders you change the value of the <option>s

import instantsearch from 'instantsearch.js';

function render(
  {items, refine, widgetParams: {containerNode, title}},
  isFirstRendering
) {
  let select;
  if (isFirstRendering) {
    const header = document.createElement('div');
    header.innerText = title;
    containerNode.appendChild(header);
    select = document.createElement('select');

    select.addEventListener('change', e => refine(e.target.value));

    containerNode.appendChild(select);
  } else {
    select = containerNode.querySelector('select');
  }

  const options = items.map(item => {
    const option = document.createElement('option');

    option.innerText = `${item.label} ${item.count}`;
    option.value = item.value;
    option.selected = item.isRefined;

    return option;
  });

  select.textContent = '';
  options.forEach(el => select.appendChild(el));
}

export default instantsearch.connectors.connectMenu(render);

You can then call this connected menu via the following way:

import selectMenu from './custom-widgets/selectMenu.js';

search.addWidget(selectMenu({
  containerNode: document.getElementById('#menu'),
  attributeName: 'brand',
  limit: 10,
  title: 'Brands',
}));

I know it's quite late, but let me know if this helps!

  • https://community.algolia.com/instantsearch.js/v2/guides/customization.html
  • https://community.algolia.com/instantsearch.js/v2/connectors/connectMenu.html
like image 166
Haroen Viaene Avatar answered Mar 22 '23 23:03

Haroen Viaene