How to select and deselect on dropdown list react

2.7k Views Asked by At

I have a dropdown. Users are able to select multiple items from the dropdown. At the same time, users are able to deselect the items that they have selected by clicking the selected items again. If users select all, all numbers in the array will display.

How to implement this? This is what I have so far enter link description here

import "./styles.css";
import React, { useState } from "react";

const options = [1, 2, 3, 4, 5];

export default function App() {
  const [nums, setNum] = useState([]);

  const handleArrChange = ({ target }) => {
    setNum([...nums, target.value]);
  };
  return (
    <div className="App">
      <select
        onChange={handleArrChange}
        value={"select a number" || nums.length > 0}
      >
        <option disabled>select a number</option>
        {options.map((option) => (
          <option>{option}</option>
        ))}
      </select>
      {nums.map((num) => (
        <p>{num}</p>
      ))}
    </div>
  );
}
2

There are 2 best solutions below

0
On

It seems like a multiple selector (A custom implementation of a select)

Example:

import React, { useState } from 'react';
import Select from 'react-select';
 
function App() {
  const data = [
    {
      value: 1,
      label: "cerulean"
    },
    {
      value: 2,
      label: "fuchsia rose"
    },
    {
      value: 3,
      label: "true red"
    },
    {
      value: 4,
      label: "aqua sky"
    },
    {
      value: 5,
      label: "tigerlily"
    },
    {
      value: 6,
      label: "blue turquoise"
    }
  ];
 
  // set value for default selection
  const [selectedValue, setSelectedValue] = useState([]);
 
  // handle onChange event of the dropdown
  const handleChange = (e) => {
    setSelectedValue(Array.isArray(e) ? e.map(x => x.value) : []);
  }
 
  return (
    <div className="App">
      <h3>Get selected by only value for multi select - <a href="https://www.cluemediator.com">Clue Mediator</a></h3>
 
      <Select
        className="dropdown"
        placeholder="Select Option"
        value={data.filter(obj => selectedValue.includes(obj.value))} // set selected values
        options={data} // set list of the data
        onChange={handleChange} // assign onChange function
        isMulti
        isClearable
      />
 
      {selectedValue && <div style={{ marginTop: 20, lineHeight: '25px' }}>
        <div><b>Selected Value: </b> {JSON.stringify(selectedValue, null, 2)}</div>
      </div>}
    </div>
  );
}
 
export default App;

enter image description here

Ref: https://www.cluemediator.com/how-to-get-selected-by-only-value-for-multi-select-in-react-select

8
On

Live working example: https://react-3gte8y.stackblitz.io/

code : https://stackblitz.com/edit/react-3gte8y?file=src/App.js

First keep your options array contain only numbers:

const options = [1, 2, 3, 4, 5];

then in your onChange handler function check if the selected value already exist in the nums state, if not exist add it, else remove it how to that? easy get the index of the value using indexOf method, if it return -1 means number not exist in num array, else indexOf will return the actual index of your chosen number:

const handleArrChange = ({ target }) => {

        setNum((prev) => {

          //get index of actual target.value
          const index = prev.indexOf(target.value);

          /*if index === -1 means not exist in array will return the prev 
          state and appending new chosen value*/
          if (index === -1) {

            return [...prev, target.value];

          }

           /* else (value exist) use splice to remove the chosen value from 
           the array */
          prev.splice(index, 1);

          /* don't use return prev, React will not detect changes in your 
          state and will not re render it */
          return [...prev];

        });
      };

prev is the previous state, it hold actual state before making any change to the num state.

Now make some change to your JSX, first don't forget keys, and make sure to set default select value to select the disabled option:

<select onChange={handleArrChange} value={"select"}>
    <option disabled>select</option>
    {options.map((option) => (
        <option key={option}>{option}</option>
    ))}
</select>

and

{nums.map((num) => (
        <p key={num}>{num}</p>
      ))}

Now you need one thing is to select All and deselect all

first add all to your options:

<select onChange={handleArrChange} value={"select"}>
        <option disabled>select</option>
        <option>All</option>
        {options.map((option) => (
          <option key={option}>{option}</option>
        ))}
</select>

then in the onChange function handler check if is All is checked:

if(target.value === "All"){
        if(nums.length > 0 ){
            setNum([])
        }else{
            setNum(options)
        }
        return
    }

this code must be first thing you do when select value changes, add it to the top of your onChange function:

here is the full working code:

import React, { useState } from "react";

const options = [1, 2, 3, 4, 5];

export default function App() {


  const [nums, setNum] = useState([]);
  
  const handleArrChange = ({ target }) => {

    if(target.value === "All"){
        if(nums.length > 0 ){
            setNum([])
        }else{
            setNum(options)
        }
        return
    }

    setNum((prev) => {

      const index = prev.indexOf(target.value);

      if (index === -1) {

        return [...prev, target.value];

      }

      prev.splice(index, 1);

      

      return [...prev];
    });

  };
  return (
    <div className="App">

        <select onChange={handleArrChange} value={"select"}>

            <option disabled>select</option>

            <option>All</option>

            {options.map((option) => (

            <option key={option}>{option}</option>

            ))}

        </select>

        {nums.map((num) => (

            <p key={num}>{num}</p>

        ))}

    </div>

  );
}