Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

material ui autoComplete with icons

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: enter image description here

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>

                    )}
                />
like image 214
user3657538 Avatar asked Dec 19 '19 08:12

user3657538


1 Answers

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" 
        />
    )}
  />

enter image description here

like image 108
Júlio Almeida Avatar answered Sep 19 '22 13:09

Júlio Almeida