【问题标题】:Material ui Autocomplete press enter to create new chipsMaterial ui Autocomplete 按回车键创建新芯片
【发布时间】:2020-08-04 11:10:58
【问题描述】:

我希望我可以使用材料 ui 的自动完成来做这样的事情:wertarbyte

也就是说,插入文本(字符串)而没有必须从中选择的元素列表。

因此 noOptions 消息不应出现,每次在键盘上按下 enter 键时都会插入文本。

链接:codesandbox

代码:

import React from "react";
import Chip from "@material-ui/core/Chip";
import Autocomplete from "@material-ui/lab/Autocomplete";
import { makeStyles } from "@material-ui/core/styles";
import TextField from "@material-ui/core/TextField";

const useStyles = makeStyles(theme => ({
  root: {
    width: 500,
    "& > * + *": {
      marginTop: theme.spacing(3)
    }
  }
}));

export default function Tags() {
  const classes = useStyles();

  return (
    <div className={classes.root}>
      <Autocomplete
        multiple
        id="tags-outlined"
        options={[]}
        defaultValue={["foo", "bar"]}
        //getOptionLabel={(option) => option}
        //defaultValue={[top100Films[13]]}
        //filterSelectedOptions
        renderInput={params => (
          <TextField
            {...params}
            variant="outlined"
            label="filterSelectedOptions"
            placeholder="Favorites"
          />
        )}
      />
    </div>
  );
}

【问题讨论】:

    标签: javascript reactjs autocomplete material-ui


    【解决方案1】:

    如果你有简单的元素(不是对象,只是字符串),并且你真的不需要处理状态(你的自动完成不受控制),你可以使用 AutocompletefreeSolo 属性。

    <Autocomplete
        multiple
        freeSolo
        id="tags-outlined"
        options={["foo", "bar"]}
        defaultValue={["foo", "bar"]}
        renderInput={params => (
            <TextField
                {...params}
                variant="outlined"
                label="filterSelectedOptions"
                placeholder="Favorites"
            />
        )}
    />
    

    如果您的元素更复杂并且您确实需要控制该元素:

    1. 确保自动完成标签是受控标签(您设法重视)。

    2. 监听 TextField 上的按键事件。

    3. 如果代码是 Enter (e.code === 'Enter') - 获取输入值并将其推送到您拥有的当前值列表中。

    4. 确保您还处理 onChange 来处理元素的删除:

    代码如下:

    const [autoCompleteValue, setAutoCompleteValue] = useState(["foo", "bar"]);
    
    return (
      
      <Autocomplete
        multiple
        id="tags-outlined"
        options={[]}
        value={autoCompleteValue}
        onChange={(e, newval, reason) => {
          setAutoCompleteValue(newval);
        }}
        renderInput={params => (
          <TextField
            {...params}
            variant="outlined"
            label="filterSelectedOptions"
            placeholder="Favorites"
            onKeyDown={e => {
              if (e.code === 'enter' && e.target.value) {
                setAutoCompleteValue(autoCompleteValue.concat(e.target.value));
              }
            }}
          />
        )}
      />
    );
    

    查看两个选项的实时工作示例:https://codesandbox.io/s/mui-autocomplete-create-options-on-enter-gw1jc

    【讨论】:

    • 我看过这个例子但是有一些问题:1)如果我点击芯片的x(删除)它不会被删除2)如果我点击芯片的x(删除)输入字段,并不是所有的芯片都被删除 3)每次我在输入字段上写一个文本时,都会出现文本'No option'
    • @Paul 代码更新以支持两个选项(受控/不受控元素)
    • 感谢您的帮助,但似乎仍然存在问题。考虑以下版本的第一个示例:codesandbox.io/s/… 如何访问自动完成中包含的元素的值?
    • 你不能。这正是受控自动完成(使用value)和非受控自动完成(使用defaultValue)之间的区别。如果您移动到受控的 - 您可以访问它(但您需要对其进行管理)。
    • 请注意,您仍然可以使用onChange 函数onChange={(e, val, reason) =&gt; { console.log(val) }},但您需要在某处设置相同的值才能访问它。
    【解决方案2】:

    为此,请勿使用 MUI 中的 Autocomplete 元素。只需使用标准的TextFieldInputProps。您需要做的就是向TextField 添加一个onKeyDown 侦听器以侦听“Enter”,并在触发该函数时将其添加到InputProps 中的芯片数组中。它可能看起来像这样:

    const [inputValue, setInputValue] = useState('');
    const [chips, setChips] = useState([])
    const inputChange = ({target: {value}}) => {setInputValue(value)};
    const handleKeyDown = ({key}) => {
     if(key === 'Enter') {
      setChips([...chips, inputValue])
     }
    };
         <TextField
                fullWidth
                variant="outlined"
                label="Fish and Chips"
                value={inputValue}
                onChange={inputChange}
                multiline
                InputProps={{
                  startAdornment: chips.map((item) => (
                    <Chip
                      key={item}
                      label={item}
                    />
                  )),
                }}
              />
    
    

    这是未经测试的书面在这里,但它应该工作。我在我的一个应用中做了类似的事情。

    【讨论】:

    • 但是这样你会失去自动完成下拉菜单..
    猜你喜欢
    • 1970-01-01
    • 2012-05-11
    • 1970-01-01
    • 2020-12-27
    • 2019-09-12
    • 1970-01-01
    • 2018-08-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多