本文介绍了在“选择"组件中按下选项的第一个字母时,如何禁用对项目的选择?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用材料UI选择组件,并且试图在内部构建过滤器,以仅显示与用户输入的内容相匹配的项目.

I'm using material UI Select component and I'm trying to build a filter inside to display only the items that match the input entered by the user.

我为正在开发的内容构建了一个最小的示例.

I build a minimal example of what I'm developing.

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>
  );
}

我现在的问题是,默认情况下,选择组件允许用户按下任何字母,并且如果存在第一个字母与用户输入内容匹配的选项,它将选择该选项.

My problem now is that by default the select component allows the user to press any letter and if there is an option in which the first letter matches the user input, it selects that option.

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

So, if I have 3 options (One, Two and Three) and the user types O the select component will select the One option and the value of my text field won't change. However, if the user types F the text field will be updated to F.

我想禁用此行为,因此,我一直试图停止传播onKeyUpCaptureonChangeCaptureonKeyDownCapture之类的事件,但我一直无法避免这种情况.

I would like to disable this behavior, so, I have been trying to stop the propagation of events like onKeyUpCapture, onChangeCapture, onKeyDownCapture but I haven't' been able to avoid this.

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

Do you have any suggestions to fix it?You can check the functional example here:

推荐答案

文本焦点导航功能在MenuListonKeyDown中实现(我实施大约6个月前).停止该事件在MenuItem上的传播(也可以停止在TextField上的传播),以防止该事件到达MenuList.

The text focus navigation functionality is implemented in the onKeyDown of MenuList (I implemented it about 6 months ago). Stopping propagation of that event on the MenuItem (it would also work to stop propagation on the TextField) prevents the event from reaching 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);

这篇关于在“选择"组件中按下选项的第一个字母时,如何禁用对项目的选择?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

11-01 17:38