Programmatically set value in material-ui Autocomplete TextField
Solution 1
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
/>
)}
/>
Solution 2
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"
/>
)}
/>
Solution 3
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
Sergey
Enthusiastic frontend developer from Russia. In love with React.js and would like to make the World a better place <3. Green peace supporter. NBA & skateboarding lover.
Updated on February 16, 2021Comments
-
Sergey about 3 years
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.
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 } ];
-
Fogus almost 4 yearsIf your Autocomplete can have multiple values (attribute
multiple
is set), then the value to thevalue
attribute should be an array. For the above case it would besetVal([top100Films[0]]);
instead ofsetVal(top100Films[0]);
-
Aquib almost 4 yearsPassing an array does not render anything.
-
africola almost 3 yearsNote that
value
in this example would be an array of objects, whileinputValue
should be a string: material-ui.com/api/autocomplete ThushandleChange
should setinputValue
using thetitle
property, e.g.setInputValue(top100Films[0].title
-
hane Smitter over 2 yearsi did this when using mui autocomplete and formik. When i set the default value on the autocomplete, formik state is not updated to take the default selected value into its state. Any idea of how this could be done