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 false
<Datetime open={false} />
or in your case if the condition is the state.doesExist
you could use the state value
<Datetime open={!state.doesExist} />
Or if you want to keep the default behavior if your state is true maybe you could try
<Datetime open={state.doesExist ? false : null} />
Edit:
For some reason, explicitely setting the null
default value of the open
prop, doesn't work, I found that workaround which is quite ugly but works...
<Datetime
//...props
{...Object.assign({}, state.doesExist ? {open:false} : {})}
/>