1
votes

I would like to make a semantic ui "search selection dropdown" that has local filtering disabled. The desired behavior is much like the Google search input:

  1. User enters search term
  2. A list of results matching the input is loaded remotely
  3. User selects one of the results with mouse or keyboard

Our application has a means to search remote content, and so we do not wish to use semantics "API" features. The local filtering of semantic is competing with our remote loading, which causes an undesirable user experience. Before the remote content is loaded, the "No results" item displays, and stays in the list of items as the remote content is loaded.

There must be a combination of settings to the dropdown module that disables local filtering

1
Did you ever find a solution for this? - Cameron Sima
Did any of you ever find a solution for this? - Bouke

1 Answers

0
votes

There is no clean solution to this issue at the moment of writing. There are a couple of open issues that have not been solved yet, see here and here.

I have implemented a workaround: with the Dropdown component, you can use the content field instead of the text field to display the options to the user. I have set the text field of each option to the searchQuery, added an extra original field to keep track of the text before changing it and added the content field. In this way the local filtering will always match all the options. Then, when clicking on one option from the list, change back the text to original.

handleSearchChange = async (e, { searchQuery }) => {
  ...
  const response = await performSearchRequest(searchQuery);
  const results = response.data.hits
    .map((hit) => toKeyValueText(hit))
    .map((obj) => ({
      ...obj,
      text: searchQuery,
      original: obj.text,
      content: obj.content || obj.text,
    }));
  ...
  this.setState({
    isLoading: false,
    options: results,
    error: null,
  });
}

handleChange = (e, { options, value }) => {
  // find the selected option and restore the original value
  const selected = _find(options, { value: value });
  selected.text = selected.original;
  // now set only one option in the list of results
  this.setState({ options: [selected], value: value });
};

render() {
  const { options, isLoading, value, error } = this.state;
  ...
  return (
    <Dropdown
     search
     selection
     ...
     options={options}
     onChange={this.handleChange}
     onSearchChange={this.handleSearchChange}
    />
  )
}

Given a search query 'mysearch', the options list will be something like:

const results = [
  { key: 'firstKey', value: 'valueA', text: 'mysearch', original: 'Nicely displayed value A', content: '<div>Nicely displayed value A</div>' },
  { key: 'secondKey', value: 'valueB', text: 'mysearch', original: 'Nicely displayed value B', content: '<div>Nicely displayed value B</div>' },
];

Here a working example (with fake data, no remote call).