Skip to content
Snippets Groups Projects
Verified Commit 7d64f829 authored by Andreas Ellewsen's avatar Andreas Ellewsen
Browse files

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
parent dc1dbdb8
No related branches found
No related tags found
1 merge request!281Make email field validate on change again
Pipeline #116011 passed
...@@ -25,7 +25,7 @@ import { ...@@ -25,7 +25,7 @@ import {
import { Guest } from 'interfaces' import { Guest } from 'interfaces'
import SponsorInfoButtons from 'routes/components/sponsorInfoButtons' import SponsorInfoButtons from 'routes/components/sponsorInfoButtons'
import { useEffect, useState } from 'react' 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 IdentityLine from 'components/identityLine'
import { isValidEmail, submitJsonOpts } from 'utils' import { isValidEmail, submitJsonOpts } from 'utils'
...@@ -94,28 +94,18 @@ export default function GuestInfo({ ...@@ -94,28 +94,18 @@ export default function GuestInfo({
const [t] = useTranslation(['common']) const [t] = useTranslation(['common'])
const history = useHistory() const history = useHistory()
const [confirmationDialogOpen, setConfirmationDialogOpen] = useState(false) 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 // Using useForm even though only the e-mail is allow to change at present, since useForm makes setup and validation easier
const { const {
handleSubmit, handleSubmit,
setValue, setValue,
control, register,
formState: { errors }, reset,
} = useForm({ formState: { errors, isValid, isDirty },
} = useForm<Email>({
mode: 'onChange', 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) => { const submit: SubmitHandler<Email> = (data) => {
updateEmail(data.email) updateEmail(data.email)
} }
...@@ -158,19 +148,19 @@ export default function GuestInfo({ ...@@ -158,19 +148,19 @@ export default function GuestInfo({
} }
} }
const emailFieldChange = (event: any) => { const { ref, onChange, ...inputProps } = register('email', {
setValue('email', event.target.value) validate: isValidEmail,
if (event.target.value !== guest.email) { })
setEmailDirty(true)
} else { useEffect(() => {
setEmailDirty(false) reset() // Forces defaultValue to be set to the new value, making the form not dirty
} setValue('email', guest.email)
} }, [guest])
return ( return (
<Page> <Page>
<SponsorInfoButtons to="/sponsor" name={`${guest.first} ${guest.last}`} /> <SponsorInfoButtons to="/sponsor" name={`${guest.first} ${guest.last}`} />
<form> <form onSubmit={onSubmit}>
<Box sx={{ marginBottom: '2rem' }}> <Box sx={{ marginBottom: '2rem' }}>
<Typography variant="h2">{t('guestInfo.contactInfo')}</Typography> <Typography variant="h2">{t('guestInfo.contactInfo')}</Typography>
<Typography variant="body1"> <Typography variant="body1">
...@@ -183,6 +173,7 @@ export default function GuestInfo({ ...@@ -183,6 +173,7 @@ export default function GuestInfo({
<TableRow> <TableRow>
<TableHeadCell align="left" colSpan={2}> <TableHeadCell align="left" colSpan={2}>
{t('guestInfo.contactInfoTableText')} {t('guestInfo.contactInfoTableText')}
</TableHeadCell> </TableHeadCell>
</TableRow> </TableRow>
</TableHead> </TableHead>
...@@ -204,23 +195,16 @@ export default function GuestInfo({ ...@@ -204,23 +195,16 @@ export default function GuestInfo({
justifyContent: 'flex-start', justifyContent: 'flex-start',
}} }}
> >
<Controller <TextField
name="email" InputLabelProps={{ shrink: true }}
control={control} id="email"
rules={{ label={t('input.email')}
validate: isValidEmail, error={!!errors.email}
}} helperText={errors?.email?.message}
render={({ field: { value }, ...rest }) => ( defaultValue={guest.email}
<TextField inputRef={ref}
id="email" onChange={onChange}
label={t('input.email')} {...inputProps}
error={!!errors.email}
helperText={errors.email && errors.email.message}
value={value}
{...rest}
onChange={emailFieldChange}
/>
)}
/> />
{/* If the guest has not completed the registration process, he should have an invitation he has not responded to */} {/* 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({ ...@@ -292,9 +276,9 @@ export default function GuestInfo({
</Table> </Table>
</TableContainer> </TableContainer>
<Button <Button
type="submit"
color="secondary" color="secondary"
disabled={!errors.email && !emailDirty} disabled={!isValid || !isDirty}
onClick={onSubmit}
> >
{t('button.save')} {t('button.save')}
</Button> </Button>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment