如何使用 createFilterOptions 自定义 MUI 自动完成过滤器

问题描述 投票:0回答:1

我有一个自动完成 MUI 组件,并且我仍在学习它的一些功能。我的基本实现按预期工作,这意味着使用以下代码:

import Autocomplete from '@mui/material/Autocomplete';
import { TextField } from '@mui/material';
import * as React from 'react';

const options = [
  {
    "value": {"name": "Bill Simmons HR"},
    "label": "BILL SIMMONS HR"
    },
]

const label = "Field"
export function MyAutocomplete() {
  return (
    <label>
      <Autocomplete
        sx={{width: 200}}
        options={options}
        id="custom-input-demo"
        renderInput={(params) => (
          <TextField
            {...params}
            label={label}
            placeholder={label}
          />
          )}
        />
    </label>
  );
}

...如果我输入其中任何一个,它会按预期工作并且自动完成选项可见:

"bill"  
"bill "  
"bill s"  
"bill simmons"  
"bill simmons hr"  
"simmons"  
"simmons "  

我的问题是,我有一个要求 - 除了上述功能之外 - 应该通过键入以下任何输入来显示自动完成可见选项,因此我需要这些功能:

"simmons b"  
"simmons bill" 

通过我的基本实现,上面的两个输入会导致任何自动完成选项消失。

MUI 文档建议,要更改默认选项过滤器行为,我应该使用

createFilterOptions
工厂创建自定义过滤器。所以,我做到了:

import Autocomplete, { createFilterOptions } from '@mui/material/Autocomplete';
import { TextField } from '@mui/material';
import * as React from 'react';

const options = [
  {
    "value": {"name": "Bill Simmons HR"},
    "label": "BILL SIMMONS HR"
    },
]

const SPACE = " "
function parse(label:string) {
  const arr = label.split(SPACE)
  return arr[1] + SPACE + arr[0] + SPACE + arr[2] // <<<--- enables new requirement, but disables original functionality
}

const filterOptions = createFilterOptions({
  matchFrom: 'start',
  stringify: (option:any) => parse(option.label),
})

const label = "Field"
export function MyAutocomplete() {
  return (
    <label>
      <Autocomplete
        filterOptions={filterOptions}
        sx={{width: 200}}
        options={options}
        id="custom-input-demo"
        renderInput={(params) => (
          <TextField
            {...params}
            label={label}
            placeholder={label}
          />
          )}
        />
    </label>
  );
}

现在这个自定义过滤器满足了新的要求,但它禁用了原来的功能。

我该怎么做才能满足以下所有输入都显示自动完成选项的两种用例?

"bill"
"bill "
"bill s"
"bill simmons"
"bill simmons hr"
"simmons"
"simmons "

"simmons b"
"simmons bill"

反应:v18,muiv:5

reactjs material-ui autocomplete
1个回答
0
投票

听起来你想要的是模糊搜索,这样无论词序如何,你都可以看到你想要的东西。

我尝试了一下,并使用了文档“高级”部分中的示例,以及“高级”部分中链接的示例代码,并且能够实现您所要求的 -- const filterOptions = (options, { inputValue }) => { const optionsForSearch = options.map((o) => o.label) const terms = inputValue.split(' ') const result = terms.reduceRight( (accu, term) => matchSorter(accu, term), optionsForSearch ) Ï return result }

简而言之,
createFilterOptions

将无法实现您所要求的仅仅是因为它的限制(同时仍然非常足智多谋)。因此,您需要一个更加自定义的过滤器才能使模糊搜索正常工作。

这里是演示,其中包含部分代码和部分代码片段,灵感来自 MUI 的文档 - 

https://codesandbox.io/s/cool-river-f2m8gt?file=/src/Demo.tsx:333 -602

© www.soinside.com 2019 - 2024. All rights reserved.