Cant get event.target.value using select item from material-ui autocomplete with onchange
Solution 1
Edit: Using e.target.textContent
will do the trick.
Here is a live Codesandbox to check the code (modified some parts, applying the tips below and some other things).
Don't mutate state manually like this:
this.state.itemSelected = true
Use setState (like you're already doing for other state items):
updateState(e) {
this.setState({ inputVal: e.target.value, itemSelected: true });
console.log(e.target.value);
// eventually I want to render a DIV with data from the selected value
}
Also a tip, you can use array destructuring:
const {isLoaded, itemSelected} = this.state;
Instead of
var isloaded = this.state.isLoaded;
var itemSelected = this.state.itemSelected;
Solution 2
onChange signature: function(event: object, value: any) => void
Here's an example:
import React from 'react';
import Chip from '@material-ui/core/Chip';
import Autocomplete from '@material-ui/lab/Autocomplete';
import TextField from '@material-ui/core/TextField';
export default class Tags extends React.Component {
constructor(props) {
super(props);
this.state = {
tags: []
};
this.onTagsChange = this.onTagsChange.bind(this);
}
onTagsChange = (event, values) => {
this.setState({
tags: values
}, () => {
// This will output an array of objects
// given by Autocompelte options property.
console.log(this.state.tags);
});
}
render() {
return (
<div style={{ width: 500 }}>
<Autocomplete
multiple
options={top100Films}
getOptionLabel={option => option.title}
defaultValue={[top100Films[13]]}
onChange={this.onTagsChange}
renderInput={params => (
<TextField
{...params}
variant="standard"
label="Multiple values"
placeholder="Favorites"
margin="normal"
fullWidth
/>
)}
/>
</div>
);
}
}
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 },
{ title: '12 Angry Men', year: 1957 },
{ title: "Schindler's List", year: 1993 },
{ title: 'Pulp Fiction', year: 1994 },
{ title: 'The Lord of the Rings: The Return of the King', year: 2003 },
{ title: 'The Good, the Bad and the Ugly', year: 1966 },
{ title: 'Fight Club', year: 1999 },
{ title: 'The Lord of the Rings: The Fellowship of the Ring', year: 2001 },
{ title: 'Star Wars: Episode V - The Empire Strikes Back', year: 1980 },
{ title: 'Forrest Gump', year: 1994 },
{ title: 'Inception', year: 2010 },
];
Sean Wayland
Updated on June 05, 2022Comments
-
Sean Wayland almost 2 years
*** CODE UPDATED FROM SUGGESTIONS ****** I am learning to use material-ui. I cant find many examples of combining it with event handling. I have used an autocomplete and a textfield to create a suggested list of data fetched from an API. I can render the selected list but on clicking one of the selections I can't get the value clicked on to be passed to a member function of the react class. Do I need to bind the event properly to the autocomplete? How should I do this. Line 25 in my code logs the event target to the console but it is always 0 ( null I assume ) . How can I set the value of the this.state.data to the clicked option ?
I tried adding autoSelect={true}
I also tried moving this line of code into the textarea .
onChange={this.updateState}import React from "react" import TextField from '@material-ui/core/TextField'; import Autocomplete from '@material-ui/lab/Autocomplete'; class App extends React.Component { constructor(props) { super(props); this.state = { data: null, isLoaded: false, itemSelected: false, inputVal: ''} this.updateState = this.updateState.bind(this) }; updateState(e) { e.persist() const newValue = e.target.value this.setState({inputVal: newValue, itemSelected: true}); console.log(e.target.value); // eventually I want to render a DIV with data from the selected value } /// fetch some data componentDidMount() { fetch('http://jsonplaceholder.typicode.com/posts') .then(response => response.json()) /* .then(json => console.log(json)) */ .then(data => this.setState({data, isLoaded: true})); } render() { const {isLoaded, itemSelected} = this.state; if (!isLoaded) { return <div> loading ...</div>; } else if (itemSelected) { return <div> item selected </div> } else { const limo = this.state.data; return ( <div> <Autocomplete freeSolo disableClearable autoSelect={true} id = "limoSelect" onChange={this.updateState} value = {this.state.inputVal} options={limo.map(option => "body: '" + option.body + '\n' + "' id: " + option.id)} renderInput={params => ( <TextField {...params} label="Type In Content" id="limoText" value = '' autoSelect={true} margin="normal" variant="outlined" fullWidth InputProps={{...params.InputProps, type: 'search'}} /> )} /> </div> ); } } } App.defaultProps = {} export default App;
console logs zero . When you click on the option the updateState is called and this variable is being set this.state.itemSelected = true; No error messages . I am hoping the console.log in the updateState can be made to log the clicked item !
-
EduardoSaverin over 4 yearstry using e.persist() before fetching value
-
Sean Wayland over 4 yearsThanks Eduardo. I tried this code but still logging zero : updateState(e) { e.persist() this.setState({inputVal: e.target.value, itemSelected: true}); console.log(e.target.value); // eventually I want to render a DIV with data from the selected value }
-
Sean Wayland over 4 yearsI also tried storing the value at the top of the function to try and deal with what might be an asynchronous issue : const newValue = e.target.value . That didn't help either.
-
Nicolas Hevia over 4 yearsI think I've found a solution, check my answer's edit
-
Sean Wayland over 4 yearsThanks !! That's a great help Nicolas. I am still trying to dig into that event and get the id of the clicked on option. I tried logging console.log(e.target) : I wonder how I can access the value of the "data-option-index" . If I could pull that id out I could render what I need which is all the info from the json data. <li tabindex="-1" role="option" id="limoSelect-option-4" data-option-index="4" aria-disabled="false" aria-selected="false" class="MuiAutocomplete-option" data-focus="true">body: 'repudiandae veniam quaerat
-
Nicolas Hevia over 4 years@SeanWayland You can get it using
console.log(e.target.getAttribute("data-option-index"))
. If it solved your issue, please accept my answer as the solution.
-
-
Sean Wayland over 4 yearsThanks Nicolas those are good suggestions. Using your updateState method the console.log(e.target.value) produces a zero. The clicked on option is not being passed up to that function I think.
-
Sean Wayland over 4 yearsthe const suggestion created this error . "Line 49:14: 'isloaded' is not defined no-undef"
-
Nicolas Hevia over 4 yearsThe error is because you had "var isloaded" and state is "isLoaded". Change
isloaded
toIsLoaded
hereif (!isloaded)