Kumara
Kumara

Reputation: 528

React datepicker disable entering date manually

I am using React date-picker for my form. Currently it's working well, but the user can delete the date and enter whatever values. How do I restrict it?

This is my code:

import DatePicker from "react-datepicker";

    <DatePicker
    name="invoiceDate"
    className="form-control form-control-sm"
    type="text"
    size="sm"
    placeholder=""
    selected={date}
    minDate={new Date()}
    value={values.setDate}
    onChange={datePickerChange}
    dateFormat="dd/MM/yyyy"
    />

Upvotes: 13

Views: 27486

Answers (8)

Nody00
Nody00

Reputation: 1

You can use the editable prop on your component:

<DatePicker editable={false} />

Upvotes: 0

Abinesh Rajendran
Abinesh Rajendran

Reputation: 1

Try this: <DatePicker onFocus={e => e.target.blur()} />

Upvotes: 0

Denis S Dujota
Denis S Dujota

Reputation: 611

accepted answer does not solve the problem accross browsers.

you need to do a combination of hacks to get this working on IOS, Safari, FireFox, Smart TV Browsers etc..

There is no need to make a custom input if you are just trying to resolve the keyboard showing up on Mobile/Tablet/TVs.

  const handleFocus = (e: ReactClickEvent<HTMLInputElement>) => {
    const { target } = e;

    if (target) {
      target.readOnly = true;  // -------> this for all others
      target.blur(); //  ------> this for ios iphone, TV Browsers, Ipad, Safari
    }
  };

  <ReactDatePicker 
     ..whatever your props are
     onFocus={handleFocus} /// <----- add this prop
   />

Upvotes: 3

Henry
Henry

Reputation: 45

On your <DatePicker /> component:

<DatePicker onKeyDown={(e) => {e.preventDefault()}} />

This will prevent anything from being typed in the input as the prop name suggests

Upvotes: 0

mahan
mahan

Reputation: 14935

The accepted answer does not hide keyboard in mobile.


You need to use a custom input component. Instead of input, use a HTMLButtonElement. You may style it to look like a HTMLInputElement.

type DatePickerCustomInputProps = { value: string; onClick: (event: React.MouseEvent<HTMLElement>) => void }

const DatePickerCustomInput = forwardRef(
  ({ value, onClick }: DatePickerCustomInputProps, ref: ForwardedRef<HTMLButtonElement>) => (
    <button type="button" className={"date-picker-custom-input"} onClick={onClick} ref={ref}>
      {value}
    </button>
  )
)

<DatePicker
  dateFormat={setting.datoFormat}
  selected={new Date(value)}
  onSelect={(date: Date) => {
    onChange(date.toISOString())
  }}
  customInput={React.createElement(DatePickerButtonInput)}
  onChange={(date: Date) => {
    onChange(date.toISOString())
  }}
/>

If you do not use typescript, do this:

<DatePicker
  dateFormat={setting.datoFormat}
  selected={new Date(value)}
  onSelect={(date: Date) => {
    onChange(date.toISOString())
  }}
  customInput={<DatePickerButtonInput />}
  onChange={(date: Date) => {
    onChange(date.toISOString())
  }}
/>

Upvotes: 1

Gaurav Mahor
Gaurav Mahor

Reputation: 71

Just add this line of code to DatePicker:

disabledKeyboardNavigation={false}
format="dd/MM/yy"

You can add your date format; It will only take date.

Upvotes: 3

andras
andras

Reputation: 3645

I think onBeforeInput should be used in this case, as opposed to onKeyDown.

So just simply:

onBeforeInput={(e) => {
    e.preventDefault();
}}

The reason being, that onKeyDown prevents a lot of 'normal' functionality from working when the input is focused. E.g.:

  • Page reload with CTRL + R
  • Opening devtools with F12
  • Going to the next input with Tab

And in case of ReactDatePicker, the customInput property has to be used to pass in an input that has onBeforeInput overridden as explained.

Upvotes: 1

Majid M.
Majid M.

Reputation: 4954

Just add this line of code to DatePicker :

onKeyDown={(e) => {
    e.preventDefault();
}}

After adding this event, your component's code will be like the below code :

<DatePicker
    name="invoiceDate"
    className="form-control form-control-sm"
    type="text"
    size="sm"
    placeholder=""
    selected={date}
    minDate={new Date()}
    value={values.setDate}
    onChange={datePickerChange}
    dateFormat="dd/MM/yyyy"
    onKeyDown={(e) => {
       e.preventDefault();
    }}
  />

Edit patient-silence-ybz45

Upvotes: 31

Related Questions