I'm using Material UI Autocomplete component. I would like that when the user types something, and he gets no results, the noOptionsText
shows a button that can be clicked to do something:
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>
}
/>
);
}
Here the button appears successfully, but then when I click it the Autocomplete is closed before the button can receive the click.
It works if I set debug={true}
to force keep the menu open, but this have many other side effects.
Tried also forcing open={true}
but it still gets closed.
How would you do that?
Codesandbox demo: https://codesandbox.io/s/vigilant-haslett-sngyb?file=/src/App.js
When you click the button in the no-option menu, the TextField
is blurred (unfocused), you can know that by logging reason in onClose
callback
onClose={(e, reason) => {
console.log("on close", reason);
}}
The only way to suppress this is to set debug = true
as documented in Material-UI API docs.
But if you don't want to use debug
, there is another workaround by making the button part of the option menu itself. Remember unlike the no-option menu, you can register a click in the Autocomplete
menu to select option normally.
You can do that by filtering the option as usual but if there is no option found, return the button option instead. Here is an example
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;
}}
/>
);
}