首页 > 解决方案 > React Fuzzy Search with Datalists - 带有空格和编辑输入的值

问题描述

我创建了一个fuzzy search反应组件。目的是能够将数据集名称输入到 an中input,并datalist填充与当前值接近匹配的建议。基本设计已经实施并且工作正常。

代码沙盒: https ://codesandbox.io/s/38yxk6wqq1

我面临两个问题:

1) Datalist 无法识别whitespace。如果搜索字符串用 分隔,whitespace则不datalist填充。为了解决这个问题,我将whitespace字符替换为_. 我宁愿不必替换 characters,因为结果fuse.js是有效且准确的。它的datalist标签似乎不喜欢我正在做的事情。

2)Datalist编辑字符串中间时不填充。例如,假设用户输入搜索字符串freki_talis_lagg_test_05,则datalist适当地搜索并正确填充。如果用户随后将输入字符串编辑为freki_talis__test_05,然后从字符串中间再次将其编辑为 ,即使已返回适当的结果并且我对数据库的异步调用有效freki_talis_lagg_test_05,也不会呈现。datalistfuse.js

用文字表达有点困难,所以我在下面创建了一个简短的 gif:

编辑输入中间

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>
    );
  }
}

标签: reactjshtml-inputhtml-datalist

解决方案


推荐阅读