From 7d64f829f32f5c0956fc4de3d0057b81b9ff1b63 Mon Sep 17 00:00:00 2001 From: Andreas Ellewsen <ae@uio.no> Date: Thu, 10 Feb 2022 16:03:37 +0100 Subject: [PATCH] Make email field validate on change again Switches from using a Controller to the simpler uncontrolled setup. Label has been set to be permanently shrunk since mui refuses to realise that the field has input when using rhf's setValue. Validation now happens onChange, alerting the user while typing. Submit button is disabled if you have not touched the field and when the content of the field is an invalid email. After submissions, the new value is treated as the default, disabling the save button until the field has been touched again. Resolves: GREG-196 --- .../routes/sponsor/guest/guestInfo/index.tsx | 70 +++++++------------ 1 file changed, 27 insertions(+), 43 deletions(-) diff --git a/frontend/src/routes/sponsor/guest/guestInfo/index.tsx b/frontend/src/routes/sponsor/guest/guestInfo/index.tsx index ed588018..6001f018 100644 --- a/frontend/src/routes/sponsor/guest/guestInfo/index.tsx +++ b/frontend/src/routes/sponsor/guest/guestInfo/index.tsx @@ -25,7 +25,7 @@ import { import { Guest } from 'interfaces' import SponsorInfoButtons from 'routes/components/sponsorInfoButtons' import { useEffect, useState } from 'react' -import { SubmitHandler, useForm, Controller } from 'react-hook-form' +import { SubmitHandler, useForm } from 'react-hook-form' import IdentityLine from 'components/identityLine' import { isValidEmail, submitJsonOpts } from 'utils' @@ -94,28 +94,18 @@ export default function GuestInfo({ const [t] = useTranslation(['common']) const history = useHistory() const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false) - const [emailDirty, setEmailDirty] = useState(false) - const defaultValues = { - email: guest.email, - } // Using useForm even though only the e-mail is allow to change at present, since useForm makes setup and validation easier const { handleSubmit, setValue, - control, - formState: { errors }, - } = useForm({ + register, + reset, + formState: { errors, isValid, isDirty }, + } = useForm<Email>({ mode: 'onChange', - defaultValues, }) - useEffect(() => { - setValue('email', guest.email) - // E-mail just updated so it is not dirty - setEmailDirty(false) - }, [guest]) - const submit: SubmitHandler<Email> = (data) => { updateEmail(data.email) } @@ -158,19 +148,19 @@ export default function GuestInfo({ } } - const emailFieldChange = (event: any) => { - setValue('email', event.target.value) - if (event.target.value !== guest.email) { - setEmailDirty(true) - } else { - setEmailDirty(false) - } - } + const { ref, onChange, ...inputProps } = register('email', { + validate: isValidEmail, + }) + + useEffect(() => { + reset() // Forces defaultValue to be set to the new value, making the form not dirty + setValue('email', guest.email) + }, [guest]) return ( <Page> <SponsorInfoButtons to="/sponsor" name={`${guest.first} ${guest.last}`} /> - <form> + <form onSubmit={onSubmit}> <Box sx={{ marginBottom: '2rem' }}> <Typography variant="h2">{t('guestInfo.contactInfo')}</Typography> <Typography variant="body1"> @@ -183,6 +173,7 @@ export default function GuestInfo({ <TableRow> <TableHeadCell align="left" colSpan={2}> {t('guestInfo.contactInfoTableText')} + </TableHeadCell> </TableRow> </TableHead> @@ -204,23 +195,16 @@ export default function GuestInfo({ justifyContent: 'flex-start', }} > - <Controller - name="email" - control={control} - rules={{ - validate: isValidEmail, - }} - render={({ field: { value }, ...rest }) => ( - <TextField - id="email" - label={t('input.email')} - error={!!errors.email} - helperText={errors.email && errors.email.message} - value={value} - {...rest} - onChange={emailFieldChange} - /> - )} + <TextField + InputLabelProps={{ shrink: true }} + id="email" + label={t('input.email')} + error={!!errors.email} + helperText={errors?.email?.message} + defaultValue={guest.email} + inputRef={ref} + onChange={onChange} + {...inputProps} /> {/* If the guest has not completed the registration process, he should have an invitation he has not responded to */} @@ -292,9 +276,9 @@ export default function GuestInfo({ </Table> </TableContainer> <Button + type="submit" color="secondary" - disabled={!errors.email && !emailDirty} - onClick={onSubmit} + disabled={!isValid || !isDirty} > {t('button.save')} </Button> -- GitLab