Is there any simple way to have the menu widget appear as a select field? Also to have the first option to be "All" that would remove the refinement?
Hi, do you mean you would want the menu to have the form of a <select> element?
Exactly. But I also want to have the first and default item to be "All" where the refinement is removed.
@candypaint I must say you will have to implement this widget yourself using our:
This is basically the only tools we use to build custom widgets. If you have some coding experience this is feasible.
Let's say you want to build a menu on the "categories" attribute name:
getConfigurationWe want to inform the helper that we want to add a new attribute for faceting.
var selectCategories = {
getConfiguration: function() {
return {
hierarchicalFacets: [{
name: 'categories',
attributes: ['categories']
}]
}
}
};
initWe will bind the change event on the select and refine the value using the helper.
Here's the select html that you need to put in your page
<select id="select-categories"></select>
The the widget code you complete:
var selectCategories = {
getConfiguration...,
$selectCategories: document.querySelector('#select-categories'),
this._refine: function(helper, changeEvent) {
// this is where we refine the categories
helper.toggleRefinement('categories', changeEvent.target.value);
// now trigger a new search
helper.search();
},
init: function(params) {
this._refine = this._refine.bind(this, params.helper);
// regular HTML/JS coding to create or bind to an existing select box change event
this.$mySelect.addEventListener('change', this._refine);
}
};
renderWe are going to rebuild the select values at each new result set, be it an action on the select or a new query or an action on another widget.
var selectCategories = {
getConfiguration...,
$selectCategories...,
this._refine...,
init...,
render: function(params) {
var hasCategorySelected = params.helper.hasRefinements('categories');
var all = {name: 'All', value: ''};
if (!hasCategorySelected) {
all.isRefined = true;
}
var results = [all];
results = results.concat(params.results.getFacetValues('categories').data || []);
var selectValues = results.map(function(result) {
return '<option value="' + result.value + '"' + result.isRefined ? ' selected' : '' + '>' + result.name + '<option>';
});
this.$selectCategories.innerHTML = selectValues;
}
};
addWidgetsearch.addWidget(selectCategories);
search.start(); // should already be present in your page
Some steps might not be accurate and the code might fail but that's the general idea. If you have any question, add it here.
Thanks. Got the idea.
I still think you should consider having it built in as a option. The long list of categories for refinement is not practical in most cases for mobile.
@candypaint That's a good idea. We are currently not focused enough on mobile indeed.
yes @vvo this would be very nice as a basic builtin for instantsearch.js. Would make Algolia instantsearch.js a lot more mobile friendly, which would of course help the bulk of our 1m+ monthly unique users.
See #1904, thanks for feedback
Super, thank you @vvo!
@vvo
Is there support for converting a numericRefinementList into a numericSelector or menuSelector?
For example, my widget options look like this:
options: [
{name: 'Any'},
{start: (timeNow-86400), end: timeNow, name: 'Past 24 hours'},
{start: (timeNow-592200), end: timeNow, name: 'Past Week'}
]
Hi @Brotakuu. Can you describe in more details what would you like to achieve?
@bobylito I'm looking for the same. Basically, we want to show numericRefinementList as a select instead of a list of radio buttons. Would be great if it was a mode.
@sjelfull you can use connectNumericRefinementList and make it into a select. I鈥檓 on my phone now but the example in the documentation is exactly that, but you just need to change the DOM tags.
That looks perfect - i'll take a look.