mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-07-10 11:00:04 +00:00
implement expand indicator
This commit is contained in:
@@ -72,6 +72,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
|
||||
});
|
||||
|
||||
const tableCaption = (caption && <Caption>{ caption }</Caption>);
|
||||
const expandRow = this.resolveExpandRowProps();
|
||||
|
||||
return (
|
||||
<div className={ tableWrapperClass }>
|
||||
@@ -86,6 +87,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
|
||||
onFilter={ this.props.onFilter }
|
||||
onExternalFilter={ this.props.onExternalFilter }
|
||||
selectRow={ headerCellSelectionInfo }
|
||||
expandRow={ expandRow }
|
||||
/>
|
||||
<Body
|
||||
data={ data }
|
||||
@@ -97,7 +99,7 @@ class BootstrapTable extends PropsBaseResolver(Component) {
|
||||
cellEdit={ this.props.cellEdit || {} }
|
||||
selectRow={ cellSelectionInfo }
|
||||
selectedRowKeys={ selected }
|
||||
expandRow={ this.resolveExpandRowProps() }
|
||||
expandRow={ expandRow }
|
||||
rowStyle={ rowStyle }
|
||||
rowClasses={ rowClasses }
|
||||
rowEvents={ rowEvents }
|
||||
@@ -151,9 +153,12 @@ BootstrapTable.propTypes = {
|
||||
expanded: PropTypes.array,
|
||||
nonExpandable: PropTypes.array,
|
||||
showExpandColumn: PropTypes.bool,
|
||||
expandColumnRenderer: PropTypes.func
|
||||
expandColumnRenderer: PropTypes.func,
|
||||
expandHeaderColumnRenderer: PropTypes.func
|
||||
}),
|
||||
onRowExpand: PropTypes.func,
|
||||
onAllRowExpand: PropTypes.func,
|
||||
isAnyExpands: PropTypes.func,
|
||||
rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
||||
rowEvents: PropTypes.object,
|
||||
rowClasses: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
|
||||
|
||||
@@ -42,12 +42,41 @@ export default (
|
||||
this.setState(() => ({ expanded: currExpanded }));
|
||||
}
|
||||
|
||||
handleAllRowExpand = (e, expandAll) => {
|
||||
const {
|
||||
data,
|
||||
keyField,
|
||||
expandRow: {
|
||||
onExpandAll,
|
||||
nonExpandable
|
||||
}
|
||||
} = this.props;
|
||||
const { expanded } = this.state;
|
||||
|
||||
let currExpanded;
|
||||
|
||||
if (expandAll) {
|
||||
currExpanded = expanded.concat(dataOperator.expandableKeys(data, keyField, nonExpandable));
|
||||
} else {
|
||||
currExpanded = expanded.filter(s => typeof data.find(d => d[keyField] === s) === 'undefined');
|
||||
}
|
||||
|
||||
if (onExpandAll) {
|
||||
onExpandAll(expandAll, dataOperator.getExpandedRows(data, keyField, currExpanded), e);
|
||||
}
|
||||
|
||||
this.setState(() => ({ expanded: currExpanded }));
|
||||
}
|
||||
|
||||
render() {
|
||||
const { data, keyField } = this.props;
|
||||
return (
|
||||
<RowExpandContext.Provider
|
||||
value={ {
|
||||
isAnyExpands: dataOperator.isAnyExpands(data, keyField, this.state.expanded),
|
||||
expanded: this.state.expanded,
|
||||
onRowExpand: this.handleRowExpand
|
||||
onRowExpand: this.handleRowExpand,
|
||||
onAllRowExpand: this.handleAllRowExpand
|
||||
} }
|
||||
>
|
||||
{ this.props.children }
|
||||
|
||||
15
packages/react-bootstrap-table2/src/header.js
vendored
15
packages/react-bootstrap-table2/src/header.js
vendored
@@ -5,6 +5,7 @@ import Const from './const';
|
||||
|
||||
import HeaderCell from './header-cell';
|
||||
import SelectionHeaderCell from './row-selection/selection-header-cell';
|
||||
import ExpandHeaderCell from './row-expand/expand-header-cell';
|
||||
|
||||
const Header = (props) => {
|
||||
const { ROW_SELECT_DISABLED } = Const;
|
||||
@@ -17,12 +18,21 @@ const Header = (props) => {
|
||||
sortField,
|
||||
sortOrder,
|
||||
selectRow,
|
||||
onExternalFilter
|
||||
onExternalFilter,
|
||||
expandRow
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<thead>
|
||||
<tr className={ className }>
|
||||
{
|
||||
(expandRow && expandRow.showExpandColumn)
|
||||
? <ExpandHeaderCell
|
||||
onAllRowExpand={ expandRow.onAllRowExpand }
|
||||
anyExpands={ expandRow.isAnyExpands }
|
||||
renderer={ expandRow.expandHeaderColumnRenderer }
|
||||
/> : null
|
||||
}
|
||||
{
|
||||
(selectRow.mode !== ROW_SELECT_DISABLED && !selectRow.hideSelectColumn)
|
||||
? <SelectionHeaderCell { ...selectRow } /> : null
|
||||
@@ -62,7 +72,8 @@ Header.propTypes = {
|
||||
sortOrder: PropTypes.string,
|
||||
selectRow: PropTypes.object,
|
||||
onExternalFilter: PropTypes.func,
|
||||
className: PropTypes.string
|
||||
className: PropTypes.string,
|
||||
expandRow: PropTypes.object
|
||||
};
|
||||
|
||||
export default Header;
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
export default ExtendBase =>
|
||||
class ExpandRowResolver extends ExtendBase {
|
||||
resolveExpandRowProps() {
|
||||
const { expandRow, expanded, onRowExpand } = this.props;
|
||||
const { expandRow, expanded, onRowExpand, onAllRowExpand, isAnyExpands } = this.props;
|
||||
if (expandRow) {
|
||||
return {
|
||||
...expandRow,
|
||||
expanded,
|
||||
onRowExpand,
|
||||
onAllRowExpand,
|
||||
isAnyExpands,
|
||||
nonExpandable: expandRow.nonExpandable || []
|
||||
};
|
||||
}
|
||||
|
||||
42
packages/react-bootstrap-table2/src/row-expand/expand-cell.js
vendored
Normal file
42
packages/react-bootstrap-table2/src/row-expand/expand-cell.js
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
/* eslint
|
||||
react/require-default-props: 0
|
||||
jsx-a11y/no-noninteractive-element-interactions: 0
|
||||
*/
|
||||
/* eslint no-nested-ternary: 0 */
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default class ExpandCell extends Component {
|
||||
static propTypes = {
|
||||
rowKey: PropTypes.any,
|
||||
expanded: PropTypes.bool.isRequired,
|
||||
onRowExpand: PropTypes.func.isRequired,
|
||||
expandColumnRenderer: PropTypes.func,
|
||||
rowIndex: PropTypes.number
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.handleClick = this.handleClick.bind(this);
|
||||
}
|
||||
|
||||
handleClick(e) {
|
||||
const { rowKey, expanded, onRowExpand, rowIndex } = this.props;
|
||||
|
||||
onRowExpand(rowKey, expanded, rowIndex, e);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { expanded, expandColumnRenderer } = this.props;
|
||||
|
||||
return (
|
||||
<td onClick={ this.handleClick }>
|
||||
{
|
||||
expandColumnRenderer ? expandColumnRenderer({
|
||||
expanded
|
||||
}) : (expanded ? '(-)' : '(+)')
|
||||
}
|
||||
</td>
|
||||
);
|
||||
}
|
||||
}
|
||||
40
packages/react-bootstrap-table2/src/row-expand/expand-header-cell.js
vendored
Normal file
40
packages/react-bootstrap-table2/src/row-expand/expand-header-cell.js
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
/* eslint react/require-default-props: 0 */
|
||||
/* eslint no-nested-ternary: 0 */
|
||||
import React, { Component } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
|
||||
export default class SelectionHeaderCell extends Component {
|
||||
static propTypes = {
|
||||
anyExpands: PropTypes.bool.isRequired,
|
||||
onAllRowExpand: PropTypes.func.isRequired,
|
||||
renderer: PropTypes.func
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.handleCheckBoxClick = this.handleCheckBoxClick.bind(this);
|
||||
}
|
||||
|
||||
handleCheckBoxClick(e) {
|
||||
const { anyExpands, onAllRowExpand } = this.props;
|
||||
|
||||
onAllRowExpand(e, !anyExpands);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { anyExpands, renderer } = this.props;
|
||||
const attrs = {
|
||||
onClick: this.handleCheckBoxClick
|
||||
};
|
||||
|
||||
return (
|
||||
<th data-row-selection { ...attrs }>
|
||||
{
|
||||
renderer ?
|
||||
renderer({ isAnyExpands: anyExpands }) :
|
||||
(anyExpands ? '(-)' : '(+)')
|
||||
}
|
||||
</th>
|
||||
);
|
||||
}
|
||||
}
|
||||
14
packages/react-bootstrap-table2/src/row.js
vendored
14
packages/react-bootstrap-table2/src/row.js
vendored
@@ -6,6 +6,7 @@ import PropTypes from 'prop-types';
|
||||
import _ from './utils';
|
||||
import Cell from './cell';
|
||||
import SelectionCell from './row-selection/selection-cell';
|
||||
import ExpandCell from './row-expand/expand-cell';
|
||||
import eventDelegater from './row-event-delegater';
|
||||
import Const from './const';
|
||||
|
||||
@@ -22,6 +23,8 @@ class Row extends eventDelegater(Component) {
|
||||
cellEdit,
|
||||
selected,
|
||||
selectRow,
|
||||
expanded,
|
||||
expandRow,
|
||||
selectable,
|
||||
editable: editableRow
|
||||
} = this.props;
|
||||
@@ -39,10 +42,21 @@ class Row extends eventDelegater(Component) {
|
||||
|
||||
const key = _.get(row, keyField);
|
||||
const { hideSelectColumn } = selectRow;
|
||||
const { showExpandColumn } = expandRow || {};
|
||||
const trAttrs = this.delegate(attrs);
|
||||
|
||||
return (
|
||||
<tr style={ style } className={ className } { ...trAttrs }>
|
||||
{
|
||||
showExpandColumn ? (
|
||||
<ExpandCell
|
||||
{ ...expandRow }
|
||||
rowKey={ key }
|
||||
rowIndex={ rowIndex }
|
||||
expanded={ expanded }
|
||||
/>
|
||||
) : null
|
||||
}
|
||||
{
|
||||
(selectRow.mode !== Const.ROW_SELECT_DISABLED && !hideSelectColumn)
|
||||
? (
|
||||
|
||||
28
packages/react-bootstrap-table2/src/store/expand.js
vendored
Normal file
28
packages/react-bootstrap-table2/src/store/expand.js
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
import _ from '../utils';
|
||||
import { getRowByRowId } from './rows';
|
||||
|
||||
export const isAnyExpands = (
|
||||
data,
|
||||
keyField,
|
||||
expanded = []
|
||||
) => {
|
||||
for (let i = 0; i < data.length; i += 1) {
|
||||
const rowKey = _.get(data[i], keyField);
|
||||
if (typeof expanded.find(x => x === rowKey) !== 'undefined') {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const expandableKeys = (data, keyField, skips = []) => {
|
||||
if (skips.length === 0) {
|
||||
return data.map(row => _.get(row, keyField));
|
||||
}
|
||||
return data
|
||||
.filter(row => !skips.includes(_.get(row, keyField)))
|
||||
.map(row => _.get(row, keyField));
|
||||
};
|
||||
|
||||
export const getExpandedRows = (data, keyField, expanded) =>
|
||||
expanded.map(k => getRowByRowId(data, keyField, k));
|
||||
@@ -1,11 +1,13 @@
|
||||
import * as rows from './rows';
|
||||
import * as selection from './selection';
|
||||
import * as expand from './expand';
|
||||
import * as mutate from './mutate';
|
||||
import * as sort from './sort';
|
||||
|
||||
export default {
|
||||
...rows,
|
||||
...selection,
|
||||
...expand,
|
||||
...mutate,
|
||||
...sort
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user