Shadcn 表单选择 + 服务器操作

问题描述 投票:0回答:1

我无法读取 shadcn 表单 Select 中的选择值。我正在使用服务器操作。 因此,我正在创建一个表单来发送电子邮件,我可以读取其他字段的值,但不能读取选择标签的值

这就是表格

'use client'

import * as z from "zod"
import React, { useState } from 'react'
import { zodResolver } from "@hookform/resolvers/zod"
import { Message, useForm } from "react-hook-form"
 
import { Button } from "@/components/ui/button"
import {
  Form,
  FormControl,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Textarea } from "@/components/ui/textarea"
import {toast} from "react-hot-toast"

import { sendEmail} from "@/actions/integrations/Email.actions"
import EmailSubmitButton from "./EmailSubmitButton"
import { useFormState } from "react-dom"
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from "@/components/ui/select"


const formSchema = z.object({
  from: z.string()
        .email()
  ,
  to: z.string()
        .email()
  ,
  subject: z.string().min(3, {
    message: "Subject is required and must be of atleast 3 characters.",
  }),
  message: z.string().min(10, {
    message: "Message is required and must be of atleast 10 characters.",
  }),
  calendlylink : z.string()
})


const EmailApplicantForm = () => {

  const initialState = {message  : null, errors : { } };
  const [state, dispatch] = useFormState(sendEmail, initialState)
  
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
    defaultValues: {
      from: "[email protected]", 
      to: "[email protected]",
      subject: "",
      message: "",
      calendlylink : ""
    },
  })

  console.log('STATE', state)

  type InterviewLinkType = {
    id : string,
    title : string,
    link : string
  }
  
  const interviewLinks: InterviewLinkType[] = [
    {
      id : '1',
      title : 'Interview For Frontend Engineer Round-1',
      link : 'https://calendly.com/sobitp59/interview-round-1',
    },
    {
      id : '2',
      title : 'Interview for Backend Engineer Round-2',
      link : 'https://calendly.com/sobitp59/interview-for-backend-engineer-round-2',
    },
    {
      id : '3',
      title : 'Interview for Backend Engineer Round-3',
      link : 'https://calendly.com/sobitp59/interview-for-backend-engineer-round-3',
    },
    {
      id : '4',
      title : 'Interview for Backend Engineer Round-4',
      link : 'https://calendly.com/sobitp59/interview-for-backend-engineer-round-4',
    },
  ]


  return (
    <Form {...form}>
    <form action={dispatch}
      className="space-y-8">
     
      <!-- OTHER FIELDS  -->
      
      <FormField
        control={form.control}
        name="calendlylink"
        render={({ field }) => (
          <FormItem>
            <FormLabel>Select calendly link</FormLabel>
              <Select onValueChange={field.onChange} value={field.value}>
            <FormControl>

              <SelectTrigger>
                <SelectValue placeholder="Choose your calendly link"/>
              </SelectTrigger>
            </FormControl>
              <SelectContent>
              {interviewLinks.map(({id, title, link} : InterviewLinkType) => (
                  <SelectItem key={id.toString()} value={link}>{title}</SelectItem>
                  ))}
              </SelectContent>
              </Select>
          </FormItem>
        )}
      />

      <div className="flex justify-end">
        <EmailSubmitButton />
      </div>
      
    </form>
  </Form>
  )
}

export default EmailApplicantForm

这就是行动

"use server"

import { z } from 'zod'
import React from "react";
import { Resend } from "resend";

import SendCandidateEmailTemplate from "@/components/applicants/email_applicant_form/EmailTemplate";
const resend = new Resend(process.env.RESEND_API_KEY);

import {
    UNAUTHORIZED_ACTION,
  } from "@/lib/exceptions/exceptions";

import { currentUser } from '@clerk/nextjs';
 
const sendEmailFormSchema = z.object({
    to: z.string()
        .email()
    ,
    from: z.string()
        .email()
    ,
    message: z.string()
        .min(10, {message : 'Message is required and should be atleast of 10 characters.'})
    ,
    subject: z.string()
        .min(3, {message : 'Subject is required and should be atleast of 3 characters.'})
        ,
    calendlylink : z.string()
        .min(3, {message : 'Subject is required and should be atleast of 3 characters.'})
})

export type State = {
    errors?: {
        from ?: string[];
        to ?: string[];
        subject?: string[];
        message?: string[];
        calendlylink ?: string[]
      };
    message?: string | null;
}

export async function sendEmail(prevState : State, formData : FormData){

    console.log("FORM DATA", formData)

    const validateFields =  sendEmailFormSchema.safeParse({
        from : formData.get('from'),
        to : formData.get('to'),
        subject : formData.get('subject'),
        message : formData.get('message'),
        calendlylink : formData.get('calendlylink')
    })

    if(!validateFields.success) {
        return {
          errors: validateFields.error.flatten().fieldErrors,
          message: 'Missing Fields. Failed to Send Email.',
        };
    }

    const {to, from, subject, message, calendlylink } = validateFields.data;
    console.log('FOMR DATA', {to, from, subject, message, calendlylink})
    try {
        const user = await currentUser();

        if (!user) {
            return UNAUTHORIZED_ACTION();
        }

        
        const data = await resend.emails.send({
            from: 'TEST <[email protected]>',
            to: '[email protected]',
            subject: subject,
            react: React.createElement(SendCandidateEmailTemplate, {
                message : message,
                candidateName   : 'Sobit',
                subject : subject
            }),
        });
        
        return {data : data};
    } catch (error) {
        return {
            message: 'Failed to send email.',
          }; 
    }
}

我正在尝试服务器端验证。我应该获取具有所选值的 formData。但无法读取该数据。我尝试阅读其他博客,但没有服务器操作的正确答案。 我无法弄清楚

next.js13 zod server-action
1个回答
0
投票

您无法通过表单提交操作检索 shadcn select 的值,因为它不是真正的表单元素。所以表单不知道它是否存在。解决方案是使用隐藏的 html 元素。在提交表单之前,将 shadcdn select 的值放入隐藏的 html 元素中。您可以通过 html 隐藏元素检索值。

© www.soinside.com 2019 - 2024. All rights reserved.