Handling Unique Options in Dropdowns with React JS

  • Code 1

  import React, { useEffect, useState } from 'react'
  import Select from 'react-select'
  import "./App.css"
  const nameDropdown = [
    { label: "Joy", value: "Joy" },
    { label: "Mac", value: "Mac" },
    { label: "Jack", value: "Jack" },
    { label: "Neck", value: "Neck" }
  ]
  const App = () => {
    const [dataArr, setDataArr] = useState([{ name: "" }])
    const [uniqueDropdown, setUniqueDropdown] = useState([])

    useEffect(() => {
      if (dataArr.length > 0) {
        const nameStr = dataArr.map(feeType => feeType.name)

        const nonSelectFeeTypeItem = []
        const selectFeeTypeItem = []
        JSON.parse(JSON.stringify(nameDropdown)).map(item => {
          if (!nameStr.includes(item.value)) {
            nonSelectFeeTypeItem.push(item)
          }
          if (nameStr.includes(item.value)) {
            selectFeeTypeItem.push(item)
          }
        })
        setUniqueDropdown(JSON.parse(JSON.stringify(nonSelectFeeTypeItem)))
      }
    }, [dataArr])


    return (<>
      <div className='container'>

        {dataArr.map((item, index) => (
          <div
            className='sub-container'
            key={index}
          >
            <div style={{ width: "100%" }}>
              <Select
                options={uniqueDropdown}
                onChange={(e) => {
                  if (e) {
                    item.name = e.value
                    setDataArr([...dataArr])
                  } else {
                    item.name = ""
                    setDataArr([...dataArr])
                  }
                }}
                value={nameDropdown.filter(io => io.value === item.name)}
                isClearable={true}
                required={true}
                placeholder="Select Name"
              />
            </div>
            <div style={{ display: "flex" }}>
              {dataArr.length < nameDropdown.length && (<>
                <div>
                  <button
                    className='btn-style'
                    type='button'
                    onClick={() => {
                      setDataArr([...dataArr, { name: "" }])
                    }}
                  >Add</button>
                </div>
              </>)}
              {dataArr.length > 1 && (<>
                <div>
                  <button
                    className='btn-style'
                    type='button'
                    onClick={() => {
                      dataArr.splice(index, 1)
                      setDataArr([...dataArr])
                    }}
                  >Del</button>
                </div>
              </>)}
            </div>
          </div>
        ))}
      </div>
    </>)
  }

  export default App

  • Code 2 (improved version)

  import React, { useEffect, useState } from 'react';
  import Select from 'react-select';
  import "./App.css";

  const nameDropdown = [
    { label: "Joy", value: "Joy" },
    { label: "Mac", value: "Mac" },
    { label: "Jack", value: "Jack" },
    { label: "Neck", value: "Neck" },
  ];

  const App = () => {
    const [dataArr, setDataArr] = useState([{ name: "" }]);
    const [uniqueDropdown, setUniqueDropdown] = useState([]);

    // Update uniqueDropdown whenever dataArr changes
    useEffect(() => {
      const selectedNames = dataArr.map(item => item.name);
      const availableOptions = nameDropdown.filter(option => !selectedNames.includes(option.value));
      setUniqueDropdown(availableOptions);
    }, [dataArr]);

    const handleChange = (selectedOption, index) => {
      setDataArr(currentData =>
        currentData.map((item, idx) =>
          idx === index ? { ...item, name: selectedOption ? selectedOption.value : "" } : item
        )
      );
    };

    const handleAdd = () => {
      setDataArr(currentData => [...currentData, { name: "" }]);
    };

    const handleDelete = (index) => {
      setDataArr(currentData => currentData.filter((_, idx) => idx !== index));
    };

    return (
      <div className='container'>
        {dataArr.map((item, index) => (
          <div
            className='sub-container'
            key={index}
          >
            <div style={{ width: "100%" }}>
              <Select
                options={uniqueDropdown}
                onChange={e => handleChange(e, index)}
                value={nameDropdown.find(io => io.value === item.name) || null}
                isClearable={true}
                placeholder="Select Name"
              />
            </div>
            <div style={{ display: "flex" }}>
              {dataArr.length < nameDropdown.length && (
                <button className='btn-style' type='button' onClick={handleAdd}>Add</button>
              )}
              {dataArr.length > 1 && (
                <button className='btn-style' type='button' onClick={() => handleDelete(index)}>Del</button>
              )}
            </div>
          </div>
        ))}
      </div>
    );
  };

  export default App;

  • Styling

  .btn-style {
    background-color: #db6969;
    border: none;
    padding: 10px 20px;
    color: white;
    font-size: 16px;
    cursor: pointer;
  }

  .container {
    display: flex;
    justify-content: center;
    flex-direction: column;
    align-items: center;
    height: 100vh;
    overflow: auto;
    width: 100%;
  }

  .sub-container {
    display: flex;
    width: 400px;
    margin-bottom: 10px;
  }


No comments:

Post a Comment