diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js index e9ee145..6967b8e 100644 --- a/packages/react-bootstrap-table2/src/bootstrap-table.js +++ b/packages/react-bootstrap-table2/src/bootstrap-table.js @@ -42,7 +42,6 @@ class BootstrapTable extends PropsBaseResolver(Component) { renderTable() { const { - store, columns, keyField, id, @@ -74,8 +73,8 @@ class BootstrapTable extends PropsBaseResolver(Component) { const headerCellSelectionInfo = this.resolveSelectRowPropsForHeader({ onAllRowsSelect: this.props.onAllRowsSelect, - selected: store.selected, - allRowsSelected: isSelectedAll(store) + selected: this.props.selected, + allRowsSelected: isSelectedAll(this.state.data, this.props.selected) }); const tableCaption = (caption && { caption }); @@ -87,8 +86,8 @@ class BootstrapTable extends PropsBaseResolver(Component) {
{ + const SelectionContext = React.createContext(); + + class SelectionProvider extends React.Component { + static propTypes = { + children: PropTypes.node.isRequired, + data: PropTypes.array.isRequired, + keyField: PropTypes.string.isRequired + } + + state = { selected: (this.props.selectRow && this.props.selectRow.selected) || [] }; + + componentWillReceiveProps(nextProps) { + if (nextProps.selectRow) { + this.setState(() => ({ + selected: nextProps.selectRow.selected || this.state.selected + })); + } + } + + handleRowSelect = (rowKey, checked, rowIndex, e) => { + const { data, keyField, selectRow: { mode, onSelect } } = this.props; + const { ROW_SELECT_SINGLE } = Const; + + let currSelected = [...this.state.selected]; + + if (mode === ROW_SELECT_SINGLE) { // when select mode is radio + currSelected = [rowKey]; + } else if (checked) { // when select mode is checkbox + currSelected.push(rowKey); + } else { + currSelected = currSelected.filter(value => value !== rowKey); + } + + if (onSelect) { + const row = getRowByRowId(data, keyField, rowKey); + onSelect(row, checked, rowIndex, e); + } + + this.setState(() => ({ selected: currSelected })); + } + + handleAllRowsSelect = (e) => { + const { + data, + keyField, + selectRow: { + onSelectAll, + nonSelectable + } + } = this.props; + const { selected } = this.state; + const anySelected = selectionHandler.isAnySelectedRow(selected, nonSelectable); + + const result = !anySelected; + + const currSelected = result ? + selectionHandler.selectableKeys(data, keyField, nonSelectable) : + selectionHandler.unSelectableKeys(selected, nonSelectable); + + if (onSelectAll) { + onSelectAll(result, selectionHandler.getSelectedRows(data, keyField, currSelected), e); + } + + this.setState(() => ({ selected: currSelected })); + } + + render() { + return ( + + { this.props.children } + + ); + } + } + return { + Provider: SelectionProvider, + Consumer: SelectionContext.Consumer + }; +}; diff --git a/packages/react-bootstrap-table2/src/row-selection/wrapper.js b/packages/react-bootstrap-table2/src/row-selection/wrapper.js deleted file mode 100644 index 51472dc..0000000 --- a/packages/react-bootstrap-table2/src/row-selection/wrapper.js +++ /dev/null @@ -1,107 +0,0 @@ -/* eslint no-param-reassign: 0 */ -import React, { Component } from 'react'; -import PropTypes from 'prop-types'; - -import Const from '../const'; -import { - isAnySelectedRow, - selectableKeys, - unSelectableKeys, - getSelectedRows -} from '../store/selection'; -import { getRowByRowId } from '../store/rows'; - -export default Base => - class RowSelectionWrapper extends Component { - static propTypes = { - store: PropTypes.object.isRequired, - selectRow: PropTypes.object.isRequired - } - - constructor(props) { - super(props); - this.handleRowSelect = this.handleRowSelect.bind(this); - this.handleAllRowsSelect = this.handleAllRowsSelect.bind(this); - - props.store.selected = props.selectRow.selected || []; - this.state = { - selectedRowKeys: props.store.selected - }; - } - - componentWillReceiveProps(nextProps) { - nextProps.store.selected = nextProps.selectRow.selected || []; - this.setState(() => ({ - selectedRowKeys: nextProps.store.selected - })); - } - - /** - * row selection handler - * @param {String} rowKey - row key of what was selected. - * @param {Boolean} checked - next checked status of input button. - */ - handleRowSelect(rowKey, checked, rowIndex, e) { - const { selectRow: { mode, onSelect }, store } = this.props; - const { ROW_SELECT_SINGLE } = Const; - - let currSelected = [...store.selected]; - - if (mode === ROW_SELECT_SINGLE) { // when select mode is radio - currSelected = [rowKey]; - } else if (checked) { // when select mode is checkbox - currSelected.push(rowKey); - } else { - currSelected = currSelected.filter(value => value !== rowKey); - } - - store.selected = currSelected; - - if (onSelect) { - const row = getRowByRowId(store)(rowKey); - onSelect(row, checked, rowIndex, e); - } - - this.setState(() => ({ - selectedRowKeys: currSelected - })); - } - - /** - * handle all rows selection on header cell by store.selected - */ - handleAllRowsSelect(e) { - const { store, selectRow: { - onSelectAll, - nonSelectable - } } = this.props; - const selected = isAnySelectedRow(store)(nonSelectable); - - const result = !selected; - - const currSelected = result ? - selectableKeys(store)(nonSelectable) : - unSelectableKeys(store)(nonSelectable); - - - store.selected = currSelected; - - if (onSelectAll) { - onSelectAll(result, getSelectedRows(store), e); - } - - this.setState(() => ({ - selectedRowKeys: currSelected - })); - } - - render() { - return ( - - ); - } - }; diff --git a/packages/react-bootstrap-table2/src/store/rows.js b/packages/react-bootstrap-table2/src/store/rows.js index 4115122..c57de06 100644 --- a/packages/react-bootstrap-table2/src/store/rows.js +++ b/packages/react-bootstrap-table2/src/store/rows.js @@ -1,4 +1,4 @@ export const matchRow = (keyField, id) => row => row[keyField] === id; -export const getRowByRowId = ({ data, keyField }) => id => data.find(matchRow(keyField, id)); +export const getRowByRowId = (data, keyField, id) => data.find(matchRow(keyField, id)); diff --git a/packages/react-bootstrap-table2/src/store/selection.js b/packages/react-bootstrap-table2/src/store/selection.js index 4c6c10a..246c5f5 100644 --- a/packages/react-bootstrap-table2/src/store/selection.js +++ b/packages/react-bootstrap-table2/src/store/selection.js @@ -1,16 +1,16 @@ import _ from '../utils'; import { getRowByRowId } from './rows'; -export const isSelectedAll = ({ data, selected }) => data.length === selected.length; +export const isSelectedAll = (data, selected) => data.length === selected.length; -export const isAnySelectedRow = ({ selected }) => (skips = []) => { +export const isAnySelectedRow = (selected, skips = []) => { if (skips.length === 0) { return selected.length > 0; } return selected.filter(x => !skips.includes(x)).length; }; -export const selectableKeys = ({ data, keyField }) => (skips = []) => { +export const selectableKeys = (data, keyField, skips = []) => { if (skips.length === 0) { return data.map(row => _.get(row, keyField)); } @@ -19,15 +19,13 @@ export const selectableKeys = ({ data, keyField }) => (skips = []) => { .map(row => _.get(row, keyField)); }; -export const unSelectableKeys = ({ selected }) => (skips = []) => { +export const unSelectableKeys = (selected, skips = []) => { if (skips.length === 0) { return []; } return selected.filter(x => skips.includes(x)); }; -export const getSelectedRows = (store) => { - const getRow = getRowByRowId(store); - return store.selected.map(k => getRow(k)); -}; +export const getSelectedRows = (data, keyField, selected) => + selected.map(k => getRowByRowId(data, keyField, k));