How to make the MUI Autocomplete read only?

Viewed 2344

Using @mui/material/Autocomplete, I cannot for the life of me make the component read only!

Even if the renderInput function returns a <TextField readOnly /> component, the drop down menu still trigger onChange events.

I tried <Autocomplete readOnly />, but the property gets ignored.

This seems to be a gross design oversight, or am I missing something? Not all components support the same properties.

Currently, I found that using disabled instead of readOnly yields the desired result, however this creates a non uniform form; certain fields are read only, others are disabled.


** Edit **

Those finding this issue should upvote and follow the ongoing issue on Github.


** Solution **

This is the working solution I have used :

import React, { forwardRef, useState } from 'react';
import PropType from 'prop-types';

import Autocomplete from '@mui/material/Autocomplete';

const AutocompleteEx = forwardRef(({
   readOnly,
   renderInput,
   ...props
}, ref) => {
   const [open, setOpen] = useState(false);
   
   return (
      <Autocomplete ref={ ref }
         open={ open }
         onOpen={ () => !readOnly && setOpen(true) }
         onClose={ () => setOpen(false) }
         disableClearable={ readOnly }
         renderInput={ ({ inputProps, ...params }) => renderInput({ ...params, inputProps: { readOnly, ...inputProps } }) }
         { ...props }
      />
   );
});
AutocompleteEx.propTypes = {
   readOnly: PropType.bool,
   renderInput: PropType.func.isRequired
};
AutocompleteEx.defaultProps = {
   readOnly: false
};

export default AutocompleteEx
3 Answers

In the v5.4.0 release, MUI added a readOnly prop that can be passed directly to the Autocomplete component:

<Autocomplete readOnly {...yourOtherProps} />

You can control the open state and make sure the dropdown is not opened if the Autocomplete is read only:

const [open, setOpen] = React.useState(false);
const [readOnly, setReadOnly] = React.useState(false);

return (
  <>
    <Button onClick={() => setReadOnly((o) => !o)}>toggle readonly</Button>
    <Autocomplete
      options={top100Films}
      open={open}
      onOpen={() => !readOnly && setOpen(true)}
      onClose={() => setOpen(false)}
      disableClearable={readOnly}
      renderInput={(params) => (
        <TextField
          {...params}
          InputProps={{ ...params.InputProps, readOnly }}
          label="Movie"
        />
      )}
    />
  </>
);

Live Demo

Codesandbox Demo

Simple solution could be :- just add readOnly={Boolean} as prop.

attached working sample

 <Autocomplete
    autoComplete
    id='combo-box-demo'
    options={allCities}
    getOptionLabel={(option) => {
      return option?.name;
    }}
    openOnFocus
    readOnly={!isEditable}
    includeInputInList
/>
Related