7

I have a date picker that I want to show when the users click anywhere in the field not just on the calendar icon.

Here's the picker

enter image description here

export function DatePickerField(props) {
  ......

  return (
      <Grid container>
          <MuiPickersUtilsProvider utils={DateFnsUtils}>
              <KeyboardDatePicker
                  {...field}
                  {...props}
                  disableToolbar
                  inputVariant="outlined"
                  value={selectedDate}
                  onChange={_onChange}
                  error={isError}
                  autoOk
                  invalidDateMessage={isError && error}
                  helperText={isError && error}
              />
          </MuiPickersUtilsProvider>
      </Grid>
  );
}

I need to do this because if date entered manually, it throws no errors but I get invalid date in the form data.

How can show the picker when the field is clicked?

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
Yankz Kuyateh
  • 612
  • 1
  • 5
  • 18

3 Answers3

17

MUI v5 added the DatePicker component in the @mui/lab package. If you want a picker to be opened after when the user clicked inside the TextField, use MobileDatePicker, this doesn't have the calendar icon though, see this answer if you want to have one.

<MobileDatePicker
  {...}
  renderInput={(params) => <TextField {...params} />}
/>

The DesktopDatePicker however does have the calendar icon, but you have to write additional code to control the open state and tell the picker to open when TextField is clicked:

<DatePicker
  open={open}
  onOpen={() => setOpen(true)}
  onClose={() => setOpen(false)}
  renderInput={(params) => {
    return (
      <TextField
        {...params}
        onClick={(e) => setOpen(true)}
      />
    );
  }}
/>

Codesandbox Demo


Original Answer

You can control the KeyboardDatePicker's open state and set it to true when the TextField is clicked:

const [open, setOpen] = useState(false);

return (
  <KeyboardDatePicker
    open={open}
    onOpen={() => setOpen(true)}
    onClose={() => setOpen(false)}
    TextFieldComponent={(props) => (
      <TextField {...props} onClick={(e) => setOpen(true)} />
    )}
    {...other}
  />
);

Live Demo

Edit 67053310/material-ui-datepicker

NearHuscarl
  • 66,950
  • 18
  • 261
  • 230
  • 1
    i'm facing one issue while using this after this my variant prop with inline value is not functioning properly, that datepicker does to top of the page not get inline with my textField. How can i fix this – sagg1295 Sep 30 '21 at 14:42
  • @sagg1295 what MUI version are you using? I'll update this answer to v5 right away. – NearHuscarl Sep 30 '21 at 14:46
  • i'm using @date-io/moment(1.3.13) & @material-ui/pickers(3.3.10) for implementing date picker. my code is something like this in this codesanbox link https://codesandbox.io/s/67053310-material-ui-datepicker-forked-bvr22?file=/demo.tsx:1159-1190 i'm not using MUI one native date picker using one you have used before, wrapping it in utils basically take care of all issues and you don;t have to handle it by yourself for maintaining logic for minDate, maxDate, errormsg etc everything is customisable. Please lmk if something is vague in my explaination of my problem – sagg1295 Sep 30 '21 at 16:19
4

For MUI-X Datepicker v6 using the slotProps it looks like this:

const [open,setOpen] = useState(false);
<DatePicker     
   open={open}
   onClose={() => setOpen(false)}
   slotProps={{
     textField: {
      onClick: () => setOpen(true),             
     },
   }}
 />
sirclesam
  • 2,109
  • 17
  • 13
0

If you are using <TextInput/> and not <DatePicker/>. If you are on an older version of Material UI that doesn't have DatePicker or just want to use TextInput.

import { useRef } from 'react'
import TextField from '@material-ui/core/TextField'

const DateInput = (props) => {
  const inputRef = useRef()
  return (
   <TextField
      {...props}
      type={'date'}
      inputRef={inputRef}
      onClick={() => {
        inputRef.current.showPicker()
      }} 
   />
)}
John Franke
  • 1,444
  • 19
  • 23