In my React app I have an input which could take value from the dropdown list. For that putpose I use material-ui Autocomplete and TextField components.
Question: how can I programmaticaly set an input value by clicking on the button without choosing from the dropdown list? For example, I want to set "The Godfather" from the example and this value should be visually seen in the input.
Codesandbox example here
import React from "react";
import Autocomplete from "@material-ui/lab/Autocomplete";
import { TextField, Button } from "@material-ui/core";
export default function ComboBox() {
const handleClick = () => {
// set value in TextField from dropdown list
};
return (
<React.Fragment>
<Autocomplete
options={top100Films}
getOptionLabel={option => option.title}
style={{ width: 300 }}
renderInput={params => (
<TextField
{...params}
label="Combo box"
variant="outlined"
fullWidth
/>
)}
/>
<Button onClick={handleClick}>Set value</Button>
</React.Fragment>
);
}
// Top 100 films as rated by IMDb users. http://www.imdb.com/chart/top
const top100Films = [
{ title: "The Shawshank Redemption", year: 1994 },
{ title: "The Godfather", year: 1972 },
{ title: "The Godfather: Part II", year: 1974 },
{ title: "The Dark Knight", year: 2008 }
];
if you want to show the default selected value in input you must also set inputValue property and onInputChange event of the Autocompelete component
changes in state:
const [value, setValue] = useState("");
const [inputValue, setInputValue] = useState("");
changes in handle click
const handleClick = () => {
setValue(top100Films[0]);
setInputValue(top100Films[0]);
};
changes in autocompelete
<Autocomplete
{...custom}
value={value}
inputValue={inputValue}
onChange={(event, newValue) => {
setValue(newValue);
}}
onInputChange={(event, newInputValue) => {
setInputValue(newInputValue);
}}
options={top100Films}
getOptionLabel={option => option.title}
renderInput={(params) => (
<TextField
{...input}
{...params}
variant="outlined"
/>
)}
/>
you can store desired value in state and pass it to auto complete component.
Import useState:
import React, { useState } from 'react';
using useState:
const [val,setVal]=useState({})
changin value on click of button
const handleClick = () => {
setVal(top100Films[0]);//you pass any value from the array of top100Films
// set value in TextField from dropdown list
};
and pass this value to component in render
<Autocomplete
value={val}
options={top100Films}
getOptionLabel={option => option.title}
style={{ width: 300 }}
renderInput={params => (
<TextField
{...params}
label="Combo box"
variant="outlined"
fullWidth
/>
)}
/>
If you're here trying to test a change handler that is called from MUI's Autocomplete
component:
In your setupTests.js file
import '@testing-library/jest-dom/extend-expect'
document.createRange = () => ({
setStart: () => {},
setEnd: () => {},
commonAncestorContainer: {
nodeName: 'BODY',
ownerDocument: document
}
})
In your test file:
import { render, fireEvent } from '@testing-library/react'
...
const { getByRole } = render(<MyComponentWithAutocomplete />)
const autocomplete = getByRole('textbox')
// click into the component
autocomplete.focus()
// type "a"
fireEvent.change(document.activeElement, { target: { value: 'a' } })
// arrow down to first option
fireEvent.keyDown(document.activeElement, { key: 'ArrowDown' })
// select element
fireEvent.keyDown(document.activeElement, { key: 'Enter' })
expect(autocomplete.value).toEqual('Arkansas')
expect(someChangeHandler).toHaveBeenCalledTimes(1)
For more examples, check out the tests in the library
No one gives the correct answer...
const options = [
{ label: "A", value: 1 },
{ label: "B", value: 2 },
{ label: "A", value: 3 },
];
function MyInput() {
const [value, setValue] = useState(options[0].value);
return (
<Autocomplete
value={options.find((option) => option.value === value)}
onChange={(_, v) => setValue(v?.value)}
options={options}
getOptionLabel={(option) => option.label}
renderInput={(params) => (
<TextField {...params}/>
)}
/>
)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With