Hi I am trying to implement material UI autocomplete dropbox with an icon next to the displayed text. my implementation is working, but when I select one of the options its not being displayed. The problem is with this part of the code:
renderInput={params => (
<Fragment>
<TextField
{...params}
variant="outlined"
label="Select Account"
placeholder="Favorites"
margin="normal"
fullWidth
/>
</Fragment>
)}
if I remove he icon rendering from getOptionLabel
then when selecting the selected text show just fine.
any help would be very much appreciated.
right now the result of this code looks like:
import React, { Fragment, useState } from 'react';
import { connect } from 'react-redux';
import PropTypes from 'prop-types';
import {makeStyles} from "@material-ui/core";
import Autocomplete from "@material-ui/lab/Autocomplete/Autocomplete";
import TextField from "@material-ui/core/TextField";
import FacebookIcon from '@material-ui/icons/Facebook';
import AppleIcon from '@material-ui/icons/Apple';
import IconButton from "@material-ui/core/IconButton";
const useStyles = makeStyles(theme => ({
Select: {
width: 425,
},
icon: {
color: '#0095e2'
},
}));
const SelectAccount = ({ clientAccountsData, accountSelected }) => {
const accountSelectedHandler = async (event, values) => {
if ( values !== null )
{
accountSelected(values);
}
else {
accountSelected('');
}
};
const renderCorrectAccountChannelIcon = (network_id) => {
if ( network_id=== '1' )
{
return (
<FacebookIcon/>
);
}
else if ( network_id=== '2' )
{
return (
<img
src={'/Icons/snapchat.png'}
height={30}
width={30}
/>
);
}
else if ( network_id=== '3' )
{
return (
<img
src={'/Icons/google.png'}
height={30}
width={30}
/>
);
}
else if ( network_id=== '4' )
{
return (
<AppleIcon/>
);
}
};
const classes = useStyles();
return (
<div className='material-ui'>
<Autocomplete
className={classes.Select}
id="account_select"
options={clientAccountsData}
onChange={accountSelectedHandler}
getOptionLabel={option =>
{
return(
<Fragment>
<Icon className={classes.icon}>
{
renderCorrectAccountChannelIcon(option.network_id)
}
</Icon>
{option.accountName + ' (' + option.accountId + ')'}
</Fragment>
);
}
}
filterSelectedOptions
renderInput={params => (
<Fragment>
<TextField
{...params}
variant="outlined"
label="Select Account"
placeholder="Favorites"
margin="normal"
fullWidth
/>
</Fragment>
)}
/>
</div>
);
};
SelectAccount.prototypes = {
accountSelected: PropTypes.func.isRequired,
clientAccountsData: PropTypes.array.isRequired,
};
const mapStateToProps = state => ({
clientAccountsData: state.client.clientAccountsData,
});
export default connect(mapStateToProps, {})(SelectAccount);
EDIT!: Found a fix, we need to use renderOption to render the icon + text and use getOptionLabel just for the label text it looks like this:
<Autocomplete
className={classes.Select}
id="account_select"
options={clientAccountsData}
onChange={accountSelectedHandler}
getOptionLabel={option => option.accountName + ' (' + option.accountNumber + ')'}
renderOption={option => {
return (
<Fragment>
<Icon className={classes.icon}>
{
renderCorrectAccountChannelIcon(option.network_id)
}
</Icon>
{option.accountName + ' (' + option.accountNumber + ')'}
</Fragment>
);
}}
filterSelectedOptions
renderInput={params => (
<Fragment>
<TextField
{...params}
variant="outlined"
label="Select Account"
placeholder="Favorites"
margin="normal"
fullWidth
/>
</Fragment>
)}
/>
I want to share maybe a new spin off of this solution that is based of the autocomplete example in the documentation (autocomplete demos). Keeps the image in the selected tag as well.
<Autocomplete
multiple
limitTags={2}
id="multiple-limit-tags"
options={top100Films}
getOptionLabel={(option) => option.title}
defaultValue={[top100Films[13], top100Films[12], top100Films[11]]}
renderTags={options =>
{
return (
options.map(option =>
<Fragment>
<IconButton color="primary">
<img src={'../src/img/Tables.svg'}/> {/*Mock image, attribute in option*/}
</IconButton>
{option.title}
</Fragment>))
}}
renderOption={option => {
return (
<Fragment>
<IconButton color="primary">
<img src={'../src/img/Tables.svg'}/> {/*Mock image, attribute in option*/}
</IconButton>
{option.title}
</Fragment>
);
}}
renderInput={(params) => (
<TextField
{...params}
variant="outlined"
label="limitTags"
placeholder="Favorites"
/>
)}
/>
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