Search code examples
reactjsformsvalidationreact-final-form

React-Final-Form not reruning the validation when checkbox is unchecked


I'm using react-final-form with fonk. My problem is that the user can submit the form without the checkbox being checked - this happens when you check is and then uncheck it. I don't know why but then it doesn't show any errors and it gives a green light to submit the form.

        return (
        <MessageFormSection>
            <h2>Wypełnij formularz</h2>
            <small>Odpowiadamy naprawdę szybko!</small>

            <Form 
                onSubmit={() => {
                    emailjs.sendForm('service_xuu4z8k', 'template_54zt0z9', '#contact-form', 'user_C1OXTe9qBeqb5ZOmCejLc')
                        .then((result) => {
                            setUserInfo('Twoja wiadomośc została wysłana poprawnie');
                            disableSubmit();
                        }, (error) => {
                            setUserInfo('Podczas wysyłania twojej wiadomości pojawił się błąd - Wiadomość nie została wysłana.');
                        });
                }}
                initialValues={{
                    fullName: '',
                    email: '',
                    title: '',
                    message: '',
                    policy: null,
                }}
                validate={(values) => formValidation.validateForm(values)}
                render={({handleSubmit}) => (
                    <form onSubmit={handleSubmit} id="contact-form">
                        <Field name="fullName">
                            {({input, meta}) => (
                                <div className="fullname-box">
                                    <label htmlFor="form-fullname-input">Imię i Nazwisko</label>
                                    <input {...input} id="form-fullname-input" placeholder="Jan Kowalski"/>
                                    {meta.error && meta.touched && <span>{meta.error}</span>}
                                </div>
                            )}
                        </Field>
                        <Field name="email" type="email">
                            {({input, meta}) => (
                                <div className="email-box">
                                    <label htmlFor="form-phone-input">Email</label>
                                    <input {...input} id="form-phone-input" placeholder="[email protected]"/>
                                    {meta.error && meta.touched && <span>{meta.error}</span>}
                                </div>
                            )}
                        </Field>
                        <Field name="title">
                            {({input, meta}) => (
                                <div className="title-box">
                                    <label htmlFor="form-title-input">Tytuł</label>
                                    <input {...input} id="form-title-input" placeholder="Wspólna praca nad nowym projektem!?"/>
                                    {meta.error && meta.touched && <span>{meta.error}</span>}
                                </div>
                            )}
                        </Field>
                        <Field name="message">
                            {({input, meta}) => (
                                <div className="message-box">
                                    <label htmlFor="form-message-input">Twoja wiadomość</label>
                                    <textarea rows="3" {...input} id="form-message-input" placeholder="Chciałbym z wami współpracować!"/>
                                    {meta.error && meta.touched && <span>{meta.error}</span>}
                                </div>
                            )}
                        </Field>
                        <Field name="policy" type="checkbox">
                            {({input, meta}) => (
                                <div className="checkbox-box">
                                    <input {...input} id="form-policy-checkbox"/>
                                    <label htmlFor="form-policy-checkbox">Wyrażam zgodę na przetwarzanie moich danych osobowych</label>
                                    {meta.error && meta.touched && <span>{meta.error}</span>}
                                </div>
                            )}
                        </Field>
                        <div className="buttons">
                            <button type="submit" id="submit-btn">Submit</button>
                        </div>
                        <span className="user-info">{userInfo}</span>
                    </form>
                )}
            />
        </MessageFormSection>
    )

And my FormValidation is this

    const validationSchema = {
    field: {
        fullName: [ 
            {
                validator: Validators.required.validator,
                message: "Pełne imię i nazwisko jest wymagane."
            }
        ],
        email: [
            {
                validator: Validators.required.validator,
                message: "Email jest wymagany."
            },
            {
                validator: Validators.email.validator,
                message: "Podaj poprawny adres email."
            }
        ],
        title: [
            {
                validator: Validators.required.validator,
                message: "Podaj tytuł swojej wiadomości."
            }
        ],
        message: [
            {
                validator: Validators.required.validator,
                message: "Podaj wiadomość jaką chcesz do nas wysłać."
            }
        ],
        policy: [
            {
                validator: Validators.required.validator,
                message: "Zgoda jest wymagana do wysłania wiadomości."
            }
        ],        
    },
};

with these imports

import { createFinalFormValidation } from `@lemoncode/fonk-final-form`
import { Validators } from '@lemoncode/fonk';

Solution

  • you need to create a custom validator for the checkobx for the reasons mentioned in the comment above.

    export const checkboxValidator = ({ values }) => {
      const succeeded = values.policy;
    
      return {
        succeeded,
        message: succeeded
          ? ''
          : 'Required',
        type: 'POLICY',
      };
    };
    

    import this in FormValidation.js

    change your validation schema. remove policy from fields property and instead add it to the records property.

      const validationSchema = {
        field: {
            fullName: [ 
                {
                    validator: Validators.required.validator,
                    message: "Pełne imię i nazwisko jest wymagane."
                }
            ],
            email: [
                {
                    validator: Validators.required.validator,
                    message: "Email jest wymagany."
                },
                {
                    validator: Validators.email.validator,
                    message: "Podaj poprawny adres email."
                }
            ],
            title: [
                {
                    validator: Validators.required.validator,
                    message: "Podaj tytuł swojej wiadomości."
                }
            ],
            message: [
                {
                    validator: Validators.required.validator,
                    message: "Podaj wiadomość jaką chcesz do nas wysłać."
                }
            ],      
        },
       record: {
          policy: [checkboxValidator]
       },
    };