I am building an application with React-Bootstrap and Hooks to pre-populate the form with previously known values. However, when the date input is rendered, it shows the placeholder text 'dd/mm/yyyy' despite the underlying value of the element containing the correct pre-set value, and hence the Save action if the field is untouched still works correctly.
The field appears within a Form Group, with the form becoming editable when the button is clicked (switching the button text in the above screenshot from 'Update' to 'Save', and swapping the date field to show the datepicker rather than a text field showing the calculated age):
Form when read only Form when editable
In terms of function, the user is still able to select the date and text in the field is then updated to reflect the date selected as expected, it is just the initial default value which doesn't show. This is frustrating as the users may not need to change this field but it appears to wipe the info if they don't.
I have tried using different
Code for the input field:
//hooks
const [editable, setEditable] = useState(false);
const [name, setName] = useState(user.name);
const [dob, setDob] = useState(user.dob);
//functions called
export const dateFromDateString = (dateString) => {
return moment(new Date(dateString)).format('YYYY-MM-DDT00:00:00.000');
};
export const dateForPicker = (dateString) => {
return moment(new Date(dateString)).format('YYYY-MM-DD')
};
const calculateAge = (date) => {
return moment().diff(date, 'years', false);
};
//form with irrelevant fields removed
<Form className="personalInfo">
{editable ?
<Form.Group as={Row} className="mb-3 align-items-center" controlId="dobInput">
<Form.Label column lg={4}>Date of Birth:</Form.Label>
<Col>
<Form.Control type="date"
defaultValue={dateForPicker(dob)}
onfocus={dateForPicker(dob)}
placeholder={dob ? dateForPicker(dob) : "dd/mm/yyyy"}
onChange={(e) => setDob(dateFromDateString(e.target.value))}
/>
</Col>
</Form.Group>
:
<Form.Group as={Row} className="mb-3 align-items-center" controlId="ageDisplay">
<Form.Label column id="ageLabel" lg={4}>Age:</Form.Label>
<Col>
<Form.Control type="text" readOnly
value={calculateAge(dateFromDateString(user.dob))}/>
</Col>
</Form.Group>
}
<Form.Group as={Row} className="d-flex justify-content-end" controlId="nameInput">
<Button variant="outline-dark"
size="sm"
className="w-25 mx-2"
id="profileSubmitBtn"
onClick={editable ? saveChanges : () => toggleEditable(editable, setEditable)}
>
{editable ? "Save" : "Update"}
</Button>
</Form.Group>
</Form>
Versions: "bootstrap": "^5.1.3", "react": "^17.0.2", "react-bootstrap": "^2.1.0",
CodePudding user response:
If you change the input to a controlled component, it should fix your problem. You shouldn't need a defaultValue
on a date input, but you definitely need a value
property if you want to control the value of the component. I made those changes below.
<Form.Control
type="date"
value={dob ? dateForPicker(dob) : ''}
onfocus={dateForPicker(dob)}
placeholder={dob ? dateForPicker(dob) : "dd/mm/yyyy"}
onChange={(e) => setDob(dateFromDateString(e.target.value))}
/>