Search code examples
javascriptreactjsantd

How to change select options based on other selection ( Javascript)


I have an 4 Select component with the same list options. If I choose an option, that one will be remove from the list of other Select components so that no 2 Select have identical result. Here is the code:

listStaff = [
  {id: 1, name: 'John Doe'},
  {id: 2, name: 'Walter White},
  {id: 3, name: 'Jesse Pinkman}
  {id: 4, name: 'Saul Goodman}
  {id: 5, name: 'Gus Fring}
  {id: 6, name: 'Skyler White}
]
const [staff, setStaff] = useState([])
      <Select
        allowClear
        placeholder="Choose staff #1"
        onChange={(e) => onChangeStaff(e, 0)}
        value={staff[0]}
      >
        {listStaff?.map((item) => {
          return (
            <Select.Option key={item?.id} value={item?.id}>
              {item?.name}
            </Select.Option>
          );
        })}
      </Select>

      <Select
        allowClear
        placeholder="Choose staff #2"
        onChange={(e) => onChangeStaff(e, 1)}
        value={staff[1]}
      >
        {listStaff?.map((item) => {
          return (
            <Select.Option key={item?.id} value={item?.id}>
              {item?.name}
            </Select.Option>
          );
        })}
      </Select>

      <Select
        allowClear
        placeholder="Choose staff #3"
        onChange={(e) => onChangeStaff(e, 2)}
        value={staff[2]}
      >
        {listStaff?.map((item) => {
          return (
            <Select.Option key={item?.id} value={item?.id}>
              {item?.name}
            </Select.Option>
          );
        })}
      </Select>

      <Select
        allowClear
        placeholder="Choose staff #4"
        onChange={(e) => onChangeStaff(e, 3)}
        value={staff[3]}
      >
        {listStaff?.map((item) => {
          return (
            <Select.Option key={item?.id} value={item?.id}>
              {item?.name}
            </Select.Option>
          );
        })}
      </Select>

Here is what I try:

const onChangeStaff = (id, index) => {
      let arrTemp = [...listStaff]
      const i = arrTemp.findIndex(r => r.id == id)
      if(i > -1 ){
         arrTemp.splice(i, 1)
      } else {
         return arrTemp
      }
      setListStaff(arrTemp)
   };

I can remove the chosen option from the list but when a clear the Select or choose another option, the previous one do not revert but lost permanently. So how can I remove one option when choosing but revert that one back when deselect? Thank you. Demo: https://codesandbox.io/s/holy-dew-h6qxc4?file=/src/App.js


Solution

  • i messing around with your code a bit. try this

    import "./styles.css";
    import { Select } from "antd";
    import { useState } from "react";
    
    export default function App() {
    
      const [listStaff, setListStaff] = useState([
        { id: 1, name: "Walter White" },
        { id: 2, name: "Jesse Pinkman" },
        { id: 3, name: "Gus Fring" },
        { id: 4, name: "Saul Goodman" },
        { id: 5, name: "John Doe" },
        { id: 6, name: "Skyler White" }
      ]);
    
      const [selectedStaff, setSelectedStaff] = useState(new Array(4).fill(null));
    
      const handleChangeStaff = (id, i) => {
        setSelectedStaff(p => {
          const newSelectedStaff = [...p];
          newSelectedStaff[i] = id === undefined ? null : listStaff.find(ls => ls.id === id);
          return newSelectedStaff;
        });
      };
    
      return (
        <div className="App">
          {new Array(4).fill("").map((_, i) => ( 
            <Select
            allowClear
            placeholder={`Choose staff #${i+1}`}
            onChange={(id) => handleChangeStaff(id, i)}
            key={i}
          >
            {listStaff.filter(ls => selectedStaff.find(ss => ss !== null && ss.id === ls.id) === undefined).map(ls => (
                <Select.Option key={ls.id} value={ls.id}>
                  {ls.name}
                </Select.Option>
             ))}
          </Select>
          ))}
        </div>
      );
    }