[Bug]: Form not submitting
khawarizmus opened this issue · comments
Reproduction
https://stackblitz.com/edit/nuxt-starter-ggrskg?file=app.vue
Describe the bug
I have followed the documentation step by step but so far I am unable to make the form submit. I have attached a reproduction link to showcase the problem.
But i will go ahead and past my original code for reference:
<template>
<Dialog>
<DialogTrigger as-child>
<Button
class="px-6 py-3 mt-6 text-xl font-normal text-white bg-black rounded-md md:self-end lg:self-start dark:text-slate-200 w-fit disabled:bg-gray-400 disabled:cursor-not-allowed hover:bg-gray-700"
>
{{ waitingText }}
</Button>
</DialogTrigger>
<DialogContent :disable-outside-pointer-events="true" :trapFocus="true">
<DialogHeader>
<DialogTitle>Get notified when we launch</DialogTitle>
<Form id="sabrListForm" class="space-y-6" @submit="submitHandler">
<FormField name="email" v-slot="{ componentField }">
<FormItem v-auto-animate>
<FormLabel>
{{ $t("modal.email") }}
</FormLabel>
<FormControl>
<Input
type="email"
:placeholder="$t('modal.placeholder')"
v-bind="componentField"
/>
</FormControl>
<FormMessage />
</FormItem>
</FormField>
</Form>
<DialogDescription>
<p>
{{ $t("modal.privacy") }}
<NuxtLink to="/privacy" class="underline cursor-pointer">{{
$t("modal.policy")
}}</NuxtLink>
</p>
</DialogDescription>
<DialogFooter>
<Button form="sabrListForm" type="submit">{{
$t("modal.join")
}}</Button>
</DialogFooter>
</DialogHeader>
</DialogContent>
</Dialog>
</template>
<script setup lang="ts">
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import {
Form,
FormField,
FormItem,
FormLabel,
FormControl,
FormMessage,
} from "@/components/ui/form";
import { useApiFetch } from "~/composables/useApiFetch";
import { vAutoAnimate } from "@formkit/auto-animate/vue";
import * as z from "zod";
import { toTypedSchema } from "@vee-validate/zod";
defineProps({
waitingText: {
type: String,
required: true,
},
});
const emitter = useEmitter();
let loading = ref(false);
const schema = z.object({
email: z
.string({
required_error: "Email is required",
})
.email("Invalid email address"),
});
const { handleSubmit } = useForm({
validationSchema: toTypedSchema(schema),
});
const submitHandler = handleSubmit(async (values) => {
console.log("submitHandler");
console.log(values);
const { error, pending } = await useApiFetch("waitlist", {
method: "POST",
body: JSON.stringify(values?.email),
});
loading = pending;
if (!error.value) {
emitter.emit("success", {
title: "You have been added to the patently waiting!",
});
} else {
emitter.emit("error", {
title: "Something went wrong",
options: {
description: error.value?.message || "Please try again later",
},
});
}
});
</script>
System Info
System:
OS: macOS 14.2.1
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Memory: 547.92 MB / 32.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 18.18.2 - ~/.nvm/versions/node/v18.18.2/bin/node
Yarn: 1.22.19 - ~/.nvm/versions/node/v18.18.2/bin/yarn
npm: 9.8.1 - ~/.nvm/versions/node/v18.18.2/bin/npm
pnpm: 8.15.4 - ~/.nvm/versions/node/v18.18.2/bin/pnpm
bun: 1.1.8 - ~/.bun/bin/bun
Browsers:
Chrome: 124.0.6367.208
Safari: 17.2.1
npmPackages:
@vueuse/core: ^10.9.0 => 10.9.0
nuxt: ^3.5.0 => 3.11.2
radix-vue: ^1.7.4 => 1.7.4
shadcn-nuxt: ^0.10.4 => 0.10.4
Contributes
- I am willing to submit a PR to fix this issue
- I am willing to submit a PR with failing tests
Well it seems that the issue is that i was using the Form
component instead of the form
element.
Not sure if this is an expected behaviour but if it is then the documentation should fix the anatomy section.
If it isn't then the bug is still present and demo-able here where you have tow identical dialogues one works and the other one doesn't.
https://stackblitz.com/edit/nuxt-starter-ggrskg?file=app.vue
@khawarizmus Hi you are mixing two different ways together which it's not the best practices
While using <Form>
component you don't need useForm
composable and handleSubmit
function, you just need to use <Form>
component props like
<Form :validation-schema="schema" @submit="onSubmit">
If you are validation something inside Dialog
component <Form>
component is recommended
Related issue: #459
Thank you it makes sense now