Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mantine with zod: Setting validation messages for two fields updates only one field #6772

Open
1 of 2 tasks
HypeillingerChillinger opened this issue Sep 4, 2024 · 1 comment

Comments

@HypeillingerChillinger
Copy link

HypeillingerChillinger commented Sep 4, 2024

Dependencies check up

  • I have verified that I use latest version of all @mantine/* packages

What version of @mantine/* packages do you have in package.json?

7.12.2

What package has an issue?

@mantine/form

What framework do you use?

Next.js

In which browsers you can reproduce the issue?

Chrome

Describe the bug

The validation rules are: "If both fields have text or no field have text everything is ok. Otherwise show the validation message on both fields.". But it does not work.

  • Typing into the first field shows the validation on the first field but not on the other one and vice versa.
  • Then typing into the other field should remove the validation on the first field but it doesn't

So it seems that the validation happens only on the field that is currently written to. I also tried to use both field names within the path array in superRefine with no success.

const schema = z.object({
        descriptionEnglish: z.string().optional(),
        typeEnglish: z.string().optional(),
    })
        .superRefine((data, ctx) => {
            const { descriptionEnglish, typeEnglish } = data;
            const bothEmpty: boolean = !descriptionEnglish && !machineTypeEnglish;
            const bothFilled: boolean = !!descriptionEnglish && !!machineTypeEnglish;

            console.log('descriptionEnglish:', descriptionEnglish);
            console.log('typeEnglish:', typeEnglish);

            const res: boolean = bothEmpty || bothFilled;

            console.log('Validation result:', res);

            if (!res) {
                ctx.addIssue({
                    code: z.ZodIssueCode.custom,
                    message: 'Both description and type must be filled or both must be empty',
                    path: ['typeEnglish'],
                });
                ctx.addIssue({
                       code: z.ZodIssueCode.custom,
                       message: 'Both description and type must be filled or both must be empty',
                       path: ['descriptionEnglish'],
                 });
            }
        });
const form = useForm<AdFormType>({
        validateInputOnChange: true,
        validateInputOnBlur: true,

        mode: 'uncontrolled',
        onValuesChange(values, previous) {
            console.log('Values changed:', JSON.stringify(values, null, 2));

        },
        initialValues: {
            descriptionEnglish: '',
           typeEnglish: '',
        },
        validate: zodResolver(schema),
    });
<TextInput
      label={t("fieldNames.typeEnglish")}
      autoComplete='off'
      autoCorrect="false"
      spellCheck="false"
      placeholder={t("fieldNames.typeEnglish")}
      name="typeEnglish"
      key={form.key('typeEnglish')}
      {...form.getInputProps('typeEnglish')}
/>
<Textarea
    minRows={3}
    resize="vertical"
    autoComplete='off'
    autoCorrect="false"
    spellCheck="false"
    label={t("fieldNames.descriptionEnglish")}
    placeholder={t("fieldNames.descriptionEnglish")}
    name="descriptionEnglish"
    key={form.key('descriptionEnglish')}
    {...form.getInputProps('descriptionEnglish')}
/>

If possible, include a link to a codesandbox with a minimal reproduction

No response

Possible fix

No response

Self-service

  • I would be willing to implement a fix for this issue
@alesmit
Copy link

alesmit commented Sep 27, 2024

@HypeillingerChillinger I believe it's the default behavior to only trigger validation on the field that is being edited. To make sure the error message appears also on the other field, you should call form.validate() in a useEffect.

const { typeEnglish, descriptionEnglish } = form.values;

useEffect(() => {
  form.validate();
}, [typeEnglish, descriptionEnglish])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants