重大ui自动完成功能:可以在"Enter"事件以外的事件上创建标签吗? [英] Material ui Autocomplete: can tags be created on events aside from 'Enter' events?

查看:70
本文介绍了重大ui自动完成功能:可以在"Enter"事件以外的事件上创建标签吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前正在使用freesolo自动完成功能,并且我的特殊用例需要在逗号或空格跟随输入文本时创建标记.目前,自动完成功能会在Enter事件上创建标签,但我认为自动完成功能中没有内置任何功能,但支持任何其他事件的标签创建.我想知道我是否缺少任何东西,或者如果我没有,我该如何解决这个问题?

I am currently working with the freesolo Autocomplete and my particular use case requires tags to be created when commas or spaces follow the input text. Autocomplete currently creates tags on the Enter event, but I don't think there is anything built into Autocomplete yet that supports tag creation on any other event. I'm wondering if I'm missing anything, or if I'm not, how could I approach this problem?

当前,我正在尝试使用自动完成功能中的onInputChange属性来捕获传入的字符串.我检查该字符串中的逗号和空格,并在成功找到其中一个字符的情况下,使用以下命令手动触发了Enter事件:一些本地JS代码.这在某些情况下有效,但并非在所有情况下都有效,并且考虑所有情况变得很乏味.这种方法似乎容易出现很多问题,而且我不认为这是在不同事件上实现标记创建的最佳方法.寻找一些想法.谢谢

Currently, I'm attempting to use the onInputChange attribute in Autocomplete to capture the string coming in. I check that string for commas and spaces, and on a successful find of one of those characters I manually fire off the Enter event using some native JS code. This works in some cases, but not in all cases and accounting for all cases is becoming tedious. This approach seems like it's prone to a lot of issues, and I'm not convinced it's the best way to go about implementing tag creation on different events. Looking for some thoughts. Thanks

onInputChange属性用法:

<Autocomplete
        multiple
        freeSolo
        filterSelectedOptions
        id="auto-complete"
        options={foo.map(bar => bar.name)}
        ref={autoRef}
        onInputChange={(e, value) => {
            createTagOnEvent(value);
        }}/>

在输入中搜索逗号和空格,然后手动触发Enter事件:

Searching through input for commas and spaces and firing off Enter event manually:

const createTagOnEvent = (bar) => {
    if (pattern.test(bar)) {
        const ke = new KeyboardEvent("keydown", {bubbles: true, cancelable: true, keyCode: 13});
        autoRef.current.dispatchEvent(ke);
    }
};

推荐答案

以下是我推荐的方法.

该方法有两个主要方面:

There are two main aspects to the approach:

  1. 使用受控"输入方法用于Autocomplete,以便您可以完全控制当前值.

  1. Use a "controlled" input approach for the Autocomplete so that you have full control over the current value.

为通过params.inputProps.onKeyDown输入的TextField输入onKeyDown处理程序指定适当的逻辑以添加新值.

Specify the onKeyDown handler for the TextField input via params.inputProps.onKeyDown with appropriate logic for adding the new value.

import React from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete from "@material-ui/lab/Autocomplete";

export default function Tags() {
  const [value, setValue] = React.useState([top100Films[13]]);
  const handleKeyDown = event => {
    switch (event.key) {
      case ",":
      case " ": {
        event.preventDefault();
        event.stopPropagation();
        if (event.target.value.length > 0) {
          setValue([...value, event.target.value]);
        }
        break;
      }
      default:
    }
  };
  return (
    <div style={{ width: 500 }}>
      <Autocomplete
        multiple
        freeSolo
        id="tags-outlined"
        options={top100Films}
        getOptionLabel={option => option.title || option}
        value={value}
        onChange={(event, newValue) => setValue(newValue)}
        filterSelectedOptions
        renderInput={params => {
          params.inputProps.onKeyDown = handleKeyDown;
          return (
            <TextField
              {...params}
              variant="outlined"
              label="filterSelectedOptions"
              placeholder="Favorites"
              margin="normal"
              fullWidth
            />
          );
        }}
      />
    </div>
  );
}

// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
const top100Films = [
  { title: "The Shawshank Redemption", year: 1994 },
  { title: "The Godfather", year: 1972 },
// ... many more options
];

这是打字稿版本:

/* eslint-disable no-use-before-define */
import React from "react";
import TextField from "@material-ui/core/TextField";
import Autocomplete, { RenderInputParams } from "@material-ui/lab/Autocomplete";

interface ObjectOption {
  title: string;
  year: number;
}
type Option = ObjectOption | string;

interface MyInputProps {
  onKeyDown: (event: object) => void;
}
interface MyParams extends RenderInputParams {
  inputProps: MyInputProps;
}

export default function Tags() {
  const [value, setValue] = React.useState([top100Films[13]]);
  const handleKeyDown = event => {
    switch (event.key) {
      case ",":
      case " ": {
        event.preventDefault();
        event.stopPropagation();
        if (event.target.value.length > 0) {
          setValue([...value, event.target.value]);
        }
        break;
      }
      default:
    }
  };
  return (
    <div style={{ width: 500 }}>
      <Autocomplete
        multiple
        freeSolo
        id="tags-outlined"
        options={top100Films}
        getOptionLabel={option => {
          if (typeof option === "string") {
            return option;
          }
          return option.title;
        }}
        value={value}
        onChange={(event, newValue) => setValue(newValue)}
        filterSelectedOptions
        renderInput={(params: MyParams) => {
          params.inputProps.onKeyDown = handleKeyDown;
          return (
            <TextField
              {...params}
              variant="outlined"
              label="filterSelectedOptions"
              placeholder="Favorites"
              margin="normal"
              fullWidth
            />
          );
        }}
      />
    </div>
  );
}

// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
const top100Films: ObjectOption[] = [
  { title: "The Shawshank Redemption", year: 1994 },
  { title: "The Godfather", year: 1972 },
// ... many more options
];

这篇关于重大ui自动完成功能:可以在"Enter"事件以外的事件上创建标签吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆