react-datepicker icon indicating copy to clipboard operation
react-datepicker copied to clipboard

readOnly={true} disables DatePicker instead of preventing edit (and keyboard appearing on mobiles)

Open steinarb opened this issue 6 years ago • 39 comments

The problem occurs in react-picker version 1.6.0

Expected behavior

That the DatePicker would pop up allowing to select a date when clicking into the DatePicker <input> field, but the keyboard wouldn't appear on mobile devices

Actual behavior

The DatePicker doesn't appear when clicking into the DatePicker <input> field

Steps to reproduce

Create a <DatePicker> component with readOnly set to true, e.g. like so:

<DatePicker selected={performedjob.transactionDate} dateFormat="YYYY-MM-DD" onChange={(selectedValue) => onDateFieldChange(selectedValue, performedjob)} readOnly={true} />

steinarb avatar Sep 05 '18 15:09 steinarb

Looks like the new behaviour is intentional: c8c106e766f7893efe3833bebf8fcfe8fea2bf46

steinarb avatar Sep 05 '18 15:09 steinarb

Downgrading to 1.5.0 and setting readOnly={true} gave me the desired behaviour on mobile devices: tapping into the date field pops up the date picker, but not the mobile keyboard

steinarb avatar Sep 05 '18 15:09 steinarb

If you want your users to only use the calendar control and not the input field, you need to use an alternate method for blocking text input - read-only has a defined meaning, per W3C - it specifies the value can not be edited by the user. see

https://www.w3.org/TR/html401/interact/forms.html#adef-readonly

bcullman avatar Sep 18 '18 17:09 bcullman

@bcullman I understand the way you've interpreted W3C's read-only definition, but you understand it now acts differently than the HTML input's readonly functionality which is what the react-datepicker element renders?

mellis481 avatar Nov 15 '18 19:11 mellis481

@steinarb I downgraded to 1.5.0 and the readOnly behavior is the same as 1.7.0 (it disabled the input) in Chrome.

mellis481 avatar Nov 16 '18 02:11 mellis481

@steinarb I downgraded to 1.5.0 and the readOnly behavior is the same as 1.7.0 (it disabled the input) in Chrome.

Maybe a caching issue? Try opening your application in chrome incognito.

steinarb avatar Nov 17 '18 06:11 steinarb

I'm having the same issue. I would like to disable keyboard for mobile rendering, as it hides the actual date picker, making it quite non-user-friendly at the moment.

I see that using readOnly used to work, and that you have decided to disable that functionality. Could you maybe change your mind and go back to the way it worked before, or implement support for this in another way? It seems several people needs this functionality :)

lendresen87 avatar Dec 04 '18 13:12 lendresen87

+1

Yakima-Teng avatar Dec 04 '18 15:12 Yakima-Teng

There is also an accessibility concern here. readonly is announced by screen readers and other assistive technologies.

If you are allowing editing via the datepicker when it is set readonly, you are creating an inaccessible experience. Users with screen readers will be told the field is readonly and will have no incentive to explore using the supplied datepicker.

bcullman avatar Dec 04 '18 22:12 bcullman

@bcullman , I see, I guess it is good that you take that into consideration. Maybe readOnly should be kept as it is. But would you consider implementing support for disabling keyboard in another way? My alternative is to use another date picker, and I'd prefer using yours.

lendresen87 avatar Dec 05 '18 08:12 lendresen87

Found a workaround for now.

Workaround is to force read only on input field to make it work as before, if it will help anyone else in the same boat:

if (this.datePicker && this.datePicker.input) { this.datePicker.input.readOnly = true; }

Hope to be able to use a built-in feature in the future instead of this workaround. :)

lendresen87 avatar Dec 05 '18 10:12 lendresen87

There is also an accessibility concern here. readonly is announced by screen readers and other assistive technologies.

If you are allowing editing via the datepicker when it is set readonly, you are creating an inaccessible experience. Users with screen readers will be told the field is readonly and will have no incentive to explore using the supplied datepicker.

Yes, it quite a good consideration to take into. Actually, people found this webpack want to have this datepicker to be available in mobile platform, it's not so important that whether the detailed implementation for this feature is related to the readOnly attribute or not. :)

I don't have a good workaround now, maybe you can support this feature just using readOnly like before but with strong emphasis on its accessibility problem in the documentation. Or otherwise, it would be better to add note in the documentation that this datepicker is not suitable for mobile platform. Actually I find this datepicker by searching in npm repository and this plugin has good ranking in the searching result, then I read the documentation finding no statement whether it's for PC or mobile platform, then I had a try... If the documentation can includes content for the suitable scene, it will save me some time.

Yakima-Teng avatar Dec 06 '18 14:12 Yakima-Teng

This works for me.

<DatePicker placeholderText="Click to select a date" onChange={this.handleChange} selected={this.state.date} dateFormat="MMMM DD, YYYY" minDate={moment()} ref={el => this.onDatepickerRef(el)} customInput={ <Input labelPosition="right" label={<div className="label__text">Date</div>} /> } />

and

onDatepickerRef(el) { if (el && el.input) { el.input.inputRef.readOnly = true; } }

radicalloop avatar Dec 07 '18 08:12 radicalloop

This works for me.

<DatePicker placeholderText="Click to select a date" onChange={this.handleChange} selected={this.state.date} dateFormat="MMMM DD, YYYY" minDate={moment()} ref={el => this.onDatepickerRef(el)} customInput={ <Input labelPosition="right" label={<div className="label__text">Date</div>} /> } />

and

onDatepickerRef(el) { if (el && el.input) { el.input.inputRef.readOnly = true; } }

Thank you. That worked for me too. I had to make a minor change though.

onDatepickerRef(el) { if (el && el.input) { el.input.readOnly = true; } }

OmkarRa avatar Jan 17 '19 10:01 OmkarRa

Try this. works for me

const CustomInput = React.forwardRef((props,ref) => {
    return (
        <input
            className={[classes.TransparentInput, "uk-input"].join(" ")}
            onClick={props.onClick}
            value={props.value}
            type="text"
            readOnly={true}
            ref={ref}
        />
    )

})
<DatePicker
  customInput={<CustomInput />}
  name={'from'}
  value={values['from']}
  onChange={e => setFieldValue('from', moment(e).format('L'))}
 />

The setFieldValue is from formik. you can choose not to use formik. Your choice.

charmstead avatar Apr 23 '19 19:04 charmstead

@wilarz89 thats not what people want. People want an input that is readonly and when clicked on the date picker opens, they select a date and then the readonly inout populates with their date.

@charmstead Might be on to something here.

AdamKyle avatar May 30 '19 00:05 AdamKyle

This is ridiculous - you should at least give us the option to make input read-only, while allowing for datepicker to appear. Right now this issue is forcing devs to come up with some weird spaghetti just because you changed the important part of your library without providing the alternatives.

ghost avatar Aug 19 '19 10:08 ghost

Simple fix was inputProps={{readOnly: true}}

vigneshnallamad avatar Aug 29 '19 10:08 vigneshnallamad

this work like a charm @vigneshnallamad (y)

gowdruNikhil avatar Aug 29 '19 10:08 gowdruNikhil

This seems to work

onFocus={e => e.target.blur()}

alinjie avatar Jan 14 '20 07:01 alinjie

@AliNjie 's solution works, tested on Android tablet with Firefox

simoneborgio avatar Jan 16 '20 14:01 simoneborgio

Simple fix was inputProps={{readOnly: true}}

but after applying this, the "required" does not work

santi-oktavia avatar Mar 17 '20 13:03 santi-oktavia

Simple fix was inputProps={{readOnly: true}}

You're a life savior !

Josha2 avatar May 27 '20 17:05 Josha2

Another option can be to use a custom input button

https://reactdatepicker.com/#example-custom-input

() => {
 const [startDate, setStartDate] = useState(new Date());
 const ExampleCustomInput = ({ value, onClick }) => (
   <button className="example-custom-input" onClick={onClick}>
     {value}
   </button>
 );
 return (
   <DatePicker
     selected={startDate}
     onChange={date => setStartDate(date)}
     customInput={<ExampleCustomInput />}
   />
 );
};

addiegupta avatar Jun 29 '20 08:06 addiegupta

Simple fix was inputProps={{readOnly: true}}

This works pretty cool for me thank you Pal

christian-manrique avatar Nov 07 '20 15:11 christian-manrique

This seems to work

onFocus={e => e.target.blur()}

It works for me. Thanks a lot

ValeryFilipyeu avatar Feb 16 '21 16:02 ValeryFilipyeu

Simple fix was inputProps={{readOnly: true}}

Thank you @vigneshnallamad

anuj-developer avatar Apr 07 '21 05:04 anuj-developer

SIMPLE SOLUTION:

in your return component use onInput that triggers validDateInput function

const validDateInput = function(e) { e.target.value = "" }

<DatePicker onInput={(e) => validDateInput(e)} maxDate={new Date()} dayPlaceholder="DD" monthPlaceholder="MM" yearPlaceholder="YYY" value={dateOfJoin} onChange={(dateOfJoin) => { setDateOfJoin(dateOfJoin) }} className="mx-3" ></DatePicker>

novel-code avatar Oct 19 '21 12:10 novel-code

This works for me:

<DatePicker
  allowClear={readOnly ? false : undefined}
  open={readOnly ? false : undefined}
  inputReadOnly={readOnly}
/>

DavraYoung avatar Mar 05 '22 22:03 DavraYoung

If you want add readOnly to the datePicker(React MUI) and only want you to use calender for taking input. You can do this.

 const readOnlyOnFocus = (e) => {
    console.log(e.target.readOnly=true)
 }
<DatePicker
          renderInput={(params) => (
                  <LightTextField
                      onFocus={readOnlyOnFocus}
                       defaultValue=""
                   />
          )}
 />

chahat15 avatar Mar 30 '22 06:03 chahat15