Реагировать на нечеткий поиск со списками данных - значения с пробелами и редактирование ввода - PullRequest
0 голосов
/ 12 июня 2018

Я создал fuzzy search компонент реакции.Намерение состоит в том, чтобы иметь возможность ввести имя набора данных в input, и datalist заполняется предложениями о близком соответствии с текущим значением.Базовый дизайн был реализован и отлично работает.

CodeSandbox: https://codesandbox.io/s/38yxk6wqq1

У меня возникли две проблемы:

1) Datalist не распознаетwhitespace.Если строки поиска разделены whitespace, datalist не заполняется.Чтобы учесть это, я заменяю символы whitespace на _. Идентификатор * не обязательно заменяет символы , так как результаты fuse.js действительны и точны.Это тег datalist, который не похож на то, что я делаю.

2) Datalist не заполняется при редактировании середины строки.Допустим, пользователь вводит строку поиска, например, freki_talis_lagg_test_05, datalist соответствующим образом ищет и заполняет правильно.Если пользователь затем редактирует входную строку в freki_talis__test_05, а затем снова редактирует ее из середины строки в freki_talis_lagg_test_05, datalist не рендерится, даже если fuse.js вернул соответствующие результаты и мой асинхронный вызовк моей базе данных работает.

Это немного сложно сформулировать в тексте, поэтому я создал короткий gif ниже:

Editing middle of input

import React from 'react';
import Fuse from 'fuse.js';
import _ from 'lodash';


class DatasetSearch extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      datasets: [{"name":"freki_recorder_test_20180404_093731"},{"name":"freki_talis_lagg_test_05"},{"name":"freki_talis_lagg_test_03"},{"name":"freki_talis_lagg_test_02"},{"name":"freki_recorder_test_20180403_irb_force_2"}],
      name: this.props.datasetName,
      results: [],
      options: {
        shouldSort: true,
        threshold: 0.6,
        location: 0,
        distance: 100,
        maxPatternLength: 32,
        minMatchCharLength: 1,
        keys: [
          "name",
        ]
      },
    };
    this.handleChange = this.handleChange.bind(this);
    this.handleFuzzySearch = this.handleFuzzySearch.bind(this);
  }

  handleChange(e) {
    const { handleUpdateConfig } = this.props;
    const value = _.replace(e.target.value, ' ', '_');
    console.log(value);
    this.setState({
      name: value
    }, () => {
      this.handleFuzzySearch(this.state.name);
    })
  }

  handleFuzzySearch(value) {
    const { datasets } = this.props;
    const { options } = this.state;
    const fuse = new Fuse(this.state.datasets, options);
    const results = fuse.search(value).slice(0,5);
    this.setState({
      results: results
    });
  }

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

    return (
      <div style={{width: '100%'}}>
        <input type='search' list='datasets' onChange={this.handleChange} style={{width: '100%'}} value={this.state.name}/>
        <datalist id='datasets'>
          { results.map((dataset) => <option key={dataset.id} value={dataset.name} />) }
        </datalist>
      </div>
    );
  }
}
...