Breif About Material UI AutoComplete feature and types
Material UI AutoComplete is the advanced version of Select dropdown field. It can be used in two ways Free Solo and Combo Box.
Free Solo – This type allows the user to select any arbitrary value by typing in the autocomplete text field but it is recommended to show possible values to the user through the list.
Combo Box – It restricts the user to choose only those values which are predefined set of values. If the user types any arbitrary value then that value will disappear once the user move away from the field and leaves the focus. These predefined values also ensure that user will always select the valid input for the autocomplete field.
We will see the different uses and custom styles of the two types of AutoComplete in the below examples.All the given example will work with the latest version MUI v5.
CUSTOMIZING THE DIFFERENT NESTED COMPONENTS OF THE MATERIAL UI AUTOCOMPLETE
1. HOW TO CUSTOMIZE THE MUI AUTOCOMPLETE DROPDOWN MENU
We can change the dropdown menu style using
PaperComponent prop of Autocomplete ,Paper component of mui with the sx props for styling the dropdown menu.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import TextField from "@mui/material/TextField"; import Autocomplete from "@mui/material/Autocomplete"; import Paper from "@mui/material/Paper"; export default function ComboBox() { return ( <Autocomplete options={optionList} renderInput={(params) => <TextField {...params} label="title" />} PaperComponent={(props) => ( <Paper sx={{ background: "lightblue", color: "red", fontSize: "25px", "&:hover": { border: "1px solid #00FF00", color: "gray", backgroundColor: "white" } }} {...props} /> )} /> ); } const optionList = [ { label: "The Shawshank Redemption", year: 1994 }, { label: "The Godfather", year: 1972 } ]; |
2. HOW TO SELECT THE MULTIPLE VALUES AND CHANGE THE STYLE OF MATERIAL UI AUTOCOMPLETE INPUT TAGS OR CHIPS
If we want to select multiple options from dropdown in autocomplete then we need to use the multiple prop.
To change the style of tags used to display multiple values , we need to use the renderTags prop and customize the tag style using the MUI Chip component as shown below.
We can change the default delete icon or clear button using the deleteIcon prop and use our own Icon.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
import { TextField, Chip } from "@mui/material"; import Autocomplete from "@mui/material/Autocomplete"; import DeleteIcon from "@mui/icons-material/Delete"; export default function ComboBox() { return ( <Autocomplete options={optionList} multiple renderInput={(params) => <TextField {...params} label="title" />} renderTags={(value, getTagProps) => value.map((option, index) => ( <Chip variant="filled" label={option.label} deleteIcon={<DeleteIcon />} {...getTagProps({ index })} sx={{height: "20px", background: "#F7EEFF", color: "#004AE0", fontSize: "10px" }} /> )) } /> ); } const optionList = [ { label: "The Shawshank Redemption", year: 1994 }, { label: "The Godfather", year: 1972 } ]; |
3. HOW TO STYLE THE AUTOCOMPLETE FIELD BORDER
We have to style the fieldset inside the TextField Component of AutoComplete to change the border style or to make other style changes like changing the background color etc.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
import { TextField, Autocomplete } from "@mui/material"; export default function ComboBox() { return ( <Autocomplete options={optionList} multiple renderInput={(params) => ( <TextField {...params} label="title" sx={{ fieldset: { border: "2px solid grey", borderRadius: "16px", boxShadow: "rgba(0, 0, 0, 0.35) 0px 5px 15px" } }} /> )} /> ); } const optionList = [ { label: "The Shawshank Redemption", year: 1994 }, { label: "The Godfather", year: 1972 } ]; |
4. HOW TO MAKE THE AUTOCOMPLETE TEXT FIELD WHICH CAN ACCEPT MULTIPLE ARBITRARY VALUES WITHOUT SHOWING THE DROPDOWN MENU
We can achieve this feature using autocomplete FreeSolo type. We can create a simple text field where we can type any value and press enter and then again type and press enter and so on to choose multiple values. There is no need to show the drop down to the user.
We will have to pass the empty array to the options prop to not to show the menu items.
1 2 3 4 5 6 7 8 9 10 11 12 |
import { TextField, Autocomplete } from "@mui/material"; export default function styledAutoComplete() { return ( <Autocomplete options={[]} freeSolo multiple renderInput={(params) => <TextField {...params} label="InputField" />} /> ); } |
5. HOW TO RESTRICT THE USER TO TYPE INPUT OF A FIXED MAXIMUM LENGTH AND DISABLE THE ENTER ONCE THE MAX LIMIT REACHES
If we are using the freesolo type like we used in the above example no.4 and we want to let the user type only the string of length 10 then we can restrict it by disabling the enter key.
We will use onKeyDown event to capture the key press for input length and capturing the enter key press and prevent the user to press enter using the defaultMuiPrevented.
Similarly, we can put the check of min and max date selection from the date calendar in input type=’date’
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import { TextField, Autocomplete } from "@mui/material"; export default function styledAutoComplete() { return ( <Autocomplete options={[]} freeSolo multiple renderInput={(params) => <TextField {...params} label="InputField" />} onKeyDown={(e) => { if (e.target.value.length > 10 && e.key === "Enter") { e.defaultMuiPrevented = true; } }} /> ); } |
6. HOW TO CUSTOMIZE THE FILTER OPTIONS IN MUI AUTOCOMPLETE
Suppose we have an array of options for Autocomplete options prop which has the following structure
Sometimes we come across a use case where we need to use multiple properties of an item to search from the list.
Like in the above example if somebody wants to search the item using the id or price values then autocomplete will not allow to do that until we use the prop know as filterOptions.
In filterOptions prop we will provide the filter method known as createFilterOptions(can be imported from mui library) to change the default filter option behaviour.
You can test the below example. It will allow you to search the item using any of the three properties(id,item_name,price) provided in the option list.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
import { TextField, Autocomplete, createFilterOptions } from "@mui/material"; export default function customFilterOptions() { return ( <Autocomplete options={optionList} renderInput={(params) => <TextField {...params} label="title" />} getOptionLabel={(option) => option.item_name || ""} filterOptions={createFilterOptions({ stringify: (option) => option.id + option.item_name + option.price })} /> ); } const optionList = [ { id: 101, item_name: "football", price: 2000 }, { id: 121, item_name: "basketball", price: 2300 }, { id: 123, item_name: "volleyball", price: 2500 }, { id: 124, item_name: "tennisball", price: 3300 } ]; |
IMPORTANT NOTE:-
Make sure that you do not return the number in the stringify inside the createFilterOptions method otherwise you will get the error because it uses the built in string methods like toLowerCase()
Suppose if you only return the id and typeof id is a number , it will throw an error. But if you are passing id along with the item_name by appending it using ‘+’ then there will be no error because it will convert the number into a string because you have concatenated a string with a number.