Reputation: 1214
I have TextField Select Material UI components based on a certain number of value in a variable.
{this.state.selectedNextHops.map((nextHop, index) => (
<div>
<TextField
select
className="vnfprofile-field"
InputProps={{ className: 'variable-value site-details-view-textfield' }}
InputLabelProps={{ shrink: true }}
SelectProps={{
MenuProps: {
className: 'vnf-designer-value',
getContentAnchorEl: null,
anchorOrigin: {
vertical: 'bottom',
horizontal: 'left',
}
},
}}
value = {this.state.selectedNextHops[index] || ''}
disabled={this.props.newPopoverPanelView === 'VIEW' ? true : false}
onChange={(e) => this.handleChange('nexthop', e)}
>
{this.state.remainingNextHops.length !== 0 ? this.state.remainingNextHops.map((option, i) => (
<MenuItem key ={i} value = {option || ''}>
{option}
</MenuItem>
)) :
<MenuItem value = {'No Data Available'}>
{'No Data Available'}
</MenuItem>}
</TextField>
<TextField
className="vnfprofile-field subnet-textfield"
InputProps={{ className: 'variable-value' }}
InputLabelProps={{ shrink: true }}
value = {'29'}
/>
</div>
))
}
The TextFields show up sequentially when I select value from the previous dropdown and filters the menu based on previous selection.
if(selectedNextHops.indexOf(event.target.value) === -1) {
selectedNextHops.push(event.target.value);
}
remainingNextHops = this.props.nextHopSapds.filter(nextHop => selectedNextHops.indexOf(nextHop) === -1);
this.setState({
selectedNextHops: selectedNextHops,
remainingNextHops: remainingNextHops
});
Update: Here is my handleChange Method ->
handleChange(type, event) {
let selectedNextHops = JSON.parse(JSON.stringify(this.state.selectedNextHops));
let remainingNextHops = [];
if(type === 'nexthop') {
selectedNextHops = selectedNextHops.filter(nh => nh !== '');
isContentChanged = true;
if(selectedNextHops.indexOf(event.target.value) === -1) {
selectedNextHops.push(event.target.value);
}
remainingNextHops = this.props.nextHopSapds.filter(nextHop => selectedNextHops.indexOf(nextHop) === -1);
if(remainingNextHops.length !== 0) {
selectedNextHops.push('');
}
this.setState({
selectedNextHops: selectedNextHops,
remainingNextHops: remainingNextHops
});
}
}
The state is updating fine, but the textfield does not display the selected value. I have tried everything I knew. Any help is appreciated.
Upvotes: 4
Views: 15026
Reputation: 8774
So you try to access the key with e.target.value.id but the target object has only the value and not the id itself. That is why it is undefined after you call the handleChange method. There is a way to access the key though:
The callback does not only pass the event but also the child object as second parameter and this can be used to get the key like this:
handleChangeTest = (event, child) => {
this.setState({
selectedID: child.key,
visibleValue: event.target.value
});
};
This will set the key as selectedID and the value of the selected item as visibleValue.
Upvotes: 3
Reputation: 17654
This is hard to debug without seeing a working snippet or the state ( especially this.state.selectedNextHops
) , but based on the code sandbox provided ( in the comment ) , I assume it's the same problem, so this answer will apply to the sandbox code :
this.setState({
selectedID: event.target.value.id,
visibleValue: event.target.value.name
});
event.target.value.id
and event.target.value.name
are undefined
,
console.log(console.log(event.target)) // {value: "S0002", name: undefined}
For the select
to display a selected option
, the value
attribute for both need to match :
<select value="2">
^^^^^^^^^
<option value="1">first value</option>
<option value="2">second value</option>
^^^^^^^^^
</select>
in the example in the code sandbox, the value of the Select
is value={this.state.visibleValue}
and the values of the options are value={x.label}
Since this.state.visibleValue
is always undefined
, you'll never see the value of the select
update.
A quick fix for this is to change the handleChage
function to :
handleChangeTest = event => {
this.setState({
selectedID: event.target.id,
visibleValue: event.target.value
});
};
but that will leave selectedID
undefined , to set it, add the attribute id={x.id}
to the option
and use event.currentTarget
to get its value :
{this.state.data.map(x => (
<MenuItem key={x.id} value={x.label} id={x.id}>
^^^^^^^^^
{x.name}
</MenuItem>
))}
And
handleChangeTest = event => {
this.setState({
selectedID: event.currentTarget.id,
^^^^^^^^^^^^^^^^^^^^^^
visibleValue: event.target.value
});
};
Upvotes: 5