Thinking in Navigation Step 4

by navigation

HTML

<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.2.0/css/bootstrap.min.css">
<script src="https://unpkg.com/react@16.3.0/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@16.3.0/umd/react-dom.development.js"></script>
<script src="https://grahammendick.github.io/navigation/download/navigation-5.0.1.min.js"></script>
<script src="https://grahammendick.github.io/navigation/download/navigation.react-3.1.0.min.js"></script>
<div id="container">
</div>

CSS

body {
    padding: 20px
}

Babel + JSX

class ProductCategoryRow extends React.Component {
  render() {
    return (<tr><th colSpan="2">{this.props.category}</th></tr>);
  }
}

class ProductRow extends React.Component {
  render() {
    var name = this.props.product.stocked ?
      this.props.product.name :
      <span style={{color: 'red'}}>
        {this.props.product.name}
      </span>;
    return (
      <tr>
        <td>{name}</td>
        <td>{this.props.product.price}</td>
      </tr>
    );
  }
}

class ProductTable extends React.Component {
  render() {
    var rows = [];
    var lastCategory = null;
    this.props.products.forEach(function(product) {
      if (product.name.indexOf(this.props.filterText) === -1 || (!product.stocked && this.props.inStockOnly)) {
        return;
      }
      if (product.category !== lastCategory) {
        rows.push(<ProductCategoryRow category={product.category} key={product.category} />);
      }
      rows.push(<ProductRow product={product} key={product.name} />);
      lastCategory = product.category;
    }.bind(this));
    return (
      <table>
        <thead>
          <tr>
            <th>Name</th>
            <th>Price</th>
          </tr>
        </thead>
        <tbody>{rows}</tbody>
      </table>
    );
  }
}

class SearchBar extends React.Component {
  render() {
    return (
      <form>
        <input
          type="text"
          placeholder="Search..."
          value={this.props.filterText}
          ref="filterTextInput"
          onChange={() => {
            this.props.stateNavigator.refresh({
              filterText: this.refs.filterTextInput.value,
              inStockOnly: this.refs.inStockOnlyInput.checked 
            });
          }}
        />
        <p>
          <input
            type="checkbox"
            checked={this.props.inStockOnly}
            ref="inStockOnlyInput"
            onChange={() => {
              this.props.stateNavigator.refresh({
                filterText: this.refs.filterTextInput.value,
           ...