javascript - 如何在选择组件中按下选项的第一个字母时禁用项目的选择?

标签 javascript reactjs typescript material-ui

我正在使用 Material UI Select 组件,我正在尝试在内部构建一个过滤器以仅显示与用户输入的输入相匹配的项目。

我构建了一个我正在开发的最小示例。

function App() {
  const [selectedOption, setSelectedOption] = React.useState("");
  const [filterExpression, setFilterExpression] = React.useState("");

  const onChangeSelection = (
    event: React.ChangeEvent<{ name?: string | undefined; value: unknown }>,
    child: React.ReactNode
  ) => {
    const value = event.target.value.toString();
    setSelectedOption(value);
  };

  const onChangeExpression = (
    event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    const value = event.target.value.toString();
    console.log(`value:`, value);
    setFilterExpression(value);
  };

  const stopImmediatePropagation = (e: any) => {
    e.stopPropagation();
    e.preventDefault();
  };

  return (
    <div className="App">
      <Select onChange={onChangeSelection} value={selectedOption}>
        <MenuItem
          dense
          divider
          value={""}
          onClickCapture={stopImmediatePropagation}
        >
          <TextField value={filterExpression} onChange={onChangeExpression} />
        </MenuItem>

        <MenuItem dense key={"One"} value={"One"}>
          One
        </MenuItem>
        <MenuItem dense key={"Two"} value={"Two"}>
          Two
        </MenuItem>
        <MenuItem dense key={"Three"} value={"Three"}>
          Three
        </MenuItem>
      </Select>
    </div>
  );
}

我现在的问题是,默认情况下,选择组件允许用户按任何字母,如果有第一个字母与用户输入匹配的选项,它会选择该选项。

所以,如果我有 3 个选项(OneTwoThree)并且用户输入 O选择组件将选择 One 选项,我的文本字段的值不会改变。但是,如果用户键入 F,文本字段将更新为 F

我想禁用此行为,因此,我一直在尝试阻止诸如 onKeyUpCaptureonChangeCaptureonKeyDownCapture 等事件的传播但我无法避免这一点。

您有任何修复建议吗? 您可以在此处查看功能示例:

Edit inspiring-ramanujan-sv25c

最佳答案

文本焦点导航功能是在 MenuListonKeyDown 中实现的(我 implemented it 大约 6 个月前)。停止在 MenuItem 上传播该事件(它也可以停止在 TextField 上传播)阻止事件到达 MenuList

import * as React from "react";
import { render } from "react-dom";
import TextField from "@material-ui/core/TextField";
import Select from "@material-ui/core/Select";
import MenuItem from "@material-ui/core/MenuItem";

import "./styles.css";

function App() {
  const [selectedOption, setSelectedOption] = React.useState("");
  const [filterExpression, setFilterExpression] = React.useState("");

  const onChangeSelection = (
    event: React.ChangeEvent<{ name?: string | undefined; value: unknown }>,
    child: React.ReactNode
  ) => {
    const value = event.target.value.toString();
    setSelectedOption(value);
  };

  const onChangeExpression = (
    event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>
  ) => {
    const value = event.target.value.toString();
    console.log(`value:`, value);
    setFilterExpression(value);
  };

  const stopImmediatePropagation = (e: any) => {
    e.stopPropagation();
    e.preventDefault();
  };

  return (
    <div className="App">
      <Select onChange={onChangeSelection} value={selectedOption}>
        <MenuItem
          dense
          divider
          value={""}
          onClickCapture={stopImmediatePropagation}
          onKeyDown={e => e.stopPropagation()}
        >
          <TextField value={filterExpression} onChange={onChangeExpression} />
        </MenuItem>

        <MenuItem dense key={"One"} value={"One"}>
          One
        </MenuItem>
        <MenuItem dense key={"Two"} value={"Two"}>
          Two
        </MenuItem>
        <MenuItem dense key={"Three"} value={"Three"}>
          Three
        </MenuItem>
      </Select>
    </div>
  );
}

const rootElement = document.getElementById("root");
render(<App />, rootElement);

Edit Stop text focus navigation

关于javascript - 如何在选择组件中按下选项的第一个字母时禁用项目的选择?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58378786/

相关文章:

javascript - 方 block 几乎不动(Javascript)

javascript - PubNub 存在重复 403 禁止错误

javascript - 为什么 fetch 在捕获错误后仍返回?

node.js - 如何在生产模式下使用 npm 代理(如 package.json 中的 proxy 参数)?

Typescript:对象类型到数组类型(元组)

javascript - 将文本区域中的特定文本设为粗体

javascript - 我如何在函数组件中使用 typeScript 来限制类型和默认值

reactjs - 如果状态码为400,如何获取获取响应数据

javascript - 如何将 Tradingview js 注入(inject) React Typescript 渲染函数?

javascript - React.FunctionComponent 和普通的 JS 函数组件有什么区别?