mantine icon indicating copy to clipboard operation
mantine copied to clipboard

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

Open HypeillingerChillinger opened this issue 5 months ago • 1 comments

Dependencies check up

  • [X] 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

HypeillingerChillinger avatar Sep 04 '24 08:09 HypeillingerChillinger