diff --git a/docs/row-selection.md b/docs/row-selection.md index 9a09361..c8b97e3 100644 --- a/docs/row-selection.md +++ b/docs/row-selection.md @@ -211,18 +211,44 @@ const selectRow = { }; ``` +> If you want to reject current select action, just return `false`: + +```js +const selectRow = { + mode: 'checkbox', + onSelect: (row, isSelect, rowIndex, e) => { + if (SOME_CONDITION) { + return false; + } + } +}; +``` + ### selectRow.onSelectAll - [Function] This callback function will be called when select/unselect all and it only work when you configure [`selectRow.mode`](#mode) as `checkbox`. ```js const selectRow = { mode: 'checkbox', - onSelectAll: (isSelect, results, e) => { + onSelectAll: (isSelect, rows, e) => { // ... } }; ``` +> If you want to control the final selection result, just return a row key array: + +```js +const selectRow = { + mode: 'checkbox', + onSelectAll: (isSelect, rows, e) => { + if (isSelect && SOME_CONDITION) { + return [1, 3, 4]; // finally, key 1, 3, 4 will being selected + } + } +}; +``` + ### selectRow.hideSelectColumn - [Bool] Default is `false`, if you don't want to have a selection column, give this prop as `true` diff --git a/packages/react-bootstrap-table2-example/examples/row-selection/selection-advance-management.js b/packages/react-bootstrap-table2-example/examples/row-selection/selection-advance-management.js new file mode 100644 index 0000000..22af899 --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/row-selection/selection-advance-management.js @@ -0,0 +1,88 @@ +/* eslint no-alert: 0 */ +/* eslint consistent-return: 0 */ +import React from 'react'; + +import BootstrapTable from 'react-bootstrap-table-next'; +import Code from 'components/common/code-block'; +import { productsGenerator } from 'utils/common'; + +const products = productsGenerator(); + +const columns = [{ + dataField: 'id', + text: 'Product ID' +}, { + dataField: 'name', + text: 'Product Name' +}, { + dataField: 'price', + text: 'Product Price' +}]; + +const sourceCode = `\ +import BootstrapTable from 'react-bootstrap-table-next'; + +class AdvSelectionManagment extends React.Component { + handleOnSelect = (row, isSelect) => { + if (isSelect && row.id < 3) { + alert('Oops, You can not select Product ID which less than 3'); + return false; // return false to deny current select action + } + return true; // return true or dont return to approve current select action + } + + handleOnSelectAll = (isSelect, rows) => { + if (isSelect) { + return rows.filter(r => r.id >= 3).map(r => r.id); + } + } + + render() { + const selectRow = { + mode: 'checkbox', + clickToSelect: true, + onSelect: this.handleOnSelect, + onSelectAll: this.handleOnSelectAll + }; + return ( +
+

You can not select Product ID less than 3

+ + { sourceCode } +
+ ); + } +} +`; + +export default class AdvSelectionManagment extends React.Component { + handleOnSelect = (row, isSelect) => { + if (isSelect && row.id < 3) { + alert('Oops, You can not select Product ID which less than 3'); + return false; // return false to deny current select action + } + return true; // return true or dont return to approve current select action + } + + handleOnSelectAll = (isSelect, rows) => { + if (isSelect) { + return rows.filter(r => r.id >= 3).map(r => r.id); + } + } + + render() { + const selectRow = { + mode: 'checkbox', + clickToSelect: true, + onSelect: this.handleOnSelect, + onSelectAll: this.handleOnSelectAll + }; + return ( +
+

You can not select Product ID less than 3

+ + { sourceCode } +
+ ); + } +} diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js index 7ba6b1b..fd04751 100644 --- a/packages/react-bootstrap-table2-example/stories/index.js +++ b/packages/react-bootstrap-table2-example/stories/index.js @@ -118,6 +118,7 @@ import MultipleSelectionTable from 'examples/row-selection/multiple-selection'; import ClickToSelectTable from 'examples/row-selection/click-to-select'; import DefaultSelectTable from 'examples/row-selection/default-select'; import SelectionManagement from 'examples/row-selection/selection-management'; +import AdvanceSelectionManagement from 'examples/row-selection/selection-advance-management'; import ClickToSelectWithCellEditTable from 'examples/row-selection/click-to-select-with-cell-edit'; import SelectionWithExpansionTable from 'examples/row-selection/selection-with-expansion'; import SelectionNoDataTable from 'examples/row-selection/selection-no-data'; @@ -312,6 +313,7 @@ storiesOf('Row Selection', module) .add('Click to Select', () => ) .add('Default Select', () => ) .add('Selection Management', () => ) + .add('Advance Selection Management', () => ) .add('Click to Select and Edit Cell', () => ) .add('Row Select and Expand', () => ) .add('Selection without Data', () => ) diff --git a/packages/react-bootstrap-table2/src/contexts/selection-context.js b/packages/react-bootstrap-table2/src/contexts/selection-context.js index ce8d354..f266824 100644 --- a/packages/react-bootstrap-table2/src/contexts/selection-context.js +++ b/packages/react-bootstrap-table2/src/contexts/selection-context.js @@ -43,20 +43,23 @@ class SelectionProvider extends React.Component { 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 = dataOperator.getRowByRowId(data, keyField, rowKey); - onSelect(row, checked, rowIndex, e); - } - - this.setState(() => ({ selected: currSelected })); + this.setState(() => { + let result = true; + if (onSelect) { + const row = dataOperator.getRowByRowId(data, keyField, rowKey); + result = onSelect(row, checked, rowIndex, e); + } + if (result === true || result === undefined) { + 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); + } + } + return { selected: currSelected }; + }); } handleAllRowsSelect = (e, isUnSelect) => { @@ -78,19 +81,24 @@ class SelectionProvider extends React.Component { currSelected = selected.filter(s => typeof data.find(d => d[keyField] === s) === 'undefined'); } - if (onSelectAll) { - onSelectAll( - !isUnSelect, - dataOperator.getSelectedRows( - data, - keyField, - isUnSelect ? this.state.selected : currSelected - ), - e - ); - } - - this.setState(() => ({ selected: currSelected })); + this.setState(() => { + let result; + if (onSelectAll) { + result = onSelectAll( + !isUnSelect, + dataOperator.getSelectedRows( + data, + keyField, + isUnSelect ? this.state.selected : currSelected + ), + e + ); + if (Array.isArray(result)) { + currSelected = result; + } + } + return { selected: currSelected }; + }); } render() {