I use combobox from Shadcn-ui (https://www.shadcn-vue.com/docs/components/combobox#combobox) in my Nuxt 3 project. I cannot validate my combobox with zod. When I select an element and submit the form, I always get the error message "Account is required" which appears. No matter what I choose, the validation does not pass. Could someone help me find the problem please?
My code:
<script setup lang="ts">
const accounts = [
{ value: 'nuxt.js', label: 'Nuxt.js' },
{ value: 'remix', label: 'Remix' },
{ value: 'astro', label: 'Astro' },
]
const open = ref(false)
const value = ref('')
const formSchema = toTypedSchema(z.object({
accountSelected: z.string({
required_error: "Account is required"
}),
setupName: z.string({
required_error: "Setup is required"
})
}))
const form = useForm({
validationSchema: formSchema,
})
const submitForm = form.handleSubmit((values) => {
console.log("form submitted");
})
</script>
<template>
<form @submit="submitForm">
<FormField v-slot="{ componentField }" name="accountSelected">
<FormItem class="flex flex-col">
<FormLabel>Select account</FormLabel>
<FormControl>
<Popover v-model:open="open">
<PopoverTrigger as-child>
<Button variant="outline" role="combobox" :aria-expanded="open">
{{ value
? accounts.find((account) => account.value === value)?.label
: "Select account..." }}
<ChevronsUpDown class="ml-2 h-4 w-4 shrink-0 opacity-50" />
</Button>
</PopoverTrigger>
<PopoverContent>
<Command>
<CommandInput placeholder="Search account..." />
<CommandEmpty>No account found.</CommandEmpty>
<CommandList>
<CommandGroup>
<CommandItem v-bind="componentField" v-for="account in accounts"
:key="account.value" :value="account.value" @select="(ev) => {
if (typeof ev.detail.value === 'string') {
value = ev.detail.value
}
open = false
}">
{{ account.label }}
<Check :class="cn(
'ml-auto h-4 w-4',
value === account.value ? 'opacity-100' : 'opacity-0',
)" />
</CommandItem>
</CommandGroup>
</CommandList>
</Command>
</PopoverContent>
</Popover>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<FormField v-slot="{ componentField }" name="setupName">
<FormItem>
<FormLabel>Name</FormLabel>
<FormControl>
<Input type="text" v-bind="componentField" />
</FormControl>
<FormMessage />
</FormItem>
</FormField>
<Button type="submit" class="flex justify-center items-center">
Send
</Button>
</form>
</template>
Try to set value manually as below:
@select="(ev) => {
if (typeof ev.detail.value === 'string') {
value = ev.detail.value
form.setFieldValue('accountSelected', ev.detail.value)
}
open = false
}"