Material UI Autocomplete 在 noOptionsText 中创建可点击按钮

Posted

技术标签:

【中文标题】Material UI Autocomplete 在 noOptionsText 中创建可点击按钮【英文标题】:Material UI Autocomplete create clickable Button in noOptionsText 【发布时间】:2020-12-27 05:44:46 【问题描述】:

我正在使用 Material Ui 自动完成组件。我希望当用户输入某些内容但没有得到任何结果时,noOptionsText 会显示一个可以单击以执行某些操作的按钮:

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

export default function App() 
  return (
    <Autocomplete
      options=["HELLO", "HI"]
      renderInput=(params) => (
        <TextField ...params label="Combo box" variant="outlined" />
      )
      noOptionsText=
        <Button onClick=() => console.log("CLICK SUCCESSFUL")>
          No results! Click me
        </Button>
      
    />
  );

这里按钮显示成功,但是当我点击它时,自动完成功能在按钮接收点击之前关闭。

如果我设置debug=true 强制保持菜单打开,它会起作用,但这会产生许多其他副作用。 也试过强制open=true,但它仍然被关闭。

你会怎么做?

Codesandbox 演示:https://codesandbox.io/s/vigilant-haslett-sngyb?file=/src/App.js

【问题讨论】:

【参考方案1】:

在Button组件上,不要使用onClick,试试onMouseDown这样:

  noOptionsText=
    <Button onMouseDown=() => 
        console.log("CLICK SUCCESSFUL")
    >
      No results! Click me
    </Button>

这是一个副本的副本:Action button in Material UI Autocomplete for No Options

【讨论】:

【参考方案2】:

单击无选项菜单中的按钮时,TextField 模糊(未聚焦),您可以通过在onClose 回调中记录原因来知道

onClose=(e, reason) => 
  console.log("on close", reason);

抑制这种情况的唯一方法是设置 debug = true,如 Material-UI API docs 中所述。

但如果您不想使用debug,还有另一种解决方法,即使按钮成为选项菜单本身的一部分。请记住,与无选项菜单不同,您可以在Autocomplete 菜单中注册单击以正常选择选项。

您可以像往常一样通过过滤选项来做到这一点,但如果没有找到选项,请改为返回按钮选项。这是一个例子

import Autocomplete,  createFilterOptions  from "@material-ui/lab/Autocomplete";

const options = ["HELLO", "HI"];
const buttonOption = (
  <Button
    onClick=(e) => 
      console.log("CLICK SUCCESSFUL");
      e.stopPropagation();
    
  >
    No results! Click me
  </Button>
);
const defaultFilterOptions = createFilterOptions();

export default function App() 
  const [selectedOptions, setSelectedOptions] = React.useState("");

  return (
    <Autocomplete
      options=options
      onChange=(_, value) => 
        if (typeof value === "string") 
          setSelectedOptions(value);
        
      
      renderOption=(o) => o
      getOptionLabel=(o) => (typeof o === "string" ? o : "")
      renderInput=(params) => (
        <TextField ...params label="Combo box" variant="outlined" />
      )
      filterOptions=(options, state) => 
        const results = defaultFilterOptions(options, state);

        if (results.length === 0) 
          return [buttonOption];
        

        return results;
      
    />
  );

现场演示

【讨论】:

我发现了一个小错误:当按钮出现时,我可以单击按钮 (ok) 或按钮外的行,就像我“选择”按钮作为选项一样.在这种情况下,我得到:自动完成返回对象的getOptionLabel 方法([object Object])。 @edoedoedo 我已经在现场演示中解决了这个问题。该按钮不像其他选项那样是字符串,因此它会抱怨【参考方案3】:

有一个简单的方法,你必须声明一个状态,让你说“打开”并覆盖 Autocomplete 的 Open 属性,设置 debug=true,当你点击 noOption 中的按钮时,在那里你可以将你的打开状态设置为 false。这样,它会在按钮单击时关闭。

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

export default function App() 
const [Open, setOpen] = React.useState(true);
  return (
    <Autocomplete
      Open=Open
      debug=true
      options=["HELLO", "HI"]
      renderInput=(params) => (
        <TextField ...params label="Combo box" variant="outlined" />
      )
      noOptionsText=
        <Button onClick=() => 
            console.log("CLICK SUCCESSFUL")
            setOpen(false)
        >
          No results! Click me
        </Button>
      
    />
  );

【讨论】:

以上是关于Material UI Autocomplete 在 noOptionsText 中创建可点击按钮的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Material-ui 中的 onFocus 上隐藏 Autocomplete 的标签?

将 Material-UI 的 Autocomplete 组件与 Formik 一起使用

Material-ui <Autocomplete /> getOptionLabel - 将空字符串作为值传递

获取 React Material-UI Autocomplete 中的值

Material-UI 中的 Autocomplete 组件不会导致任何渲染

在 Material-ui Autocomplete 组件上设置文本颜色、轮廓和填充