Disabling text input on MUI DateTimePicker - reactjs

I have a MUI DateTimePicker in my react app, and I would like to disable the text input so that it is only possible to change the date/time by clicking on the icon and launching the overlays to edit them.
I have tried a few things, such as adding disabled={true} to the renderInput, like this:
renderInput={(params: any) => <TextField
{...params}
disabled={true}
InputProps={{...params.InputProps, disableUnderline: true}}
variant="standard"/>}
Doesn't quite work as expected though. I have tried a lot of other things too, but not sure how that detail would support my question.
Suggestions?

Adding readOnly to the inputProps which will be passed down to the native html input element will do the trick. This also leaves the MUI component in its "normal" visual state.
<TextField
{...params}
disabled={true}
InputProps={{...params.InputProps, disableUnderline: true}}
inputProps={{ ...params.inputProps, readOnly: true }}
variant="standard"
/>

I was able to do exactly what you're asking by just adding the disabled prop to the TextField in renderInput.
<DateTimePicker
label="Date&Time picker"
value={value}
onChange={handleChange}
renderInput={(params) => <TextField {...params} disabled />}
/>
It's possible that you are trying to set the disabled property to true when it just assumes the property being on the component means it is disabled.

Related

How to remove of MUI 5 TextField label without having notched style?

I'm working on replacing the DatePicker component in our app with the new #mui DatePicker, and I'm having some trouble getting the TextField to render without the floating label and the notched input style. Here is my latest attempt:
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
onError={(reason, value) => console.log(reason, value)}
disableOpenPicker
className={styles.datepicker}
disableMaskedInput
onChange={() => undefined}
onAccept={handleAccept}
open={datePickerVisible}
value={getSafeDate(value) as Date}
onClose={partial(handleDatepickerVisibilityChange, false)}
{...datepickerProps}
renderInput={(params) => (
<TextField
id={id}
{...inputProps}
{...params}
onChange={handleInputChange}
error={errorText !== null}
helperText={errorText}
onBlur={handleValueChange}
onKeyPress={handleKeyPress}
hiddenLabel
size='small'
fullWidth
/>
)}
/>
</LocalizationProvider>
I've tried many different combinations for TextField props, such as adding InputLabelProps={{shrink:false}}, InputLabelProps={{shrink:true}}, and inputProps={{notched:false}} but always end up looking like this:
Does anyone have an idea of how to correct this, or if it's possible?
Thanks!
The issue was fixed in release v5.4.0
​[TextField] Remove notch when no label is added (#30560) #alisasanib
Updating to v5.4.0 should solve the issue.

How to set an empty label on Material-UI V5 (#mui/lab) datepicker component?

I'm working on migrating material-ui v4 to MUI v5 and I was using material-ui-pickers along with it.
I read the migration guide: https://mui.com/guides/pickers-migration/ and the docs, but I can't find and equivalent for the emptyLabel feature in: https://material-ui-pickers.dev/api/KeyboardDatePicker
emptyLabel on material-ui-pickers allowed you to set a custom text, that showed up when the value on the picker was set to null.
Is this a missing feature in MUI's date picker or am I missing something?
KeyboardDatePicker is no longer maintained and is now part of the lab components in MUI v5 as DatePicker (as explained in migration guide).
Actually there's no "emptyLabel" prop for DatePicker but you can achieve the same effect using the label prop and a check on your value provided to DatePicker:
<DatePicker
label={value === null ? "null value!" : "placeholder"}
value={value}
onChange={(newValue) => {
setValue(newValue);
}}
renderInput={(params) => <TextField {...params} />}
/>
see example here
Wouldn't using placeholder cover your desired use case?
<DatePicker
...
renderInput={(params) => (
<TextField
{...params}
inputProps={{
...params.inputProps,
placeholder: "Place for extra info"
}}
/>
)}
/>
Here is a live codesandbox example.

How to override autocomplete/autofill in material-ui autocomplete - React JS

I am using material-ui autocomplete ( https://mui.com/components/autocomplete/#free-solo ).
It's working fine, demo is here : https://codesandbox.io/s/0v9v9?file=/demo.tsx
by default Text input is showing autoComplete='off' but i want to change it to autoComplete='new-something' but it's not working and autoComplete='new-something' is showing as parent dev attribute instead of Input
I used this code
<TextField
{...params}
inputProps={{
...params.inputProps,
autoComplete: 'new-something',
}}
/>
But it's not working. In input it's still showing autocomplete="off" as input attribute.
As you can see in the doc https://mui.com/api/text-field/#props there is two props with the same name
inputProps: Attributes applied to the input element.
InputProps: Props applied to the Input element.
For autocomplete attribute you need inputProps
<TextField
{...params}
label="Search input"
InputProps={
...params.InputProps,
type: 'search',
}}
inputProps={{
autocomplete: 'something'
}}
/>
Here a working exanple in the codesanbox https://codesandbox.io/s/freesolo-material-demo-forked-8g2n1?file=/demo.tsx

How to make autocomplete field of material UI required?

I have tried a couple of ways in order to make the material UI's autocomplete field of type required but I am not getting the behavior that I wanted. I had encapsulated my field inside react hook form <Controller/> yet no luck. I want to trigger message 'Field is mandatory' on submit when nothing is added to the field.
Below is the code snippet, I have not removed comments so that it becomes a bit easier for others to understand the approach that I had followed earlier -
<Controller
name="displayName"
as={
<Autocomplete
value={lists}
multiple
fullWidth
size="small"
limitTags={1}
id="multiple-limit-lists"
options={moduleList}
getOptionLabel={(option) => option.displayName}
renderInput={(params,props) => {
return (
<div>
<div className="container">
<TextValidator {...params} variant="outlined" label="Display Name*" className="Display Text"
name="displayName" id="outlined-multiline-static"
placeholder="Enter Display-Name" size="small"
onChange={handleDisplay}
// validators={['required']} this and below line does throw a validation but the problem is this validation stays on the screen when user selects something in the autocomplete field which is wrong.
// errorMessages={['This field is required']}
// withRequiredValidator
/>
</div>
</div>
)
}}
/>
}
// onChange={handleDisplay}
control={control}
rules={{ required: true }}
// required
// defaultValue={options[0]}
/>
<ErrorMessage errors={errors} name="displayName" message="This is required" />
You can use the following logic to get it worked. Though this might not be the best solution but works.
<Autocomplete
renderInput={(params) => (
<TextField
{...params}
label={value.length === 0 ? title : title + " *"} //handle required mark(*) on label
required={value.length === 0}
/>
)}
/>
I tried using the built in required in textfield for autocomplete, and it works like a charm. Maybe you can use this as a reference.
<Autocomplete
renderInput={(params) => {
<TextField {...params} required />
}
// Other codes
/>
Since you are rendering <TextValidator>, you should apply mandatory(required) attribute to that component not on <AutomComplete>.
Try this if your Material UI version is v5
<TextField
{...params}
required
label="Tags"
value={value}
InputProps={{
...params.InputProps,
required: value.length === 0,
}}
/>

Setting a Max Length for a Material-UI AutoComplete that uses free solo

So I was using a Material-UI autocomplete with "free solo" set to true, and trying to limit the number of characters you can enter.
Just for reference, that's using
"#material-ui/core": "^4.10.0",
"#material-ui/lab": "^4.0.0-alpha.54",
I tried adding maxLength to InputProps on the inner TextField as an attribute with no joy.
I decided to post the answer, which I figured out, because it's NOT OBVIOUS.
<Autocomplete
freeSolo
options={
optionType === "alpha"
? alpha_options.map((option) => option.behavior)
: beta_options.map((option) => option.behavior)
}
onInputChange={(event, value) => {
setBehavior(value);
}}
renderInput={(params) => (
<TextField
{...params}
className={classes.input}
inputProps={{ ...params.inputProps, maxLength: process.env.REACT_APP_ENTRY_MAX_LENGTH}}
autoFocus={false}
margin="dense"
id="behavior"
label="Behavior"
placeholder="Complete this sentence"
type="text"
variant="outlined"
fullWidth
/>
)}
/>
Here are the CRUCIAL TRUTHS:
1) InputProps and inputProps are NOT the same thing. From the MUI docs on TextField....
inputProps: Attributes applied to the input element.
InputProps: Props applied to the Input element. It will be a
FilledInput, OutlinedInput or Input component depending on the
variant prop value.
Yes, I know this is incredibly stupid and frustrating.
2) In an AutoComplete, the TextField is a child component of the AutoComplete itself. In order to preserve that sweet, sweet AutoComplete functionality goodness, you have to pass the AutoComplete's inputProps down to the TextField.
Hence this line:
inputProps={{ ...params.inputProps, maxLength: process.env.REACT_APP_ENTRY_MAX_LENGTH}}
That is, using the spread operator, grab all the inputProps in the params, and spread 'em into the TextField's inputProps, then add to it with maxLength. That process.env value is just one stored in my create-react-app's .env file.
You're welcome.

Resources