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

6ovsh4lw  于 2023-05-16  发布在  Java
关注(0)|答案(2)|浏览(157)

我使用的材料UI选择组件,我试图建立一个过滤器内只显示的项目相匹配的输入由用户。
我建立了一个我正在开发的最小示例。

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,则select组件将选择One选项,并且我的文本字段的值不会更改。但是,如果用户键入F,则文本字段将更新为F
我想禁用此行为,所以,我一直试图阻止像onKeyUpCaptureonChangeCaptureonKeyDownCapture这样的事件的传播,但我还没有能够避免这一点。
你有什么建议来解决它吗?你可以在这里查看函数示例:

h9a6wy2h

h9a6wy2h1#

文本焦点导航功能是在MenuListonKeyDown中实现的(我大约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);

jgovgodb

jgovgodb2#

我多次面对这个问题,但我找到了一个最好的解决方案。
你可以通过在你的搜索输入菜单项上添加stopPropagation来解决它-

<MenuItem onKeyDown={e => e.stopPropagation()}><input type="text" /></MenuItem>

相关问题