将自动建议功能添加到标签输入框。

4

我使用JavaScript、React框架和mui库编写网站。

在我的网站上,用户的其中一个输入字段是使用TagsInput完成的。因此,用户可以输入数据,按下回车键,看到标签,并可选择删除它。

对于TagsInput,我没有使用库,而是自己编写了代码。下面将呈现这部分代码。

我希望为用户改进功能并添加预测搜索(自动填充)。也就是说,当用户开始输入字母(例如汽车品牌),如果当前数据库中存在该汽车品牌(不要复杂化问题,可以制作一个常规列表或其他方便的数据类型),则向用户提供自动填充选项。

例如:用户点击输入标签的字段并输入第一个字母“A”,然后提示出现- Alfa Romeo,Aston Martin。如果Audi目前不在数据库中,则不会弹出Audi提示。

我将很高兴得到任何帮助。

FilterMarkAuto.jsx

export default function FilterMarkAuto({ isExpanded, setIsExpanded }){
const [values, setValues] = useState([]);

return (
    <ArrowDropdown
        isExpanded={isExpanded}
        setIsExpanded={setIsExpanded}
        title="Name car"
        onClick={() => setIsExpanded(!isExpanded)}>
            
        {isExpanded && 
            <TagsInput tags={values} 
                       setTags={setValues} 
                       inputPlaceholder="Enter a car" />}
    </ArrowDropdown>
);
}

TagsInput.jsx

export default function TagsInput(props) {
    const tags = props.tags
    const setTags = props.setTags
    const [input, setInput] = React.useState('');
    const [isKeyReleased, setIsKeyReleased] = React.useState(false);

    const onChange = (e) => {
        const { value } = e.target;
        setInput(value);
    };

    const onKeyDown = (e) => {
        const { key } = e;
        const trimmedInput = input.trim();

        if ((key === ',' || key === 'Enter') && trimmedInput.length && !tags.includes(trimmedInput)) {
            e.preventDefault();
            setTags(prevState => [...prevState, trimmedInput]);
            setInput('');
        }

        if (key === "Backspace" && !input.length && tags.length && isKeyReleased) {
            e.preventDefault();
            const tagsCopy = [...tags];
            const poppedTag = tagsCopy.pop();

            setTags(tagsCopy);
            setInput(poppedTag);
            setIsKeyReleased(false);
        }

    };

    const onKeyUp = () => {
        setIsKeyReleased(true);
    }

    const deleteTag = (index) => {
        setTags(prevState => prevState.filter((tag, i) => i !== index))
    }

    return (
        <div className={classes.container}>
            {tags.map((tag, index) => <div className={classes.tag}>
                <ClearIcon className={classes.del} fontSize="big" onClick={() => deleteTag(index)} />
                {tag}
            </div>
            )}
            <input
                className={classes.input}
                value={input}
                placeholder={props.inputPlaceholder}
                onKeyDown={onKeyDown}
                onKeyUp={onKeyUp}
                onChange={onChange}
            />
        </div>);
}

缺少TagsInputclasses。请将其添加到您的问题中。我还想要一个文件,展示这段代码的基本用法。FilterMarkAuto在哪里获取expandedvalue包含什么?通常最好分享一些最小可重现示例,这样我们不必先让基础代码工作,然后再解决实际问题。 - Swiffy
@innocent 因此,为了让用户不必输入整个汽车名称,而是可以点击提示,汽车品牌将出现在标签中。 - Paul
@Swiffy 我已经添加了你要求的内容。 - Paul
1
@Swiffy 现在检查一下。 - Paul
1
@Павел 做得好!如果可能的话,总是包含一个小演示,这会使问题更容易解决,也更有吸引力。 :) - Swiffy
显示剩余3条评论
1个回答

1

这是您需要的内容:https://codesandbox.io/s/beautiful-albattani-kn1yfr

我建议添加以下标签:

const tagSuggestions = [
    "Audi",
    "Mercedes Benz",
    "Renault",
    "Ford",
    "Ferrari"
]

这里并不复杂,这部分负责呈现建议:

{suggestedTags.length > 0 && (
    <div className={classes.tagSuggestionWrapper}>
        {suggestedTags.map((t) => {
            return (<div key={t} className={classes.tagSuggestion} onClick={() => { selectTag(t) }}>{t}</div>);
        })}
    </div>
)}

接下来是从建议中选择标签:

const selectTag = (tag) => {
    setTags((prevState) => [...prevState, tag]);
    setSuggestedTags([]);
    setInput("");
}

搜索建议基于用户已输入的内容:

const onChange = (e) => {
    const { value } = e.target;
    setInput(value);

    if(value.length < 2) return;

    const matchedSuggestions = tagSuggestions.filter((s) => {
        return s.toLowerCase().search(value.toLowerCase()) > -1;
    })
    setSuggestedTags(matchedSuggestions);
};

完美的解决方案,非常感谢!只有一个小问题。 在我的代码中,规定了一个标签不能重复输入,但现在这个规则被违反了。有办法修复吗? - Paul
你可能还应该将所有标签保存为小写形式到 tags 中,这样就不会引起问题了。 - Swiffy
1
if(value.length < 2) { setSuggestedTags([]); return; } - Swiffy
我已经基本上完成了你的代码,但我仍然无法确定在没有合适的汽车品牌的情况下应该添加代码,以显示相关内容。如果您不介意,请告诉我。 - Paul
你好。我又回来看了你的答案和代码。我想问一下,目前只能使用鼠标光标并通过单击适当选项的左键来选择提议的选项。是否可以使建议的选项可以使用上下箭头和回车键进行选择(同时保留以前的功能)。也就是说,用户输入字符并使用上下箭头浏览建议的选项,并使用回车键选择标签的方案如下。 - Paul
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接