在ReactBootstrapTypeahead中选择中间匹配的项目

时间:2019-07-04 15:04:12

标签: reactjs react-bootstrap-typeahead

在我的ReactBootstrapTypeahead组件中,我可以单击任何选项来选择它,但是使用 Tab 时,如果它在字符串的开头匹配,则只会选择第一个选项。如果第一个选项在中间匹配,则按 Tab 只会移动焦点而不会选择任何选项。如果您先使用箭头键突出显示该选项,它就会起作用

enter image description here

每个选项包含一个idmakemodel,我将最后两个合并成name(例如'Toyota Prius'),供{ {1}}。一切正常,除了选择第一个项目而不用箭头键突出显示它。

labelKey

我正在使用自定义的<AsyncTypeahead id="search" selectHintOnEnter labelKey="name" filterBy={startsWith} renderMenu={renderMenu} options={results} /> 函数对选项进行分组...

renderMenu

...并且仅突出显示任何单词开头的匹配项。

const renderMenu = (results, menuProps) => {
    const items = [];
    let makesHeader, lastMake, idx = 0;
    results.forEach(result => {
        const { id, make, model } = result;
        if (!make) {
            // skip "click to load more..." text
            items.push(
                <Menu.Header key="more-header">
                    More Results Hidden…
                </Menu.Header>
            );
        }
        else if (!model) {
            if (!makesHeader) {
                items.push(
                    <Menu.Header key="makes-header">
                        Makes
                    </Menu.Header>
                );
                makesHeader = true;
            }
            items.push(
                <MenuItem key={id} option={result} position={idx}>
                    <WordHighlighter search={menuProps.text}>
                        {make}
                    </WordHighlighter>
                </MenuItem>
            );
        }
        else {
            if (make !== lastMake) {
                items.push(
                    <Menu.Header key={`${make}-header`}>
                        {make}
                    </Menu.Header>
                );
                lastMake = make;
            }
            items.push(
                <MenuItem key={id} option={result} position={idx}>
                    <WordHighlighter search={menuProps.text}>
                        {model}
                    </WordHighlighter>
                </MenuItem>
            );
        }
        idx++;
    });
    return <Menu {...menuProps}>{items}</Menu>;
};

1 个答案:

答案 0 :(得分:0)

我自己用overriding the Typeahead's onKeyDown callback解决了这个问题。

const typeahead = useRef();

const onChange = useCallback(([ result ]) => {
    typeahead.current.getInstance().clear();
    typeahead.current.getInstance().blur();
    history.push(`/cars/${result.slug}`);
}, [ typeahead ]);

useEffect(() => {
    const instance = typeahead.current.getInstance(),
        original = instance._handleKeyDown;
    instance._handleKeyDown = (e, results, isMenuDown) => {
        if (results && results.length && (e.key === 'Enter' || e.key === 'Tab')) {
            e.preventDefault();
            e.stopPropagation();
            onChange(results);
        }
        else {
            return original(e, results, isMenuDown);
        }
    };
}, [ typeahead, onChange ]);