最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Material-ui Autocomplete - onChange not triggered when updating value in onHighlightChange - Stack Overflow

programmeradmin4浏览0评论

I've been working on an extended version of Material UI's Autoplete where I am implementing a feature that allows the user to move the option to the input via keyboard events (Arrow key up + down). The user should then be allowed to select one of the options via the ENTER key.

For some reason, the onChange event is not triggered and I am kind of puzzled to understand why this happens.

export default function Autopleter() {
  const [input, setInput] = React.useState(null);

  const handleInputChange = (event, option, reason) => {
    console.log('On input change triggered');
  };

  const handleOnChange = (event, value, reason) => {
    console.log('On change triggered! ');
  };

  const handleHighlightChange = (event, option, reason) => {
    if (option && reason === 'keyboard') {
      setInput(option);
    }
  };

  const handleFilterOptions = (currentOptions) => currentOptions;

  const handleGetOptionsLabel = (option) => {
    return option.label;
  };

  return (
    <Autoplete
      id="bo-box-demo"
      freeSolo={true}
      value={input}
      onChange={handleOnChange}
      onInputChange={handleInputChange}
      options={top100Films}
      isOptionEqualToValue={(option, value) => option.label === value.label}
      includeInputInList={true}
      onHighlightChange={handleHighlightChange}
      getOptionLabel={handleGetOptionsLabel}
      filterOptions={handleFilterOptions}
      style={{ width: 300 }}
      renderInput={(params) => (
        <TextField {...params} label="Combo box" variant="outlined" />
      )}
    />
  );
}

Here is also a working example:

.tsx,App.tsx,Autopleter.tsx

NOTE: This is a light example of my original code, but it should be enough to address the issue.

There are a few things I tried such as using inputValue in bination with the onHighlightChange but this does not seem to work either.

includeInputInList seemed to be the solution according to the doc, but it does nothing? Does anyone understand what it is supposed to do and is it helpful in my case?

UPDATE:

Updating the input state in onHighlightChange breaks the onChange. Unfortunately, I do want to update the input every time the user highlights an option via keyboard events.

Thank you for any kind of help and idea

I've been working on an extended version of Material UI's Autoplete where I am implementing a feature that allows the user to move the option to the input via keyboard events (Arrow key up + down). The user should then be allowed to select one of the options via the ENTER key.

For some reason, the onChange event is not triggered and I am kind of puzzled to understand why this happens.

export default function Autopleter() {
  const [input, setInput] = React.useState(null);

  const handleInputChange = (event, option, reason) => {
    console.log('On input change triggered');
  };

  const handleOnChange = (event, value, reason) => {
    console.log('On change triggered! ');
  };

  const handleHighlightChange = (event, option, reason) => {
    if (option && reason === 'keyboard') {
      setInput(option);
    }
  };

  const handleFilterOptions = (currentOptions) => currentOptions;

  const handleGetOptionsLabel = (option) => {
    return option.label;
  };

  return (
    <Autoplete
      id="bo-box-demo"
      freeSolo={true}
      value={input}
      onChange={handleOnChange}
      onInputChange={handleInputChange}
      options={top100Films}
      isOptionEqualToValue={(option, value) => option.label === value.label}
      includeInputInList={true}
      onHighlightChange={handleHighlightChange}
      getOptionLabel={handleGetOptionsLabel}
      filterOptions={handleFilterOptions}
      style={{ width: 300 }}
      renderInput={(params) => (
        <TextField {...params} label="Combo box" variant="outlined" />
      )}
    />
  );
}

Here is also a working example:

https://stackblitz./edit/react-ts-rsodyc?file=index.tsx,App.tsx,Autopleter.tsx

NOTE: This is a light example of my original code, but it should be enough to address the issue.

There are a few things I tried such as using inputValue in bination with the onHighlightChange but this does not seem to work either.

includeInputInList seemed to be the solution according to the doc, but it does nothing? Does anyone understand what it is supposed to do and is it helpful in my case?

UPDATE:

Updating the input state in onHighlightChange breaks the onChange. Unfortunately, I do want to update the input every time the user highlights an option via keyboard events.

Thank you for any kind of help and idea

Share Improve this question edited Oct 26, 2022 at 13:25 dsudo asked Oct 20, 2022 at 6:01 dsudodsudo 1934 silver badges23 bronze badges 1
  • Check this answer stackoverflow./a/59751227/5761648 – Bojan Tomić Commented Oct 20, 2022 at 6:27
Add a ment  | 

2 Answers 2

Reset to default 3 +50

Since I found that to my knowledge its not possible to check for a "Enter" key on the handleHighlightChange function I've e up with this.

highlightedInput is a seperate state for the highlighted value, this way you can keep track of the currently highlighted input. We set this in the handleHighlightChange after our checks.

We want to change our input state when we click Enter, normally when clicking the Enter key the dropdown closes. To handle this we can create a state for the open state of the dropdown. For this we need a handleOpen and a custom close handler handleOnclose here we can set the currently highlighted value (highlightedInput) to the actual input state.

const [input, setInput] = React.useState(null);
const [isOpen, setIsOpen] = React.useState(false);
const [highlightedInput, setHighlightedInput] = React.useState(null);

const handleOpen = () => {
  setIsOpen(true);
};

const handleOnClose = (event, option, reason, details) => {
  if (option && event.key === "Enter") {
    setInput(highlightedInput);
  }
  setIsOpen(false);
};

const handleInputChange = (event, option, reason) => {
  console.log("On input change triggered");
};

const handleOnChange = (event, value, reason) => {
  console.log("On change triggered!");
};

const handleHighlightChange = (event, option, reason) => {
  if (option && reason === "keyboard") {
    setHighlightedInput(option);
  }
};

const handleFilterOptions = (currentOptions) => currentOptions;

const handleGetOptionsLabel = (option) => {
  return option.label;
};

Note that we changed the value from the AutoComplete to the highlightedInput instead of input.

return (
  <React.Fragment>
    <Autoplete
      id="bo-box-demo"
      freeSolo={true}
      open={isOpen}
      onOpen={handleOpen}
      onClose={handleOnClose}
      value={highlightedInput}
      onChange={handleOnChange}
      onInputChange={handleInputChange}
      options={top100Films}
      isOptionEqualToValue={(option, value) => option.label === value.label}
      includeInputInList={true}
      onHighlightChange={handleHighlightChange}
      getOptionLabel={handleGetOptionsLabel}
      filterOptions={handleFilterOptions}
      style={{ width: 300 }}
      renderInput={(params) => (
        <TextField {...params} label="Combo box" variant="outlined" />
      )}
    />
    <div style={{ height: "200px" }}></div>
    {input?.label}
  </React.Fragment>
);

Live version

The onChange handler runs when the user selects an option from the drop down. Seams that you want the onInputChange event. That one fires when you type in the input field.

发布评论

评论列表(0)

  1. 暂无评论