Skip to content

Commit

Permalink
Merge pull request #62 from algolia/feature/indexSelector
Browse files Browse the repository at this point in the history
feat: indexSelector widget
  • Loading branch information
Vincent Voyer committed Sep 8, 2015
2 parents dabe537 + e7ac953 commit a52fb6d
Show file tree
Hide file tree
Showing 7 changed files with 152 additions and 1 deletion.
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,43 @@ search.addWidget(
);
```

### indexSelector

This widget will let you change the current index being targeted. This is
especially useful for changing the current sort order. If you need your results
ordered following a special rule (like price ascending or price descending),
you'll need several indices. This widget lets you easily change it.

![Example of the indexSelector widget](./docs/index-selector.jpg)

```html
<div id="index-selector"></div>
```

```javascript
search.addWidget(
instantsearch.widgets.indexSelector({
container: '#index-selector',
indices: [
{name: 'instant_search', label: 'Most relevant'},
{name: 'instant_search_price_asc', label: 'Lowest price'},
{name: 'instant_search_price_desc', label: 'Highest price'}
],
cssClass: 'form-control'
})
);
```

```javascript
/**
* Instantiate a dropdown element to choose the current targeted index
* @param {String|DOMElement} options.container Valid CSS Selector as a string or DOMElement
* @param {Array} options.indices Array of objects defining the different indices to choose from. Each object must contain a `name` and `label` key.
* @param {String} [options.cssClass] Class name(s) to be added to the generated select element
* @return {Object}
*/
```

### pagination

```html
Expand Down
37 changes: 37 additions & 0 deletions components/IndexSelector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
var React = require('react');

class IndexSelector extends React.Component {
handleChange(event) {
this.props.setIndex(event.target.value).search();
}

render() {
var currentIndex = this.props.currentIndex;
var indices = this.props.indices;
var cssClass = this.props.cssClass;
var selectId = this.props.containerId + '-select';

return (
<select
id={selectId}
className={cssClass}
onChange={this.handleChange.bind(this)}
value={currentIndex}
>
{indices.map(function(index) {
return <option key={index.name} value={index.name}>{index.label}</option>;
})}
</select>
);
}
}

IndexSelector.propTypes = {
containerId: React.PropTypes.string,
cssClass: React.PropTypes.string,
currentIndex: React.PropTypes.string,
indices: React.PropTypes.array,
setIndex: React.PropTypes.func
};

module.exports = IndexSelector;
Binary file added docs/index-selector.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions example/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@ search.addWidget(
})
);

search.addWidget(
instantsearch.widgets.indexSelector({
container: '#index-selector',
indices: [
{name: 'instant_search', label: 'Most relevant'},
{name: 'instant_search_price_asc', label: 'Lowest price'},
{name: 'instant_search_price_desc', label: 'Highest price'}
],
cssClass: 'form-control'
})
);

search.addWidget(
instantsearch.widgets.hits({
container: '#hits',
Expand Down
15 changes: 14 additions & 1 deletion example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,20 @@ <h1>Instant search demo <small>using instantsearch.js</small></h1>

</div>
<div class="col-md-9">
<div id="stats"></div>
<div class="row">
<div class="col-md-8">
<div id="stats"></div>
</div>
<div class="col-md-4 text-right">
<div class="form-inline">
<div class="form-group">
<label for="index-selector-select">Sort by:</label>
<span id="index-selector"></span>
</div>
</div>
</div>

</div>
<div id="hits"></div>
<div id="pagination" class="text-center"></div>
</div>
Expand Down
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ module.exports = {
InstantSearch: require('./lib/InstantSearch'),
widgets: {
hits: require('./widgets/hits'),
indexSelector: require('./widgets/index-selector'),
menu: require('./widgets/menu'),
multipleChoiceList: require('./widgets/multiple-choice-list'),
pagination: require('./widgets/pagination'),
Expand Down
51 changes: 51 additions & 0 deletions widgets/index-selector.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
var React = require('react');

var findIndex = require('lodash/array/findIndex');
var utils = require('../lib/widget-utils.js');

/**
* Instantiate a dropdown element to choose the current targeted index
* @param {String|DOMElement} options.container Valid CSS Selector as a string or DOMElement
* @param {Array} options.indices Array of objects defining the different indices to choose from. Each object must contain a `name` and `label` key.
* @param {String} [options.cssClass] Class name(s) to be added to the generated select element
* @return {Object}
*/
function indexSelector({
container = null,
cssClass = {},
indices = null
}) {
var IndexSelector = require('../components/IndexSelector');
var containerNode = utils.getContainerNode(container);

var usage = 'Usage: indexSelector({container, indices[, cssClass]})';
if (container === null || indices === null) {
throw new Error(usage);
}

return {
init: function(state, helper) {
var currentIndex = helper.getIndex();
var isIndexInList = findIndex(indices, {'name': currentIndex}) !== -1;
if (!isIndexInList) {
throw new Error('[stats]: Index ' + currentIndex + ' not present in `indices`');
}
},

render: function(results, state, helper) {
var containerId = containerNode.id;
React.render(
<IndexSelector
containerId={containerId}
cssClass={cssClass}
currentIndex={helper.getIndex()}
indices={indices}
setIndex={helper.setIndex.bind(helper)}
/>,
containerNode
);
}
};
}

module.exports = indexSelector;

0 comments on commit a52fb6d

Please sign in to comment.