AllenFang / react-bootstrap-table

A Bootstrap table built with React.js
https://allenfang.github.io/react-bootstrap-table/
MIT License
2.24k stars 783 forks source link

Expand row by column : Expand row by multiple columns and load different components according to the column clicked #2075

Open nikitagupta55 opened 5 years ago

nikitagupta55 commented 5 years ago

I am following below example to implement "expand row by column".

/* eslint max-len: 0 */
import React from 'react';
import { BootstrapTable, TableHeaderColumn } from 'react-bootstrap-table';

const products = [];

function addProducts(quantity) {
  const startId = products.length;
  for (let i = 0; i < quantity; i++) {
    const id = startId + i;
    if (i < 3) {
      products.push({
        id: id,
        name: 'Item name ' + id,
        price: 2100 + i,
        expand: [ {
          fieldA: 'test1',
          fieldB: (i + 1) * 99,
          fieldC: (i + 1) * Math.random() * 100,
          fieldD: '123eedd' + i
        }, {
          fieldA: 'test2',
          fieldB: i * 99,
          fieldC: i * Math.random() * 100,
          fieldD: '123eedd' + i
        } ]
      });
    } else {
      products.push({
        id: id,
        name: 'Item name ' + id,
        price: 2100 + i
      });
    }
  }
}
addProducts(5);

class BSTable extends React.Component {
  render() {
    if (this.props.data) {
      return (
        <BootstrapTable data={ this.props.data }>
          <TableHeaderColumn dataField='fieldA' isKey={ true }>Field A</TableHeaderColumn>
          <TableHeaderColumn dataField='fieldB'>Field B</TableHeaderColumn>
          <TableHeaderColumn dataField='fieldC'>Field C</TableHeaderColumn>
          <TableHeaderColumn dataField='fieldD'>Field D</TableHeaderColumn>
        </BootstrapTable>);
    } else {
      return (<p>?</p>);
    }
  }
}

export default class ExpandRow extends React.Component {
  constructor(props) {
    super(props);
  }

  isExpandableRow(row) {
    if (row.id < 3) return true;
    else return false;
  }

  expandComponent(row) {
    return (
      <BSTable data={ row.expand } />
    );
  }

  render() {
    const options = {
      expandRowBgColor: 'rgb(242, 255, 163)',
      expandBy: 'column'  // Currently, available value is row and column, default is row
    };
    return (
      <BootstrapTable data={ products }
        options={ options }
        expandableRow={ this.isExpandableRow }
        expandComponent={ this.expandComponent }
        search>
        <TableHeaderColumn dataField='id' isKey={ true }>Product ID</TableHeaderColumn>
        <TableHeaderColumn dataField='name' expandable={ false }>Product Name</TableHeaderColumn>
        <TableHeaderColumn dataField='price' expandable={ false }>Product Price</TableHeaderColumn>
      </BootstrapTable>
    );
  }
}

Questions: Que 1.) I want to implement expand row on "multiple columns". For eg:

I would make 2 columns out of 3 to expand rows.

<TableHeaderColumn dataField='id' isKey={ true }>Product ID</TableHeaderColumn>
<TableHeaderColumn dataField='name' >Product Name</TableHeaderColumn>
<TableHeaderColumn dataField='price' expandable={ false }>Product Price</TableHeaderColumn>

Behavior I want is :

1.) When user clicks on "product id" column, I want to show some other BSTTableNew component like above (on expand row) but with columns "field A" & "field B" and some other functionality.

2.) When user clicks on "product name" column, I want to show BSTTable (on expand row) with similarly as above.

What changes I have to make in below code to load respective component class based upon the column I click to expand row with additional details?

I believe i have to make some changes in below code to load other components:

expandComponent(row) {

if( column === "productID") { //something of this sort I want
    return (
      <BSTableNew data={ row.expand } />
    );
}

if( column === "productName") {  //something of this sort I want
    return (
      <BSTable data={ row.expand } />
    );
}
  }

Que 2.) In BSTTable component class, i want to "dataFormat" "field A" column. I'm doing it like below:

class BSTable extends React.Component {

formatter(cell, row) {
  return cell.join("<br>");
}
  render() {
    if (this.props.data) {
      return (
        <BootstrapTable data={ this.props.data }>
          <TableHeaderColumn dataField='fieldA' isKey={ true } dataFormat={this.formatter}>Field A</TableHeaderColumn>
          <TableHeaderColumn dataField='fieldB'>Field B</TableHeaderColumn>
          <TableHeaderColumn dataField='fieldC'>Field C</TableHeaderColumn>
          <TableHeaderColumn dataField='fieldD'>Field D</TableHeaderColumn>
        </BootstrapTable>);
    } else {
      return (<p>?</p>);
    }
  }
}

But formatting is not getting applied here, I'm getting an error like "TypeError: cell.join is not a function. (In 'cell.join("
")', 'cell.join' is undefined)"

What is wrong here? Please help @AllenFang