`<select>` custom validation inside a `variant` schema
devatina11yb opened this issue · comments
Let’s say there’s a <select>
element inside a form and other form fields are displayed according to the selected option, the default selected option is empty but validation must ensure there’s a selected value when submitting.
I’ve tried implementing this using a variant
schema like this:
const schema = variant("type", [
object({
type: literal("")
}, [custom((input) => input.type !== "", "Please select an option")]),
object({
type: literal("foo"),
// ...
}),
object({
type: literal("bar"),
// ...
}),
], /* also tried custom validation here with the same result */);
The custom validation function does get executed but the error message never reaches the form object, so I can’t use getError(form, "type")
to display it. Is it the expected behavior?
This schema does seem to work as expected:
const schema = variant("type", [
object({
type: literal("foo"),
// ...
}),
object({
type: literal("bar"),
// ...
}),
], "Please select an option")
But then I can’t use {getValue(form, "type") !== "" ? <>...</> : undefined}
without TypeScript complaining that ""
doesn’t match "foo" | "bar"
.
Maybe there’s a better way avoiding this issue?
Please try the following schema and let me know if it works.
const schema = variant('type', [
object({ type: literal('') }, [
forward(
custom((input) => input.type !== '', 'Please select an option'),
['type']
),
]),
object({
type: literal('foo'),
// ...
}),
object({
type: literal('bar'),
// ...
}),
]);
Please try the following schema and let me know if it works.
const schema = variant('type', [ object({ type: literal('') }, [ forward( custom((input) => input.type !== '', 'Please select an option'), ['type'] ), ]), object({ type: literal('foo'), // ... }), object({ type: literal('bar'), // ... }), ]);
Thank you, it solved my issue.
Would you please explain why forwarding is needed?
This might also work. But the variant
error cannot be associated with a specific field. Instead, it may be available via form.response
. That's why I used forward
in the preview schema I sent you to forward the issue to the type field.
const schema = variant("type", [
object({
type: literal("foo"),
// ...
}),
object({
type: literal("bar"),
// ...
}),
], "Please select an option")
This might also work. But the
variant
error cannot be associated with a specific field. Instead, it may be available viaform.response
. That's why I usedforward
in the preview schema I sent you to forward the issue to the type field.const schema = variant("type", [ object({ type: literal("foo"), // ... }), object({ type: literal("bar"), // ... }), ], "Please select an option")
Makes sense, thank you again for your help with this.