Skip to content

Commit b3ef871

Browse files
committed
feat(searchBox): ability to be non-instant
If `searchOnEnterKeyPressOnly` is set to true, the search is only triggered if ENTER is pressed. - Added some tests on even registration - Removed an outdated version of the searchbox that was at the root level of the widgets/ directory. - Updated jsdoc Fix #458
1 parent 68adc0d commit b3ef871

File tree

4 files changed

+86
-107
lines changed

4 files changed

+86
-107
lines changed

docs/_includes/widget-jsdoc/searchBox.md

+5-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
| <span class='attr-required'>`options.container`</span> | CSS Selector or DOMElement to insert the widget |
44
| <span class='attr-optional'>`options.placeholder`</span> | Input's placeholder |
55
| <span class='attr-optional'>`options.cssClasses`</span> | CSS classes to add |
6+
| <span class='attr-optional'>`options.cssClasses.root`</span> | CSS class to add to the wrapping div (if wrapInput set to `true`) |
67
| <span class='attr-optional'>`options.cssClasses.input`</span> | CSS class to add to the input |
78
| <span class='attr-optional'>`options.cssClasses.poweredBy`</span> | CSS class to add to the poweredBy element |
8-
| <span class='attr-optional'>`options.poweredBy`</span> | Show a powered by Algolia link below the input |
9-
| <span class='attr-optional'>`options.autofocus`</span> | autofocus on the input |
9+
| <span class='attr-optional'>`poweredBy`</span> | Show a powered by Algolia link below the input |
10+
| <span class='attr-optional'>`wrapInput`</span> | Wrap the input in a div.ais-search-box |
11+
| <span class='attr-optional'>`autofocus`</span> | autofocus on the input |
12+
| <span class='attr-optional'>`searchOnEnterKeyPressOnly`</span> | If false, trigger the search once <Enter> is pressed only |
1013

1114
<p class="attr-legend">* <span>Required</span></p>

widgets/search-box.js

-101
This file was deleted.

widgets/search-box/__tests__/search-box-test.js

+70
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ describe('search-box()', () => {
3232
};
3333
helper = {
3434
on: sinon.spy(),
35+
setQuery: sinon.spy(),
36+
search: sinon.spy(),
3537
state: {
3638
query: ''
3739
}
@@ -166,6 +168,74 @@ describe('search-box()', () => {
166168
});
167169
});
168170

171+
context('keyup', () => {
172+
let input;
173+
beforeEach(() => {
174+
container = document.createElement('div');
175+
input = createHTMLNodeFromString('<input />');
176+
input.addEventListener = sinon.spy();
177+
});
178+
179+
context('instant search', () => {
180+
beforeEach(() => {
181+
widget = searchBox({container, autofocus: 'auto'});
182+
widget.getInput = sinon.stub().returns(input);
183+
});
184+
185+
it('performs the search on keyup', () => {
186+
// Given
187+
helper.state.query = 'foo';
188+
// When
189+
widget.init(initialState, helper);
190+
// Then
191+
expect(input.addEventListener.called).toEqual(true);
192+
expect(input.addEventListener.args[0].length).toEqual(2);
193+
expect(input.addEventListener.args[0][0]).toEqual('keyup');
194+
let fn = input.addEventListener.args[0][1];
195+
fn({});
196+
expect(helper.setQuery.calledOnce).toBe(true);
197+
expect(helper.search.calledOnce).toBe(true);
198+
});
199+
});
200+
201+
context('non-instant search', () => {
202+
beforeEach(() => {
203+
widget = searchBox({container, autofocus: 'auto', searchOnEnterKeyPressOnly: true});
204+
widget.getInput = sinon.stub().returns(input);
205+
});
206+
207+
it('performs the search on <ENTER>', () => {
208+
// Given
209+
helper.state.query = 'foo';
210+
// When
211+
widget.init(initialState, helper);
212+
// Then
213+
expect(input.addEventListener.called).toEqual(true);
214+
expect(input.addEventListener.args[0].length).toEqual(2);
215+
expect(input.addEventListener.args[0][0]).toEqual('keyup');
216+
let fn = input.addEventListener.args[0][1];
217+
fn({keyCode: 13});
218+
expect(helper.setQuery.calledOnce).toBe(true);
219+
expect(helper.search.calledOnce).toBe(true);
220+
});
221+
222+
it('doesn\'t perform the search on keyup', () => {
223+
// Given
224+
helper.state.query = 'foo';
225+
// When
226+
widget.init(initialState, helper);
227+
// Then
228+
expect(input.addEventListener.called).toEqual(true);
229+
expect(input.addEventListener.args[0].length).toEqual(2);
230+
expect(input.addEventListener.args[0][0]).toEqual('keyup');
231+
let fn = input.addEventListener.args[0][1];
232+
fn({});
233+
expect(helper.setQuery.calledOnce).toBe(true);
234+
expect(helper.search.calledOnce).toBe(false);
235+
});
236+
});
237+
});
238+
169239
context('focus', () => {
170240
let input;
171241
beforeEach(() => {

widgets/search-box/search-box.js

+11-4
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ let forEach = require('lodash/collection/forEach');
55
let bem = require('../../lib/utils').bemHelper('ais-search-box');
66
let cx = require('classnames');
77

8+
const KEY_ENTER = 13;
9+
810
/**
911
* Instantiate a searchbox
1012
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
@@ -16,6 +18,7 @@ let cx = require('classnames');
1618
* @param {boolean} [poweredBy=false] Show a powered by Algolia link below the input
1719
* @param {boolean} [wrapInput=true] Wrap the input in a div.ais-search-box
1820
* @param {boolean|string} [autofocus='auto'] autofocus on the input
21+
* @param {boolean} [searchOnEnterKeyPressOnly=false] If set, trigger the search once <Enter> is pressed only
1922
* @return {Object}
2023
*/
2124
function searchBox({
@@ -24,10 +27,11 @@ function searchBox({
2427
cssClasses = {},
2528
poweredBy = false,
2629
wrapInput = true,
27-
autofocus = 'auto'
30+
autofocus = 'auto',
31+
searchOnEnterKeyPressOnly = false
2832
}) {
2933
if (!container) {
30-
throw new Error('Usage: searchBox({container[, placeholder, cssClasses.{input,poweredBy}, poweredBy, wrapInput, autofocus]})');
34+
throw new Error('Usage: searchBox({container[, placeholder, cssClasses.{input,poweredBy}, poweredBy, wrapInput, autofocus, searchOnEnterKeyPressOnly]})');
3135
}
3236

3337
container = utils.getContainerNode(container);
@@ -96,8 +100,11 @@ function searchBox({
96100

97101
// Add all the needed attributes and listeners to the input
98102
this.addDefaultAttributesToInput(input, initialState.query);
99-
input.addEventListener('keyup', () => {
100-
helper.setQuery(input.value).search();
103+
input.addEventListener('keyup', (e) => {
104+
helper.setQuery(input.value);
105+
if (!searchOnEnterKeyPressOnly || e.keyCode === KEY_ENTER) {
106+
helper.search();
107+
}
101108
});
102109

103110
if (isInputTargeted) {

0 commit comments

Comments
 (0)