Jeyanth Kanagaraj
Jeyanth Kanagaraj

Reputation: 271

Selecting Multiple options in Reactjs

I have some data in arrays. I am getting it by using map, as you see in the below example. Also, i pass that into the button. Now, if, i select a button, it will get selected. But, if i select the next button, the previous button will get unselected and the current button will get selected. I don't want it to happen. I want to select multi buttons, if it all get clicked.

Thanks in advance.

Below is the Solution

   import React, { Component } from 'react';


const BUTTONS = [
    {id:0, title:'button1'},
    {id:1, title:'button2'},
    {id:2, title:'button3'}
]
class Map extends Component {
    constructor(props){
        super(props);
        this.state = {
            values: []
        }
    }
    handleButton = button => {
        let tmp = this.state.values;
        if (this.state.values.includes(button)) {
            this.setState({
                values: this.state.values.filter(el => el !== button)
            })
        } else {
            tmp.push(button);
            this.setState({
                values: tmp
            })
        }
    }

    render () {
        return (
            <div>
                {BUTTONS.map(bt=>(
                <button 
                    key={bt.id} 
                    onClick={()=>this.handleButton(bt.id)} 
                    className={this.state.values.includes(bt.id) ? "buttonPressed" : "button"}>
                    {bt.title}
                </button>
                ))}
            </div>
        );
    }
} 

export default Map;

Upvotes: 1

Views: 5933

Answers (3)

Harmelodic
Harmelodic

Reputation: 6159

The reason your button is getting deselected is because you're overwriting this.state.value every time you click a button.

If you want multiple selections, you'll need to hold all of the selected items in the state, as an array, and then when rendering, check if the button id is included in that array.

Something like:

import React, { Component } from 'react';


const BUTTONS = [
    {id:0, title:'button1'},
    {id:1, title:'button2'},
    {id:2, title:'button3'}
]
class Map extends Component {
    constructor(props){
        super(props);
        this.state = {
            selectedValues: []
        }
    }

    handleButton = buttonId => {
        let newSelectedValues = this.state.selectedValues;
        newSelectedValues.push(buttonId);
        this.setState({
            selectedValues: newSelectedValues
        })
    }

    render () {
        return (
            <div>
                {BUTTONS.map(bt => (
                    <button 
                        key={bt.id} 
                        onClick={()=>this.handleButton(bt.id)} 
                        className={this.state.selectedValues.includes(bt.id) ? "buttonPressed" : "button"}>
                            {bt.title}
                    </button>
                ))}
            </div>
        );
    }
} 

export default Map;

Upvotes: 1

kyun
kyun

Reputation: 10294

  1. Selecting multiple buttons

    you'd better use the state as an array.

this.state = {
  values: []
}

and you can push items.

let tmp = this.state.values;
tmp.push(button);
this.setState({
  values: tmp
});

in render() you have to check state.values has bt.id

className={this.state.values.includes(bt.id) ? "buttonPressed" : "button"
  1. Toggling multiple buttons

    you can check in handleButton() whether that selected button is already selected

handleButton = button => {
  if (this.state.values.includes(button)) {
    this.setState({
      values: this.state.values.filter(el => el !== button)
    })
  }

const BUTTONS = [
    { id: 0, title: 'button1' },
    { id: 1, title: 'button2' },
    { id: 2, title: 'button3' }
]
class Map extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            values: []
        }
    }

    handleButton = button => {
        let tmp = this.state.values;
        if (this.state.values.includes(button)) {
            this.setState({
                values: this.state.values.filter(el => el !== button)
            })
        } else {
            tmp.push(button);
            this.setState({
                values: tmp
            })
        }
    }

    render() {
        return (
            <div>
                {BUTTONS.map(bt => (
                    <button
                        key={bt.id}
                        onClick={() => this.handleButton(bt.id)}
                        className={this.state.values.includes(bt.id) ? "buttonPressed" : "button"}>
                        {bt.title}
                    </button>
                ))}
            </div>
        );
    }
}

export default Map;

Upvotes: 1

Reza SENTAX
Reza SENTAX

Reputation: 53

if you need multiple selections you need an array:

this.state = {
   values:[]
}

and push it on each clicks Correct way to push into state array

Upvotes: 0

Related Questions