React Shadcn TextArea with Chips

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

我正在使用

React
React-Hook-Form
Zod
Shadcn-ui
。 我的问题是我想在
textarea
中输入多个名称, 一旦你在上面加上逗号,它就会像芯片一样被转换(https://mui.com/material-ui/react-chip/),然后你就可以输入另一个名字等等.

芯片也可以单独删除。

提交时的预期输出只是带逗号的名称。

代码沙盒 ----> 单击此处

代码

   <Form {...form}>
      <form
        onSubmit={form.handleSubmit(onSubmit)}
        method="post"
        className="space-y-8"
      >
        <FormField
          control={form.control}
          name="names"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Names</FormLabel>
              <FormControl>
                <Textarea placeholder="shadcn" {...field} />
              </FormControl>
              <FormDescription>
                Enter names separated by a comma
              </FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />
        <Button type="submit">Submit</Button>
      </form>
    </Form>
javascript reactjs shadcnui
1个回答
0
投票

将您的代码替换为:

<Form {...form}>
  <form
    onSubmit={form.handleSubmit(onSubmit)}
    method="post"
    className="space-y-8"
  >
    <FormField
      control={form.control}
      name="names"
      render={({ field: { value, onChange } }) => (
        <FormItem>
          <FormLabel>Names</FormLabel>
          <div className="flex gap-1 empty:hidden">
            {!!value.trim().length &&
              value?.split(",").map((name, index) => (
                <div
                  key={index}
                  className="rounded-md inline-flex items-center pl-2.5 py-1 pr-1 text-xs bg-zinc-100"
                >
                  {name}
                  <button
                    type="button"
                    onClick={() =>
                      onChange(
                        value
                          .split(",")
                          .filter((_) => _ != name)
                          .join(",")
                      )
                    }
                  >
                    <svg
                      width="12"
                      height="12"
                      viewBox="0 0 15 15"
                      fill="none"
                      xmlns="http://www.w3.org/2000/svg"
                      className="ml-2"
                    >
                      <path
                        d="M12.8536 2.85355C13.0488 2.65829 13.0488 2.34171 12.8536 2.14645C12.6583 1.95118 12.3417 1.95118 12.1464 2.14645L7.5 6.79289L2.85355 2.14645C2.65829 1.95118 2.34171 1.95118 2.14645 2.14645C1.95118 2.34171 1.95118 2.65829 2.14645 2.85355L6.79289 7.5L2.14645 12.1464C1.95118 12.3417 1.95118 12.6583 2.14645 12.8536C2.34171 13.0488 2.65829 13.0488 2.85355 12.8536L7.5 8.20711L12.1464 12.8536C12.3417 13.0488 12.6583 13.0488 12.8536 12.8536C13.0488 12.6583 13.0488 12.3417 12.8536 12.1464L8.20711 7.5L12.8536 2.85355Z"
                        fill="currentColor"
                        fillRule="evenodd"
                        clipRule="evenodd"
                      ></path>
                    </svg>
                  </button>
                </div>
              ))}
          </div>
          <FormControl>
            <Textarea
              placeholder="Enter names"
              className="min-h-40"
              onKeyDown={(e) => {
                if (e.key == ",") {
                  if (!value) {
                    onChange(e.target.value.replace(",", ""));
                    e.target.value = ""; // clear the textarea value
                  } else {
                    onChange(
                      value.concat(",", e.target.value.replace(",", ""))
                    );
                    e.target.value = "";
                  }
                  e.preventDefault(); // do not let comma ',' to enter in textarea
                }
              }}
            />
          </FormControl>
          <FormMessage />
        </FormItem>
      )}
    />
    <Button type="submit">Submit</Button>
  </form>
</Form>
© www.soinside.com 2019 - 2024. All rights reserved.