Skip to content

Re-implement row selection #1762

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

Merged
merged 35 commits into from
Oct 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
502ee11
Re-implement row selection
amanmahajan7 Oct 2, 2019
97c78fa
Re-enable jsx-curly-brace-presence
nstepien Oct 2, 2019
f5f9e86
onSelectedRowsChanged -> onSelectedRowsChange
nstepien Oct 2, 2019
c7bf8fe
Small cleanup in Canvas.tsx
nstepien Oct 2, 2019
f50d526
small tweaks
nstepien Oct 2, 2019
70c9718
Delete RowUtils tests
nstepien Oct 2, 2019
7aad306
Fix Canvas tests
nstepien Oct 2, 2019
a15cab4
Get shift selection almost working
nstepien Oct 2, 2019
f5da8d4
Simplify a few exports
nstepien Oct 2, 2019
2afa28f
Focus CellMask when clicking on a cell
nstepien Oct 2, 2019
e238aac
Working shift selection
nstepien Oct 2, 2019
90034bb
use a ref for lastSelectedRowIdx
nstepien Oct 2, 2019
a41b1c8
Add class methods to avoid recomputation
amanmahajan7 Oct 2, 2019
18d3334
Do it the react way
nstepien Oct 3, 2019
68bd0d8
Simplify 1 type
nstepien Oct 3, 2019
a6bac01
Fix selection
nstepien Oct 3, 2019
5e00be3
Merge remote-tracking branch 'origin/am-improve-props' into am-ns-sel…
nstepien Oct 3, 2019
e62c354
tweaks
nstepien Oct 3, 2019
1242b30
Remove references to `enableRowSelect`
nstepien Oct 3, 2019
b303f93
More cleanup
nstepien Oct 3, 2019
3df4710
fix some tests
nstepien Oct 3, 2019
edb4fa7
fix tests
nstepien Oct 3, 2019
9438985
Remove @testing-library/react/cleanup-after-each
nstepien Oct 3, 2019
c79be1f
Fix some examples
nstepien Oct 3, 2019
604cb90
Fix another example
nstepien Oct 3, 2019
2a0d7fd
optimize all-features example
nstepien Oct 3, 2019
785f0d7
Cleanup viewport events
amanmahajan7 Oct 3, 2019
9f6762d
Cleanup props, remove PureComponent
amanmahajan7 Oct 3, 2019
ba576e8
Fix draggable header example
amanmahajan7 Oct 3, 2019
b92761a
Commit reordering fixes (not working)
amanmahajan7 Oct 3, 2019
3519c43
Remove row-reordering components
amanmahajan7 Oct 4, 2019
5ce39f9
Fix eslint errors
amanmahajan7 Oct 4, 2019
ce14794
Remove re-ordering refrences
amanmahajan7 Oct 4, 2019
2e1a989
Remove tests for the deleted file
amanmahajan7 Oct 4, 2019
390434b
Fix types
amanmahajan7 Oct 4, 2019
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 .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,7 +357,7 @@ const rules = {
'react/jsx-no-undef': 0,
'react/jsx-no-useless-fragment': 0,
'react/jsx-one-expression-per-line': 0,
'react/jsx-curly-brace-presence': 0,
'react/jsx-curly-brace-presence': 1,
'react/jsx-fragments': 1,
'react/jsx-pascal-case': 1,
'react/jsx-props-no-multi-spaces': 1,
Expand Down
1 change: 0 additions & 1 deletion examples/components/ExampleList.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ export default class ExampleList extends React.Component {
<li><Link to="/examples/grouping">Grouping Example</Link></li>
<li><Link to="/examples/custom-filters">Custom Filters Example</Link></li>
<li><Link to="/examples/immutable-data-grouping">Immutable Data Grouping Example</Link></li>
<li><Link to="/examples/row-reordering">Row Reordering Example</Link></li>
<li><Link to="/examples/draggable-header">Draggable Header Example</Link></li>
<li><Link to="/examples/tree-view">Tree View Example</Link></li>
<li><Link to="/examples/tree-view-no-add-delete">Tree View No Add Delete Example</Link></li>
Expand Down
2 changes: 0 additions & 2 deletions examples/components/Examples.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import CellSelectionEvents from '../scripts/example21-cell-selection-events';
import Grouping from '../scripts/example21-grouping';
import CustomFilters from '../scripts/example22-custom-filters';
import ImmutableDataGrouping from '../scripts/example23-immutable-data-grouping';
import RowOrdering from '../scripts/example23-row-reordering';
import DraggableHeader from '../scripts/example24-draggable-header';
import TreeView from '../scripts/example25-tree-view';
import TreeViewNoAddDelete from '../scripts/example26-tree-view-no-add-delete';
Expand Down Expand Up @@ -78,7 +77,6 @@ export default function Examples({ match }) {
<Route path="/examples/grouping" component={Grouping} />
<Route path="/examples/custom-filters" component={CustomFilters} />
<Route path="/examples/immutable-data-grouping" component={ImmutableDataGrouping} />
<Route path="/examples/row-reordering" component={RowOrdering} />
<Route path="/examples/draggable-header" component={DraggableHeader} />
<Route path="/examples/tree-view" component={TreeView} />
<Route path="/examples/tree-view-no-add-delete" component={TreeViewNoAddDelete} />
Expand Down
34 changes: 16 additions & 18 deletions examples/scripts/example13-all-features.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React from 'react';
import ReactDataGrid from 'react-data-grid';
import ReactDataGrid, { SelectColumn } from 'react-data-grid';
import { Editors, Toolbar, Formatters } from 'react-data-grid-addons';
import update from 'immutability-helper';
import faker from 'faker';
Expand All @@ -16,7 +16,8 @@ const titles = ['Dr.', 'Mr.', 'Mrs.', 'Miss', 'Ms.'];
class Example extends React.Component {
constructor(props, context) {
super(props, context);
this._columns = [
this.columns = [
SelectColumn,
{
key: 'id',
name: 'ID',
Expand All @@ -38,8 +39,8 @@ class Example extends React.Component {
width: 200,
resizable: true,
events: {
onDoubleClick() {
console.log('The user double clicked on title column');
onClick: (ev, { idx, rowIdx }) => {
this.grid.openCellEditor(rowIdx, idx);
}
}
},
Expand Down Expand Up @@ -115,7 +116,10 @@ class Example extends React.Component {
}
];

this.state = { rows: this.createRows(2000) };
this.state = {
rows: this.createRows(2000),
selectedRows: new Set()
};
}

createRows = (numberOfRows) => {
Expand Down Expand Up @@ -145,17 +149,6 @@ class Example extends React.Component {
};
};

getColumns = () => {
const clonedColumns = this._columns.slice();
clonedColumns[2].events = {
onClick: (ev, { idx, rowIdx }) => {
this.grid.openCellEditor(rowIdx, idx);
}
};

return clonedColumns;
};

handleGridRowsUpdated = ({ fromRow, toRow, updated }) => {
const rows = this.state.rows.slice();

Expand Down Expand Up @@ -193,19 +186,24 @@ class Example extends React.Component {
return this.state.rows.length;
};

onSelectedRowsChange = (selectedRows) => {
this.setState({ selectedRows });
};

render() {
return (
<ReactDataGrid
ref={node => this.grid = node}
enableCellSelect
columns={this.getColumns()}
columns={this.columns}
rowGetter={this.getRowAt}
rowsCount={this.getSize()}
onGridRowsUpdated={this.handleGridRowsUpdated}
toolbar={<Toolbar onAddRow={this.handleAddRow} />}
enableRowSelect
rowHeight={50}
minHeight={600}
selectedRows={this.state.selectedRows}
onSelectedRowsChange={this.onSelectedRowsChange}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a new API. We should mark it and add docs later.

/>
);
}
Expand Down
55 changes: 13 additions & 42 deletions examples/scripts/example16-row-select.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import React from 'react';
import ReactDataGrid from 'react-data-grid';
import ReactDataGrid, { SelectColumn } from 'react-data-grid';

import exampleWrapper from '../components/exampleWrapper';

class Example extends React.Component {
constructor(props) {
super(props);
this._columns = [
SelectColumn,
{
key: 'id',
name: 'ID'
Expand All @@ -29,71 +30,41 @@ class Example extends React.Component {
count: i * 1000
});
}
this.state = { rows, selectedIndexes: [] };
this.state = {
rows,
selectedRows: new Set()
};
}

rowGetter = (i) => {
return this.state.rows[i];
};

onRowsSelected = (rows) => {
this.setState({ selectedIndexes: this.state.selectedIndexes.concat(rows.map(r => r.rowIdx)) });
};

onRowsDeselected = (rows) => {
const rowIndexes = rows.map(r => r.rowIdx);
this.setState({ selectedIndexes: this.state.selectedIndexes.filter(i => rowIndexes.indexOf(i) === -1) });
onSelectedRowsChange = (selectedRows) => {
this.setState({ selectedRows });
};

render() {
const rowText = this.state.selectedIndexes.length === 1 ? 'row' : 'rows';
const rowText = this.state.selectedRows.size === 1 ? 'row' : 'rows';
return (
<div>
<span>{this.state.selectedIndexes.length} {rowText} selected</span>
<span>{this.state.selectedRows.size} {rowText} selected</span>
<ReactDataGrid
rowKey="id"
columns={this._columns}
rowGetter={this.rowGetter}
rowsCount={this.state.rows.length}
minHeight={500}
rowSelection={{
showCheckbox: true,
enableShiftSelect: true,
onRowsSelected: this.onRowsSelected,
onRowsDeselected: this.onRowsDeselected,
selectBy: {
indexes: this.state.selectedIndexes
}
}}
selectedRows={this.state.selectedRows}
onSelectedRowsChange={this.onSelectedRowsChange}
/>
</div>
);
}
}

const exampleDescription = (
<div>
<p>Row selection is enabled via the <code>rowSelection</code> prop (object). The following keys control behaviour:</p>
<h4>selectBy</h4>
<p>
This allows rows to be selected programatically. The options are:<br />
indexes - <code dangerouslySetInnerHTML={{ __html: 'selectBy: {indexes: [0, 1, 2]}' }} /> to select rows by index.<br />
keys - <code dangerouslySetInnerHTML={{ __html: "selectBy: {keys: {rowKey: 'title', values: ['Title1', 'Title2']}}" }} /> to select rows by specified key and values.<br />
isSelectedKey - <code dangerouslySetInnerHTML={{ __html: "selectBy: {isSelectedKey: 'isSelected'}" }} /> to select rows by specified key (based on value being truthy or falsy).
</p>
<h4>onRowsSelected/onRowsDeselected</h4>
<p>
When rows are selected or de-selected, <code>onRowsSelected</code> or <code>onRowsDeselected</code> functions will be called (set as props) with an array of <code dangerouslySetInnerHTML={{ __html: '{rowIdx, row}' }} />.<br />
This allows for single or multiple selection to be implemented as desired, by either appending to or replacing the list of selected items.
</p>
<h4>showCheckbox</h4>
<p>Allows the row selection checkbox to be hidden (shown by default). Useful for selecting rows programatically and controlling selection via the<code>onRowClick</code> event.</p>
<h4>enableShiftSelect</h4>
<p>
Allows a continuous range of rows to be selected by holding the shift key when clicking the row selection checkbox.
</p>
<p><b>Note:</b> These props supercede the existing <code>enableRowSelect</code> and <code>onRowUpdated</code> props which will be removed in a later release.</p>
</div>
<div />
);

export default exampleWrapper({
Expand Down
40 changes: 21 additions & 19 deletions examples/scripts/example17-grid-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,10 @@ class Example extends React.Component {
}
];

this.state = { rows: this.createRows(1000) };
this.state = {
rows: this.createRows(),
selectedRows: new Set()
};
}

createRows = () => {
Expand All @@ -30,8 +33,7 @@ class Example extends React.Component {
rows.push({
id: i,
title: `Title ${i}`,
count: i * 1000,
isSelected: false
count: i * 1000
});
}

Expand All @@ -43,24 +45,28 @@ class Example extends React.Component {
};

onRowClick = (rowIdx, row) => {
const rows = this.state.rows.slice();
rows[rowIdx] = { ...row, isSelected: !row.isSelected };
this.setState({ rows });
const newSelectedRows = new Set(this.state.selectedRows);
if (newSelectedRows.has(row.id)) {
newSelectedRows.delete(row.id);
} else {
newSelectedRows.add(row.id);
}
this.onSelectedRowsChange(newSelectedRows);
};

onKeyDown = (e) => {
if (e.ctrlKey && e.keyCode === 65) {
e.preventDefault();

const rows = [];
this.state.rows.forEach((r) => {
rows.push({ ...r, isSelected: true });
});

this.setState({ rows });
const newSelectedRows = new Set(this.state.selectedRows);
this.state.rows.forEach(row => newSelectedRows.add(row.id));
this.onSelectedRowsChange(newSelectedRows);
}
};

onSelectedRowsChange = (selectedRows) => {
this.setState({ selectedRows });
};

render() {
return (
<ReactDataGrid
Expand All @@ -69,14 +75,10 @@ class Example extends React.Component {
rowGetter={this.rowGetter}
rowsCount={this.state.rows.length}
minHeight={500}
rowSelection={{
showCheckbox: false,
selectBy: {
isSelectedKey: 'isSelected'
}
}}
onRowClick={this.onRowClick}
onGridKeyDown={this.onKeyDown}
selectedRows={this.state.selectedRows}
onSelectedRowsChange={this.onSelectedRowsChange}
/>
);
}
Expand Down
6 changes: 0 additions & 6 deletions examples/scripts/example21-cell-selection-events.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,6 @@ class Example extends React.Component {
return this._rows[index];
};

onRowSelect = (rows) => {
this.setState({ selectedRows: rows });
};

onCellSelected = ({ rowIdx, idx }) => {
this.grid.openCellEditor(rowIdx, idx);
};
Expand All @@ -55,9 +51,7 @@ class Example extends React.Component {
columns={this._columns}
rowGetter={this.rowGetter}
rowsCount={this._rows.length}
enableRowSelect="multi"
minHeight={500}
onRowSelect={this.onRowSelect}
enableCellSelect
onCellSelected={this.onCellSelected}
onCellDeSelected={this.onCellDeSelected}
Expand Down
Loading