diff --git a/docs/row-selection.md b/docs/row-selection.md
index ac7eba7..d7f2e57 100644
--- a/docs/row-selection.md
+++ b/docs/row-selection.md
@@ -16,6 +16,8 @@
* [onSelect](#onSelect)
* [onSelectAll](#onSelectAll)
* [hideSelectColumn](#hideSelectColumn)
+* [selectionRenderer](#selectionRenderer)
+* [selectionHeaderRenderer](#selectionHeaderRenderer)
### selectRow.mode - [String]
@@ -156,6 +158,34 @@ const selectRow = {
};
```
+### selectRow.selectionRenderer - [Bool]
+Provide a callback function which allow you to custom the checkbox/radio box. This callback only have one argument which is an object and contain following properties:
+
+```js
+const selectRow = {
+ mode: 'checkbox',
+ selectionRenderer: ({ mode, checked, disabled }) => (
+ // ....
+ )
+};
+```
+
+> By default, `react-bootstrap-table2` will help you to handle the click event, it's not necessary to handle again by developer.
+
+### selectRow.selectionHeaderRenderer - [Bool]
+Provide a callback function which allow you to custom the checkbox/radio box in the selection header column. This callback only have one argument which is an object and contain following properties:
+
+```js
+const selectRow = {
+ mode: 'checkbox',
+ selectionHeaderRenderer: ({ mode, checked, indeterminate }) => (
+ // ....
+ )
+};
+```
+
+> By default, `react-bootstrap-table2` will help you to handle the click event, it's not necessary to handle again by developer.
+
### selectRow.onSelect - [Function]
This callback function will be called when a row is select/unselect and pass following three arguments:
`row`, `isSelect`, `rowIndex` and `e`.
diff --git a/packages/react-bootstrap-table2-example/examples/row-selection/custom-selection.js b/packages/react-bootstrap-table2-example/examples/row-selection/custom-selection.js
new file mode 100644
index 0000000..4291c68
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/row-selection/custom-selection.js
@@ -0,0 +1,107 @@
+/* eslint react/prop-types: 0 */
+/* eslint no-param-reassign: 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 selectRow1 = {
+ mode: 'radio',
+ clickToSelect: true,
+ selectionHeaderRenderer: () => 'X',
+ selectionRenderer: ({ mode, ...rest }) => (
+
+ )
+};
+
+const selectRow2 = {
+ mode: 'checkbox',
+ clickToSelect: true,
+ selectionHeaderRenderer: ({ indeterminate, ...rest }) => (
+ {
+ if (input) input.indeterminate = indeterminate;
+ } }
+ { ...rest }
+ />
+ ),
+ selectionRenderer: ({ mode, ...rest }) => (
+
+ )
+};
+
+const sourceCode1 = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+
+const columns = ....;
+
+const selectRow = {
+ mode: 'radio',
+ clickToSelect: true,
+ selectionHeaderRenderer: () => 'X',
+ selectionRenderer: ({ mode, ...rest }) => (
+
+ )
+};
+
+
+`;
+
+const sourceCode2 = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+
+const columns = ....;
+
+const selectRow = {
+ mode: 'checkbox',
+ clickToSelect: true,
+ selectionHeaderRenderer: ({ indeterminate, ...rest }) => (
+ {
+ if (input) input.indeterminate = indeterminate;
+ } }
+ { ...rest }
+ />
+ ),
+ selectionRenderer: ({ mode, ...rest }) => (
+
+ )
+};
+
+
+`;
+
+export default () => (
+
+
+ { sourceCode1 }
+
+ { sourceCode2 }
+
+);
diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js
index 42f2985..a3fe4c3 100644
--- a/packages/react-bootstrap-table2-example/stories/index.js
+++ b/packages/react-bootstrap-table2-example/stories/index.js
@@ -95,6 +95,7 @@ import ClickToSelectWithCellEditTable from 'examples/row-selection/click-to-sele
import SelectionNoDataTable from 'examples/row-selection/selection-no-data';
import SelectionStyleTable from 'examples/row-selection/selection-style';
import SelectionClassTable from 'examples/row-selection/selection-class';
+import CustomSelectionTable from 'examples/row-selection/custom-selection';
import NonSelectableRowsTable from 'examples/row-selection/non-selectable-rows';
import SelectionBgColorTable from 'examples/row-selection/selection-bgcolor';
import SelectionHooks from 'examples/row-selection/selection-hooks';
@@ -222,6 +223,7 @@ storiesOf('Row Selection', module)
.add('Selection without Data', () => )
.add('Selection Style', () => )
.add('Selection Class', () => )
+ .add('Custom Selection', () => )
.add('Selection Background Color', () => )
.add('Not Selectabled Rows', () => )
.add('Selection Hooks', () => )
diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js
index 91e46cc..27e96ab 100644
--- a/packages/react-bootstrap-table2/src/bootstrap-table.js
+++ b/packages/react-bootstrap-table2/src/bootstrap-table.js
@@ -142,7 +142,9 @@ BootstrapTable.propTypes = {
classes: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
nonSelectable: PropTypes.array,
bgColor: PropTypes.oneOfType([PropTypes.string, PropTypes.func]),
- hideSelectColumn: PropTypes.bool
+ hideSelectColumn: PropTypes.bool,
+ selectionRenderer: PropTypes.func,
+ selectionHeaderRenderer: PropTypes.func
}),
onRowSelect: PropTypes.func,
onAllRowsSelect: PropTypes.func,
diff --git a/packages/react-bootstrap-table2/src/row-selection/selection-cell.js b/packages/react-bootstrap-table2/src/row-selection/selection-cell.js
index 3050cf2..bec0ef0 100644
--- a/packages/react-bootstrap-table2/src/row-selection/selection-cell.js
+++ b/packages/react-bootstrap-table2/src/row-selection/selection-cell.js
@@ -14,7 +14,8 @@ export default class SelectionCell extends Component {
onRowSelect: PropTypes.func,
disabled: PropTypes.bool,
rowIndex: PropTypes.number,
- clickToSelect: PropTypes.bool
+ clickToSelect: PropTypes.bool,
+ selectionRenderer: PropTypes.func
}
constructor() {
@@ -53,16 +54,25 @@ export default class SelectionCell extends Component {
const {
mode: inputType,
selected,
- disabled
+ disabled,
+ selectionRenderer
} = this.props;
return (
-
+ {
+ selectionRenderer ? selectionRenderer({
+ mode: inputType,
+ checked: selected,
+ disabled
+ }) : (
+
+ )
+ }
|
);
}
diff --git a/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js b/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js
index 0105bf3..9879026 100644
--- a/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js
+++ b/packages/react-bootstrap-table2/src/row-selection/selection-header-cell.js
@@ -22,7 +22,8 @@ export default class SelectionHeaderCell extends Component {
static propTypes = {
mode: PropTypes.string.isRequired,
checkedStatus: PropTypes.string,
- onAllRowsSelect: PropTypes.func
+ onAllRowsSelect: PropTypes.func,
+ selectionHeaderRenderer: PropTypes.func
}
constructor() {
@@ -52,25 +53,37 @@ export default class SelectionHeaderCell extends Component {
render() {
const {
- CHECKBOX_STATUS_CHECKED, CHECKBOX_STATUS_INDETERMINATE, ROW_SELECT_SINGLE
+ CHECKBOX_STATUS_CHECKED, CHECKBOX_STATUS_INDETERMINATE, ROW_SELECT_MULTIPLE
} = Const;
- const { mode, checkedStatus } = this.props;
+ const { mode, checkedStatus, selectionHeaderRenderer } = this.props;
const checked = checkedStatus === CHECKBOX_STATUS_CHECKED;
const indeterminate = checkedStatus === CHECKBOX_STATUS_INDETERMINATE;
- return mode === ROW_SELECT_SINGLE
- ? |
- : (
-
-
- |
+ const attrs = {};
+ let content;
+ if (selectionHeaderRenderer) {
+ content = selectionHeaderRenderer({
+ mode,
+ checked,
+ indeterminate
+ });
+ attrs.onClick = this.handleCheckBoxClick;
+ } else if (mode === ROW_SELECT_MULTIPLE) {
+ content = (
+
);
+ attrs.onClick = this.handleCheckBoxClick;
+ }
+
+ return (
+ { content } |
+ );
}
}
diff --git a/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js b/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js
index c0069e2..02e9d85 100644
--- a/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js
+++ b/packages/react-bootstrap-table2/test/row-selection/selection-cell.test.js
@@ -193,5 +193,36 @@ describe('', () => {
expect(wrapper.find('input').get(0).props.disabled).toBeTruthy();
});
});
+
+ describe('when selectionRenderer prop is defined', () => {
+ const DummySelection = () => ;
+ const selectionRenderer = jest.fn().mockReturnValue();
+
+ beforeEach(() => {
+ selectionRenderer.mockClear();
+ wrapper = shallow(
+
+ );
+ });
+
+ it('should render component correctly', () => {
+ expect(wrapper.find(DummySelection)).toHaveLength(1);
+ });
+
+ it('should call props.selectionRenderer correctly', () => {
+ expect(selectionRenderer).toHaveBeenCalledTimes(1);
+ expect(selectionRenderer).toHaveBeenCalledWith({
+ mode,
+ checked: selected,
+ disabled: wrapper.prop('disabled')
+ });
+ });
+ });
});
});
diff --git a/packages/react-bootstrap-table2/test/row-selection/selection-header-cell.test.js b/packages/react-bootstrap-table2/test/row-selection/selection-header-cell.test.js
index d1e4b03..73571d4 100644
--- a/packages/react-bootstrap-table2/test/row-selection/selection-header-cell.test.js
+++ b/packages/react-bootstrap-table2/test/row-selection/selection-header-cell.test.js
@@ -126,6 +126,36 @@ describe('', () => {
expect(wrapper.find(CheckBox).get(0).props.indeterminate).toBe(indeterminate);
});
});
+
+ describe('when props.selectionHeaderRenderer is defined', () => {
+ const checkedStatus = Const.CHECKBOX_STATUS_CHECKED;
+ const DummySelection = () => ;
+ const selectionHeaderRenderer = jest.fn().mockReturnValue();
+
+ beforeEach(() => {
+ selectionHeaderRenderer.mockClear();
+ wrapper = shallow(
+
+ );
+ });
+
+ it('should render correctly', () => {
+ expect(wrapper.find(DummySelection)).toHaveLength(1);
+ });
+
+ it('should call props.selectionHeaderRenderer correctly', () => {
+ expect(selectionHeaderRenderer).toHaveBeenCalledTimes(1);
+ expect(selectionHeaderRenderer).toHaveBeenCalledWith({
+ mode: 'checkbox',
+ checked: checkedStatus === Const.CHECKBOX_STATUS_CHECKED,
+ indeterminate: checkedStatus === Const.CHECKBOX_STATUS_INDETERMINATE
+ });
+ });
+ });
});
});