Skip to content

Search #1

@davidhenley

Description

@davidhenley

Would love to see a Search implementation.

I've got one but it's complicated.

// Search.js

import React, { Component } from 'react';
import PropTypes from 'prop-types';
import {
  Search
} from 'semantic-ui-react';
import _ from 'lodash';

const propTypes = {
  list: PropTypes.array.isRequired,
  onChangeValue: PropTypes.func
}

const defaultProps = {
  onChangeValue(result) {
    console.log(result);
  }
}

class SearchComponent extends Component {
  state = {
    isLoading: false,
    value: '',
    results: []
  }

  componentDidMount() {
    this.resetComponent();
  }

  resetComponent = () => this.setState({ isLoading: false, results: [], value: '' })

  handleResultSelect = (e, { result }) => {
    this.setState({ value: result.description });
    this.props.onChangeValue(result);
  }

  handleSearchChange = (e, { value }) => {
    this.setState({ isLoading: true, value })

    setTimeout(() => {
      if (this.state.value.length < 1) return this.resetComponent()

      const re = new RegExp(_.escapeRegExp(this.state.value), 'i')
      const isMatch = result => re.test(`${result.title} ${result.description}`);

      this.setState({
        isLoading: false,
        results: _.filter(this.props.list, isMatch),
      })
    }, 500)
  }

  onFocus = () => {
    this.setState({ value: '' });
    this.props.onChangeValue('');
  }

  render() {
    const { isLoading, value, results } = this.state;

    return (
      <div style={{ marginBottom: 10 }}>
        <label style={{ fontSize: '.92857143em', fontWeight: 700, display: 'block', margin: '0 0 .28571429rem 0' }}>{this.props.label}</label>
        <Search
          {...this.props}
          fluid
          input={{ fluid: true }}
          loading={isLoading}
          onResultSelect={this.handleResultSelect}
          onSearchChange={this.handleSearchChange}
          results={results}
          value={value}
          minCharacters={3}
          onFocus={this.onFocus}
        />
      </div>
    );
  }
}

SearchComponent.propTypes = propTypes;
SearchComponent.defaultProps = defaultProps;

export default SearchComponent;

// common.js

export const searchField = ({ list, input, label }) => {
  return (
    <Search
      {...input}
      label={label}
      list={list}
      onChangeValue={(result) => {
        console.log(result);
        if (result !== '') return input.onChange(`${result.title} ${result.description}`);
        return input.onChange('');
      }}
    />
  );
}

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions