I'm using react-datetime module in my form along with formik.
import React, { useImperativeHandle, useReducer, forwardRef } from 'react';
import PropTypes from 'prop-types';
import { Form} from "react-bootstrap";
import "react-datetime/css/react-datetime.css";
import { useFormik} from 'formik';
import * as yup from "yup";
import Datetime from 'react-datetime';
import moment from 'moment';
import { reducer } from '../common/reducer'
// Restrict future dates when entering "Date of Birth"
const validDOB = function( current ){
return current.isBefore(moment());
};
// Initial states of WorkloadForm
const initialState = {
doesExist: false
};
const WorkloadForm = forwardRef((props, ref) => {
// State Handling
const [state, dispatch] = useReducer(reducer, initialState);
// Initial Values for the WorkfloadForm
const initialValues = {
patDOB: '',
}
// Validation schema for form fields
const validationSchema = yup.object().shape({
patDOB: yup.string()
.test('invalid-dob', 'Please enter a valid DOB.', value => {
const dob = moment(value, 'DD-MM-YYYY', true);
return dob.isValid();
}),
});
// Form Submission Action
const handleSubmit = (values, actions) =>{
}
// Formik initialization of 'useFormik'
const formik = useFormik({
initialValues: initialValues,
onSubmit: handleSubmit,
validationSchema: validationSchema
});
// 'useImperativeHandle' to call formik actions from parent component
useImperativeHandle(ref, () => ({
...formik
}), []);
return (
<>
<Form noValidate onSubmit={formik.handleSubmit}>
<Form.Group controlId="patDOB">
<Form.Label>Date of Birth</Form.Label>
<Datetime
inputProps={{
placeholder: 'DD-MM-YYYY',
id: 'patDOB',
name: 'patDOB',
readOnly: state.doesExist ? true: false,
className: formik.errors.patDOB && formik.touched.patDOB ? "form-control is-invalid": "form-control"
}}
closeOnSelect={true}
dateFormat="DD-MM-YYYY"
timeFormat={false}
value={formik.values.patDOB}
isValidDate={validDOB}
onChange={(dateFromValue) => {
formik.setFieldValue('patDOB', moment(dateFromValue).format('DD-MM-YYYY'));
}
}
renderInput={(props) => {
return <input {...props} value={(formik.values.patDOB) ? props.value : ''} />
}}
/>
{formik.errors.patDOB && formik.touched.patDOB ? (
<div className="text-danger" style={{fontSize: '0.875em'}}>{formik.errors.patDOB}</div>
) : null}
</Form.Group>
</Form>
</>
);
})
WorkloadForm.propTypes = {
api: PropTypes.object.isRequired
};
export default WorkloadForm;
readOnly prop is working fine and it's conditional.
My issue is that I can still open the calendar or picker when I touch the field even though its readOnly.
How to prevent the field from opening the picker/calendar when it's readOnly?
Thanks
You can pass the
open
prop to falseor in your case if the condition is the
state.doesExist
you could use the state valueOr if you want to keep the default behavior if your state is true maybe you could try
Edit:
For some reason, explicitely setting the
null
default value of theopen
prop, doesn't work, I found that workaround which is quite ugly but works...