From 4a1f6ad2a972bb0f30414db3dc1899d88a01d29b Mon Sep 17 00:00:00 2001
From: hmhealey <harrisonmhealey@gmail.com>
Date: Tue, 20 Oct 2015 16:50:55 -0400
Subject: Added an autocomplete dropdown to the search bar

---
 web/react/components/search_bar.jsx | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

(limited to 'web/react/components/search_bar.jsx')

diff --git a/web/react/components/search_bar.jsx b/web/react/components/search_bar.jsx
index 7540b41a4..509ca94e9 100644
--- a/web/react/components/search_bar.jsx
+++ b/web/react/components/search_bar.jsx
@@ -9,6 +9,7 @@ var utils = require('../utils/utils.jsx');
 var Constants = require('../utils/constants.jsx');
 var ActionTypes = Constants.ActionTypes;
 var Popover = ReactBootstrap.Popover;
+var SearchAutocomplete = require('./search_autocomplete.jsx');
 
 export default class SearchBar extends React.Component {
     constructor() {
@@ -21,6 +22,7 @@ export default class SearchBar extends React.Component {
         this.handleUserBlur = this.handleUserBlur.bind(this);
         this.performSearch = this.performSearch.bind(this);
         this.handleSubmit = this.handleSubmit.bind(this);
+        this.completeWord = this.completeWord.bind(this);
 
         const state = this.getSearchTermStateFromStores();
         state.focused = false;
@@ -79,6 +81,8 @@ export default class SearchBar extends React.Component {
         PostStore.storeSearchTerm(term);
         PostStore.emitSearchTermChange(false);
         this.setState({searchTerm: term});
+
+        this.refs.autocomplete.handleInputChange(e.target, term);
     }
     handleMouseInput(e) {
         e.preventDefault();
@@ -120,6 +124,24 @@ export default class SearchBar extends React.Component {
         e.preventDefault();
         this.performSearch(this.state.searchTerm.trim());
     }
+
+    completeWord(partialWord, word) {
+        const textbox = ReactDOM.findDOMNode(this.refs.search);
+        let text = textbox.value;
+
+        const caret = utils.getCaretPosition(textbox);
+        const preText = text.substring(0, caret - partialWord.length);
+        const postText = text.substring(caret);
+        text = preText + word + postText;
+
+        textbox.value = text;
+        utils.setCaretPosition(textbox, preText.length + word.length);
+
+        PostStore.storeSearchTerm(text);
+        PostStore.emitSearchTermChange(false);
+        this.setState({searchTerm: text});
+    }
+
     render() {
         var isSearching = null;
         if (this.state.isSearching) {
@@ -149,6 +171,7 @@ export default class SearchBar extends React.Component {
                     role='form'
                     className='search__form relative-div'
                     onSubmit={this.handleSubmit}
+                    style={{"overflow": "visible"}}
                 >
                     <span className='glyphicon glyphicon-search sidebar__search-icon' />
                     <input
@@ -163,6 +186,10 @@ export default class SearchBar extends React.Component {
                         onMouseUp={this.handleMouseInput}
                     />
                     {isSearching}
+                    <SearchAutocomplete
+                        ref='autocomplete'
+                        completeWord={this.completeWord}
+                    />
                     <Popover
                         placement='bottom'
                         className={helpClass}
-- 
cgit v1.2.3-1-g7c22


From a5a2826700b1fc6b19ba38698cfa703f58476bc6 Mon Sep 17 00:00:00 2001
From: hmhealey <harrisonmhealey@gmail.com>
Date: Wed, 21 Oct 2015 11:03:50 -0400
Subject: Added keyboard selection to search autocomplete

---
 web/react/components/search_bar.jsx | 19 +++++++++++++------
 1 file changed, 13 insertions(+), 6 deletions(-)

(limited to 'web/react/components/search_bar.jsx')

diff --git a/web/react/components/search_bar.jsx b/web/react/components/search_bar.jsx
index 509ca94e9..3932807d0 100644
--- a/web/react/components/search_bar.jsx
+++ b/web/react/components/search_bar.jsx
@@ -17,6 +17,7 @@ export default class SearchBar extends React.Component {
         this.mounted = false;
 
         this.onListenerChange = this.onListenerChange.bind(this);
+        this.handleKeyDown = this.handleKeyDown.bind(this);
         this.handleUserInput = this.handleUserInput.bind(this);
         this.handleUserFocus = this.handleUserFocus.bind(this);
         this.handleUserBlur = this.handleUserBlur.bind(this);
@@ -76,6 +77,11 @@ export default class SearchBar extends React.Component {
             results: null
         });
     }
+    handleKeyDown(e) {
+        if (this.refs.autocomplete) {
+            this.refs.autocomplete.handleKeyDown(e);
+        }
+    }
     handleUserInput(e) {
         var term = e.target.value;
         PostStore.storeSearchTerm(term);
@@ -101,7 +107,7 @@ export default class SearchBar extends React.Component {
             this.setState({isSearching: true});
             client.search(
                 terms,
-                function success(data) {
+                (data) => {
                     this.setState({isSearching: false});
                     if (utils.isMobile()) {
                         ReactDOM.findDOMNode(this.refs.search).value = '';
@@ -112,11 +118,11 @@ export default class SearchBar extends React.Component {
                         results: data,
                         is_mention_search: isMentionSearch
                     });
-                }.bind(this),
-                function error(err) {
+                },
+                (err) => {
                     this.setState({isSearching: false});
                     AsyncClient.dispatchError(err, 'search');
-                }.bind(this)
+                }
             );
         }
     }
@@ -165,13 +171,13 @@ export default class SearchBar extends React.Component {
                     className='search__clear'
                     onClick={this.clearFocus}
                 >
-                    Cancel
+                    {'Cancel'}
                 </span>
                 <form
                     role='form'
                     className='search__form relative-div'
                     onSubmit={this.handleSubmit}
-                    style={{"overflow": "visible"}}
+                    style={{overflow: 'visible'}}
                 >
                     <span className='glyphicon glyphicon-search sidebar__search-icon' />
                     <input
@@ -183,6 +189,7 @@ export default class SearchBar extends React.Component {
                         onFocus={this.handleUserFocus}
                         onBlur={this.handleUserBlur}
                         onChange={this.handleUserInput}
+                        onKeyDown={this.handleKeyDown}
                         onMouseUp={this.handleMouseInput}
                     />
                     {isSearching}
-- 
cgit v1.2.3-1-g7c22


From cd958a7ec76c04d9615b58f81ef910bd0ed22e23 Mon Sep 17 00:00:00 2001
From: Reed Garmsen <rgarmsen2295@gmail.com>
Date: Fri, 23 Oct 2015 17:13:10 -0700
Subject: Fixed react warning for the search bar tooltip

---
 web/react/components/search_bar.jsx | 1 +
 1 file changed, 1 insertion(+)

(limited to 'web/react/components/search_bar.jsx')

diff --git a/web/react/components/search_bar.jsx b/web/react/components/search_bar.jsx
index 3932807d0..e1d36ad7d 100644
--- a/web/react/components/search_bar.jsx
+++ b/web/react/components/search_bar.jsx
@@ -198,6 +198,7 @@ export default class SearchBar extends React.Component {
                         completeWord={this.completeWord}
                     />
                     <Popover
+                        id='searchbar-help-popup'
                         placement='bottom'
                         className={helpClass}
                     >
-- 
cgit v1.2.3-1-g7c22

