Typescript: Chips are not visible in Textfield

Issue

This Content is from Stack Overflow. Question asked by user15361826

In my project, there is a field that shows multiple address chips. Now I am facing a problem. When you copy and paste multiple address values into the field, it will not show in the field, but the value will be updated and displayed in the console:

enter image description here

enter image description here

But after that situation press any key (Not enter) which shows the values like this:

enter image description here

I want to avoid this delay. My requirement is to paste multiple values and then press “enter” key, the values will appear in the field.I tried to correct this situation but failed. Please give me some suggestions to solve this problem

import { faCircleQuestion, faXmark } from "@fortawesome/pro-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Chip, TextField } from "@mui/material";
import { JSXElementConstructor, Key, ReactElement, ReactFragment, useRef, useState } from "react";
import validator from "validator";

import styles from "./index.module.scss";

type Props = {
  LabelName?: string;
  optional?: string;
  tooltip?: string;
  placeholder?: string;
  className?: string;
  upload?: boolean;
  items?: any;
  setItem: (items: any) => void;
};
const TagActions = (props: Props) => {
  // const [items, setItem] = useState<string[]>([]);
  const [value, setValue] = useState("");
  const [error, setError] = useState("");
  const divRef = useRef<HTMLDivElement>(null);
  const [flag, setFlag] = useState(false);

  const {
    LabelName,
    optional,
    tooltip,
    placeholder,
    className,
    upload,
    items,
    setItem,
  } = props;

  const handleDelete = (item: any) => {
    const result = items.filter((i: any) => i !== item);
    setItem(result);
  };

  const handleItemEdit = (item: any) => {
    const result = items.filter((i: any) => i !== item);
    setItem(result);
    setValue(item);
  };

  const handleKeyDown = (evt: any) => {
    if (["Enter", "Tab", ","].includes(evt.key)) {
      evt.preventDefault();

      const test = value.trim();

      if (test && isValid(test)) {
        items.push(test);
        setValue("");
      }
    }
  };

  const isValid = (email: any) => {
    let error = null;

    if (isInList(email)) {
      error = `${email} has already been added.`;
    }

    if (!validator.isEmail(email)) {
      setFlag(true);
    }

    if (error) {
      setError(error);

      return false;
    }

    return true;
  };

  const isInList = (email: any) => {
    return items.includes(email);
  };

  const handleChange = (evt: any) => {
    setValue(evt.target.value);
  };

  const handlePaste = (evt: any) => {
    evt.preventDefault();

    const paste = evt.clipboardData.getData("text");
    const emails = paste.match(/[wd\.-]+@[wd\.-]+.[wd\.-]+/g);

    if (emails) {
      const toBeAdded = emails.filter((email: any) => !isInList(email));

      console.log("items inside", items);
      toBeAdded.map((i: any) => {
        items.push(i);
      });
      console.log("items after", items);
    }
  };

  return (
    <>
      <div className="formSection">
        {LabelName && (
          <div className={`control-label ${styles.label}`}>
            <label>
              <span className={styles.alignLeft}>
                <span className={styles.labelText}>{LabelName}</span>
              </span>
            </label>

            <span className={styles.alignRight}>
              {upload && (
                <label htmlFor="uploadCSV">
                  <span className={styles.upload}>Upload CSV</span>
                </label>
              )}

              {optional && <span className={styles.light}>Optional</span>}

              {tooltip && (
                <span className={styles.tooltip_ic} title={tooltip}>
                  <FontAwesomeIcon icon={faCircleQuestion} size="xs" />
                </span>
              )}
            </span>
          </div>
        )}
        <input
          type="file"
          accept=".csv"
          style={{ display: "none" }}
          id="uploadCSV"
        />
        <div className={styles.inputGroup}>
          <TextField
            className={` textfield-emailchip test ${className}`}
            InputProps={{
              startAdornment: items.map(
                (
                  item:
                    | boolean
                    | Key
                    | ReactElement<any, string | JSXElementConstructor<any>>
                    | ReactFragment
                    | null
                    | undefined
                    | any
                    | string
                ) => (
                  <Chip
                    className={
                      !validator.isEmail(item)
                        ? styles.chipTagError
                        : styles.chipTag
                    }
                    key={item}
                    tabIndex={-1}
                    label={item}
                    onDelete={() => handleDelete(item)}
                    onClick={() => handleItemEdit(item)}
                    deleteIcon={<FontAwesomeIcon icon={faXmark} size="xs" />}
                  />
                )
              ),
            }}
            ref={divRef}
            value={value}
            placeholder={placeholder}
            onKeyDown={(e) => handleKeyDown(e)}
            onChange={(e) => handleChange(e)}
            onPaste={(e) => handlePaste(e)}
          />
        </div>

        {error && <p className="error">{error}</p>}
      </div>
    </>
  );
};

export default TagActions;




Solution

This question is not yet answered, be the first one who answer using the comment. Later the confirmed answer will be published as the solution.

This Question and Answer are collected from stackoverflow and tested by JTuto community, is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?