Material UI多选Autocomplete移动端禁用键盘输入的技术问询
Hey there! I've dealt with this exact scenario before—wanting to keep the Autocomplete's desktop autocomplete and multi-select checkbox functionality, but prevent the mobile keyboard from popping up when interacting with it on phones/tablets. Let's break down the solution step by step.
Why Your Initial Attempt Didn't Work
When you added disabled to the TextField, it disables the entire input component (making it grayed out and unresponsive), but more importantly, it doesn't target mobile specifically. Plus, Autocomplete's internal logic might not propagate the disabled prop exactly as expected to the underlying input element in all cases. We need a way to block keyboard input only on mobile, while keeping the component interactive for touch selection.
Solution 1: Use readonly with Mobile Media Query (Recommended)
This approach leverages Material UI's useMediaQuery to detect mobile devices, then adds the readonly attribute to the input element. readonly prevents the keyboard from appearing while keeping the input area clickable (so users can still open the dropdown to select options).
Here's the full code example:
import Autocomplete from '@mui/material/Autocomplete'; import TextField from '@mui/material/TextField'; import Checkbox from '@mui/material/Checkbox'; import useMediaQuery from '@mui/material/useMediaQuery'; import { useTheme } from '@mui/material/styles'; function YourComponent() { const theme = useTheme(); // Detect if we're on a mobile device (adjust breakpoint as needed) const isMobile = useMediaQuery(theme.breakpoints.down('sm')); const yourOptions = [ { label: 'Option 1', value: 1 }, { label: 'Option 2', value: 2 }, { label: 'Option 3', value: 3 } ]; return ( <Autocomplete multiple options={yourOptions} disableClearable blurOnSelect="touch" // Render options with checkboxes (your existing multi-select setup) renderOption={(props, option, { selected }) => ( <li {...props}> <Checkbox checked={selected} /> {option.label} </li> )} renderInput={(params) => { // Modify input props to add readonly only on mobile const modifiedInputProps = { ...params.inputProps, ...(isMobile && { readOnly: true, // Ensure clicking the input still opens the dropdown onClick: (e) => { e.preventDefault(); params.InputProps.onClick(e); } }) }; return ( <TextField {...params} label="xxx" inputProps={modifiedInputProps} /> ); }} /> ); }
Solution 2: Block Keyboard Events on Mobile
If readonly doesn't fit your use case (e.g., you need to keep the input visually editable but block typing), you can intercept keyboard events and prevent them only on mobile:
renderInput={(params) => { const handleKeyDown = (e) => { // Block all keyboard input on mobile if (isMobile) { e.preventDefault(); } }; const modifiedInputProps = { ...params.inputProps, onKeyDown: handleKeyDown }; return ( <TextField {...params} label="xxx" inputProps={modifiedInputProps} /> ); }}
Key Notes
- Desktop remains functional: Both solutions only apply restrictions on mobile devices, so desktop users can still type to use the autocomplete feature.
- Preserves multi-select checkboxes: We keep the
renderOptionsetup for checkboxes, so your multi-select functionality stays intact. - Adjust breakpoints: The
theme.breakpoints.down('sm')targets screens smaller than 900px—you can change this tomdor a custom breakpoint if needed.
内容的提问来源于stack exchange,提问作者andyrandy

