Issue
I want to create a registration form, where all the fields are required. I'm using React Hook Form and Yup for form validaton. All fields are required, including two checkboxes. When I submit the form, I get this error for checkboxes:
termsOfUse must be a boolean
type, but the final value was: "on"
.
I think that this means I am trying to save the string value 'on' into the yup field, which requires a boolean. This is because of the checkbox is passing target.value instead of target.checked: {...register("privacyPolicy")}
I still don't know how to pass 'checked' instead of 'value' and use checkbox inputs in RHF in general. Any help would be really appreciated. Thank you :)
The component:
import React from "react";
import { useHistory } from "react-router-dom";
import { useState } from "react";
import {
IonPage,
IonHeader,
IonToolbar,
IonTitle,
IonContent,
IonButton,
IonInput,
IonLabel,
IonItem,
IonLoading,
IonToast,
IonSelectOption,
IonSelect,
IonRadio,
IonCheckbox,
IonGrid,
IonRow,
IonCol,
IonAlert,
} from "@ionic/react";
import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup";
import * as yup from "yup";
import axios from "axios";
// form validation rules
const validationSchema = yup.object().shape({
email: yup
.string()
.email("E-mail is invalid!")
.min(7, "E-Mail must have 7 characters")
.required("E-Mail is required"),
password: yup
.string()
.min(8, "Password should have at least 8 characters!")
.required("Password is required"),
termsOfUse: yup
.boolean()
.oneOf([true], "You should accept terms of use"),
privacyPolicy: yup
.boolean()
.oneOf([true], "You should accept privacy policy"),
});
const CreateAccountPage: React.FC = () => {
const [checkedTermsOfUse, setCheckedTermsOfUse] = useState(false);
const [checkedPrivacyPolicy, setCheckedPrivacyPolicy] = useState(false);
const history = useHistory();
const {
register,
handleSubmit,
formState: { errors },
getValues,
} = useForm({
mode: "onChange",
resolver: yupResolver(validationSchema),
});
const doCreateAccount = () => {
const data = {
eMail: getValues("email"),
password: getValues("password"),
};
axios
.post("xx/register", data)
.then((response) => {
return response.data;
})
};
return (
<IonPage>
<IonHeader>
</IonHeader>
<IonContent className="ion-padding">
<form
className="ion-padding"
onSubmit={handleSubmit(doCreateAccount)}
>
<IonItem>
<IonLabel position="floating">E-Mail *</IonLabel>
<IonInput type="email" {...register("email")} />
</IonItem>
{errors.email && <p>{errors.email.message}</p>}
<IonItem>
<IonLabel position="floating">
Password *
</IonLabel>
<IonInput type="password" {...register("password")} />
</IonItem>
<div>
<IonCheckbox
checked={checkedTermsOfUse}
{...register("termsOfUse")}
></IonCheckbox>{" "}
<a
href="https://wss-rest.api.woehlke.de/type/agreement-version-content/1"
target="_blank"
>
I accept terms of use
</a>
</div>
{errors.termsOfUse && <p>{errors.termsOfUse.message}</p>}
<div>
<IonCheckbox
{...register("privacyPolicy")}
checked={checkedPrivacyPolicy}
></IonCheckbox>{" "}
<a
href="https://wss-rest.api.woehlke.de/type/agreement-version-content/3"
target="_blank"
>
I accept privacy policy
</a>
</div>
{errors.privacyPolicy && <p>{errors.privacyPolicy.message}</p>}
<IonButton type="submit">Submit</IonButton>
<IonButton onClick={() => history.goBack()} color="danger">
CANCEL
</IonButton>
</form>
</IonContent>
</IonPage>
);
};
export default CreateAccountPage;
"@hookform/resolvers": "^2.4.0",
"react-hook-form": "^7.1.1",
"yup": "^0.32.9"
Solution
For a native checkbox the register
call would be sufficient:
<input
type="checkbox"
{...register("nativeCheckbox")}
/>
But as you are using an external, controlled component with <IonCheckbox />
, you need to use the Controller
component:
<Controller
control={control}
name="checkbox"
render={({ field: { value, onChange } }) => (
<IonCheckbox
checked={value}
onIonChange={({ detail: { checked } }) => onChange(checked)}
/>
)}
/>
Check this section in the documentation for more infos.
Answered By - knoefel
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.