1
votes

I relatively new to React and Semantic UI as well. There is a component called Dropdown with a props multiple and selection, which allows to select multiple items.

On the output my state looks like this:

const selectedItems = [
   {key: 1, value: 1, text: 'Item 1'},
   {key: 2, value: 2, text: 'Item 2'},
   {key: 3, value: 3, text: 'Item 3'},
];

How can I do setup limit of N amount of elements?

Many thanks

4

4 Answers

2
votes

The Semantic UI React Dropdown option provides a function called as onAddItem. You will have to use the value data key and do something like this:

const onAddItem = (event, data) => {

    1.Fetch the state of the selected values, stored in the value key
    2. Check if the limit is greater than 2
    3. If the condition is met, then add
    4. Else, show an error

}

Documentation Link

1
votes

Well according to https://react.semantic-ui.com/modules/dropdown#dropdown-example-multiple-selection you need to create controlled component, which means you will bind value={this.state.selectedItems} then you will bind onChange={(e,data) => { this.handleChange(e,data )} and in your code

onChange (e, data) {
  const currentItems = this.state.selectedItems

  if (currentItems.length <= MAX_SELECTION ) {
    currentItems.push(data)

    this.setState({
      selectedItems: currentItems
    })
  }
}

this will crate controlled component which will allows you to control state by yourself, and you will limit changing state, probably you will need to also handle removing items from state inside this onChange event.

1
votes

I would like to suggest another approach. set useState directly to the dropdown value.

import React, { useState } from 'react';
import { Dropdown } from 'semantic-ui-react';

const MAX_FRUITS_SELECTION = 3;

const FruitsSelect = () => {
  const [fruitId, setFruitId] = useState([]);

  const optionsFRUITSFake = [
    { key: 1, value: 1, text: 'Orange' },
    { key: 2, value: 2, text: 'Lemon' },
    { key: 3, value: 3, text: 'Apple' },
    { key: 4, value: 4, text: 'Banana' },
    { key: 5, value: 5, text: 'Melon' },
    { key: 6, value: 6, text: 'Pineapple' }
  ];

  const handleDropFilterFruit = (e: any, data?: any) => {
    if (data.value.length <= MAX_FRUITS_SELECTION) {
      setFruitId(data.value);
    }
  };

  return (
    <Dropdown
      placeholder="Select Fruits"
      onChange={handleDropFilterFruit}
      value={fruitId}
      fluid
      multiple
      selectOnNavigation={false}
      search
      selection
      options={optionsFRUITSFake}
    />
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(
  <React.StrictMode>
    <FruitsSelect />
  </React.StrictMode>,
  rootElement
);
<!DOCTYPE html>
<html lang="en">
<body>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
	<div id="root"></div>
</body>
</html>
0
votes

I'm posting my workaround here. It's probably more short and simple.

At first, save the values in the state (preferably redux state) after every onChange. React state also would do fine. Then, make it disabled when a certain array length of the value is reached.

const districtData = ['Dhaka', 'Bagerhat', 'Bandarban', 
'Barguna', 'Barishal', 'Bhola']

const [districtValue, setDistrictValue] = useState();

<Dropdown
onChange={async (e, { name, value }) => {setDistrictValue(value)}}
options={districtData.map((currentValue, index) => {
    return {
    key: `${currentValue}`,
    value: `${currentValue}`,
    text: `${currentValue}`,
    disabled: districtValue.length > 2 ? true : false 
}
// Do other things here
// Max 3 values here, then options will be disabled. 
// Will be live again if any selected options are less than 3 here                

/>