From 180902af8269a00b2af324189180a0bfaec8ab3b Mon Sep 17 00:00:00 2001 From: Alex S Date: Tue, 26 Sep 2017 09:44:21 +0200 Subject: [PATCH] fix(searchbox): use initial input value if provided in the dom (#2342) Fix #2289 --- dev/app/init-builtin-widgets.js | 13 +++++++++++ dev/app/wrap-with-hits.js | 1 + .../search-box/__tests__/search-box-test.js | 5 +++-- src/widgets/search-box/search-box.js | 22 +++++++++++++++---- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/dev/app/init-builtin-widgets.js b/dev/app/init-builtin-widgets.js index 0f0c399245..fb9896a7cf 100644 --- a/dev/app/init-builtin-widgets.js +++ b/dev/app/init-builtin-widgets.js @@ -51,6 +51,19 @@ export default () => { }) ); }) + ) + .add( + 'input with initial value', + wrapWithHits(container => { + container.innerHTML = ''; + const input = container.firstChild; + container.appendChild(input); + window.search.addWidget( + instantsearch.widgets.searchBox({ + container: input, + }) + ); + }) ); storiesOf('Stats').add( diff --git a/dev/app/wrap-with-hits.js b/dev/app/wrap-with-hits.js index 7ac4c90c63..28cda70ce7 100644 --- a/dev/app/wrap-with-hits.js +++ b/dev/app/wrap-with-hits.js @@ -26,6 +26,7 @@ export default (initWidget, opts = {}) => container => { container: '#results-search-box-container', placeholder: 'Search into our furnitures', poweredBy: false, + autofocus: false, }) ); diff --git a/src/widgets/search-box/__tests__/search-box-test.js b/src/widgets/search-box/__tests__/search-box-test.js index 6111b0d9de..5b522be16e 100644 --- a/src/widgets/search-box/__tests__/search-box-test.js +++ b/src/widgets/search-box/__tests__/search-box-test.js @@ -680,11 +680,12 @@ describe('searchBox()', () => { }); it('does not update the input value when focused', () => { - container = document.body.appendChild(document.createElement('input')); + const input = document.createElement('input'); + container = document.body.appendChild(input); container.value = 'initial'; - container.focus(); widget = searchBox({ container }); widget.init({ state, helper, onHistoryChange }); + input.focus(); widget.render({ helper: { state: { query: 'new value' } } }); expect(container.value).toBe('initial'); }); diff --git a/src/widgets/search-box/search-box.js b/src/widgets/search-box/search-box.js index 8e43a66534..7634bad13e 100644 --- a/src/widgets/search-box/search-box.js +++ b/src/widgets/search-box/search-box.js @@ -29,6 +29,8 @@ const renderer = ({ const INPUT_EVENT = window.addEventListener ? 'input' : 'propertychange'; const input = createInput(containerNode); const isInputTargeted = input === containerNode; + let queryFromInput = query; + if (isInputTargeted) { // To replace the node, we need to create an intermediate node const placeholderNode = document.createElement('div'); @@ -36,17 +38,29 @@ const renderer = ({ const parentNode = input.parentNode; const wrappedInput = wrapInput ? wrapInputFn(input, cssClasses) : input; parentNode.replaceChild(wrappedInput, placeholderNode); + + const initialInputValue = input.value; + + // if the input contains a value, we provide it to the state + if (initialInputValue) { + queryFromInput = initialInputValue; + refine(initialInputValue, false); + } } else { const wrappedInput = wrapInput ? wrapInputFn(input, cssClasses) : input; containerNode.appendChild(wrappedInput); } + if (magnifier) addMagnifier(input, magnifier, templates); if (reset) addReset(input, reset, templates, clear); - addDefaultAttributesToInput(placeholder, input, query, cssClasses); + + addDefaultAttributesToInput(placeholder, input, queryFromInput, cssClasses); + // Optional "powered by Algolia" widget if (poweredBy) { addPoweredBy(input, poweredBy, templates); } + // When the page is coming from BFCache // (https://developer.mozilla.org/en-US/docs/Working_with_BFCache) // then we force the input value to be the current query @@ -57,7 +71,7 @@ const renderer = ({ // - use back button // - input query is empty (because autocomplete = off) window.addEventListener('pageshow', () => { - input.value = query; + input.value = queryFromInput; }); // Update value when query change outside of the input @@ -65,9 +79,9 @@ const renderer = ({ input.value = fullState.query || ''; }); - if (autofocus === true || (autofocus === 'auto' && query === '')) { + if (autofocus === true || (autofocus === 'auto' && queryFromInput === '')) { input.focus(); - input.setSelectionRange(query.length, query.length); + input.setSelectionRange(queryFromInput.length, queryFromInput.length); } // search on enter