algolia / instantsearch

⚡️ Libraries for building performant and instant search and recommend experiences with Algolia. Compatible with JavaScript, TypeScript, React and Vue.
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/js/
MIT License
3.59k stars 504 forks source link

Api proposal: Wrapper widget #111

Closed maxiloc closed 8 years ago

maxiloc commented 8 years ago

The idea is to provide a way to have a widget that handle a set of widget. This will allow to have less selector by grouping widgets. The first example that comes to my mind is facet widgets but I can see myself grouping stats and hits for example.

Here the api proposal:

var widgets = [];

widgets.push(instantsearch.widgets.refinementList({
    facetName: 'brands',
    operator: 'and'
  })
);

widgets.push(instantsearch.widgets.refinementList({
    facetName: 'price',
    operator: 'or'
  })
);

search.addWidget(
 instantsearch.widgets.wrapper({
    container: '#sidebar',
    widgets: widgets
 })
);

Resulting dom

Just a concatenation of each widget html

What do you think ?

vvo commented 8 years ago

Can you precise your examples showing how widgets: widgets is generated.

And add the resulting DOM generated by it.

maxiloc commented 8 years ago

Just updated the proposal

pixelastic commented 8 years ago

Could you explain the use-cases where this is better than:

<div id="sidebar">
  <div id="brands"></div>
  <div id="price"></div>
</div>
instantsearch.widgets.refinementList({
  container: '#brands',
  facetName: 'brands',
  operator: 'and'
});
instantsearch.widgets.refinementList({
  container: '#price',
  facetName: 'price',
  operator: 'or'
});

I remember this had to do with the Magento/WP implementation, but I don't remember why.

maxiloc commented 8 years ago

Facet in integration are implemented in a generic way. So right now the dom <div id="brands"></div> and <div id="price"></div> need to be generated because we do not know the name and number of facet in advance. This will avoid that

vvo commented 8 years ago

need to be generated because we do not know the name and number of facet in advance

Ok so this is a way to avoid doing yourself something like document.createElement('div') etc..?

The proposal would introduce "you can create a widget without a container".

This is something hard to manage: you then need to "detect" when it's inserted into the DOM or provide an API to indicate that you inserted it into the DOM (widget.ready()..).

This would complexify quite a bit the interface.

What we should do is provide a helper inside the integrations bundle that will take care of this: dynamically create containers and widgets given a big configuration object.

Then we will see if the "here's a big configuration object, instantiate me an instantsearch.js" makes sense in the instantsearch.js API.

what do you think?

maxiloc commented 8 years ago

Yes that makes sense

vvo commented 8 years ago

Underlying code for such a helper (currently to be implemented in integrations):

var $siderbar = document.querySelector('#sidebar');
[{type: 'rangeSlider', configuration: {facetName: 'price'}}, /*...*/].forEach(function(widget) {
  var container = $siderbar.appendChild(document.createElement('div'));
  widget.configuration.container = container;

  instantsearch.addWidget(instantsearch.widgets[widget.type](widget.configuration))
});