6

I'm using react-date-picker, but on mobile the native keyboard shows up when clicked causing the date-picker to open on top, which doesn't look great. The online solution is to put the readonly attribute on the input field the date picker is bind with. But the read-date-picker component won't let me pass that prop...

Any nice solutions for this?

valdeci
  • 13,962
  • 6
  • 55
  • 80

10 Answers10

10

The readOnly is a good option to prevent the browser from showing the keyboard and typing on mobile. With the readonly set you will still be able to launch a click event on it.

When talking about the react-date-picker module the this will be also useful in non-mobile devices.

It is possible to add the option readOnly={true}, but it will disable completely the date picker inputs on all devices, as we can see on the following issues:

Also, you will need to handle the onClick event and I don't think that this is a good idea.

Current workaround

At the moment, the solution to make the keyboard disabled on mobile and set the readOnly for all datePickers inputs will be edit the input properties on the component componentDidMount event:

 componentDidMount() {
    const datePickers = document.getElementsByClassName("react-datepicker__input-container");
    Array.from(datePickers).forEach((el => el.childNodes[0].setAttribute("readOnly", true)))
};
valdeci
  • 13,962
  • 6
  • 55
  • 80
4

A working solution using React hooks

const pickerRef = useRef(null)

useEffect(() => {
    if (isMobile && pickerRef.current !== null) {
      pickerRef.current.input.readOnly = true;
    }
}, [isMobile, pickerRef]);

return (<DatePicker ref={pickerRef} ... />)

nattog
  • 81
  • 3
4
<DatePicker
. . . . .
onFocus={(e) => e.target.readOnly = true}
/>

This works for me.

  • 1
    You have not provided any _reason_ why your solution is an improvement on the ones already provided. – kimbert Oct 04 '21 at 19:38
  • 1
    This worked for me and was the easiest and shortest to implement of all the solutions – Vee20 Jan 27 '22 at 06:06
2

So I ended up modifying the input-element in the componentDidMount lifecycle, like so;

document.getElementsByTagName("input")[0].setAttribute("readonly", "readonly");

This prevents the native visual keyboard on my phone to display. However it creates this "not allowed" red ugly cursor on desktop when hovering the input field, so I fixed that with by targeting my date-picker input.

.react-datepicker-wrapper input[readonly]{cursor: pointer;}

I welcome alternative solutions though.

1

A variation on Caroline Waddell's answer that got me unblocked on react-datepicker 2.8.0. The id of the date picker element is date-picker-input so modifying the the attribute after getting it by the id:

componentDidMount() {
    document.getElementById('date-picker-input').setAttribute('readonly', 'readonly');
  }

Did the trick for me if you have more than one input on the page.

John
  • 11
  • 1
0

Just hit this myself. Create a custom input with a button that opens the picker with the text of the selected value.

const ReadonlyInput = ({ value, onClick }: any) => (
  <button onClick={onClick}>
    {value}
  </button>
);

return (
  <ReactDatePicker
     selected={fieldValue}
    ...
     customInput = {<ReadonlyInput />}
   />
)
0

React datepicker has className react-datepicker__input-container. So

const datePickers = document.getElementsByClassName(
      "react-datepicker__input-container"
    );

This returns an HTML collection which needs to be converted to an array. You can use Array.from but this is not supported in IE 11. So, it is better to use native for loop. So

for (let i = 0; i < datePickers.length; i++) {
      datePickers[i].childNodes[0].setAttribute("readonly", true);
    }
0

I used something like this onChangeRaw={(e)=>handleDateChangeRaw(e)} which allowed me to disable keyboard type option and i made the cursor pointer .

 const handleDateChangeRaw = (e:React.FormEvent<HTMLInputElement>) => {
        e.preventDefault();
      }

           <DatePicker                
                selected={(value && new Date(value)) || null}
               onChange={val => { onChange(name, val); }}
                dateFormat={ dateFormat }
                minDate={new Date()}
                timeIntervals={1}
                onChangeRaw={(e)=>handleDateChangeRaw(e)}
                />  
    .react-datepicker__input-container input {
       cursor: pointer;
    }
Dharman
  • 30,962
  • 25
  • 85
  • 135
0

JSX (React) Create a Custom Input with readOnly option

const DateCustomInput = ({ value, onClick }) => (
    <input className="classes" readOnly onClick={onClick} placeholder='Date of 
    Birth' value={value}/>
 );

Use this with datePicker

 <DatePicker
        id="preferred-date" name="EnquireNow[prefered_date]"
        selected={date}
        customInput={<DateCustomInput />}
    />

This will ensure calendar still pops up (which is not happening with readOnly props with DatePicker) but native keyboards do not pop up. This will not allow to edit the input even in desktop mode. To allow that use readOnly with mobile devices only

0

You can blur it onFocus to keep the keyboard closed but the datepicker options open, like:

<Datepicker onFocus={e => e.target.blur()} />
Nate Beers
  • 1,355
  • 2
  • 13
  • 22