material-ui adding search icon in autocomplete component - reactjs

I am using #material-ui autocomplete for search and I want to add search icon next to autocomplete component
I tried something like this but after changing ---- option fields is not displaying
import TextField from "#material-ui/core/TextField";
import Autocomplete from "#material-ui/lab/Autocomplete";
.
.
.
<Autocomplete
id="combo-box-demo"
options={this.state.results} // .map((option) => option.title_display)
getOptionLabel={(option) => option.title}
style={{ width: 300 }}
onInputChange={this.handleInputChange}
renderInput={(params) => (
<TextField
{...params}
variant="outlined"
InputProps={{
endAdornment: (
<InputAdornment>
<IconButton>
<SearchIcon />
</IconButton>
</InputAdornment>
)
}}
/>
)}
/>
ANd if I just add searchicon it get added below the autocomplete component
<Fragment>
<Autocomplete
id="combo-box-demo"
options={top100Films}
getOptionLabel={(option) => option.title}
style={{ width: 300 }}
renderInput={(params) => <TextField {...params} label="Combo box" variant="outlined" />}
/>
<SearchIcon />
</Fragment>
https://codesandbox.io/s/material-demo-forked-qt99q?file=/demo.js

[this is output][1]
[1]: https://i.stack.imgur.com/JBSvO.png
import React, { useState, useEffect } from 'react';
import { TextField} from '#material-ui/core'
import InputAdornment from '#material-ui/core/InputAdornment';
import Autocomplete from '#material-ui/lab/Autocomplete';
import SearchIcon from '#material-ui/icons/Search';
import { makeStyles, Theme } from "#material-ui/core/styles";
export default function AddBusiness() {
const useStyles = makeStyles((theme: Theme) => ({
margin: {
padding: "10px 5px 5px 5px",
borderRadius: 4,
backgroundColor: theme.palette.common.white,
margin: theme.spacing(0),
border: "1px solid rgb(157, 157, 157)",
width: "100%",
},
}));
const classes = useStyles();
const [cityData, setCityData] = React.useState([]);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/todos')
.then(data => data.json())
.then(res => setCityData(res))
.catch(error => console.log(error))
}, [])
return (
<Autocomplete
id="combo-box-demo"
options={cityData}
getOptionLabel={(option: any) => option.title}
className={classes.margin}
style={{ paddingBottom: '8px' }}
renderInput={(params) => <TextField {...params} label=""
placeholder="Search City"
InputProps={{ ...params.InputProps,
startAdornment: ( <InputAdornment position="start"> <SearchIcon />
</InputAdornment> ),
disableUnderline: true }} />}
/>
)}

You can use display: "flex" for the parent to align its child in the same line.
And also align search icon at the center of the element,
<SearchIcon style={{ cursor: "pointer", padding: "17px" }} />
Hope you are expecting the same use case. Let me know if you are facing any issue.
Sample demo:- https://codesandbox.io/s/material-demo-forked-v17jz?file=/demo.js

This is the way you can customize the popup Icon
<Autocomplete
className={classes.root}
id="combo-box-demo"
options={boards}
getOptionLabel={(option) => option}
forcePopupIcon={true}
popupIcon={<SearchIcon />}
renderInput={(params) => (
<>
<TextField
placeholder="search"
{...params}
label="Combo box"
variant="filled"
/>
</>
)}
/>

Related

How not to spin mui autocomplete popup icon?

how not to spin search icon after open autocomplete input?
<Autocomplete
popupIcon={<Search />}
onChange={(e, value) => handleFound(value)}
options={['0', '2', '3', '1']}
sx={{ width: '100%' }}
renderInput={(params) =>
<TextField {...params} placeholder={'type anything...'} />
}
/>
You need to stop the rotation from the popup indicator styles, like this:
<Autocomplete
popupIcon={<Search />}
onChange={(e, value) => handleFound(value)}
options={["0", "2", "3", "1"]}
sx={{
width: "100%",
"& .MuiAutocomplete-popupIndicator": { transform: "none" },
}}
renderInput={(params) => (
<TextField {...params} placeholder={"type anything..."} />
)}
/>
Note that this is not the only solution but in my opinion is the fastest...

MUI textfield label not floating to the top left properly

I try to use the MUI in my project, and all the input fields I use don't behave correctly.
it supposed to look like this
but when I use it it will look like this
import Box from '#mui/material/Box'
import TextField from '#mui/material/TextField'
import Autocomplete from '#mui/material/Autocomplete'
<Autocomplete
className="mt-3"
size="small"
id="country-select-demo"
options={arr}
autoHighlight
getOptionLabel={(option) => option.label}
renderOption={(props, option) => (
<Box
component="li"
sx={{ '& > img': { mr: 2, flexShrink: 0 } }}
{...props}
>
{option.label}
</Box>
)}
renderInput={(params) => (
<TextField
{...params}
label="Choose.."
inputProps={{
...params.inputProps,
}}
/>
)}
I just found out that uninstalling the react-bootstrap fix this problem.

How can I set the placeholder of Autocomplete in a new line?

I'm using Autocomplete of material-ui and I have the list of the selected values and the placeholder in the same area. I would like to set the placeholder in a new line. I'm able to change the style of placeholder using makeStyles but I didn't find a way to going in a new line.
const useStyles = makeStyles ({
placeholder: {
"& input::placeholder": {
display: "block",
},
})
renderInput={(params) => (
<TextField
/* eslint-disable react/jsx-props-no-spreading */
{...params}
classes={{root: classes.placeholder}}
label="Selected Options"
placeholder="Availables Options"
variant="outlined"
color="primary"
/>
)
You can override the renderTags method, add a wrapper component around all selected tags, and set the wrapper width to 100% to push the placeholder element down like this:
<Autocomplete
multiple
options={top100Films.map((option) => option.title)}
renderTags={(value: string[], getTagProps) => (
<div style={{ width: "100%" }}>
{value.map((option: string, index: number) => (
<Chip
variant="outlined"
label={option}
{...getTagProps({ index })}
/>
))}
</div>
)}
renderInput={(params) => <TextField {...params} />}
/>
Live Demo

Material UI - Autocomplete Styling

I am trying to style the padding so that the icon is pushed to the far right side in an AutoComplete Material UI component which is currently being overridden by this style:
.MuiAutocomplete-hasPopupIcon.MuiAutocomplete-hasClearIcon .MuiAutocomplete-inputRoot[class*="MuiOutlinedInput-root"]
This is the code:
const useStyles = makeStyles(theme => ({
inputRoot: {
color: "blue",
fontFamily: "Roboto Mono",
backgroundColor: fade("#f2f2f2", 0.05),
"& .MuiOutlinedInput-notchedOutline": {
borderWidth: '2px',
borderColor: "blue"
},
"&:hover .MuiOutlinedInput-notchedOutline": {
borderWidth: "2px",
borderColor: "blue"
},
"&.Mui-focused .MuiOutlinedInput-notchedOutline": {
borderWidth: "2px",
borderColor: "blue"
}
}
}));
const textStyles = makeStyles({
formControlRoot: {
fontFamily: "Roboto Mono",
width: "50vw",
color: "#ffffff",
borderRadius: "7px",
position: "relative",
"& label.Mui-focused": {
color: "blue"
},
},
inputLabelRoot: {
color: "#ffffff",
fontFamily: "Roboto Mono",
"&.focused": {
color: "#ffffff"
}
},
});
export default function ComboBox() {
const classes = useStyles();
const textClasses = textStyles();
return (
<Autocomplete
id="combo-box-demo"
classes={classes}
// options={top100Films}
getOptionLabel={option => option.title}
renderInput={params => {
return (
<TextField
{...params}
label="Combo box"
variant="outlined"
classes={{ root: textClasses.formControlRoot }}
fullWidth
InputProps={{
...params.InputProps,
endAdornment: (
<InputAdornment position="end">
<SearchIcon />
</InputAdornment>
)
}}
InputLabelProps={{ classes: {root: textClasses.inputLabelRoot}}}
/>
);
}}
/>
);
}
And this is the result:
You are specifying the endAdornment for the Input, but Autocomplete also tries to specify the endAdornment. Your endAdornment is winning, but the Autocomplete is still trying to apply all of the CSS related to its end adornment (space for the popup icon and clear icon).
You can turn off the CSS related to the Autocomplete's end adornment by passing the props that turn off those features:
<Autocomplete
disableClearable
forcePopupIcon={false}
v4 CodeSandbox: https://codesandbox.io/s/autocomplete-with-custom-endadornment-86c87?file=/src/App.js
v5 CodeSandbox: https://codesandbox.io/s/autocomplete-with-custom-endadornment-euzor?file=/src/App.js
Alternatively, if you want to keep the clear icon and/or force-popup icon (arrow-drop-down icon), you can leverage cloneElement to add the search icon to the existing end adornment as shown below.
import React from "react";
import Autocomplete from "#mui/material/Autocomplete";
import TextField from "#mui/material/TextField";
import SearchIcon from "#mui/icons-material/Search";
import { styled } from "#mui/material/styles";
const StyledSearchIcon = styled(SearchIcon)`
vertical-align: middle;
`;
function addSearchIconToEndAdornment(endAdornment) {
const children = React.Children.toArray(endAdornment.props.children);
children.push(<StyledSearchIcon />);
return React.cloneElement(endAdornment, {}, children);
}
export default function ComboBox() {
return (
<Autocomplete
id="combo-box-demo"
options={top100Films}
getOptionLabel={(option) => option.title}
renderInput={(params) => {
return (
<TextField
{...params}
label="Combo box"
variant="outlined"
fullWidth
InputProps={{
...params.InputProps,
endAdornment: addSearchIconToEndAdornment(
params.InputProps.endAdornment
)
}}
/>
);
}}
/>
);
}

How to customize Autocomplete tag - Material UI

I'm using autocomplete of material ui and this is what default tag looks like
I want to customize tag like this.
How can i do that? Thank you.
<Autocomplete
disableCloseOnSelect={true}
multiple
options={this.options}
getOptionLabel={options => options.title}
value={this.state.value}
onChange={(e, techs) => {
this.newValue(techs);
}}
renderInput={params => (
<TextField
{...params}
variant="outlined"
placeholder={Technology}
fullWidth
/>
)}
></Autocomplete>
The renderTags prop from the Autocomplete API docs: https://material-ui.com/api/autocomplete/
The "tags" are Material UI Chips https://material-ui.com/components/chips/
so you can style an individual Chip component or variants to your liking and then override the default tags for Autocomplete.
Your styling for the chip would look something like
import { makeStyles } from '#material-ui/core/styles';
import Chip from '#material-ui/core/Chip';
export const useStyles = makeStyles((theme) => ({
root: {
borderRadius: 0,
color: labelColor,
boxSizing: 'border-box',
border: '1px solid',
borderColor: '#bddaff',
}
}));
;
const MyChip = (props) => {
const classes = useStyles();
return (
<Chip
className={classes.root}
{...props}
/>
);
};
And then you override the default chips
<Autocomplete
getOptionLabel={(option) => option.title}
label
placeHolder
multiple
openOnFocus
renderInput={(params) => <TextField {...params} label={label} placeholder={placeHolder} />}
renderTags={(tagValue, getTagProps) => {
return tagValue.map((option, index) => (
<MyChip {...getTagProps({ index })} label={option.title} />
));
}}
{...rest}
/>
);
You can use the tag CSS class to customize the tags as shown below.
import React from "react";
import TextField from "#material-ui/core/TextField";
import Autocomplete from "#material-ui/lab/Autocomplete";
import { withStyles } from "#material-ui/core/styles";
const CustomAutocomplete = withStyles({
tag: {
backgroundColor: "#a0a",
height: 24,
position: "relative",
zIndex: 0,
"& .MuiChip-label": {
color: "#fff"
},
"& .MuiChip-deleteIcon": {
color: "red"
},
"&:after": {
content: '""',
right: 10,
top: 6,
height: 12,
width: 12,
position: "absolute",
backgroundColor: "white",
zIndex: -1
}
}
})(Autocomplete);
export default function Tags() {
return (
<div style={{ width: 500 }}>
<CustomAutocomplete
multiple
id="tags-standard"
options={top100Films}
getOptionLabel={option => option.title}
defaultValue={[top100Films[13]]}
renderInput={params => (
<TextField
{...params}
variant="standard"
label="Multiple values"
placeholder="Favorites"
margin="normal"
fullWidth
/>
)}
/>
</div>
);
}
// 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 },
// ... plus many more
];

Resources