Skip to content
11 changes: 11 additions & 0 deletions docs/row-selection.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
* [mode (**required**)](#mode)

## Optional
* [selected](#selected)
* [style](#style)
* [classes)](#classes)
* [bgColor](#bgColor)
Expand Down Expand Up @@ -52,6 +53,16 @@ const selectRow = {
/>
```

### <a name='selected'>selectRow.selected - [Array]</a>
`selectRow.selected` allow you have default selections on table.

```js
const selectRow = {
mode: 'checkbox',
selected: [1, 3] // should be a row keys array
};
```

### <a name='style'>selectRow.style - [Object | Function]</a>
`selectRow.style` allow you to have custom style on selected rows:

Expand Down
5 changes: 3 additions & 2 deletions packages/react-bootstrap-table2-editor/src/text-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,10 @@ TextEditor.propTypes = {
defaultValue: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number
]).isRequired
])
};
TextEditor.defaultProps = {
className: null
className: null,
defaultValue: ''
};
export default TextEditor;
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
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 selectRow = {
mode: 'checkbox',
clickToSelect: true,
selected: [1, 3]
};

const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';

const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price'
}];

const selectRow = {
mode: 'checkbox',
clickToSelect: true,
selected: [1, 3]
};

<BootstrapTable
keyField='id'
data={ products }
columns={ columns }
selectRow={ selectRow }
/>
`;

export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } selectRow={ selectRow } />
<Code>{ sourceCode }</Code>
</div>
);
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,28 @@ const columns = [{
<BootstrapTable keyField='id' data={ products } columns={ columns } />
`;

export default () => (
<div>
<BootstrapTable keyField="id" data={ products } columns={ columns } />
<Code>{ sourceCode }</Code>
</div>
);
export default class Test extends React.Component {
constructor(props) {
super(props);
this.state = { data: products };
}

handleClick = () => {
this.setState(() => {
const newProducts = productsGenerator(21);
return {
data: newProducts
};
});
}

render() {
return (
<div>
<button className="btn btn-default" onClick={ this.handleClick }>Change Data</button>
<BootstrapTable keyField="id" data={ this.state.data } columns={ columns } />
<Code>{ sourceCode }</Code>
</div>
);
}
}
2 changes: 2 additions & 0 deletions packages/react-bootstrap-table2-example/stories/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ import CellEditClassTable from 'examples/cell-edit/cell-edit-class-table';
import SingleSelectionTable from 'examples/row-selection/single-selection';
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 ClickToSelectWithCellEditTable from 'examples/row-selection/click-to-select-with-cell-edit';
import SelectionStyleTable from 'examples/row-selection/selection-style';
import SelectionClassTable from 'examples/row-selection/selection-class';
Expand Down Expand Up @@ -189,6 +190,7 @@ storiesOf('Row Selection', module)
.add('Single Selection', () => <SingleSelectionTable />)
.add('Multiple Selection', () => <MultipleSelectionTable />)
.add('Click to Select', () => <ClickToSelectTable />)
.add('Default Select', () => <DefaultSelectTable />)
.add('Click to Select and Edit Cell', () => <ClickToSelectWithCellEditTable />)
.add('Selection Style', () => <SelectionStyleTable />)
.add('Selection Class', () => <SelectionClassTable />)
Expand Down
4 changes: 3 additions & 1 deletion packages/react-bootstrap-table2/src/bootstrap-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,12 @@ class BootstrapTable extends PropsBaseResolver(Component) {
allRowsSelected: isSelectedAll(store)
});

const tableCaption = (caption && <Caption>{ caption }</Caption>);

return (
<div className="react-bootstrap-table">
<table className={ tableClass }>
<Caption>{ caption }</Caption>
{ tableCaption }
<Header
columns={ columns }
sortField={ store.sortField }
Expand Down
84 changes: 84 additions & 0 deletions packages/react-bootstrap-table2/src/row-event-delegater.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import _ from './utils';

const events = [
'onClick',
'onMouseEnter',
'onMouseLeave'
];

export default ExtendBase =>
class RowEventDelegater extends ExtendBase {
constructor(props) {
super(props);
this.clickNum = 0;
this.createDefaultEventHandler = this.createDefaultEventHandler.bind(this);
this.createClickEventHandler = this.createClickEventHandler.bind(this);
}

createDefaultEventHandler(cb) {
return (e) => {
const { row, rowIndex } = this.props;
cb(e, row, rowIndex);
};
}

createClickEventHandler(cb) {
return (e) => {
const {
row,
selected,
keyField,
selectable,
rowIndex,
selectRow: {
onRowSelect,
clickToEdit
},
cellEdit: {
mode,
DBCLICK_TO_CELL_EDIT,
DELAY_FOR_DBCLICK
}
} = this.props;

const clickFn = () => {
if (cb) {
cb(e, row, rowIndex);
}
if (selectable) {
const key = _.get(row, keyField);
onRowSelect(key, !selected, rowIndex);
}
};

if (mode === DBCLICK_TO_CELL_EDIT && clickToEdit) {
this.clickNum += 1;
_.debounce(() => {
if (this.clickNum === 1) {
clickFn();
}
this.clickNum = 0;
}, DELAY_FOR_DBCLICK)();
} else {
clickFn();
}
};
}

delegate(attrs = {}) {
const newAttrs = {};
if (this.props.selectRow && this.props.selectRow.clickToSelect) {
newAttrs.onClick = this.createClickEventHandler(attrs.onClick);
}
Object.keys(attrs).forEach((attr) => {
if (!newAttrs[attr]) {
if (events.includes(attr)) {
newAttrs[attr] = this.createDefaultEventHandler(attrs[attr]);
} else {
newAttrs[attr] = attrs[attr];
}
}
});
return newAttrs;
}
};
11 changes: 11 additions & 0 deletions packages/react-bootstrap-table2/src/row-selection/wrapper.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint no-param-reassign: 0 */
import React, { Component } from 'react';
import PropTypes from 'prop-types';

Expand All @@ -21,11 +22,21 @@ export default Base =>
super(props);
this.handleRowSelect = this.handleRowSelect.bind(this);
this.handleAllRowsSelect = this.handleAllRowsSelect.bind(this);
props.store.selected = this.props.selectRow.selected || [];
this.state = {
selectedRowKeys: props.store.selected
};
}

componentWillReceiveProps(nextProps) {
if (nextProps.selectRow) {
this.store.selected = nextProps.selectRow.selected || [];
this.setState(() => ({
selectedRowKeys: this.store.selected
}));
}
}

/**
* row selection handler
* @param {String} rowKey - row key of what was selected.
Expand Down
72 changes: 4 additions & 68 deletions packages/react-bootstrap-table2/src/row.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,68 +6,10 @@ import PropTypes from 'prop-types';
import _ from './utils';
import Cell from './cell';
import SelectionCell from './row-selection/selection-cell';
import eventDelegater from './row-event-delegater';
import Const from './const';

class Row extends Component {
constructor(props) {
super(props);
this.clickNum = 0;
this.handleRowClick = this.handleRowClick.bind(this);
this.handleSimpleRowClick = this.handleSimpleRowClick.bind(this);
}

handleRowClick(e) {
const {
row,
selected,
keyField,
selectable,
rowIndex,
selectRow: {
onRowSelect,
clickToEdit
},
cellEdit: {
mode,
DBCLICK_TO_CELL_EDIT,
DELAY_FOR_DBCLICK
},
attrs
} = this.props;

const clickFn = () => {
if (attrs.onClick) {
attrs.onClick(e, row, rowIndex);
}
if (selectable) {
const key = _.get(row, keyField);
onRowSelect(key, !selected, rowIndex);
}
};

if (mode === DBCLICK_TO_CELL_EDIT && clickToEdit) {
this.clickNum += 1;
_.debounce(() => {
if (this.clickNum === 1) {
clickFn();
}
this.clickNum = 0;
}, DELAY_FOR_DBCLICK)();
} else {
clickFn();
}
}

handleSimpleRowClick(e) {
const {
row,
rowIndex,
attrs
} = this.props;

attrs.onClick(e, row, rowIndex);
}

class Row extends eventDelegater(Component) {
render() {
const {
row,
Expand Down Expand Up @@ -96,14 +38,8 @@ class Row extends Component {
} = cellEdit;

const key = _.get(row, keyField);
const { clickToSelect, hideSelectColumn } = selectRow;

const trAttrs = { ...attrs };
if (clickToSelect) {
trAttrs.onClick = this.handleRowClick;
} else if (attrs.onClick) {
trAttrs.onClick = this.handleSimpleRowClick;
}
const { hideSelectColumn } = selectRow;
const trAttrs = this.delegate(attrs);

return (
<tr style={ style } className={ className } { ...trAttrs }>
Expand Down
10 changes: 4 additions & 6 deletions packages/react-bootstrap-table2/src/sort/wrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,12 +39,10 @@ export default Base =>
}

componentWillReceiveProps(nextProps) {
if (nextProps.isDataChanged) {
const sortedColumn = nextProps.columns.find(
column => column.dataField === nextProps.store.sortField);
if (sortedColumn) {
nextProps.store.sortBy(sortedColumn);
}
const sortedColumn = nextProps.columns.find(
column => column.dataField === nextProps.store.sortField);
if (sortedColumn && sortedColumn.sort) {
nextProps.store.sortBy(sortedColumn);
}
}

Expand Down
Loading