Widget refinementList - Color (name,hexacode)

Have the follow widget where the attribute/field color is a array of objects as follow:

  "color": [
    {
      "name": "Rosa",
      "hexa": "#FE2EF7"
    },
    {
      "name": "Azul",
      "hexa": "#0174DF"
    }
  ]

search.addWidget(
      instantsearch.widgets.refinementList({
        container: '#color_filter',
        attribute: 'color',
        templates: {
        	item(hit) { debugger; console.log(hit); return `
            	<button class="btn" group="brand" onclick="brandSelected(1);">${hit.label}<strong>${hit.count}</strong></button>
            `;
           }		
        },
      })
    );

and wanted in the template to get the color name and the color hexa code as well as the count. In case the attribute is ‘color.name’ it will get the name well but also want to get hexa code associated to that name…

if that is possible how to do so?

was able to make it work by adding in the name of color field the name and the hexacode seperated by ‘,’

  "color": [
    {
      "name": "Rosa,#FE2EF7",
      "hexa": "#FE2EF7"
    },
    {
      "name": "Azul,#0174DF",
      "hexa": "#0174DF"
    }
  ],

and the template

   templates: {
    	item(hit) { return `
        	<button class="btn" group="colour" onclick="brandSelected(1);" initialized="1"><span style="background:${hit.label.split(',')[1]}"></span>${hit.label.split(',')[0]}<strong>1</strong></button>
        `;
       }		
    },

but there must be a better way of doing this, if so please give a example.

Hi @henrique.corte,

Thanks for your question!

I’m glad to see that you got this working!

If you want to keep the attributes separate in your data, then the solution you have is probably the simplest.

The other option would be to combine the two attributes into one. You could still leave the other attributes if you need them for other reasons and just add a third attribute that combines the two:

"color": [
    {
      "name": "Rosa",
      "hexa": "#FE2EF7",
      "label": "Rosa, #FE2EF7"
    },
    {
      "name": "Azul",
      "hexa": "#0174DF",
      "label": "Azul, #0174DF"
    }
  ]

Then your refinementList could look like this:

search.addWidget(
  instantsearch.widgets.refinementList({
    container: '#brand-list',
    attribute: 'color.label',
  })
);

You can see a codesandbox here.
You could still add the template for the button.

Let us know how this works for you!
Best regards,

Thanks Cindy for the answer,

Used your solution of the label having the name and the hexa code combined instead of the name.

where my color widget read the attribute color.label as follow:

search.addWidget(
instantsearch.widgets.refinementList({
  container: '#color_filter',
  attribute: 'color.label',
    templates: {
    item(hit) { return `
      <button class="btn" group="colour" onclick="optionSelected({'type':'colors','name':'${hit.label.split(',')[0]}'})" initialized="1"><span 
      ${ (`${typeof hit.label.split(',')[1]}` != 'undefined') ?
          `style="background:${hit.label.split(',')[1]}"` : ''}
        ></span>${hit.label.split(',')[0]}<strong>${hit.count}</strong></button>
      `;
     }		
  },
})
);

and in my personalized search widget in the init have as follow to filter by the color.name instead of color.label:

  search.addWidget({
  init(opts) {
      const helper = opts.helper;

      opts.state.disjunctiveFacets.push('color.name');

...

      (typeof historyState.colors != 'undefined' ? historyState.colors.split(',').map( param => {
        if(param != ''){
          helper.addDisjunctiveFacetRefinement('color.name', decodeURIComponent(param));
        }
      }) : '') ; 

  helper.setQuery((typeof GetURLParameter('search') != 'undefined' ? GetURLParameter('search') : historyState.search)).search();

and it filter’s well but now since the widget of color look’s at the attribute of color.label instead of color.name it doesn’t appear with that option as selected.
How can I make it appear as selected now that I making the search by parameter color.name?

Hi @henrique.corte,

Would it be possible to create a codesandbox demonstrating the problem?

We have starter templates to help get you started.

Let us know when you have that ready!

Hi @cindy.cullen,

as follow the codesandbox the browser url must be https://3h9oq.csb.app/pesquisa-algolia?search=fatos so that will start by searching for the word ‘fatos’ .

Then it will appear 3 buttons to filter that are the colors ‘Unica’ that the count is 4, ‘Negro’ that the count is 1 and ‘Preto e Roxo’ that the count is 1, by selecting the first that is ‘Unica’ it will filter well and show only 4 products and the button text (of the button selected) as aqua color now if url is refresh it will still show the 4 products well but the button ‘Unica’ will not be showed as selected (should show as aqua color).

Following this question and anwser

Now have my color widget read the attribute color.label as follow:

search.addWidget(
instantsearch.widgets.refinementList({
  container: '#color_filter',
  attribute: 'color.label',
    templates: {
    item(hit) { return `
      <button class="btn" group="colour" onclick="optionSelected({'type':'colors','name':'${hit.label.split(',')[0]}'})" initialized="1"><span 
      ${ (`${typeof hit.label.split(',')[1]}` != 'undefined') ?
          `style="background:${hit.label.split(',')[1]}"` : ''}
        ></span>${hit.label.split(',')[0]}<strong>${hit.count}</strong></button>
      `;
     }		
  },
})
);

and in my personalized search widget in the init have as follow to filter by the color.name instead of color.label:

  search.addWidget({
  init(opts) {
      const helper = opts.helper;

      opts.state.disjunctiveFacets.push('color.name');

...

      (typeof historyState.colors != 'undefined' ? historyState.colors.split(',').map( param => {
        if(param != ''){
          helper.addDisjunctiveFacetRefinement('color.name', decodeURIComponent(param));
        }
      }) : '') ; 

  helper.setQuery((typeof GetURLParameter('search') != 'undefined' ? GetURLParameter('search') : historyState.search)).search();

and it filter’s well but now since the widget of color look’s at the attribute of color.label instead of color.name it doesn’t appear with that option as selected.
How can I make it appear as selected now that I making the search by parameter color.name?