Open DevHusariaSolutions opened 9 months ago
Just wrap your schema with zodForm$
or valiForm$
and pass the returned value to .validate
of useForm
. Please share your code if you need more help. If you are using Valibot, we plan to improve i18n to allow you to define your translations and schemas globally.
export default component$(() => {
const LoginSchema = valiForm$(
v.object({
email: v.string([
v.minLength(1, 'Please enter your email.'),
v.email('The email address is badly formatted.'),
]),
password: v.string([
v.minLength(1, 'Please enter your password.'),
v.minLength(8, 'You password must have 8 characters or more.'),
]),
})
);
// Use login form
const [loginForm, { Form, Field }] = useForm<LoginForm>({
loader: useFormLoader(),
action: useFormAction(),
validate: LoginSchema,
});
// More code here...
I've already tried this, no result of change. I don't use loader as function, I use plain object.
To test it You can use
import { $, component$, useStore, type QRL } from '@builder.io/qwik'
import type { SubmitHandler } from '@modular-forms/qwik'
import { formAction$, useForm, valiForm$ } from '@modular-forms/qwik'
import { email, minLength, object, string, type Input } from 'valibot'
export default component$(() => {
const formSchema=object({
email: string([minLength(1, 'Please enter your email.'), email('form.validation.emailInvalid')]),
firstName: string([
minLength(1, 'Please enter your password.'),
minLength(8, 'Your password must have 8 characters or more.'),
]),
})
const validate = valiForm$(formSchema)
type BootcampRegisterForm = Input<typeof formSchema>
const handleSubmit: QRL<SubmitHandler<BootcampRegisterForm>> = $((values) => {
// Runs on client
console.log(values)
})
const [, { Form, Field }] = useForm<BootcampRegisterForm>({
loader: { value: { firstName: '', email: '' } },
// action: useFormAction(),
validate,
})
return (
<Form onSubmit$={handleSubmit}>
<Field name="firstName">
{(field, props) => <input required {...props} {...field} label="First name" type="text" />}
</Field>
<Field name="email">
{(field, props) => <input required {...props} {...field} label="E-mail" type="email" />}
</Field>
<button type="submit">Login</button>
</Form>
)
});
Moving schema outside component with translation hooks gives inproper behaviour - error is not translated, only key of translation is returned
const t = inlineTranslate()
const formSchema = z.object({
firstName: z.string().min(3, { message: t('form.validation.nameInvalid') }),
email: z
.string({ required_error: t('form.validation.emailRequired') })
.email({ message: t('form.validation.emailInvalid') }),
})
export const RegisterBootcampForm = component$(() => {
const useFormAction = formAction$<BootcampRegisterForm>((values) => {
// TODO: ADD BACKEND ACTION
console.log(values)
}, zodForm$(formSchema))
type BootcampRegisterForm = z.infer<typeof formSchema>
const handleSubmit: QRL<SubmitHandler<BootcampRegisterForm>> = $((values) => {
// Runs on client
console.log(values)
})
const [, { Form, Field }] = useForm<BootcampRegisterForm>({
loader: { value: { firstName: '', email: '' } },
action: useFormAction(),
validate: zodForm$(formSchema),
})
And another test failed:
const t = inlineTranslate()
type BootcampRegisterForm = { firstName: string; email: string }
const handleSubmit: QRL<SubmitHandler<BootcampRegisterForm>> = $((values) => {
// Runs on client
console.log(values)
})
const [, { Form, Field }] = useForm<BootcampRegisterForm>({
loader: { value: { firstName: '', email: '' } },
})
return (
<Form onSubmit$={handleSubmit}>
<Field name="firstName" validate={minLength(3, t('form.validation.nameInvalid'))}>
Resigning from using formSchema and passing only validate stuff Field component also prints untranslated error...
It only works for me if I put the schema inside zodForm$
. Not just the variable that stores the schema. But this makes it harder to infer the input type of the schema.
Ok, but can we do something about that? Schema is just object, which should be composable inside component in case we would like to:
And in Qwik 1.3.1+ even wraping it as You proposed throws error.
I will investigate this issue but it will take time. I plan to rewrite Modular Forms in February. Unfortunately, I don't have a perfect solution for you at the moment. You can try to define the error messages globally in Zod with an error map. Alternatively, you can also try switching to Valibot. I plan to implement our i18n feature by the end of this week. This should allow you to define your schema globally.
For Valibot it was the same. No problem, currently I'm using this for landing page, which is not problematic to handle outside it (especially, that user shouldn't start typeing data in form controls before switching to another language first).
Have you tried Valibot's new i18n feature? https://valibot.dev/guides/introduction/
Example in docs is omitting important part of validation libraries - custom errors. If we have multi-lang website content of such errors is derived by hook function which returns translated content, but hook needs to be used inside component, so schema also needs to be defined in component. When doing so I gets error
where formSchema is variable name of my validation schema.
Moving formSchema outside component works, but ofc I won't be able to define custom errors for it.
Please publish advanced example of Your solution.