Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable functionality to limit maximum number of rows to select #825

Merged
merged 10 commits into from
Aug 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ The component accepts the following props:
|**`pagination`**|boolean|true|Enable/disable pagination
|**`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`
|**`isRowSelectable`**|function||Enable/disable selection on certain rows with custom function. Returns true if not provided. `function(dataIndex: number, selectedRows: object(lookup: {dataindex: boolean}, data: arrayOfObjects: {index, dataIndex})) => bool`.
|**`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`
Expand Down
4 changes: 3 additions & 1 deletion examples/selectable-rows/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,9 @@ class Example extends React.Component {
onRowClick: (rowData, rowState) => {
console.log(rowData, rowState);
},
isRowSelectable: (dataIndex) => {
isRowSelectable: (dataIndex, selectedRows) => {
//prevents selection of any additional row after the third
if (selectedRows.data.length > 2 && selectedRows.data.filter(d => d.dataIndex === dataIndex).length === 0) return false;
//prevents selection of row with title "Attorney"
return data[dataIndex][1] != "Attorney";
}
Expand Down
4 changes: 2 additions & 2 deletions src/MUIDataTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -1022,15 +1022,15 @@ class MUIDataTable extends React.Component {
const { isRowSelectable } = this.options;
this.setState(
prevState => {
const { displayData } = prevState;
const { displayData, selectedRows: prevSelectedRows } = prevState;
const selectedRowsLen = prevState.selectedRows.data.length;
const isDeselect =
selectedRowsLen === displayData.length || (selectedRowsLen < displayData.length && selectedRowsLen > 0)
? true
: false;

let selectedRows = displayData.reduce((arr, d, i) => {
const selected = isRowSelectable ? isRowSelectable(displayData[i].dataIndex) : true;
const selected = isRowSelectable ? isRowSelectable(displayData[i].dataIndex, prevSelectedRows) : true;
selected && arr.push({ index: i, dataIndex: displayData[i].dataIndex });
return arr;
}, []);
Expand Down
7 changes: 4 additions & 3 deletions src/components/TableBody.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,12 @@ class TableBody extends React.Component {
}

isRowSelectable(dataIndex) {
const { options } = this.props;
const { options, selectedRows } = this.props;
if (options.isRowSelectable) {
return options.isRowSelectable(dataIndex);
return options.isRowSelectable(dataIndex, selectedRows);
} else {
return true;
}
return true;
}

handleRowSelect = data => {
Expand Down
115 changes: 113 additions & 2 deletions test/MUIDataTableBody.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,14 +235,14 @@ describe('<TableBody />', function() {
assert.strictEqual(toggleExpandRow.callCount, 0);
});

it('should not gather selected row data when clicking row with selectableRowsOnClick=true when it is disabled with isRowSelectable.', () => {
it('should not gather selected row data when clicking row with selectableRowsOnClick=true when it is disabled with isRowSelectable via index.', () => {
let selectedRowData;
const options = {
selectableRows: true,
selectableRowsOnClick: true,
isRowSelectable: dataIndex => (dataIndex === 2 ? false : true),
};
const selectRowUpdate = (type, data) => (selectedRowData = data);
const selectRowUpdate = (_, data) => (selectedRowData = data);
const toggleExpandRow = spy();

const mountWrapper = mount(
Expand Down Expand Up @@ -271,6 +271,86 @@ describe('<TableBody />', function() {
assert.strictEqual(toggleExpandRow.callCount, 0);
});

it('should not gather selected row data when clicking row with selectableRowsOnClick=true when it is disabled with isRowSelectable via selectedRows.', () => {
endrjuskr marked this conversation as resolved.
Show resolved Hide resolved
let selectedRowData;
const options = {
selectableRows: true,
selectableRowsOnClick: true,
isRowSelectable: (index, selectedRows) => selectedRows.lookup[index] || selectedRows.data.length < 1,
};
const selectRowUpdate = (_, data) => (selectedRowData = data);
const toggleExpandRow = spy();
const initialSelectedRows = {
data: [{ index: 1, dataIndex: 1 }],
lookup: { 1: true },
};

const mountWrapper = mount(
<TableBody
data={displayData}
count={displayData.length}
columns={columns}
page={0}
rowsPerPage={10}
selectedRows={initialSelectedRows}
selectRowUpdate={selectRowUpdate}
expandedRows={[]}
toggleExpandRow={toggleExpandRow}
options={options}
searchText={''}
filterList={[]}
/>,
);

mountWrapper
.find('#MUIDataTableBodyRow-2')
.first()
.simulate('click');

assert.isUndefined(selectedRowData);
assert.strictEqual(toggleExpandRow.callCount, 0);
});

it('should gather selected row data when clicking row with selectableRowsOnClick=true when it is enabled with isRowSelectable via index.', () => {
let selectedRowData;
const options = {
selectableRows: true,
selectableRowsOnClick: true,
isRowSelectable: (index, selectedRows) => selectedRows.lookup[index] || selectedRows.data.length < 1,
};
const selectRowUpdate = (_, data) => (selectedRowData = data);
const toggleExpandRow = spy();
const initialSelectedRows = {
data: [{ index: 1, dataIndex: 1 }],
lookup: { 1: true },
};

const mountWrapper = mount(
<TableBody
data={displayData}
count={displayData.length}
columns={columns}
page={0}
rowsPerPage={10}
selectedRows={initialSelectedRows}
selectRowUpdate={selectRowUpdate}
expandedRows={[]}
toggleExpandRow={toggleExpandRow}
options={options}
searchText={''}
filterList={[]}
/>,
);

mountWrapper
.find('#MUIDataTableBodyRow-1')
.first()
.simulate('click');

assert.isDefined(selectedRowData);
assert.strictEqual(toggleExpandRow.callCount, 0);
});

it('should gather expanded row data when clicking row with expandableRows=true and expandableRowsOnClick=true.', () => {
let expandedRowData;
const options = { selectableRows: true, expandableRows: true, expandableRowsOnClick: true };
Expand Down Expand Up @@ -493,4 +573,35 @@ describe('<TableBody />', function() {

expect(html).to.contain('Test_Text');
});

it('should pass in selectedRows to isRowSelectable', () => {
const selectedIndex = 2;
const originalSelectedRows = {
data: [{ index: selectedIndex, dataIndex: selectedIndex }],
lookup: { [selectedIndex]: true },
};
const isRowSelectable = spy((_, selectedRows) => {
assert.deepEqual(selectedRows, originalSelectedRows);
return true;
});

const options = { selectableRows: true, isRowSelectable };

mount(
<TableBody
data={displayData}
count={displayData.length}
columns={columns}
page={0}
selectedRows={originalSelectedRows}
rowsPerPage={10}
expandedRows={[]}
options={options}
searchText={''}
filterList={[]}
/>,
);

assert.equal(isRowSelectable.callCount, displayData.length);
});
});