代码之家  ›  专栏  ›  技术社区  ›  Stykgwar

如果用户没有完成第一步,我如何禁用下一步按钮?

  •  0
  • Stykgwar  · 技术社区  · 1 年前

    所以我使用shadcn、react钩子形式和zod创建了一个多步骤形式。我已经创建了3种类型的zod模式,并使用 z.union 来自zod。我现在遇到的问题是,即使我没有完成输入,我仍然可以按下下一个按钮。

    约会.ts

    export const AppointmentSchema = z.union([
        FirstPartSchema,
        SecondPartSchema,
        ThirdPartSchema,
    ])
    
    //There came from different Ts files
    export const FirstPartSchema= z.object({
        title: z.string(),
      });
    
    export const SecondPartSchema= z.object({
        name: z.string(),
      });
    
    
    export const ThirdPartSchema= z.object({
        description: z.string(),
      });
    

    这是我的表格。

    const steps = [
      {
        id: 'Step 1',
        name: 'General Information',
        fields: ['title']
      },
      {
        id: 'Step 2',
        name: 'Date , Time and Assistance ',
        fields: ['name']
      },
      {
        id: "Step 3",
        name: "Dry Run",
        fields: ['description']
      },
    ]
    
    const CreateScheduleDialog = ({ open, setOpen }: Props) => {
    
      const [step, setStep] = useState(0);
      const currentStep = steps[step];
    
      const nextStep = () => {
        if (step < steps.length - 1) {
          setStep(step + 1);
        }
      };
    
      const prevStep = () => {
        if (step > 0) {
          setStep(step - 1);
        }
      };
    
      const form = useForm<AppointmentSchemaType>({
        resolver: zodResolver(AppointmentSchema),
        defaultValues: {
        }
      })
    
      return (
        <Dialog>
          <DialogTrigger asChild>
            <Button disabled={open !== false ? false : true} className='w-full' color="primary-foreground">Add Schedule</Button>
          </DialogTrigger>
          <DialogContent className={cn(`max-w-[400px] md:max-w-[800px]`)}>
            <DialogHeader>
              <DialogTitle>{currentStep.name}</DialogTitle>
              <DialogDescription>
                Step {step + 1} of {steps.length}
              </DialogDescription>
            </DialogHeader>
            <Form {...form}>
              {step == 0 && (
                <div className='flex flex-col gap-y-2'>
                  <FormField
                    control={form.control}
                    name="title"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Title</FormLabel>
                        <FormControl>
                          <Input placeholder="Title" {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                </div>
              )}
              {step == 1 && (
                <div>
                  <FormField
                    control={form.control}
                    name="name"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Name</FormLabel>
                        <FormControl>
                          <Input placeholder="Name" {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                </div>
              )}
              {step == 2 && (
                <div>
                  <FormField
                    control={form.control}
                    name="description"
                    render={({ field }) => (
                      <FormItem>
                        <FormLabel>Description</FormLabel>
                        <FormControl>
                          <Input placeholder="Description" {...field} />
                        </FormControl>
                        <FormMessage />
                      </FormItem>
                    )}
                  />
                </div>
              )}
            </Form>
            <DialogFooter>
              <Button onClick={prevStep} disabled={step === 0}>Back</Button>
              {step === steps.length - 1 ? (
                <Button
                // onClick={form.handleSubmit(onSubmit)}
                >Submit</Button>
              ) : (
                <Button onClick={nextStep}>Next</Button>
              )}
            </DialogFooter>
          </DialogContent>
    
        </Dialog>
      )
    }
    
    1 回复  |  直到 1 年前
        1
  •  1
  •   Anil Singha    1 年前

    首先,您可以在函数中使用此标志

    const nextStep = async () => {
        const isValid = await form.trigger(); // Trigger validation for all fields
        if (isValid) {
          setStep((prevStep) => prevStep + 1);
        }
      }
    

    而不是这样做

    <Button onClick={prevStep} disabled={step === 0}>
      Back
    </Button>
    {step === steps.length - 1 ? (
      <Button
        // onClick={form.handleSubmit(onSubmit)}
      >
        Submit
      </Button>
    ) : (
      <Button onClick={nextStep}>
        Next
      </Button>
    )}
    

    你现在可以使用这个

    <Button onClick={prevStep} disabled={step === 0}>
          Back
        </Button>
        {step === steps.length - 1 ? (
          <Button onClick={form.handleSubmit(onSubmit)} disabled={!form.formState.isValid}>
            Submit
          </Button>
        ) : (
          <Button onClick={nextStep} disabled={!form.formState.isValid}>
            Next
          </Button>
        )}
    

    禁用“下一步”按钮 (disabled={!form.formState.isValid}) 基于 form.formState.isValid. 如果当前步骤的字段无效,这将阻止用户前进到下一个步骤。

    推荐文章