javascript - 逐列展开 : Expand row by multiple columns and load different components according to the column clicked

标签 javascript reactjs bootstrap-4 react-bootstrap react-bootstrap-table

我按照下面的例子来实现“逐列展开”。

/* 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>
    );
  }
}

问题: 我想在“多列”上实现扩展行。例如:

我会用 3 列中的 2 列来扩展行。

产品编号 产品名称 产品价格

我想要的行为是:

1.) 当用户点击“product id”列时,我想显示一些其他 BSTTableNew 组件,如上面(在展开行)但具有“字段 A”和“字段 B”列以及一些其他功能。

2.) 当用户点击“产品名称”列时,我想显示与上面类似的 BSTTable(在展开行上)。

我必须在下面的代码中进行哪些更改才能根据我单击以展开包含更多详细信息的行的列加载相应的组件类?

我相信我必须对下面的代码进行一些更改才能加载其他组件:

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 } />
  );
}
}

如何实现以上?

最佳答案

react-bootstrap-table 已弃用,您应该使用 react-bootstrap-table2


如果我正确理解了要求,您想要展开行,但展开的内容应该不同,具体取决于单击的列/单元格。

第 1 - 扩展行

服用 'Expand Management'示例作为基础,我们可以看到如何使用状态中的数组来控制展开的行。这很简单,但我们不能使用 onExpand 处理程序,因为它不依赖于列。我们可以使用 expanded 选项:

expanded: this.state.expanded,

这个数组只包含展开的行索引。

第二 - 点击了什么列?

例子包含'Column Event' - onClick 获取我们需要的column 参数。此事件必须在 columns 中定义,例如像:

const columns = [{
  dataField: 'id',
  text: 'Product ID',
  events: {
    onClick: (e, column, columnIndex, row, rowIndex) => {
      console.log(row, column);
      const isRowExpanded = this.state.expanded.includes( row );
      this.setState( {
        column: 'id',
        expanded: isRowExpanded ? 
          this.state.expanded.filter(x => x !== row)
          : [...this.state.expanded, row]
      });
    }
  }
}, {
  dataField: 'name',
  text: 'Product Name',
  events: {
    onClick: (e, column, columnIndex, row,     rowIndex) => {
      console.log(row, column);
      const isRowExpanded =     this.state.expanded.includes( row );
      this.setState( {
        column: 'name',
        expanded: isRowExpanded ? 
          this.state.expanded.filter(x => x !== row)
          : [...this.state.expanded, row]
      });
    }
  }
}, {
  dataField: 'price',
  text: 'Product Price'
}];

这样我们就可以同时处理 - 展开的行和最后点击的列。

第三 - 显示适当的组件

我们只需要扩展渲染器参数化:

const expandRow = {
  renderer: row => {
    if (this.state.column==='id') {
      return (
        <ColumnIDClickedTable someParam={someData[row]} />
      )
    } else {
      return <ColumnNameClickedTable />
    }
  },

应该就这些了。 只为前 3 行可扩展添加条件是一项简单的任务。 所有展开的行都将更改列更改的内容 - 仅最后一次点击保存。如果您需要单独的行行为,请将列保存在索引数组中。

关于javascript - 逐列展开 : Expand row by multiple columns and load different components according to the column clicked,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55875136/

相关文章:

reactjs - 如何验证 ReactJS 中嵌套对象的 PropTypes?

javascript - 谷歌地图 - 单击 map 时关闭信息窗口

javascript - PHP 后端与 JS xHTMLRequest 前端

javascript - 如何使 Cytoscape.js Canvas 尊重其父级的位置

html - 无法对齐移动设备的品牌标识、图标和汉堡菜单按钮

javascript - bootstrap-validate:如何在 bootstrap4 中启用验证?

javascript - 在输入焦点上打开引导下拉菜单

javascript - onclick时扩展css的高度并使用jQUERY关闭

javascript - 在悬停动态时显示/隐藏 div

javascript - html 元素呈现为变量名称