Skip to content

Commit

Permalink
feat(searchBox): add headerFooter decorator to the Component
Browse files Browse the repository at this point in the history
Added to searchBox:
- templates.header
- templates.footer
- cssClasses.input

BREAKING CHANGE:
- removed: inputClass
  • Loading branch information
vvo committed Sep 24, 2015
1 parent 4291014 commit 5974a88
Show file tree
Hide file tree
Showing 7 changed files with 88 additions and 46 deletions.
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,27 @@ npm run test:watch # developer mode, test only

![Example of the searchBox widget][searchBox]


#### API

```js
/**
* Instantiate a searchbox
* @param {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {String} [options.placeholder='Search here'] Input's placeholder
* @param {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, input
* @param {String|String[]} [options.cssClasses.root=null]
* @param {String|String[]} [options.cssClasses.input=null]
* @param {Object} [options.templates] Templates to use for the widget
* @param {String|Function} [options.templates.header=''] Header template
* @param {String|Function} [options.templates.footer=''] Footer template
* @param {boolean} [poweredBy=false] Show a powered by Algolia link below the input
* @return {Object}
*/
```

#### Usage

```html
<div id="search-box"></div>
```
Expand Down
21 changes: 11 additions & 10 deletions components/SearchBox.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
var React = require('react');

var PoweredBy = require('./PoweredBy');
var headerFooter = require('../decorators/headerFooter');
var bem = require('../lib/utils').bemHelper('as-search-box');
var cx = require('classnames');

Expand All @@ -24,14 +25,12 @@ class SearchBox extends React.Component {
}

render() {
var classNames = cx(bem('input'), this.props.inputClass);

return (
<div>
<input type="text"
placeholder={this.props.placeholder}
name="algolia-query"
className={classNames}
className={cx(bem('input'), this.props.cssClasses.input)}
autoComplete="off"
autoFocus="autofocus"
onChange={this.handleChange.bind(this)}
Expand All @@ -47,16 +46,18 @@ class SearchBox extends React.Component {
}

SearchBox.defaultProps = {
onBlur: function() {},
onFocus: function() {}
onBlur() {},
onFocus() {}
};

SearchBox.propTypes = {
placeholder: React.PropTypes.string,
inputClass: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.array
]),
cssClasses: React.PropTypes.shape({
input: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.arrayOf(React.PropTypes.string)
])
}),
poweredBy: React.PropTypes.bool,
setQuery: React.PropTypes.func,
search: React.PropTypes.func,
Expand All @@ -65,4 +66,4 @@ SearchBox.propTypes = {
value: React.PropTypes.string
};

module.exports = SearchBox;
module.exports = headerFooter(SearchBox);
9 changes: 7 additions & 2 deletions example/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ search.addWidget(
instantsearch.widgets.searchBox({
container: '#search-box',
placeholder: 'Search for products',
cssClass: 'form-control',
cssClasses: {
input: 'form-control'
},
poweredBy: true
})
);
Expand Down Expand Up @@ -100,7 +102,10 @@ search.addWidget(
container: '#free-shipping',
facetName: 'free_shipping',
label: 'Free Shipping',
template: require('./templates/free-shipping.html')
templates: {
header: '<div class="panel-heading">Shipping</div>',
body: require('./templates/free-shipping.html')
}
})
);

Expand Down
9 changes: 1 addition & 8 deletions example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,7 @@ <h1>Instant search demo <small>using instantsearch.js</small></h1>

<div class="panel panel-default" id="price-range"></div>

<div class="panel panel-default">
<div class="panel-heading">Shipping</div>
<div class="panel-body">
<ul class="nav nav-stacked">
<li><div id="free-shipping"></div></li>
</ul>
</div>
</div>
<div class="panel panel-default" id="free-shipping"></div>

<div class="panel panel-default">
<div class="panel-heading">Price</div>
Expand Down
5 changes: 1 addition & 4 deletions example/templates/free-shipping.html
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
<div class="checkbox">
<div class="checkbox panel-body">
<label>
<input type="checkbox" {{#isRefined}}checked{{/isRefined}} />
<span class="badge">{{label}}</span>
</label>
</div>



62 changes: 40 additions & 22 deletions widgets/search-box.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,44 +2,62 @@ var React = require('react');

var utils = require('../lib/utils.js');

function searchbox(params) {
/**
* Instantiate a searchbox
* @param {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {String} [options.placeholder='Search here'] Input's placeholder
* @param {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, input
* @param {String|String[]} [options.cssClasses.root=null]
* @param {String|String[]} [options.cssClasses.input=null]
* @param {Object} [options.templates] Templates to use for the widget
* @param {String|Function} [options.templates.header=''] Header template
* @param {String|Function} [options.templates.footer=''] Footer template
* @param {boolean} [poweredBy=false] Show a powered by Algolia link below the input
* @return {Object}
*/
function searchbox({
container = null,
placeholder = 'Search here',
cssClasses = {
input: null,
root: null
},
templates = {
header: '',
footer: ''
},
poweredBy = false
}) {
var SearchBox = require('../components/SearchBox');

var container = utils.getContainerNode(params.container);
var containerNode = utils.getContainerNode(container);
var isFocused = false;

return {
init: function(initialState, helper) {
_render(state, helper) {
React.render(
<SearchBox
onFocus={()=> { isFocused = true; }}
onBlur={()=> { isFocused = false; }}
setQuery={helper.setQuery.bind(helper)}
search={helper.search.bind(helper)}
placeholder={params.placeholder}
inputClass={params.cssClass}
value={initialState.query}
poweredBy={params.poweredBy}
placeholder={placeholder}
templates={templates}
cssClasses={cssClasses}
value={state.query}
poweredBy={poweredBy}
/>,
container
containerNode
);
},

render: function({state, helper}) {
init(initialState, helper) {
this._render(initialState, helper);
},

render({state, helper}) {
if (!isFocused) {
React.render(
<SearchBox
onFocus={()=> { isFocused = true; }}
onBlur={()=> { isFocused = false; }}
setQuery={helper.setQuery.bind(helper)}
search={helper.search.bind(helper)}
placeholder={params.placeholder}
inputClass={params.cssClass}
value={state.query}
poweredBy={params.poweredBy}
/>,
container
);
this._render(state, helper);
}
}
};
Expand Down
7 changes: 7 additions & 0 deletions widgets/toggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,13 @@ function toggle({
}),
render: function({helper, results}) {
var isRefined = helper.hasRefinements(facetName);
var values = find(results.getFacetValues(facetName), {name: isRefined.toString()});

var facetValue = {
name: label,
isRefined: isRefined,
count: values && values.count || null
};

function toggleFilter() {
var methodToCall = isRefined ? 'removeFacetRefinement' : 'addFacetRefinement';
Expand Down

0 comments on commit 5974a88

Please sign in to comment.