How do I spawn my date picker UI upon first clicking on the date text field? How do I spawn my date picker UI upon first clicking on the date text field? reactjs reactjs

How do I spawn my date picker UI upon first clicking on the date text field?


Multiple issues to handle while solving this:

  1. Since you want to the focus on the Input to control the opening of the DatePicker Popover - has to be a controlled component (which you control the opening of it using a state.
    This state is actually the open prop of the KeyboardDatePicker
  2. Next issue is that once the Popover is closed - the focus is getting back to the Input, and once we have a focus the the Popover will open (not good). We can solve this using the disableRestoreFocus prop of the Popover.
  3. We need to use the onFocus of the Input to open the Popover, but the onClose of the Popover to actually close it (because we control the open-state of the Popover).
  4. Lastly - the icon is no longer controlling the opening of the Popover. We need to do this, using the onFocus of the KeyboardButtonProps.

This is the complete code:

const KeyDatePickerContainer = () => {  const [selectedDate, handleDateChange] = useState(null);  const [isOpen, setIsOpen] = useState(false);  return (    <KeyboardDatePicker      variant="inline"      value={selectedDate}      inputVariant="outlined"      label="With keyboard"      format="MM/dd/yyyy"      onChange={newDate => {        handleDateChange(newDate);      }}      KeyboardButtonProps={{        onFocus: e => {          setIsOpen(true);        }      }}      PopoverProps={{        disableRestoreFocus: true,        onClose: () => {          setIsOpen(false);        }      }}      InputProps={{        onFocus: () => {          setIsOpen(true);        }      }}      open={isOpen}    />  );};

Here is a link to a working example: https://codesandbox.io/s/material-pickers-open-modal-click-on-text-kjgjk

Update: if you want to also close the DatePicker once the date was selected you can use the onChange function to not only set the new date, but also close the Popover:

onChange={newDate => {    handleDateChange(newDate);    setIsOpen(false); // Add this}}


For anyone else interested I came up with the following solution:

  1. You change the KeyboardDatePicker to DatePicker
  2. You take advantage of InputProps and add the calendar icon
    InputProps={{        endAdornment: (            <InputAdornment>                <Event />            </InputAdornment>        )     }}

Working sandbox:https://codesandbox.io/s/customicon-forked-zitm9?file=/src/DatePicker.js


For anyone who uses updated material-ui library (v5), you can use open={bool} attribute to make use of when to open DatePicker.

           const [dateOpen,setDateOpen] = useState(false);           const [dueDate,setDueDate] = useState(new Date());                <DatePicker                  clearable={true}                  open={dateOpen}                  onClose={() => setDateOpen(false)}                  label="Due Date"                  value={dueDate}                  minDate={new Date()}                  onChange={(newValue) => {                    setDueDate(newValue);                  }}                  renderInput={(params) => (                    <TextField                      {...params}                      onClick={() => setDateOpen(true)}                    />                  )}                />