Next.js Discord

Discord Forum

form not submitting

Answered
Common Moorhen posted this in #help-forum
Open in Discord
Common MoorhenOP
i get the log of 'im a serve side component', but never the log of 'running action'.
Answered by Nile Crocodile
View full answer

93 Replies

@Common Moorhen i get the log of 'im a serve side component', but never the log of 'running action'.
How are you using the action? Are you clicking on the delete button?
Check for browser console logs... There might be errors
@Riday 💙 Check for browser console logs... There might be errors
Common MoorhenOP
No, there is none
Knopper gall
Your button is a server component, I see you're using Shadcn/ui, that doesn't make the button a client component by default, you'll need to export it as a client component
I believe that's the issue, I had a similar issue
Oh, I never noticed this because the component library I am using has "use client" in components added by default
i have turned the whole component into client side rendering
but i still have the same problem
the form never submitts
Knopper gall
Can you show me the component please?
Common MoorhenOP
i finished that feature just by using onClick in the component
but now im having the same error
let me show u
Nile Crocodile
button being a client component has nothing to do with it
it can still submit the form
Knopper gall
I wonder if your input is interfering, you don't specify an input type, and there can't be two submit buttons
Common MoorhenOP
'use client';
type TFormData = {
  name: string;
};

export function EditBtn({
  tag,
}: {
  tag: Database["public"]["Tables"]["tag"]["Row"];
}) {
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<Boolean>(false);

  const router = useRouter();

  async function handleEditTag(data: TFormData) {
    console.log("submitting");
    setLoading(true);
    try {
      const name = data.name;

      await editTag({ name, tagId: tag.id });

      setError(false);
      setLoading(false);
      router.refresh();
    } catch (error) {
      setError(true);
    }
  }

  const {
    register,
    formState: { errors, isValid },
    handleSubmit,
  } = useForm<TFormData>({ mode: "onBlur" });

  const tagName = useMemo(() => tag.name, [tag.name]);
return (
    <>
      <Dialog>
        <DialogTrigger asChild>
          <button className="w-full text-start">Edit</button>
        </DialogTrigger>
        <DialogContent>
          <form
            onSubmit={handleSubmit(handleEditTag)}
            className="flex flex-col gap-2"
          >
            <DialogHeader>
              <DialogTitle>Edit tag</DialogTitle>
              <DialogDescription>Edit tag information</DialogDescription>
              <Label htmlFor="name">Name</Label>
              <Input
                placeholder="Birthday"
                defaultValue={tagName}
                id="name"
                {...register("name", {
                  required: { message: "Tag name is required", value: true },
                  maxLength: {
                    value: 30,
                    message: "Tag Name cannot be grater than 30",
                  },
                })}
              />
              {errors.name?.message && (
                <ValidationError>{errors.name.message}</ValidationError>
              )}
              {error && (
                <ValidationError>
                  There has been an error please try again
                </ValidationError>
              )}
            </DialogHeader>
            <DialogFooter>
              <button
                type="submit"
              >
                Update
              </button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>
    </>
  );
}
Knopper gall
You're still using shad button 🤦
Common MoorhenOP
yes
Knopper gall
as server...
Common MoorhenOP
no, as client
now i have changed it to a normal html button
but still cant submit
Knopper gall
          <form
            onSubmit={handleSubmit(handleEditTag)}
            className="flex flex-col gap-2"
          >
?????
Common MoorhenOP
that is because i'm using useForm
Nile Crocodile
that'a a shadcn button
and the action still works
so use client isnt the issue
Common MoorhenOP
if i add
<button  onClick={() => {
           console.log("on click");
          }}>
update
</button>

it works
Nile Crocodile
weird thing but have you restarted the dev env
wait
show me the top of your fill
Common MoorhenOP
this is the full file:
"use client";

import { editTag } from "@/components/feature/calendar-aside/components/tags/actions/edit";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label/label.component";
import { ValidationError } from "@/components/ui/validation-error";
import { Database } from "@/lib/utils/supabase/types";
import { useRouter } from "next/navigation";
import { useMemo, useState } from "react";
import { useForm } from "react-hook-form";

type TFormData = {
  name: string;
};

export function EditBtn({
  tag,
}: {
  tag: Database["public"]["Tables"]["tag"]["Row"];
}) {
  const [loading, setLoading] = useState<boolean>(false);
  const [error, setError] = useState<Boolean>(false);

  const router = useRouter();

  async function handleEditTag(/*data: TFormData */) {
    console.log("submitting");
    // setLoading(true);
    // try {
    //   const name = data.name;
    //
    //   await editTag({ name, tagId: tag.id });
    //
    //   setError(false);
    //   setLoading(false);
    //   router.refresh();
    // } catch (error) {
    //   setError(true);
    // }
  }

  const {
    register,
    formState: { errors, isValid },
    handleSubmit,
  } = useForm<TFormData>({ mode: "onBlur" });

  const tagName = useMemo(() => tag.name, [tag.name]);
  return (
    <>
      <Dialog>
        <DialogTrigger asChild>
          <button className="w-full text-start">Edit</button>
        </DialogTrigger>
        <DialogContent>
          <form onSubmit={handleEditTag} className="flex flex-col gap-2">
            <DialogHeader>
              <DialogTitle>Edit tag</DialogTitle>
              <DialogDescription>Edit tag information</DialogDescription>
              <Label htmlFor="name">Name</Label>
              <Input
                placeholder="Birthday"
                defaultValue={tagName}
                id="name"
                type="text"
                {...register("name", {
                  required: { message: "Tag name is required", value: true },
                  maxLength: {
                    value: 30,
                    message: "Tag Name cannot be grater than 30",
                  },
                })}
              />
              {errors.name?.message && (
                <ValidationError>{errors.name.message}</ValidationError>
              )}
              {error && (
                <ValidationError>
                  There has been an error please try again
                </ValidationError>
              )}
            </DialogHeader>
            <DialogFooter>
              <button
                // loading={loading}
                type="submit"
                // disabled={!isValid || loading}
              >
                Update
              </button>
            </DialogFooter>
          </form>
        </DialogContent>
      </Dialog>
    </>
  );
}
Nile Crocodile
you have use client at the top
that's why its not working
"use server" only works in server components
or
if you import it from another file
Common MoorhenOP
its not that its not working the server action
is that its not submitting
Nile Crocodile
create another file
and add "use server" at the top
write your async function there
Nile Crocodile
and import it in the dialog form
try it
@Common Moorhen this is the full file: tsx "use client"; import { editTag } from "@/components/feature/calendar-aside/components/tags/actions/edit"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label/label.component"; import { ValidationError } from "@/components/ui/validation-error"; import { Database } from "@/lib/utils/supabase/types"; import { useRouter } from "next/navigation"; import { useMemo, useState } from "react"; import { useForm } from "react-hook-form"; type TFormData = { name: string; }; export function EditBtn({ tag, }: { tag: Database["public"]["Tables"]["tag"]["Row"]; }) { const [loading, setLoading] = useState<boolean>(false); const [error, setError] = useState<Boolean>(false); const router = useRouter(); async function handleEditTag(/*data: TFormData */) { console.log("submitting"); // setLoading(true); // try { // const name = data.name; // // await editTag({ name, tagId: tag.id }); // // setError(false); // setLoading(false); // router.refresh(); // } catch (error) { // setError(true); // } } const { register, formState: { errors, isValid }, handleSubmit, } = useForm<TFormData>({ mode: "onBlur" }); const tagName = useMemo(() => tag.name, [tag.name]);
Common MoorhenOP
im not using server actions in this file
i created the issue with the title "server action not running" because i though it was the problem
Common MoorhenOP
but the problem is that its not never submitting
Nile Crocodile
oh okay
Common MoorhenOP
not a normal form submit
nor a server action
Nile Crocodile
instead of doing handle submit on form
try doing it on the button
Common MoorhenOP
yes
it works
Nile Crocodile
whats the issue then
you want it specifically on form?
Common MoorhenOP
yes
because the problem is that i cant submit a form
and not being able to use a server action is just one of the problems that carries with
Nile Crocodile
can you try onSubmit={handleSubmit(handleEditTag, console.warn)}
and tell me if that logs anything
Common MoorhenOP
it does not
this is the html output
its not that I don't catch the submit with javascript, is that the button never submits the form. it does not even behave as a default submit
Nile Crocodile
so onSubmit={console.log} doesnt work either
Common MoorhenOP
no
Nile Crocodile
is there any reason as to why putting handleSubmit on button itself is not sufficient?
wait
can you add name="name" to <Input
nvm thats useless
Common MoorhenOP
the input is also behaving weird
i forgot to change the onubmit
it doesnt work either if I use just
<form onSubmit={() => {console.log('here)}}>
  <button type='submit'>submit</button>
</form>
oh i found the solution
let me try it
Nile Crocodile
weird
could always also just slap handleSubmit on the submit button itself
thats what i usually do
Nile Crocodile
Answer
Nile Crocodile
its in the same shadcn dialog
Common MoorhenOP
it works
thank you
Nile Crocodile
np