Hacker0x01 / react-datepicker

A simple and reusable datepicker component for React
https://reactdatepicker.com/
MIT License
7.96k stars 2.23k forks source link

Is there a way to disable typing/pasting into the date input and only allowing users to select from the date picker? #942

Open poushy opened 7 years ago

rafeememon commented 7 years ago

Use the readOnly prop: https://github.com/Hacker0x01/react-datepicker/blob/master/docs/datepicker.md

EDIT (Sept. 19, 2018): This behavior changed with https://github.com/Hacker0x01/react-datepicker/pull/1419, and this is no longer valid.

vicky-blr commented 6 years ago

I thought to use readOnly to make sure user can't paste something in this. If I use readOnly, required is not working for me. Any reasons why? Can we not use both together?

KarloZKvasin commented 6 years ago

In react-datepicker 1.6.0 - readOnly disabled all component. I can not select from the datepicker.

steinarb commented 6 years ago

I have the same experience as the previous poster: setting readOnly to true, prevented the date picker from popping up. Version 1.6.0 for me as well

steinarb commented 6 years ago

Looks like the new behaviour is intentional and new with 1.6.0, see https://github.com/Hacker0x01/react-datepicker/issues/1480#issuecomment-418777648

vicky-blr commented 6 years ago

Then is there any other option to disable typing/pasting directly into date-picker? Currently users can type texts as well in this. Obviously I can do verification by writing my custom logic but I'm just checking if there is already some flag that can disable manual typing or pasting something into this.

RohitoOo commented 6 years ago

@vicky-blr Please share your logic for validate dates

vicky-blr commented 6 years ago

@RohitoOo I'm just using required to make sure it not blank or null (like below)

<DatePicker minDate={minStartDate} maxDate={maxDate} selected={startDate} onChange={this.onChangeStartDate} required />

But as soon as I add readOnly (below), required is not working and its allowing blank value which is weird.

<DatePicker minDate={minStartDate} maxDate={maxDate} selected={startDate} onChange={this.onChangeStartDate} required readOnly />
SandeepKapalawai commented 5 years ago

the same issue with me and also until unless we don't strict the keyboard entering here, we have a write many validation conditions to check valid date entered and if there are any 2 fields like start date and end date, in this case, there are validations that need to write based on the comparison

joe-oli commented 5 years ago

as answered by @rafeememon and closed soon after, using 'readOnly' is not really an answer. It disables the whole component, including the popup calendar. What you can do is give the DatePicker component an id, then on componentDidMount use getElementById to find the embedded input element, and use JS to set it to .readOnly = true.

rafeememon commented 5 years ago

Reopening, as this behavior changed in #1419

shellandbull commented 5 years ago

I think its important to have an API where the end user is only allowed to select a date rather than manually inputting one. It guards us from input errors and odd behaviours

daws commented 5 years ago

I was able to get the desired behavior by adding a handler to onChangeRaw and preventing default:

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

...

render() {
  ...
  <DatePicker onChangeRaw={this.handleDateChangeRaw} ... />
  ...
}
vicky-blr commented 5 years ago

I was able to get the desired behavior by adding a handler to onChangeRaw and preventing default:

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

...

render() {
  ...
  <DatePicker onChangeRaw={this.handleDateChangeRaw} ... />
  ...
}

This gives expected behavior, thanks a lot for this option :)

rbar2 commented 5 years ago

Any plans to add an option to allow only selecting a date as @mariogintili mentioned?

@daws's option works for desktop, but not for mobile since the keyboard still shows. The only way to prevent the keyboard from showing on mobile appears to be reverting to version 1.5.0

Demonico commented 5 years ago

I think its important to have an API where the end user is only allowed to select a date rather than manually inputting one. It guards us from input errors and odd behaviours

On the surface I want to agree with you but this excludes anyone that has trouble with a mouse/pointing device.

charmstead commented 5 years ago

Try this. works for me

const CustomInput = (props) => {
    return (
        <input
            className={[classes.TransparentInput, "uk-input"].join(" ")}
            onClick={props.onClick}
            value={props.value}
            type="text"
            readOnly={true}
        />
    )
}
<DatePicker
  customInput={<CustomInput />}
  name={'from'}
  value={values['from']}
  onChange={e => setFieldValue('from', moment(e).format('L'))}
 />
mccombsr commented 5 years ago

Ahh yes. Wilarz89, you are right, I scrolled right past that one and it never even occurred to me to look at it a bit closer, but changing it to a button instead of an input seems like the perfect solution. Thanks for sharing!

gotkk commented 5 years ago

Use component withPortal Let see more https://github.com/Hacker0x01/react-datepicker/blob/master/docs/datepicker.md

dharmen1901 commented 5 years ago

I was able to get the desired behavior by adding a handler to onChangeRaw and preventing default:

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

...

render() {
  ...
  <DatePicker onChangeRaw={this.handleDateChangeRaw} ... />
  ...
}

Thanks

apnerve commented 4 years ago

I was able to get the desired behavior by adding a handler to onChangeRaw and preventing default:

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

...

render() {
  ...
  <DatePicker onChangeRaw={this.handleDateChangeRaw} ... />
  ...
}

I think this issue can be closed now as using onChangeRaw seems to be the right way to achieve the functionality we require. @rafeememon

steinarb commented 4 years ago

I think this issue can be closed now as using onChangeRaw seems to be the right way to achieve the functionality we require. @rafeememon

I think adding a handler onChangeRaw to get the desired behaviour (i.e. set the value from the calendar but not edit the date value) is a kludge.

DinAlla commented 4 years ago

My solution is:

  1. Set readOnly for input
  2. Set function for prop "onChangeRaw" like "e => e.preventDefault()"
rayatemukund commented 4 years ago

I used KeyboardDatePicker from material -

work around i create is -

onKeyPress={() => { this.handleKeypress(event)}}

//handle key press event handleKeypress = (e: Event) => { e.preventDefault(); return false }

It worked for me.

thomath47D commented 4 years ago

I used KeyboardDatePicker from material -

work around i create is -

onKeyPress={() => { this.handleKeypress(event)}}

//handle key press event handleKeypress = (e: Event) => { e.preventDefault(); return false }

It worked for me.

Tried all those solutions nothing works. But this work for me @rayatemukund Thanks man

addiegupta commented 4 years ago

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 />}
    />
  );
};
OlegGedzjuns commented 4 years ago

I was able to get the desired behavior by adding a handler to onChangeRaw and preventing default:

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

...

render() {
  ...
  <DatePicker onChangeRaw={this.handleDateChangeRaw} ... />
  ...
}

Worked for me, thanks!

LukaGiorgadze commented 3 years ago

What about

<KeyboardDatePicker
    inputProps={{ readOnly: true }}
    ...
max-programming commented 3 years ago

I finally found out the solution. Hope it helps others

// Style the button as you want I was using a UI framework
<DatePicker
  customInput={<button>{date.toLocaleDateString()}</button>}
  selected={date}
  onChange={changeDate}
  required
  withPortal // your choice
/>
arjunneeliyath commented 3 years ago

### You just need to override the TextFieldComponent`.

import React from "react"; import ReactDOM from "react-dom"; import TextField from '@material-ui/core/TextField'; import { KeyboardDatePicker, MuiPickersUtilsProvider, } from "@material-ui/pickers"; import DateFnsUtils from '@date-io/date-fns';

const TextFieldComponent = (props) => { return <TextField {...props} disabled={true} /> } function App() { const [selectedDate, setSelectedDate] = React.useState( new Date("2014-08-18T21:11:54") ); const handleDateChange = date => { setSelectedDate(date); }; return (

); }

const rootElement = document.getElementById("root"); ReactDOM.render(, rootElement);###

lobatolais commented 2 years ago

I was able to get the desired behavior by adding a handler to onChangeRaw and preventing default:

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

...

render() {
  ...
  <DatePicker onChangeRaw={this.handleDateChangeRaw} ... />
  ...
}

This gives expected behavior, thanks a lot for this option :)

I guess this is no longer working, since onChangeRaw was removed from DatePicker 😪

manutorresdev commented 2 years ago

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

I just had to write the OnKeyPress html input attribute to get rid of keyboard at Date Range Picker. Hope this helps! inputdisablekeyboard

chahat15 commented 2 years ago

If you want add readOnly to the datePicker 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=""
                   />
          )}
 />
mizanmahi commented 2 years ago

handleKeypress = (e: Event) => { e.preventDefault(); return false }

I am using a functional component and it seems not working for me, here is my code snippet


   const handleChange = (newValue) => {
      setDate(newValue);
   };

   const handleDateChangeRaw = (e) => {
      e.preventDefault();
   };

   return (
      <Box sx={{ maxWidth: '300px' }}>
         <LocalizationProvider dateAdapter={DateAdapter}>
            <DesktopDatePicker
               disablePast
               label='Date'
               inputFormat='MM/dd/yyyy'
               value={date}
               onChange={handleChange}
               renderInput={(params) => <TextField {...params} />}
               onChangeRaw={handleDateChangeRaw}
            />
         </LocalizationProvider>
      </Box>
   );
};```

What should I do in order to make this work? TIA.
steinarb commented 2 years ago

Is DesktopDatePicker a component from the same npm package as DatePicker?

This works for me in functional components:

`                            <DatePicker
                                selected={new Date(bonusStartDate)}
                                dateFormat="yyyy-MM-dd"
                                onChange={d => dispatch(MODIFY_BONUS_START_DATE(d))}
                                onFocus={e => e.target.blur()} />

(And not relevant to the actual DatePicker usage, but maybe puzzling: "dispatch" comes from useDispatch() hook and MODIFY_BONUS_START_DATE is a redux action created using the createAction() method from redux toolkit like so:

export const MODIFY_BONUS_START_DATE = createAction('MODIFY_BONUS_START_DATE');

)

volevol commented 2 years ago

use onKeyDown={e => e.preventDefault()} on inner TextField for DateTimePicker

<DateTimePicker
  id="startDate"
  ampm={false}
  name="startDate"
  label="Start date"
  value={formik.values.startDate}
  minDateTime={new Date()}
  onChange={value => formik.setFieldValue('startDate', value)}
  renderInput={params => (
    <TextField
      {...params}
      onKeyDown={e => e.preventDefault()}
      error={formik.touched.startDate && Boolean(formik.errors.startDate)}
      helperText={formik.touched.startDate && formik.errors.startDate}
    />
  )}
/>
jnahumphreys commented 2 years ago

Just spent an hour or so on this exact issue, the preventDefault works albeit you'll also want to apply some CSS to the TextField component to prevent focus on click (good for UX).

You can do that like this:

<TextField
  {...params}
  onKeyDown={(event) => event.preventDefault()}
  sx={{
    "& .MuiInputBase-root": {
      pointerEvents: "none",
    },

    "& .MuiInputBase-root button": {
      pointerEvents: "all",
    },
  }}
/>;
Nikualla1 commented 2 years ago

I was able to achieve it using InputProps={{ onKeyDown: e => e.preventDefault() }} like

<DatePicker ...restProps InputProps={{ onKeyDown: e => e.preventDefault() }} />
Aziaev commented 1 year ago

I've added a button styled like input, works for me

amit-gaikwad commented 1 year ago

for MUI version 6 all above will not work.

For version 6 below code will work:

 <DatePicker
            value={value}
            onChange={onChangeDate}
            slotProps={{
              textField: {
                     disabled: true,
              },
            }}
          />
Krishnare commented 10 months ago

useEffect(() => { setTimeout(()=>{ document.getElementsByClassName("MuiOutlinedInput-input")[0].disabled = true; },1000);

}, [])

use this it's disabling only input field

rupesh-agrawal-cw commented 7 months ago

The following code worked for me:

<DatePicker
    {...otherProps}
    slotProps={{
        textField: {
             readOnly: true,
         },
      }}
/>
davideastmond commented 6 months ago

"@mui/x-date-pickers": "^6.19.4",

<DateTimePicker
          slotProps={{
            field: {
              readOnly: true,
            },
          }} 
 />
Xameon commented 1 month ago

"@mui/x-date-pickers": "^6.19.4",

<DateTimePicker
          slotProps={{
            field: {
              readOnly: true,
            },
          }} 
 />

It's works for me ("@mui/x-date-pickers": "^7.10.0"). Thank you!