From 448c155e655e03f76ac237828dac79f5e8f956e8 Mon Sep 17 00:00:00 2001 From: Andrzej Skrodzki Date: Fri, 9 Aug 2019 22:50:36 +0200 Subject: [PATCH 1/3] Introduce `maxSelectedRows` --- README.md | 1 + examples/selectable-rows/index.js | 1 + src/MUIDataTable.js | 2 ++ src/components/TableBody.js | 11 +++++++---- webpack.config.js | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fc29dcecd..cc90d0221 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,7 @@ The component accepts the following props: |**`selectableRows`**|string|'multiple'|Numbers of rows that can be selected. Options are "multiple", "single", "none". |**`selectableRowsOnClick`**|boolean|false|Enable/disable select toggle when row is clicked. When False, only checkbox will trigger this action. |**`isRowSelectable`**|function||Enable/disable selection on certain rows with custom function. Returns true if not provided. `function(dataIndex) => bool` +|**`maxSelectedRows`**|number|Infinity|Maximum number of rows to select. |**`expandableRows`**|boolean|false|Enable/disable expandable rows |**`expandableRowsOnClick`**|boolean|false|Enable/disable expand trigger when row is clicked. When False, only expand icon will trigger this action. |**`renderExpandableRow`**|function||Render expandable row. `function(rowData, rowMeta) => React Component` diff --git a/examples/selectable-rows/index.js b/examples/selectable-rows/index.js index 43235494a..05edb0ec9 100644 --- a/examples/selectable-rows/index.js +++ b/examples/selectable-rows/index.js @@ -56,6 +56,7 @@ class Example extends React.Component { selectableRowsOnClick: true, filterType: 'dropdown', responsive: 'stacked', + maxSelectedRows: 5, rowsPerPage: 10, rowsSelected: this.state.rowsSelected, onRowsSelect: (rowsSelected, allRows) => { diff --git a/src/MUIDataTable.js b/src/MUIDataTable.js index 8f4bb43ce..b5cc2aea2 100644 --- a/src/MUIDataTable.js +++ b/src/MUIDataTable.js @@ -132,6 +132,7 @@ class MUIDataTable extends React.Component { resizableColumns: PropTypes.bool, selectableRows: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['none', 'single', 'multiple'])]), selectableRowsOnClick: PropTypes.bool, + maxSelectedRows: PropTypes.number, isRowSelectable: PropTypes.func, serverSide: PropTypes.bool, onTableChange: PropTypes.func, @@ -263,6 +264,7 @@ class MUIDataTable extends React.Component { resizableColumns: false, selectableRows: 'multiple', selectableRowsOnClick: false, + maxSelectedRows: Infinity, caseSensitive: false, serverSide: false, rowHover: true, diff --git a/src/components/TableBody.js b/src/components/TableBody.js index 8207b4f50..551bd45f7 100644 --- a/src/components/TableBody.js +++ b/src/components/TableBody.js @@ -87,11 +87,14 @@ class TableBody extends React.Component { } isRowSelectable(dataIndex) { - const { options } = this.props; - if (options.isRowSelectable) { - return options.isRowSelectable(dataIndex); + const { options, selectedRows } = this.props; + const lookup = (selectedRows && selectedRows.lookup) || {}; + if (lookup[dataIndex]) { + return (!options.isRowSelectable || options.isRowSelectable(dataIndex)); + } else { + const numSelected = (selectedRows && selectedRows.data.length) || 0; + return options.maxSelectedRows > numSelected && (!options.isRowSelectable || options.isRowSelectable(dataIndex)); } - return true; } handleRowSelect = data => { diff --git a/webpack.config.js b/webpack.config.js index b98ca648c..f3cd389cb 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -3,7 +3,7 @@ const webpack = require('webpack'); module.exports = { entry: { - app: "./examples/customize-filter/index.js" + app: "./examples/selectable-rows/index.js" }, stats: "verbose", context: __dirname, From e44fa14ad2ab479bb827c37953b6a1a2b6d2bfb5 Mon Sep 17 00:00:00 2001 From: Andrzej Skrodzki Date: Fri, 9 Aug 2019 22:58:14 +0200 Subject: [PATCH 2/3] Fix existing tests. --- src/components/TableBody.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/TableBody.js b/src/components/TableBody.js index 551bd45f7..44043b0fd 100644 --- a/src/components/TableBody.js +++ b/src/components/TableBody.js @@ -92,8 +92,8 @@ class TableBody extends React.Component { if (lookup[dataIndex]) { return (!options.isRowSelectable || options.isRowSelectable(dataIndex)); } else { - const numSelected = (selectedRows && selectedRows.data.length) || 0; - return options.maxSelectedRows > numSelected && (!options.isRowSelectable || options.isRowSelectable(dataIndex)); + const numSelected = (selectedRows && selectedRows.data && selectedRows.data.length) || 0; + return (options.maxSelectedRows || Infinity) > numSelected && (!options.isRowSelectable || options.isRowSelectable(dataIndex)); } } From f2681f8c7b94c950a0bf437891a9570f31b420a2 Mon Sep 17 00:00:00 2001 From: Andrzej Skrodzki Date: Sat, 10 Aug 2019 13:31:27 +0200 Subject: [PATCH 3/3] Add test. --- test/MUIDataTableBody.test.js | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/MUIDataTableBody.test.js b/test/MUIDataTableBody.test.js index 1fb866e62..d992db6a0 100644 --- a/test/MUIDataTableBody.test.js +++ b/test/MUIDataTableBody.test.js @@ -493,4 +493,32 @@ describe('', function() { expect(html).to.contain('Test_Text'); }); + + it('should not call onRowClick when maxSelectedRows rows is reached', () => { + const options = { selectableRows: true, maxSelectedRows: 1 }; + const selectedIndex = 0; + const selectedRows = { data: [selectedIndex], lookup: {[selectedIndex]: true }}; + + const mountWrapper = mount( + , + ); + + const tableSelectCellsProps = mountWrapper.find('TableSelectCell').map(t => t.props()); + + tableSelectCellsProps.forEach((props, i) => { + assert.equal(props.checked, i === selectedIndex); + assert.equal(props.isRowSelectable, i === selectedIndex); + }); + }); });