lletgo
lletgo

Reputation: 67

How to collapse other expanded rows in react-table

I am using React Table in my project, I don't know how to close other expanded rows when user clicks one expanded, i.e. when first, second, and third rows are all expanded, I want to close all of the three when user click the fourth row.

Can someone tell me how?

Upvotes: 7

Views: 21153

Answers (6)

// this line will go into constructor (keep every accordion closed initially)
this.state = {
  expanded: {}
}

// this line will go into react table (will keep only one accordian open at any time)
expanded={this.state.expanded}
onExpandedChange={expandedList => {
    const expanded = {}
    Object.keys(expandedList).forEach(item => {
        const expand = Boolean(expandedList[item] && expandedList[item].constructor === Object)
        expanded[item] = expand
    })
    this.setState({ expanded })
}}

Upvotes: 0

Tony Huynh
Tony Huynh

Reputation: 39

onExpandedChange = (expanded, index, event) => {
    this.setState({ expanded: { [index]: expanded[index] !== false } })
}

Upvotes: -3

Estefano Timoteo
Estefano Timoteo

Reputation: 31

I've found help from Nathan Zylbersztejn at spectrum.chat/thread/ea9b94dc-6291-4a61-99f7-69af4094e90c :

<ReactTable
    ...
    expanded={this.state.expanded}
    onExpandedChange={(newExpanded, index, event) => {
        if (newExpanded[index[0]] === false) {
            newExpanded = {}
        } else {
            Object.keys(newExpanded).map(k => {
                newExpanded[k] = parseInt(k) === index[0] ? {} : false
            })
        }
        this.setState({
            ...this.state,
            expanded: newExpanded
        })
    }}
/>

I hope it helps somebody.

Upvotes: 3

Guilherme Vasconcelos
Guilherme Vasconcelos

Reputation: 319

The way Arnaud Enesvat suggests works for expansion but not to collapse an expanded row back.

I'd suggest his implementation with a change:

handleRowExpanded(rowsState, index) {
  this.setState({
    expanded: {
      [index[0]]: !this.state.expanded[index[0]],
    },
  });
}

Upvotes: 9

Arnaud Enesvat
Arnaud Enesvat

Reputation: 351

For anyone looking for more info about that :

//in component constructor, add state declaration :

this.state = {
    expanded: {}
}

//in component render function - set "expanded" to component state:

expanded={this.state.expanded}

// still in component render() - set an event callback - I prefer to use a dedicated event manager here named handleRowExpanded :

onExpandedChange={(newExpanded, index, event) => this.handleRowExpanded(newExpanded, index, event)}

// then declare an event manager :

   handleRowExpanded(newExpanded, index, event) {
        this.setState({
        // we override newExpanded, keeping only current selected row expanded
            expanded: {[index]: true}
        });
    }

HTH :)

Upvotes: 18

lletgo
lletgo

Reputation: 67

Ok, I figured it out by myself in the end. By dynamically change the "expanded" props of the react-table, I was able to control show only one expanded row each time.

Upvotes: -2

Related Questions