Reputation: 446
I would like to add a 'clear' button to a DatePicker
from @mui/lab
(5.0.0-alpha.55).
What I am attempting:
date
field in state, passed as the value
prop to DatePicker
date
to null
when desired to 'clear' the value & inputThe behaviour I observe:
date
is valid, it works as expected, and the input is cleareddate
is not valid, the error
is cleared, but the invalid date still stays in the input.The rudimentary version I have attempted which shows the behaviour above can be seen here.
If you input a partial date, then click clear
, you can observe that the input does not get cleared.
I would prefer to avoid a solution that involves changing the key
, as that brings other issues, such as not respecting an external source changing the date
to null
, and needing additional hacks to respect the label
transition when clearing the input.
Upvotes: 24
Views: 51826
Reputation: 60
To clear the Material-UI DatePicker input when the value is invalid, make sure to pass null to the value prop when the input doesn't meet your validation criteria. For example:
<DatePicker
value={isValidDate ? selectedDate : null}
...
/>
This approach ensures the DatePicker input resets appropriately
Upvotes: 0
Reputation: 21
<DatePicker
slotProps={{
actionBar: {
actions: ['clear'],
},
}}
/>
The other solution to clear an invalid date is to pass a state to your date picker to maintain the value and reset it to null. Below is the code snippet:
<DatePicker
label={props?.label}
slotProps={{
actionBar: {
actions: [props?.clearable?.toString()],
},
inputAdornment: {
onClick: () => {
setIsOpen(true);
},
},
toolbar: {
toolbarFormat: props?.disableToolbar,
},
...(!props.disablePopper && {
popper: { disablePortal: true, open: isOpen },
}),
textField: {
inputProps: {
onFocus: (e) => {
setIsOpen(false);
setDisplay(false);
},
style: props?.InputProps?.style,
onBlur: (e) => {
props?.onBlur ? props.onBlur(e) : handleDateChange(e);
},
onKeyDown: (e) => {
props?.isEXR
? props?.onKeyDown && props.onKeyDown(e)
: handleKeyDown(e);
},
},
placeholder: props?.placeholder ? props?.placeholder : "Enter Date",
},
}}
slots={{
...props,
...props?.dateProps,
}}
autoFocus={!display}
onChange={props?.isEXR ? props.onChange : () => undefined}
onAccept={handleDateChange}
onClose={() => setIsOpen(false)}
minDate={props.minDate ? dayjs(props.minDate) : null}
maxDate={props.maxDate ? dayjs(props.maxDate) : null}
sx={
props.style || {
width: props?.style?.width || "100%",
borderRadius: 4,
fontSize: props?.style?.fontSize || "12px",
}
}
format={
display
? props?.format || DIPLAY_DATE_FORMAT_DAYJS
: INPUT_DATE_FORMAT_DAYJS
}
disabled={props?.isEXR && props?.disabled}
readOnly={props.disabled}
value={props.value ? dayjs(props.value) : null}
onError={(e) => {
return props.onError ? props.onError(e) : "Date Not Valid";
}}
/>
Upvotes: 0
Reputation: 805
@mui/x-date-pickers
package version v6.16.0
now has this feature built in:
import { DatePicker } from '@mui/x-date-pickers/DatePicker';
<DatePicker
slotProps={{ field: { clearable: true } }}
/>
source: https://github.com/mui/mui-x/releases/tag/v6.16.0
Upvotes: 18
Reputation: 732
For @mui/x-date-pickers
v5 you could do:
<DatePicker
componentsProps={{
actionBar: {
actions: ['clear'],
},
}}
onAccept={(newDate) => {
console.log(newDate);
}}
/>
and see if newDate
is null
.
Important updates:
@mui/x-date-pickers
v6 please see the other commentclear
will make the user stuck on mobile. Consider having ['clear', 'accept']
for mobile and ['clear']
for desktop, or simpler, merge the behavior by using the property closeOnSelect={true|false}
to force on both platforms.Upvotes: 24
Reputation: 327
I've tried it many ways but finally what worked for me is to change key while clearing from custom clear button, looks little dirty but that only what I was possibly able to
const [pickerKey, setPickerKey] = useState("pickerKey");
const handleClear = useCallback(() => {
onChange("");
setPickerKey(Math.random().toString());
}, [onChange]);
<DatePicker
...
key={pickerKey}
...
/>
Upvotes: 5
Reputation: 141
As an extension to Thomas' answer, you can pass clear
to the slotProps
if you are using MUI 5:
<MobileDatePicker
...
slotProps={{
actionBar: {
actions: ['clear']
}
}}
...
/>
References:
Upvotes: 12
Reputation: 116
how about this custom component?.
const DatePickerClear = (props) => {
const { onClear } = props;
return (
<LocalizationProvider dateAdapter={AdapterDateFns}>
<DatePicker
{...props}
renderInput={(params) => (
<div style={{ position: "relative", display: "inline-block" }} >
<TextField {...params} />
{props.value &&
<IconButton style={{ position: "absolute", top: ".5rem", margin: "auto", right: "2rem" }} onClick={() => onClear()}>
<ClearIcon />
</IconButton>
}
</div>
)
}
/></LocalizationProvider >
)
}
export default DatePickerClear
I give you too a github basic project in react.
https://github.com/HastaCs/MUI_DatePicker_ClearButton
Upvotes: 4
Reputation: 85
This is what I did to make the clear function work. I recently found this solution so I might change this in the future... but for now it's fine.
<MobileDateTimePicker
...
clearable
clearText="Clear"
onChange={(newScheduleDateTime) => {
if (newScheduleDateTime) {
setScheduleDateTime(newScheduleDateTime);
} else {
setScheduleDateTime(null);
}
}}
/>
Upvotes: -3
Reputation: 731
MUI DatePicker has a clearable property. When set to true, it shows a clear button. You can change the text of the clear button using the clearText property. I would point out however, that it does not trigger an onChange event, nor is there an onClear event (at the time of writing this post). So when I am using it, its not possible to change the state that way. However the onAccept event is fired, and if you pass the value parameter, it will be null.
<MobileDatePicker
open
clearable
label="some label"
inputFormat="yyyy-MM-dd"
value={stateDate}
onChange={(date) => updateAvailableDate(date)}
renderInput={(params) => (
<TextField
{...params}
/>
)}
onClose={() => hideModal()}
clearText="Clear me"
onAccept={(value) => handleSave(value)}
/>
See all the api settings here. https://mui.com/api/date-picker/
Upvotes: -1
Reputation: 81390
My theory is that internally, DatePicker
only updates the input value if it's different with the last valid value. Below is how the bug can occur:
DatePicker
when there is a valid value (like the initial Date
), the state is reset successfully at first (value=null
, inputValue=''
)value=Invalid Date
, inputValue='invalid Text'
)value
is invalid, it does not count and the DatePicker
references the last valid value instead which is null
, then decide that the current value doesn't change and skip dispatching the new input value (value=null
, inputValue='invalid Text'
).I'd classify this as a bug from MUI, you can create an issue on github if you want it to be fixed. In the meanwhile, you can fix the bug by applying this patch using patch-package
:
patch-package
: npm i patch-package
postinstall
script in the package.json
"scripts": {
"postinstall": "patch-package"
}
node_modules\@mui\lab\internal\pickers\hooks\useMaskedInput.js
and change it based on this commit.npx patch-package @mui/lab
to create the patch that will be applied every time after you ran npm i @mui/lab
again.Upvotes: 6