#Example Mantine Form Client & Server Validation

10 messages · Page 1 of 1 (latest)

tired quail
#

I have been attempting to do something like this, but with mantine form:
https://conform.guide/integration/nextjs

Where you can specify the onSubmit and the action on a form. Then, it will go through the process of both client and server side validation:

export function LoginForm() {
  const [lastResult, action] = useFormState(login, undefined);
  const [form, fields] = useForm({
    // Sync the result of last submission
    lastResult,

    // Reuse the validation logic on the client
    onValidate({ formData }) {
      return parseWithZod(formData, { schema: loginSchema });
    },

    // Validate the form on blur event triggered
    shouldValidate: 'onBlur',
    shouldRevalidate: 'onInput',
  });

  return (
    <form id={form.id} onSubmit={form.onSubmit} action={action} noValidate>
      <div>

Unfortunately, I can't get it to work with mantine form. I have tried using form refs and calling things like formRef.current?.submit(); inside the form.onSubmit(), but nothing works. Does anyone have a working example for the latest version of Nextjs that shows mantine form working for both client and server validation?

ocean dragon
tired quail
#

@ocean dragon that makes sense to me, but I don't know how to call the server action from the onSubmit / handleSubmit callback that mantine form provides?

#

for example, something like this I was hoping would work, but it doesnt:

<form
  ref={formRef}
  onSubmit={form.onSubmit((values, event) => {
    event?.stopPropagation();
    formRef.current?.submit();
  })}
  action={formAction}
>
ocean dragon
severe sluice
#

You do not need to use both onSubmit and action.

import { login } from './actions';
const form = useForm({
  // ... others
  validate: zodResolver(schema)
});

<form onSubmit={form.onSubmit(async (values) => {
  // execute server action
  await login(values);
  // or with @tanstack/qurey useMutation({ mutationFn: login })
  $action.mutate(values, {...});
})}>
  <TextInput key={form.key('name')} {...form.getInputProps('name')} />
</form>

p.s. Use a single file to store schema, then import both in client component and server action

tired quail
#

@severe sluice the benefit of using both onSubmit and action is that in an environment with javascript disabled a form can still be submitted. i thought that was a nice feature, and wanted to mimic it since it worked in conform. any idea what the difference is between conform and mantine form such that it works there and not here?

tired quail
#

@ocean dragon I believe I found the issue:
https://github.com/edmundhung/conform/discussions/818

If your question is just about the action, all conform does is just calling event.preventDefault() conditionally based on the result of the client validation.

https://github.com/edmundhung/conform/blob/cb984945e9cf3a5448bafeef490d8a2dcc845226/packages/conform-react/context.tsx#L486-L501

Could we have the same behavior in mantine form? Right now we always prevent the default:
https://github.com/mantinedev/mantine/blob/master/packages/%40mantine/form/src/use-form.ts#L205

If we move that line into the if statement for no errors below, it won't run on success by default. Then we can return true/false from the form.onSubmit() which will control whether the action is run.

GitHub

Looking at this example: https://conform.guide/integration/nextjs How does conform provide the ability to call what is inside the action prop after the onSubmit is run client side? 'use client&...

GitHub

A type-safe form validation library utilizing web fundamentals to progressively enhance HTML Forms with full support for server frameworks like Remix and Next.js. - edmundhung/conform

GitHub

A fully featured React components library. Contribute to mantinedev/mantine development by creating an account on GitHub.

tired quail
#

Points 2 and 3 are nice to haves for developer experience, but point 1 is a necessity. There's no way in javascript to reverse the effect of event.preventDefault()