Thinking In React Step 5

by chez

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/css/bootstrap.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-core/5.8.24/browser.js"></script>
<script src="https://fb.me/react-with-addons-15.2.0.js"></script>
<script src="https://fb.me/react-dom-15.2.0.js"></script>
<script src="https://facebook.github.io/react/js/jsfiddle-integration-babel.js"></script>

<div id="container">
    <!-- This element's contents will be replaced with your component. -->
</div>

CSS

body {
    padding: 20px
}

JavaScript 1.7

var LiveSearch = React.createClass({
  getInitialState() {
  return {searchString: '', searchResults: []}
  },
  
  getStaticListOfOptions(searchString) {
    const listOfOptions = ['Contra', 'Comma', 'Cobra', 'Corba', 'Conman', 'Conway'];

    return listOfOptions.filter((option) => {
      return option.includes(searchString);
    });
  },
  
  handleSearchInputChange(event) {
    console.log("Handling search");
    this.setState({searchString: event.target.value});

    const results = this.getStaticListOfOptions(event.target.value);
    this.setState({searchResults: results, resultsOpen: true});
  },

  handleSearchResultClick(event) {
    var selectedResult = event.target.innerText;
    this.setState({searchString: selectedResult});
  },
  
  openResults() {
    this.setState({resultsOpen: true});
  },
  
  closeResults() {
    //this.setState({resultsOpen: false});
  },
  
  render() {
    return (
      <div>
        <div>Enter "Con" in the box below and then attempt to click on a result</div>
        <SearchInput
          value={this.state.searchString}
          onBlur={this.closeResults}
          onChange={this.handleSearchInputChange}
          onFocus={this.openResults}
        />
        <SearchResultWrapper open={this.state.resultsOpen}>
          {this.state.searchResults.map((result) => {
            return <SearchResult key={result} value={result} onClick={this.handleSearchResultClick}/>
          }.bind(this))}
        </SearchResultWrapper>
      </div>
    );
  }
});

const SearchInput = (props) => {
    return (
      <div>
        <label htmlFor="">Field:</label>
        <input autoComplete="off" type="text"
               value={props.value}
               onBlur={props.onBlur}
               onChange={props.onChange}
               onFocus={props.onFocus}
        />
      </div>
    );
};

const SearchResult = (props) => {
  return (
    <div onClick={props.onClick}>{props.value}</div>
  );
};

const SearchResultWrapper = (props) => {
  ...