mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-06-29 05:30:05 +00:00
Compare commits
44 Commits
react-boot
...
react-boot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
532581bb6e | ||
|
|
c228b229d2 | ||
|
|
10adbf472c | ||
|
|
a6e2f0f8f8 | ||
|
|
f1d93853ec | ||
|
|
bb7243c5db | ||
|
|
3ea816b2e6 | ||
|
|
b268c4e0cd | ||
|
|
8b8f336878 | ||
|
|
8517248aee | ||
|
|
ae0cd8a32f | ||
|
|
51c82cdfb3 | ||
|
|
8e087329b3 | ||
|
|
ee2885d055 | ||
|
|
901307e471 | ||
|
|
4ff5be706a | ||
|
|
f8a3fedbb2 | ||
|
|
0bf5831b4e | ||
|
|
dd0b8c6b0f | ||
|
|
8f028d9dd4 | ||
|
|
2c68f22646 | ||
|
|
02d566bb32 | ||
|
|
2b12045017 | ||
|
|
0cdf086d56 | ||
|
|
d4fa9a84e3 | ||
|
|
c84fc84b9e | ||
|
|
ad8cdde513 | ||
|
|
db19e7dd9b | ||
|
|
33b36e5108 | ||
|
|
7209441eb6 | ||
|
|
7a1ed67847 | ||
|
|
eaf9f4cd39 | ||
|
|
f0d85520c0 | ||
|
|
0e2862baa5 | ||
|
|
5ac058c489 | ||
|
|
ac38d2f28e | ||
|
|
591abaae6e | ||
|
|
b76566126c | ||
|
|
687583536a | ||
|
|
d136ec3197 | ||
|
|
37db43f5a7 | ||
|
|
a966900752 | ||
|
|
3b1fc3a559 | ||
|
|
849d9af8c4 |
@@ -13,7 +13,7 @@ Rebuilt [react-bootstrap-table](https://github.com/AllenFang/react-bootstrap-tab
|
||||
* [`react-bootstrap-table2-overlay`](https://www.npmjs.com/package/react-bootstrap-table2-overlay)
|
||||
* [`react-bootstrap-table2-toolkit`](https://www.npmjs.com/package/react-bootstrap-table2-toolkit)
|
||||
|
||||
This can help your application with less bundled size and also help us have clean design to avoid handling to much logic in kernal module(SRP).
|
||||
This can help your application with less bundled size and also help us have clean design to avoid handling to much logic in kernel module(SRP).
|
||||
|
||||
## Migration
|
||||
If you are the user from legacy [`react-bootstrap-table`](https://github.com/AllenFang/react-bootstrap-table/), please have a look on [this](./docs/migration.md).
|
||||
|
||||
@@ -10,6 +10,7 @@ $ npm install react-bootstrap-table2-editor --save
|
||||
* [blurToSave](#blurToSave)
|
||||
* [nonEditableRows](#nonEditableRows)
|
||||
* [timeToCloseMessage](#timeToCloseMessage)
|
||||
* [autoSelectText](#autoSelectText)
|
||||
* [beforeSaveCell](#beforeSaveCell)
|
||||
* [afterSaveCell](#afterSaveCell)
|
||||
* [errorMessage](#errorMessage)
|
||||
@@ -43,6 +44,11 @@ Default is `false`, enable it will be able to save the cell automatically when b
|
||||
### <a name='nonEditableRows'>cellEdit.nonEditableRows - [Function]</a>
|
||||
`cellEdit.nonEditableRows` accept a callback function and expect return an array which used to restrict all the columns of some rows as non-editable. So the each item in return array should be rowkey(`keyField`)
|
||||
|
||||
### <a name='autoSelectText'>cellEdit.autoSelectText - [Bool]</a>
|
||||
Default is false, when enable it, `react-bootstrap-table2` will help you to select the text in the text input automatically when editing.
|
||||
|
||||
> NOTE: This props only work for `text` and `textarea`.
|
||||
|
||||
### <a name='timeToCloseMessage'>cellEdit.timeToCloseMessage - [Function]</a>
|
||||
If a [`column.validator`](./columns.md#validator) defined and the new value is invalid, `react-bootstrap-table2` will popup a alert at the bottom of editor. `cellEdit.timeToCloseMessage` is a chance to let you decide how long the alert should be stay. Default is 3000 millisecond.
|
||||
|
||||
|
||||
@@ -7,11 +7,13 @@ Available properties in a column object:
|
||||
* [text (**required**)](#text)
|
||||
|
||||
#### Optional
|
||||
* [isDummyField](#isDummyField)
|
||||
* [hidden](#hidden)
|
||||
* [formatter](#formatter)
|
||||
* [formatExtraData](#formatExtraData)
|
||||
* [sort](#sort)
|
||||
* [sortFunc](#sortFunc)
|
||||
* [sortCaret](#sortCaret)
|
||||
* [onSort](#onSort)
|
||||
* [classes](#classes)
|
||||
* [style](#style)
|
||||
@@ -84,6 +86,11 @@ dataField: 'address.city'
|
||||
## <a name='text'>column.text (**required**) - [String]</a>
|
||||
`text` will be the column text in header column by default, if your header is not only text or you want to customize the header column, please check [`column.headerFormatter`](#headerFormatter)
|
||||
|
||||
## <a name='isDummyField'>column.isDummyField - [Bool]</a>
|
||||
Sometime, you just want to have a column which is not perform any data but just some action components. In this situation, we suggest you to use `isDummyField`. If column is dummy, the [`column.dataField`](#dataField) can be any string value, cause of it's meaningless.
|
||||
|
||||
There's only one different for dummy column than normal column, which is dummy column will compare the whole row value instead of cell value when call `shouldComponentUpdate`.
|
||||
|
||||
## <a name='hidden'>column.hidden - [Bool]</a>
|
||||
`hidden` allow you to hide column when `true` given.
|
||||
|
||||
@@ -148,6 +155,20 @@ Enable the column sort via a `true` value given.
|
||||
}
|
||||
```
|
||||
|
||||
## <a name='sortCaret'>column.sortCaret - [Function]</a>
|
||||
Use`column.sortCaret` to custom the sort caret. This callback function accept two arguments: `order` and `column`
|
||||
|
||||
```js
|
||||
{
|
||||
// omit...
|
||||
sort: true,
|
||||
sortCaret: (order, column) => {
|
||||
return //...
|
||||
}
|
||||
}
|
||||
```
|
||||
> The possible value of `order` argument is **`asc`**, **`desc`** and **`undefined`**.
|
||||
|
||||
## <a name='classes'>column.classes - [String | Function]</a>
|
||||
It's available to have custom class on table column:
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* [onExpand](#onExpand)
|
||||
* [onExpandAll](#onExpandAll)
|
||||
* [showExpandColumn](#showExpandColumn)
|
||||
* [onlyOneExpanding](#onlyOneExpanding)
|
||||
* [expandColumnRenderer](#expandColumnRenderer)
|
||||
* [expandHeaderColumnRenderer](#expandHeaderColumnRenderer)
|
||||
|
||||
@@ -127,3 +128,13 @@ const expandRow = {
|
||||
showExpandColumn: true
|
||||
};
|
||||
```
|
||||
|
||||
### <a name='onlyOneExpanding'>expandRow.onlyOneExpanding - [Bool]</a>
|
||||
Default is `false`. Enable this will only allow one row get expand at the same time.
|
||||
|
||||
```js
|
||||
const expandRow = {
|
||||
renderer: (row) => ...
|
||||
onlyOneExpanding: true
|
||||
};
|
||||
```
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
* [onSelect](#onSelect)
|
||||
* [onSelectAll](#onSelectAll)
|
||||
* [hideSelectColumn](#hideSelectColumn)
|
||||
* [hideSelectAll](#hideSelectAll)
|
||||
* [selectionRenderer](#selectionRenderer)
|
||||
* [selectionHeaderRenderer](#selectionHeaderRenderer)
|
||||
|
||||
@@ -222,3 +223,13 @@ const selectRow = {
|
||||
bgColor: 'red'
|
||||
};
|
||||
```
|
||||
|
||||
### <a name='hideSelectAll'>selectRow.hideSelectAll - [Bool]</a>
|
||||
Default is `false`, if you don't want to render the select all checkbox on the header of selection column, give this prop as `true`!
|
||||
|
||||
```js
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
hideSelectAll: true
|
||||
};
|
||||
```
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-editor",
|
||||
"version": "1.0.0",
|
||||
"version": "1.1.0",
|
||||
"description": "it's the editor addon for react-bootstrap-table2",
|
||||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -13,7 +13,9 @@ class CheckBoxEditor extends Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { didMount } = this.props;
|
||||
this.checkbox.focus();
|
||||
if (didMount) didMount();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
@@ -28,7 +30,7 @@ class CheckBoxEditor extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { defaultValue, className, ...rest } = this.props;
|
||||
const { defaultValue, didMount, className, ...rest } = this.props;
|
||||
const editorClass = cs('editor edit-chseckbox checkbox', className);
|
||||
return (
|
||||
<input
|
||||
@@ -50,12 +52,14 @@ CheckBoxEditor.propTypes = {
|
||||
]),
|
||||
value: PropTypes.string,
|
||||
defaultValue: PropTypes.any,
|
||||
onChange: PropTypes.func
|
||||
onChange: PropTypes.func,
|
||||
didMount: PropTypes.func
|
||||
};
|
||||
CheckBoxEditor.defaultProps = {
|
||||
className: '',
|
||||
value: 'on:off',
|
||||
defaultValue: false,
|
||||
onChange: undefined
|
||||
onChange: undefined,
|
||||
didMount: undefined
|
||||
};
|
||||
export default CheckBoxEditor;
|
||||
|
||||
@@ -23,6 +23,7 @@ export default (
|
||||
blurToSave: PropTypes.bool,
|
||||
beforeSaveCell: PropTypes.func,
|
||||
afterSaveCell: PropTypes.func,
|
||||
onStartEdit: PropTypes.func,
|
||||
nonEditableRows: PropTypes.func,
|
||||
timeToCloseMessage: PropTypes.number,
|
||||
errorMessage: PropTypes.any
|
||||
@@ -31,7 +32,7 @@ export default (
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
EditingCell = props.cellEdit.editingCellFactory(_);
|
||||
EditingCell = props.cellEdit.editingCellFactory(_, props.cellEdit.options.onStartEdit);
|
||||
this.startEditing = this.startEditing.bind(this);
|
||||
this.escapeEditing = this.escapeEditing.bind(this);
|
||||
this.completeEditing = this.completeEditing.bind(this);
|
||||
|
||||
@@ -5,9 +5,10 @@ import PropTypes from 'prop-types';
|
||||
|
||||
class DateEditor extends Component {
|
||||
componentDidMount() {
|
||||
const { defaultValue } = this.props;
|
||||
const { defaultValue, didMount } = this.props;
|
||||
this.date.valueAsDate = new Date(defaultValue);
|
||||
this.date.focus();
|
||||
if (didMount) didMount();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
@@ -15,7 +16,7 @@ class DateEditor extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { defaultValue, className, ...rest } = this.props;
|
||||
const { defaultValue, didMount, className, ...rest } = this.props;
|
||||
const editorClass = cs('form-control editor edit-date', className);
|
||||
return (
|
||||
<input
|
||||
@@ -33,10 +34,12 @@ DateEditor.propTypes = {
|
||||
PropTypes.string,
|
||||
PropTypes.object
|
||||
]),
|
||||
defaultValue: PropTypes.string
|
||||
defaultValue: PropTypes.string,
|
||||
didMount: PropTypes.func
|
||||
};
|
||||
DateEditor.defaultProps = {
|
||||
className: '',
|
||||
defaultValue: ''
|
||||
defaultValue: '',
|
||||
didMount: undefined
|
||||
};
|
||||
export default DateEditor;
|
||||
|
||||
@@ -5,9 +5,10 @@ import PropTypes from 'prop-types';
|
||||
|
||||
class DropDownEditor extends Component {
|
||||
componentDidMount() {
|
||||
const { defaultValue } = this.props;
|
||||
const { defaultValue, didMount } = this.props;
|
||||
this.select.value = defaultValue;
|
||||
this.select.focus();
|
||||
if (didMount) didMount();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
@@ -15,7 +16,7 @@ class DropDownEditor extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { defaultValue, className, options, ...rest } = this.props;
|
||||
const { defaultValue, didMount, className, options, ...rest } = this.props;
|
||||
const editorClass = cs('form-control editor edit-select', className);
|
||||
|
||||
const attr = {
|
||||
@@ -51,11 +52,13 @@ DropDownEditor.propTypes = {
|
||||
label: PropTypes.string,
|
||||
value: PropTypes.any
|
||||
}))
|
||||
]).isRequired
|
||||
]).isRequired,
|
||||
didMount: PropTypes.func
|
||||
};
|
||||
DropDownEditor.defaultProps = {
|
||||
className: '',
|
||||
defaultValue: '',
|
||||
style: {}
|
||||
style: {},
|
||||
didMount: undefined
|
||||
};
|
||||
export default DropDownEditor;
|
||||
|
||||
@@ -14,7 +14,7 @@ import TextEditor from './text-editor';
|
||||
import EditorIndicator from './editor-indicator';
|
||||
import { TIME_TO_CLOSE_MESSAGE, EDITTYPE } from './const';
|
||||
|
||||
export default _ =>
|
||||
export default (_, onStartEdit) =>
|
||||
class EditingCell extends Component {
|
||||
static propTypes = {
|
||||
row: PropTypes.object.isRequired,
|
||||
@@ -24,6 +24,7 @@ export default _ =>
|
||||
onUpdate: PropTypes.func.isRequired,
|
||||
onEscape: PropTypes.func.isRequired,
|
||||
timeToCloseMessage: PropTypes.number,
|
||||
autoSelectText: PropTypes.bool,
|
||||
className: PropTypes.string,
|
||||
style: PropTypes.object
|
||||
}
|
||||
@@ -31,6 +32,7 @@ export default _ =>
|
||||
static defaultProps = {
|
||||
timeToCloseMessage: TIME_TO_CLOSE_MESSAGE,
|
||||
className: null,
|
||||
autoSelectText: false,
|
||||
style: {}
|
||||
}
|
||||
|
||||
@@ -121,7 +123,7 @@ export default _ =>
|
||||
|
||||
render() {
|
||||
let editor;
|
||||
const { row, column, className, style, rowIndex, columnIndex } = this.props;
|
||||
const { row, column, className, style, rowIndex, columnIndex, autoSelectText } = this.props;
|
||||
const { dataField } = column;
|
||||
|
||||
const value = _.get(row, dataField);
|
||||
@@ -151,6 +153,10 @@ export default _ =>
|
||||
onBlur: this.handleBlur
|
||||
};
|
||||
|
||||
if (onStartEdit) {
|
||||
editorProps.didMount = () => onStartEdit(row, column, rowIndex, columnIndex);
|
||||
}
|
||||
|
||||
const isDefaultEditorDefined = _.isObject(column.editor);
|
||||
|
||||
if (isDefaultEditorDefined) {
|
||||
@@ -170,13 +176,13 @@ export default _ =>
|
||||
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.SELECT) {
|
||||
editor = <DropdownEditor { ...editorProps } />;
|
||||
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.TEXTAREA) {
|
||||
editor = <TextAreaEditor { ...editorProps } />;
|
||||
editor = <TextAreaEditor { ...editorProps } autoSelectText={ autoSelectText } />;
|
||||
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.CHECKBOX) {
|
||||
editor = <CheckBoxEditor { ...editorProps } />;
|
||||
} else if (isDefaultEditorDefined && column.editor.type === EDITTYPE.DATE) {
|
||||
editor = <DateEditor { ...editorProps } />;
|
||||
} else {
|
||||
editor = <TextEditor { ...editorProps } />;
|
||||
editor = <TextEditor { ...editorProps } autoSelectText={ autoSelectText } />;
|
||||
}
|
||||
|
||||
return (
|
||||
|
||||
@@ -5,9 +5,11 @@ import PropTypes from 'prop-types';
|
||||
|
||||
class TextEditor extends Component {
|
||||
componentDidMount() {
|
||||
const { defaultValue } = this.props;
|
||||
const { defaultValue, didMount, autoSelectText } = this.props;
|
||||
this.text.value = defaultValue;
|
||||
this.text.focus();
|
||||
if (autoSelectText) this.text.select();
|
||||
if (didMount) didMount();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
@@ -15,7 +17,7 @@ class TextEditor extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { defaultValue, className, ...rest } = this.props;
|
||||
const { defaultValue, didMount, className, autoSelectText, ...rest } = this.props;
|
||||
const editorClass = cs('form-control editor edit-text', className);
|
||||
return (
|
||||
<input
|
||||
@@ -36,10 +38,14 @@ TextEditor.propTypes = {
|
||||
defaultValue: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.number
|
||||
])
|
||||
]),
|
||||
autoSelectText: PropTypes.bool,
|
||||
didMount: PropTypes.func
|
||||
};
|
||||
TextEditor.defaultProps = {
|
||||
className: null,
|
||||
defaultValue: ''
|
||||
defaultValue: '',
|
||||
autoSelectText: false,
|
||||
didMount: undefined
|
||||
};
|
||||
export default TextEditor;
|
||||
|
||||
@@ -10,9 +10,11 @@ class TextAreaEditor extends Component {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
const { defaultValue } = this.props;
|
||||
const { defaultValue, didMount, autoSelectText } = this.props;
|
||||
this.text.value = defaultValue;
|
||||
this.text.focus();
|
||||
if (autoSelectText) this.text.select();
|
||||
if (didMount) didMount();
|
||||
}
|
||||
|
||||
getValue() {
|
||||
@@ -27,7 +29,7 @@ class TextAreaEditor extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { defaultValue, className, ...rest } = this.props;
|
||||
const { defaultValue, didMount, className, autoSelectText, ...rest } = this.props;
|
||||
const editorClass = cs('form-control editor edit-textarea', className);
|
||||
return (
|
||||
<textarea
|
||||
@@ -50,11 +52,15 @@ TextAreaEditor.propTypes = {
|
||||
PropTypes.string,
|
||||
PropTypes.number
|
||||
]),
|
||||
onKeyDown: PropTypes.func
|
||||
onKeyDown: PropTypes.func,
|
||||
autoSelectText: PropTypes.bool,
|
||||
didMount: PropTypes.func
|
||||
};
|
||||
TextAreaEditor.defaultProps = {
|
||||
className: '',
|
||||
defaultValue: '',
|
||||
onKeyDown: undefined
|
||||
autoSelectText: false,
|
||||
onKeyDown: undefined,
|
||||
didMount: undefined
|
||||
};
|
||||
export default TextAreaEditor;
|
||||
|
||||
182
packages/react-bootstrap-table2-example/examples/basic/exposed-function.js
vendored
Normal file
182
packages/react-bootstrap-table2-example/examples/basic/exposed-function.js
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
/* eslint no-return-assign: 0 */
|
||||
/* eslint no-console: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsGenerator(63);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
sort: true
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
sort: true,
|
||||
filter: textFilter()
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price',
|
||||
sort: true,
|
||||
filter: textFilter()
|
||||
}];
|
||||
|
||||
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'
|
||||
}];
|
||||
|
||||
class ExposedFunctionTable extends React.Component {
|
||||
handleGetCurrentData = () => {
|
||||
console.log(this.node.table.props.data);
|
||||
}
|
||||
|
||||
handleGetSelectedData = () => {
|
||||
console.log(this.node.selectionContext.state.selected);
|
||||
}
|
||||
|
||||
handleGetExpandedData = () => {
|
||||
console.log(this.node.rowExpandContext.state.expanded);
|
||||
}
|
||||
|
||||
handleGetCurrentPage = () => {
|
||||
console.log(this.node.paginationContext.currPage);
|
||||
}
|
||||
|
||||
handleGetCurrentSizePerPage = () => {
|
||||
console.log(this.node.paginationContext.currSizePerPage);
|
||||
}
|
||||
|
||||
handleGetCurrentSortColumn = () => {
|
||||
console.log(this.node.sortContext.state.sortColumn);
|
||||
}
|
||||
|
||||
handleGetCurrentSortOrder = () => {
|
||||
console.log(this.node.sortContext.state.sortOrder);
|
||||
}
|
||||
|
||||
handleGetCurrentFilter = () => {
|
||||
console.log(this.node.filterContext.currFilters);
|
||||
}
|
||||
|
||||
render() {
|
||||
const expandRow = {
|
||||
renderer: row => (
|
||||
<div>
|
||||
<p>.....</p>
|
||||
<p>You can render anything here, also you can add additional data on every row object</p>
|
||||
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||
</div>
|
||||
),
|
||||
showExpandColumn: true
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentData }>Get Current Display Rows</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetSelectedData }>Get Current Selected Rows</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetExpandedData }>Get Current Expanded Rows</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentPage }>Get Current Page</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentSizePerPage }>Get Current Size Per Page</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentSortColumn }>Get Current Sort Column</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentSortOrder }>Get Current Sort Order</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentFilter }>Get Current Filter Information</button>
|
||||
<BootstrapTable
|
||||
ref={ n => this.node = n }
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
pagination={ paginationFactory() }
|
||||
selectRow={ { mode: 'checkbox', clickToSelect: true } }
|
||||
expandRow={ expandRow }
|
||||
/>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
export default class ExposedFunctionTable extends React.Component {
|
||||
handleGetCurrentData = () => {
|
||||
console.log(this.node.table.props.data);
|
||||
}
|
||||
|
||||
handleGetSelectedData = () => {
|
||||
console.log(this.node.selectionContext.state.selected);
|
||||
}
|
||||
|
||||
handleGetExpandedData = () => {
|
||||
console.log(this.node.rowExpandContext.state.expanded);
|
||||
}
|
||||
|
||||
handleGetCurrentPage = () => {
|
||||
console.log(this.node.paginationContext.currPage);
|
||||
}
|
||||
|
||||
handleGetCurrentSizePerPage = () => {
|
||||
console.log(this.node.paginationContext.currSizePerPage);
|
||||
}
|
||||
|
||||
handleGetCurrentSortColumn = () => {
|
||||
console.log(this.node.sortContext.state.sortColumn);
|
||||
}
|
||||
|
||||
handleGetCurrentSortOrder = () => {
|
||||
console.log(this.node.sortContext.state.sortOrder);
|
||||
}
|
||||
|
||||
handleGetCurrentFilter = () => {
|
||||
console.log(this.node.filterContext.currFilters);
|
||||
}
|
||||
|
||||
render() {
|
||||
const expandRow = {
|
||||
renderer: row => (
|
||||
<div>
|
||||
<p>{ `This Expand row is belong to rowKey ${row.id}` }</p>
|
||||
<p>You can render anything here, also you can add additional data on every row object</p>
|
||||
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||
</div>
|
||||
),
|
||||
showExpandColumn: true
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentData }>Get Current Display Rows</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetSelectedData }>Get Current Selected Rows</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetExpandedData }>Get Current Expanded Rows</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentPage }>Get Current Page</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentSizePerPage }>Get Current Size Per Page</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentSortColumn }>Get Current Sort Column</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentSortOrder }>Get Current Sort Order</button>
|
||||
<button className="btn btn-default" onClick={ this.handleGetCurrentFilter }>Get Current Filter Information</button>
|
||||
<BootstrapTable
|
||||
ref={ n => this.node = n }
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
filter={ filterFactory() }
|
||||
pagination={ paginationFactory() }
|
||||
selectRow={ { mode: 'checkbox', clickToSelect: true } }
|
||||
expandRow={ expandRow }
|
||||
/>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
78
packages/react-bootstrap-table2-example/examples/cell-edit/auto-select-text-input-table.js
vendored
Normal file
78
packages/react-bootstrap-table2-example/examples/cell-edit/auto-select-text-input-table.js
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
/* eslint react/prefer-stateless-function: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
|
||||
import Code from 'components/common/code-block';
|
||||
import { jobsGenerator } from 'utils/common';
|
||||
|
||||
const jobs = jobsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Job ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Job Name'
|
||||
}, {
|
||||
dataField: 'owner',
|
||||
text: 'Job Owner'
|
||||
}, {
|
||||
dataField: 'type',
|
||||
text: 'Job Type',
|
||||
editor: {
|
||||
type: Type.TEXTAREA
|
||||
}
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import cellEditFactory, { Type } from 'react-bootstrap-table2-editor';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Job ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Job Name'
|
||||
}, {
|
||||
dataField: 'owner',
|
||||
text: 'Job Owner'
|
||||
}, {
|
||||
dataField: 'type',
|
||||
text: 'Job Type',
|
||||
editor: {
|
||||
type: Type.TEXTAREA
|
||||
}
|
||||
}];
|
||||
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ jobs }
|
||||
columns={ columns }
|
||||
cellEdit={
|
||||
cellEditFactory({
|
||||
mode: 'click',
|
||||
autoSelectText: true
|
||||
})
|
||||
}
|
||||
/>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<h3>Auto Select Text Input Field When Editing</h3>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ jobs }
|
||||
columns={ columns }
|
||||
cellEdit={
|
||||
cellEditFactory({
|
||||
mode: 'click',
|
||||
autoSelectText: true
|
||||
})
|
||||
}
|
||||
/>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
@@ -41,6 +41,7 @@ const columns = [{
|
||||
columns={ columns }
|
||||
cellEdit={ cellEditFactory({
|
||||
mode: 'click',
|
||||
onStartEdit: (row, column, rowIndex, columnIndex) => { console.log('start to edit!!!'); },
|
||||
beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
|
||||
afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
|
||||
}) }
|
||||
@@ -55,6 +56,7 @@ export default () => (
|
||||
columns={ columns }
|
||||
cellEdit={ cellEditFactory({
|
||||
mode: 'click',
|
||||
onStartEdit: (row, column, rowIndex, columnIndex) => { console.log('Start to edit!!!'); },
|
||||
beforeSaveCell: (oldValue, newValue, row, column) => { console.log('Before Saving Cell!!'); },
|
||||
afterSaveCell: (oldValue, newValue, row, column) => { console.log('After Saving Cell!!'); }
|
||||
}) }
|
||||
|
||||
@@ -52,7 +52,7 @@ const columns = [{
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<h3>Dropdown Editor</h3>
|
||||
<h3>Checkbox Editor</h3>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ todos }
|
||||
|
||||
@@ -118,7 +118,7 @@ const columns = [{
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<h3>Dropdown Editor</h3>
|
||||
<h3>Custom Editor</h3>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
|
||||
@@ -65,7 +65,7 @@ const columns = [{
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<h3>Dropdown Editor</h3>
|
||||
<h3>Date Editor</h3>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ stocks }
|
||||
|
||||
@@ -56,7 +56,7 @@ const columns = [{
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<h3>Dropdown Editor</h3>
|
||||
<h3>Textarea Editor</h3>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ jobs }
|
||||
|
||||
221
packages/react-bootstrap-table2-example/examples/columns/dummy-column-table.js
vendored
Normal file
221
packages/react-bootstrap-table2-example/examples/columns/dummy-column-table.js
vendored
Normal file
@@ -0,0 +1,221 @@
|
||||
/* eslint jsx-a11y/label-has-for: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
|
||||
|
||||
const products = [
|
||||
{ id: 12, name: 'Item 12', price: 12.5, inStock: false },
|
||||
{ id: 13, name: 'Item 13', price: 13.5, inStock: true },
|
||||
{ id: 14, name: 'Item 14', price: 14.5, inStock: true }
|
||||
];
|
||||
|
||||
const columns = [
|
||||
{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
},
|
||||
{
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
},
|
||||
{
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
},
|
||||
{
|
||||
dataField: 'inStock',
|
||||
text: 'In Stock',
|
||||
formatter: (cellContent, row) => (
|
||||
<div className="checkbox disabled">
|
||||
<label>
|
||||
<input type="checkbox" checked={ row.inStock } disabled />
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
dataField: 'df1',
|
||||
isDummyField: true,
|
||||
text: 'Action 1',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
dataField: 'df2',
|
||||
isDummyField: true,
|
||||
text: 'Action 2',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
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'
|
||||
},
|
||||
{
|
||||
dataField: 'inStock',
|
||||
text: 'In Stock',
|
||||
formatter: (cellContent, row) => (
|
||||
<div className="checkbox disabled">
|
||||
<label>
|
||||
<input type="checkbox" checked={ row.inStock } disabled />
|
||||
</label>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
dataField: 'df1',
|
||||
isDummyField: true,
|
||||
text: 'Action 1',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
},
|
||||
{
|
||||
dataField: 'df2',
|
||||
isDummyField: true,
|
||||
text: 'Action 2',
|
||||
formatter: (cellContent, row) => {
|
||||
if (row.inStock) {
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-success"> Available</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<h5>
|
||||
<span className="label label-danger"> Backordered</span>
|
||||
</h5>
|
||||
);
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
class ProductList extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { products };
|
||||
}
|
||||
|
||||
toggleInStock = () => {
|
||||
let newProducts = [...this.state.products];
|
||||
newProducts = newProducts.map((d) => {
|
||||
if (d.id === 13) {
|
||||
return {
|
||||
...d,
|
||||
inStock: !d.inStock
|
||||
};
|
||||
}
|
||||
return d;
|
||||
});
|
||||
this.setState(curr => ({ ...curr, products: newProducts }));
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<h1 className="h2">Products</h1>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ this.state.products }
|
||||
columns={ columns }
|
||||
/>
|
||||
<button onClick={ this.toggleInStock } className="btn btn-primary">
|
||||
Toggle item 13 stock status
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
class ProductList extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = { products };
|
||||
}
|
||||
|
||||
toggleInStock = () => {
|
||||
let newProducts = [...this.state.products];
|
||||
newProducts = newProducts.map((d) => {
|
||||
if (d.id === 13) {
|
||||
return {
|
||||
...d,
|
||||
inStock: !d.inStock
|
||||
};
|
||||
}
|
||||
return d;
|
||||
});
|
||||
this.setState(curr => ({ ...curr, products: newProducts }));
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<h3>Action 1 and Action 2 are dummy column</h3>
|
||||
<button onClick={ this.toggleInStock } className="btn btn-primary">
|
||||
Toggle item 13 stock status
|
||||
</button>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ this.state.products }
|
||||
columns={ columns }
|
||||
/>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default ProductList;
|
||||
98
packages/react-bootstrap-table2-example/examples/csv/export-custom-data.js
vendored
Normal file
98
packages/react-bootstrap-table2-example/examples/csv/export-custom-data.js
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider from 'react-bootstrap-table2-toolkit';
|
||||
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 sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider from 'react-bootstrap-table2-toolkit';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const MyExportCSV = (props) => {
|
||||
const handleClick = () => {
|
||||
props.onExport();
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<button className="btn btn-success" onClick={ handleClick }>Export to CSV</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
exportCSV
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<BootstrapTable { ...props.baseProps } />
|
||||
<hr />
|
||||
<MyExportCSV { ...props.csvProps } />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
const MyExportCSV = (props) => {
|
||||
const handleClick = () => {
|
||||
// passing my custom data
|
||||
props.onExport(products.filter(r => r.id > 2));
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<button className="btn btn-success" onClick={ handleClick }>Only export Product ID bigger than 2</button>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
exportCSV
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<BootstrapTable { ...props.baseProps } />
|
||||
<hr />
|
||||
<MyExportCSV { ...props.csvProps } />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
140
packages/react-bootstrap-table2-example/examples/csv/export-only-selected.js
vendored
Normal file
140
packages/react-bootstrap-table2-example/examples/csv/export-only-selected.js
vendored
Normal file
@@ -0,0 +1,140 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const { ExportCSVButton } = CSVExport;
|
||||
const products1 = productsGenerator(15);
|
||||
const products2 = productsGenerator(15);
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { CSVExport } from 'react-bootstrap-table2-toolkit';
|
||||
|
||||
const { ExportCSVButton } = CSVExport;
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
clickToSelect: true
|
||||
};
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products1 }
|
||||
columns={ columns }
|
||||
exportCSV={ { onlyExportSelection: true, exportAll: true } }
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
selectRow={ selectRow }
|
||||
pagination={ paginationFactory() }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products2 }
|
||||
columns={ columns }
|
||||
exportCSV={ { onlyExportSelection: true, exportAll: false } }
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
selectRow={ selectRow }
|
||||
pagination={ paginationFactory() }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
const selectRow = {
|
||||
mode: 'checkbox',
|
||||
clickToSelect: true
|
||||
};
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<h3>Export all selected row</h3>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products1 }
|
||||
columns={ columns }
|
||||
exportCSV={ { onlyExportSelection: true, exportAll: true } }
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
selectRow={ selectRow }
|
||||
pagination={ paginationFactory() }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<h3>Export all selected rows in currect visible rows</h3>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products2 }
|
||||
columns={ columns }
|
||||
exportCSV={ { onlyExportSelection: true, exportAll: false } }
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
selectRow={ selectRow }
|
||||
pagination={ paginationFactory() }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
73
packages/react-bootstrap-table2-example/examples/row-expand/expand-only-one.js
vendored
Normal file
73
packages/react-bootstrap-table2-example/examples/row-expand/expand-only-one.js
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsExpandRowsGenerator } from 'utils/common';
|
||||
|
||||
const products = productsExpandRowsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const expandRow = {
|
||||
onlyOneExpanding: true,
|
||||
renderer: row => (
|
||||
<div>
|
||||
<p>{ `This Expand row is belong to rowKey ${row.id}` }</p>
|
||||
<p>You can render anything here, also you can add additional data on every row object</p>
|
||||
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
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 expandRow = {
|
||||
renderer: row => (
|
||||
<div>
|
||||
<p>{ \`This Expand row is belong to rowKey $\{row.id}\` }</p>
|
||||
<p>You can render anything here, also you can add additional data on every row object</p>
|
||||
<p>expandRow.renderer callback will pass the origin row object to you</p>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
<BootstrapTable
|
||||
keyField='id'
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
expandRow={ expandRow }
|
||||
/>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
expandRow={ expandRow }
|
||||
/>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
59
packages/react-bootstrap-table2-example/examples/row-selection/hide-select-all.js
vendored
Normal file
59
packages/react-bootstrap-table2-example/examples/row-selection/hide-select-all.js
vendored
Normal file
@@ -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,
|
||||
hideSelectAll: true
|
||||
};
|
||||
|
||||
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,
|
||||
hideSelectAll: true
|
||||
};
|
||||
|
||||
<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>
|
||||
);
|
||||
83
packages/react-bootstrap-table2-example/examples/search/default-search.js
vendored
Normal file
83
packages/react-bootstrap-table2-example/examples/search/default-search.js
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/* eslint react/prop-types: 0 */
|
||||
import React from 'react';
|
||||
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
|
||||
import Code from 'components/common/code-block';
|
||||
import { productsGenerator } from 'utils/common';
|
||||
|
||||
const { SearchBar } = Search;
|
||||
const products = productsGenerator();
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
|
||||
|
||||
const { SearchBar } = Search;
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID'
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name'
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
search={ { defaultSearch: '2101' } }
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<h3>Input something at below input field:</h3>
|
||||
<SearchBar { ...props.searchProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
search={ { defaultSearch: '2101' } }
|
||||
>
|
||||
{
|
||||
props => (
|
||||
<div>
|
||||
<h3>Input something at below input field:</h3>
|
||||
<SearchBar { ...props.searchProps } />
|
||||
<hr />
|
||||
<BootstrapTable
|
||||
{ ...props.baseProps }
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</ToolkitProvider>
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
59
packages/react-bootstrap-table2-example/examples/sort/custom-sort-caret.js
vendored
Normal file
59
packages/react-bootstrap-table2-example/examples/sort/custom-sort-caret.js
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/* eslint no-unused-vars: 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',
|
||||
sort: true
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
sort: true,
|
||||
sortCaret: (order, column) => {
|
||||
if (!order) return (<span> Desc/Asc</span>);
|
||||
else if (order === 'asc') return (<span> Desc/<font color="red">Asc</font></span>);
|
||||
else if (order === 'desc') return (<span> <font color="red">Desc</font>/Asc</span>);
|
||||
return null;
|
||||
}
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
const sourceCode = `\
|
||||
import BootstrapTable from 'react-bootstrap-table-next';
|
||||
|
||||
const columns = [{
|
||||
dataField: 'id',
|
||||
text: 'Product ID',
|
||||
sort: true
|
||||
}, {
|
||||
dataField: 'name',
|
||||
text: 'Product Name',
|
||||
sort: true,
|
||||
sortCaret: (order, column) => {
|
||||
if (!order) return (<span> Desc/Asc</span>);
|
||||
else if (order === 'asc') return (<span> Desc/<font color="red">Asc</font></span>);
|
||||
else if (order === 'desc') return (<span> <font color="red">Desc</font>/Asc</span>);
|
||||
return null;
|
||||
}
|
||||
}, {
|
||||
dataField: 'price',
|
||||
text: 'Product Price'
|
||||
}];
|
||||
|
||||
<BootstrapTable keyField='id' data={ products } columns={ columns } />
|
||||
`;
|
||||
|
||||
export default () => (
|
||||
<div>
|
||||
<BootstrapTable keyField="id" data={ products } columns={ columns } />
|
||||
<Code>{ sourceCode }</Code>
|
||||
</div>
|
||||
);
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-example",
|
||||
"version": "1.0.3",
|
||||
"version": "1.0.6",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"private": true,
|
||||
@@ -15,7 +15,7 @@
|
||||
"peerDependencies": {
|
||||
"prop-types": "^15.0.0",
|
||||
"react": "^16.3.0",
|
||||
"react-dom": "^116.3.0"
|
||||
"react-dom": "^16.3.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@storybook/addon-console": "^1.0.0",
|
||||
|
||||
@@ -13,6 +13,7 @@ import NoDataTable from 'examples/basic/no-data-table';
|
||||
import CustomizedIdClassesTable from 'examples/basic/customized-id-classes';
|
||||
import CaptionTable from 'examples/basic/caption-table';
|
||||
import LargeTable from 'examples/basic/large-table';
|
||||
import ExposedAPITable from 'examples/basic/exposed-function';
|
||||
|
||||
// bootstrap 4
|
||||
import Bootstrap4DefaultSortTable from 'examples/bootstrap4/sort';
|
||||
@@ -30,6 +31,7 @@ import ColumnTitleTable from 'examples/columns/column-title-table';
|
||||
import ColumnEventTable from 'examples/columns/column-event-table';
|
||||
import ColumnHiddenTable from 'examples/columns/column-hidden-table';
|
||||
import ColumnAttrsTable from 'examples/columns/column-attrs-table';
|
||||
import DummyColumnTable from 'examples/columns/dummy-column-table';
|
||||
|
||||
// work on header columns
|
||||
import HeaderColumnFormatTable from 'examples/header-columns/column-format-table';
|
||||
@@ -82,6 +84,7 @@ import DefaultSortTable from 'examples/sort/default-sort-table';
|
||||
import DefaultSortDirectionTable from 'examples/sort/default-sort-direction';
|
||||
import SortEvents from 'examples/sort/sort-events';
|
||||
import CustomSortTable from 'examples/sort/custom-sort-table';
|
||||
import CustomSortCaretTable from 'examples/sort/custom-sort-caret';
|
||||
import HeaderSortingClassesTable from 'examples/sort/header-sorting-classes';
|
||||
import HeaderSortingStyleTable from 'examples/sort/header-sorting-style';
|
||||
|
||||
@@ -96,6 +99,7 @@ import CellEditHooks from 'examples/cell-edit/cell-edit-hooks-table';
|
||||
import CellEditValidator from 'examples/cell-edit/cell-edit-validator-table';
|
||||
import CellEditStyleTable from 'examples/cell-edit/cell-edit-style-table';
|
||||
import CellEditClassTable from 'examples/cell-edit/cell-edit-class-table';
|
||||
import AutoSelectTextInput from 'examples/cell-edit/auto-select-text-input-table';
|
||||
import EditorStyleTable from 'examples/cell-edit/editor-style-table';
|
||||
import EditorClassTable from 'examples/cell-edit/editor-class-table';
|
||||
import DropdownEditorTable from 'examples/cell-edit/dropdown-editor-table';
|
||||
@@ -114,6 +118,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 HideSelectAllTable from 'examples/row-selection/hide-select-all';
|
||||
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';
|
||||
@@ -125,6 +130,7 @@ import BasicRowExpand from 'examples/row-expand';
|
||||
import RowExpandManagement from 'examples/row-expand/expand-management';
|
||||
import NonExpandableRows from 'examples/row-expand/non-expandable-rows';
|
||||
import ExpandColumn from 'examples/row-expand/expand-column';
|
||||
import ExpandOnlyOne from 'examples/row-expand/expand-only-one';
|
||||
import CustomExpandColumn from 'examples/row-expand/custom-expand-column';
|
||||
import ExpandHooks from 'examples/row-expand/expand-hooks';
|
||||
|
||||
@@ -135,6 +141,7 @@ import CustomPaginationTable from 'examples/pagination/custom-pagination';
|
||||
|
||||
// search
|
||||
import SearchTable from 'examples/search';
|
||||
import DefaultSearch from 'examples/search/default-search';
|
||||
import DefaultCustomSearch from 'examples/search/default-custom-search';
|
||||
import FullyCustomSearch from 'examples/search/fully-custom-search';
|
||||
import SearchFormattedData from 'examples/search/search-formatted';
|
||||
@@ -145,8 +152,10 @@ import ExportCSV from 'examples/csv';
|
||||
import CSVFormatter from 'examples/csv/csv-column-formatter';
|
||||
import CustomCSVHeader from 'examples/csv/custom-csv-header';
|
||||
import HideCSVColumn from 'examples/csv/hide-column';
|
||||
import ExportOnlySelected from 'examples/csv/export-only-selected';
|
||||
import CSVColumnType from 'examples/csv/csv-column-type';
|
||||
import CustomCSVButton from 'examples/csv/custom-csv-button';
|
||||
import ExportCustomData from 'examples/csv/export-custom-data';
|
||||
import CustomCSV from 'examples/csv/custom-csv';
|
||||
|
||||
// loading overlay
|
||||
@@ -182,7 +191,8 @@ storiesOf('Basic Table', module)
|
||||
.add('Indication For Empty Table', () => <NoDataTable />)
|
||||
.add('Customized id and class table', () => <CustomizedIdClassesTable />)
|
||||
.add('Table with caption', () => <CaptionTable />)
|
||||
.add('Large Table', () => <LargeTable />);
|
||||
.add('Large Table', () => <LargeTable />)
|
||||
.add('Exposed API', () => <ExposedAPITable />);
|
||||
|
||||
storiesOf('Bootstrap 4', module)
|
||||
.addDecorator(bootstrapStyle(BOOTSTRAP_VERSION.FOUR))
|
||||
@@ -201,7 +211,8 @@ storiesOf('Work on Columns', module)
|
||||
.add('Column Event', () => <ColumnEventTable />)
|
||||
.add('Customize Column Class', () => <ColumnClassTable />)
|
||||
.add('Customize Column Style', () => <ColumnStyleTable />)
|
||||
.add('Customize Column HTML attribute', () => <ColumnAttrsTable />);
|
||||
.add('Customize Column HTML attribute', () => <ColumnAttrsTable />)
|
||||
.add('Dummy Column', () => <DummyColumnTable />);
|
||||
|
||||
storiesOf('Work on Header Columns', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
@@ -259,6 +270,7 @@ storiesOf('Sort Table', module)
|
||||
.add('Default Sort Direction Table', () => <DefaultSortDirectionTable />)
|
||||
.add('Sort Events', () => <SortEvents />)
|
||||
.add('Custom Sort Fuction', () => <CustomSortTable />)
|
||||
.add('Custom Sort Caret', () => <CustomSortCaretTable />)
|
||||
.add('Custom Classes on Sorting Header Column', () => <HeaderSortingClassesTable />)
|
||||
.add('Custom Style on Sorting Header Column', () => <HeaderSortingStyleTable />);
|
||||
|
||||
@@ -272,6 +284,7 @@ storiesOf('Cell Editing', module)
|
||||
.add('Cell Level Editable', () => <CellLevelEditable />)
|
||||
.add('Rich Hook Functions', () => <CellEditHooks />)
|
||||
.add('Validation', () => <CellEditValidator />)
|
||||
.add('Auto Select Text Input', () => <AutoSelectTextInput />)
|
||||
.add('Custom Cell Style', () => <CellEditStyleTable />)
|
||||
.add('Custom Cell Classes', () => <CellEditClassTable />)
|
||||
.add('Custom Editor Classes', () => <EditorClassTable />)
|
||||
@@ -293,6 +306,7 @@ storiesOf('Row Selection', module)
|
||||
.add('Selection without Data', () => <SelectionNoDataTable />)
|
||||
.add('Selection Style', () => <SelectionStyleTable />)
|
||||
.add('Selection Class', () => <SelectionClassTable />)
|
||||
.add('Hide Select All', () => <HideSelectAllTable />)
|
||||
.add('Custom Selection', () => <CustomSelectionTable />)
|
||||
.add('Selection Background Color', () => <SelectionBgColorTable />)
|
||||
.add('Not Selectabled Rows', () => <NonSelectableRowsTable />)
|
||||
@@ -305,6 +319,7 @@ storiesOf('Row Expand', module)
|
||||
.add('Expand Management', () => <RowExpandManagement />)
|
||||
.add('Non Expandabled Rows', () => <NonExpandableRows />)
|
||||
.add('Expand Indicator', () => <ExpandColumn />)
|
||||
.add('Expand Only One Row at The Same Time', () => <ExpandOnlyOne />)
|
||||
.add('Custom Expand Indicator', () => <CustomExpandColumn />)
|
||||
.add('Expand Hooks', () => <ExpandHooks />);
|
||||
|
||||
@@ -317,6 +332,7 @@ storiesOf('Pagination', module)
|
||||
storiesOf('Table Search', module)
|
||||
.addDecorator(bootstrapStyle())
|
||||
.add('Basic Search Table', () => <SearchTable />)
|
||||
.add('Default Search Table', () => <DefaultSearch />)
|
||||
.add('Default Custom Search', () => <DefaultCustomSearch />)
|
||||
.add('Fully Custom Search', () => <FullyCustomSearch />)
|
||||
.add('Search Fromatted Value', () => <SearchFormattedData />)
|
||||
@@ -328,8 +344,10 @@ storiesOf('Export CSV', module)
|
||||
.add('Format CSV Column', () => <CSVFormatter />)
|
||||
.add('Custom CSV Header', () => <CustomCSVHeader />)
|
||||
.add('Hide CSV Column', () => <HideCSVColumn />)
|
||||
.add('Only Export Selected Rows', () => <ExportOnlySelected />)
|
||||
.add('CSV Column Type', () => <CSVColumnType />)
|
||||
.add('Custom CSV Button', () => <CustomCSVButton />)
|
||||
.add('Export Custom Data', () => <ExportCustomData />)
|
||||
.add('Custom CSV', () => <CustomCSV />);
|
||||
|
||||
storiesOf('EmptyTableOverlay', module)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-paginator",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"description": "it's the pagination addon for react-bootstrap-table2",
|
||||
"main": "./lib/index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -68,6 +68,9 @@ export default (
|
||||
currPage = newPage;
|
||||
needNewState = true;
|
||||
}
|
||||
} else {
|
||||
this.currPage = nextProps.pagination.options.page;
|
||||
this.currSizePerPage = nextProps.pagination.options.sizePerPage;
|
||||
}
|
||||
|
||||
if (needNewState) {
|
||||
|
||||
@@ -160,6 +160,27 @@ describe('PaginationContext', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when remote pagination is enable', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(shallowContext({ ...defaultPagination }, true));
|
||||
instance = wrapper.instance();
|
||||
wrapper.render();
|
||||
nextProps = {
|
||||
data,
|
||||
pagination: { ...defaultPagination, options: { page: 3, sizePerPage: 5 } }
|
||||
};
|
||||
instance.componentWillReceiveProps(nextProps);
|
||||
});
|
||||
|
||||
it('should always set currPage from nextProps.pagination.options.page', () => {
|
||||
expect(instance.currPage).toEqual(nextProps.pagination.options.page);
|
||||
});
|
||||
|
||||
it('should always set currSizePerPage from nextProps.pagination.options.sizePerPage', () => {
|
||||
expect(instance.currSizePerPage).toEqual(nextProps.pagination.options.sizePerPage);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when page is not align', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(shallowContext({
|
||||
|
||||
@@ -63,6 +63,22 @@ const { SearchBar } = Search;
|
||||
|
||||
### Search Options
|
||||
|
||||
#### defaultSearch - [string]
|
||||
Accept a string that will be used for default searching when first time table render.
|
||||
|
||||
```js
|
||||
<ToolkitProvider
|
||||
keyField="id"
|
||||
data={ products }
|
||||
columns={ columns }
|
||||
search={ {
|
||||
defaultSearch: 'search something here'
|
||||
} }
|
||||
>
|
||||
// ...
|
||||
</ToolkitProvider>
|
||||
```
|
||||
|
||||
#### searchFormatted - [bool]
|
||||
If you want to search on the formatted data, you are supposed to enable this props. `react-bootstrap-table2` will check if you define the `column.formatter` when doing search.
|
||||
|
||||
@@ -124,3 +140,6 @@ Default is `true`.
|
||||
|
||||
#### exportAll - [bool]
|
||||
Default is `true`. `false` will only export current data which display on table.
|
||||
|
||||
#### onlyExportSelection - [bool]
|
||||
Default is `false`. `true` will only export the data which is selected.
|
||||
@@ -17,6 +17,7 @@ class ToolkitProvider extends statelessDrcorator(React.Component) {
|
||||
search: PropTypes.oneOfType([
|
||||
PropTypes.bool,
|
||||
PropTypes.shape({
|
||||
defaultSearch: PropTypes.string,
|
||||
searchFormatted: PropTypes.bool
|
||||
})
|
||||
]),
|
||||
@@ -26,7 +27,9 @@ class ToolkitProvider extends statelessDrcorator(React.Component) {
|
||||
fileName: PropTypes.string,
|
||||
separator: PropTypes.string,
|
||||
ignoreHeader: PropTypes.bool,
|
||||
noAutoBOM: PropTypes.bool
|
||||
noAutoBOM: PropTypes.bool,
|
||||
exportAll: PropTypes.bool,
|
||||
onlyExportSelection: PropTypes.bool
|
||||
})
|
||||
])
|
||||
}
|
||||
@@ -40,7 +43,7 @@ class ToolkitProvider extends statelessDrcorator(React.Component) {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
searchText: ''
|
||||
searchText: typeof props.search === 'object' ? (props.search.defaultSearch || '') : ''
|
||||
};
|
||||
this._ = null;
|
||||
this.onSearch = this.onSearch.bind(this);
|
||||
@@ -83,6 +86,7 @@ class ToolkitProvider extends statelessDrcorator(React.Component) {
|
||||
return (
|
||||
<ToolkitContext.Provider value={ {
|
||||
searchProps: {
|
||||
searchText: this.state.searchText,
|
||||
onSearch: this.onSearch
|
||||
},
|
||||
csvProps: {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-toolkit",
|
||||
"version": "1.0.2",
|
||||
"version": "1.1.1",
|
||||
"description": "The toolkit for react-bootstrap-table2",
|
||||
"main": "./lib/index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -11,7 +11,7 @@ const ExportCSVButton = (props) => {
|
||||
return (
|
||||
<button
|
||||
type="button"
|
||||
onClick={ onExport }
|
||||
onClick={ () => onExport() }
|
||||
{ ...rest }
|
||||
>
|
||||
{ children }
|
||||
|
||||
@@ -58,7 +58,7 @@ export const save = (
|
||||
}
|
||||
) => {
|
||||
FileSaver.saveAs(
|
||||
new Blob(['\ufeff', content], { type: 'text/plain;charset=utf-8' }),
|
||||
new Blob([content], { type: 'text/plain;charset=utf-8' }),
|
||||
fileName,
|
||||
noAutoBOM
|
||||
);
|
||||
|
||||
@@ -5,13 +5,14 @@ const csvDefaultOptions = {
|
||||
separator: ',',
|
||||
ignoreHeader: false,
|
||||
noAutoBOM: true,
|
||||
exportAll: true
|
||||
exportAll: true,
|
||||
onlyExportSelection: false
|
||||
};
|
||||
|
||||
export default Base =>
|
||||
class CSVOperation extends Base {
|
||||
handleExportCSV = () => {
|
||||
const { columns, exportCSV } = this.props;
|
||||
handleExportCSV = (source) => {
|
||||
const { columns, exportCSV, keyField } = this.props;
|
||||
const meta = getMetaInfo(columns);
|
||||
const options = exportCSV === true ?
|
||||
csvDefaultOptions :
|
||||
@@ -20,7 +21,19 @@ export default Base =>
|
||||
...exportCSV
|
||||
};
|
||||
|
||||
const data = options.exportAll ? this.props.data : this.getData();
|
||||
// get data for csv export
|
||||
let data;
|
||||
if (typeof source !== 'undefined') {
|
||||
data = source;
|
||||
} else {
|
||||
data = options.exportAll ? this.props.data : this.getData();
|
||||
}
|
||||
|
||||
// filter data
|
||||
if (options.onlyExportSelection) {
|
||||
const selections = this.getSelected();
|
||||
data = data.filter(row => !!selections.find(sel => row[keyField] === sel));
|
||||
}
|
||||
const content = transform(data, meta, this._.get, options);
|
||||
save(content, options);
|
||||
}
|
||||
|
||||
@@ -47,6 +47,7 @@ const SearchBar = ({
|
||||
style={ style }
|
||||
onKeyUp={ () => debounceCallback() }
|
||||
className={ `form-control ${className}` }
|
||||
defaultValue={ searchText }
|
||||
placeholder={ placeholder || SearchBar.defaultProps.placeholder }
|
||||
{ ...rest }
|
||||
/>
|
||||
|
||||
@@ -39,8 +39,10 @@ export default (options = {
|
||||
const { data, columns } = this.props;
|
||||
let { searchText } = this.props;
|
||||
|
||||
if (isRemoteSearch() && this.performRemoteSearch) {
|
||||
if (isRemoteSearch()) {
|
||||
if (this.performRemoteSearch) {
|
||||
handleRemoteSearchChange(searchText);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table-next",
|
||||
"version": "1.1.3",
|
||||
"version": "1.2.1",
|
||||
"description": "Next generation of react-bootstrap-table",
|
||||
"main": "./lib/index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -146,6 +146,7 @@ BootstrapTable.propTypes = {
|
||||
mode: PropTypes.oneOf([Const.ROW_SELECT_SINGLE, Const.ROW_SELECT_MULTIPLE]).isRequired,
|
||||
clickToSelect: PropTypes.bool,
|
||||
clickToEdit: PropTypes.bool,
|
||||
hideSelectAll: PropTypes.bool,
|
||||
onSelect: PropTypes.func,
|
||||
onSelectAll: PropTypes.func,
|
||||
style: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
|
||||
@@ -165,6 +166,7 @@ BootstrapTable.propTypes = {
|
||||
onExpandAll: PropTypes.func,
|
||||
nonExpandable: PropTypes.array,
|
||||
showExpandColumn: PropTypes.bool,
|
||||
onlyOneExpanding: PropTypes.bool,
|
||||
expandColumnRenderer: PropTypes.func,
|
||||
expandHeaderColumnRenderer: PropTypes.func
|
||||
}),
|
||||
|
||||
15
packages/react-bootstrap-table2/src/cell.js
vendored
15
packages/react-bootstrap-table2/src/cell.js
vendored
@@ -11,9 +11,18 @@ class Cell extends Component {
|
||||
}
|
||||
|
||||
shouldComponentUpdate(nextProps) {
|
||||
const shouldUpdate =
|
||||
let shouldUpdate = false;
|
||||
if (nextProps.column.isDummyField) {
|
||||
shouldUpdate = !_.isEqual(this.props.row, nextProps.row);
|
||||
} else {
|
||||
shouldUpdate =
|
||||
_.get(this.props.row, this.props.column.dataField)
|
||||
!== _.get(nextProps.row, nextProps.column.dataField) ||
|
||||
!== _.get(nextProps.row, nextProps.column.dataField);
|
||||
}
|
||||
|
||||
if (shouldUpdate) return true;
|
||||
|
||||
shouldUpdate =
|
||||
this.props.column.hidden !== nextProps.column.hidden ||
|
||||
this.props.rowIndex !== nextProps.rowIndex ||
|
||||
this.props.columnIndex !== nextProps.columnIndex ||
|
||||
@@ -64,7 +73,7 @@ class Cell extends Component {
|
||||
formatExtraData
|
||||
} = column;
|
||||
const attrs = { ...rest };
|
||||
let content = _.get(row, dataField);
|
||||
let content = column.isDummyField ? null : _.get(row, dataField);
|
||||
|
||||
if (formatter) {
|
||||
content = column.formatter(content, row, rowIndex, formatExtraData);
|
||||
|
||||
@@ -66,6 +66,7 @@ const withContext = Base =>
|
||||
selectionProps
|
||||
) => (
|
||||
<Base
|
||||
ref={ n => this.table = n }
|
||||
{ ...this.props }
|
||||
{ ...selectionProps }
|
||||
{ ...sortProps }
|
||||
@@ -91,6 +92,7 @@ const withContext = Base =>
|
||||
) => (
|
||||
<this.SelectionContext.Provider
|
||||
{ ...baseProps }
|
||||
ref={ n => this.selectionContext = n }
|
||||
selectRow={ this.props.selectRow }
|
||||
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
|
||||
>
|
||||
@@ -123,6 +125,7 @@ const withContext = Base =>
|
||||
) => (
|
||||
<this.RowExpandContext.Provider
|
||||
{ ...baseProps }
|
||||
ref={ n => this.rowExpandContext = n }
|
||||
expandRow={ this.props.expandRow }
|
||||
data={ rootProps.getData(filterProps, searchProps, sortProps, paginationProps) }
|
||||
>
|
||||
@@ -269,8 +272,9 @@ const withContext = Base =>
|
||||
}
|
||||
|
||||
render() {
|
||||
const { keyField, columns, bootstrap4 } = this.props;
|
||||
const { keyField, columns, bootstrap4, registerExposedAPI } = this.props;
|
||||
const baseProps = { keyField, columns };
|
||||
if (registerExposedAPI) baseProps.registerExposedAPI = registerExposedAPI;
|
||||
|
||||
let base = this.renderBase();
|
||||
|
||||
|
||||
@@ -25,12 +25,13 @@ export default (
|
||||
}
|
||||
|
||||
handleRowExpand = (rowKey, expanded, rowIndex, e) => {
|
||||
const { data, keyField, expandRow: { onExpand } } = this.props;
|
||||
const { data, keyField, expandRow: { onExpand, onlyOneExpanding } } = this.props;
|
||||
|
||||
let currExpanded = [...this.state.expanded];
|
||||
|
||||
if (expanded) {
|
||||
currExpanded.push(rowKey);
|
||||
if (onlyOneExpanding) currExpanded = [rowKey];
|
||||
else currExpanded.push(rowKey);
|
||||
} else {
|
||||
currExpanded = currExpanded.filter(value => value !== rowKey);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,14 @@ export default (
|
||||
keyField: PropTypes.string.isRequired
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
if (props.registerExposedAPI) {
|
||||
const getSelected = () => this.getSelected();
|
||||
props.registerExposedAPI(getSelected);
|
||||
}
|
||||
}
|
||||
|
||||
state = { selected: (this.props.selectRow && this.props.selectRow.selected) || [] };
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
@@ -25,6 +33,11 @@ export default (
|
||||
}
|
||||
}
|
||||
|
||||
// exposed API
|
||||
getSelected() {
|
||||
return this.state.selected;
|
||||
}
|
||||
|
||||
handleRowSelect = (rowKey, checked, rowIndex, e) => {
|
||||
const { data, keyField, selectRow: { mode, onSelect } } = this.props;
|
||||
const { ROW_SELECT_SINGLE } = Const;
|
||||
@@ -67,7 +80,15 @@ export default (
|
||||
}
|
||||
|
||||
if (onSelectAll) {
|
||||
onSelectAll(!isUnSelect, dataOperator.getSelectedRows(data, keyField, currSelected), e);
|
||||
onSelectAll(
|
||||
!isUnSelect,
|
||||
dataOperator.getSelectedRows(
|
||||
data,
|
||||
keyField,
|
||||
isUnSelect ? this.state.selected : currSelected
|
||||
),
|
||||
e
|
||||
);
|
||||
}
|
||||
|
||||
this.setState(() => ({ selected: currSelected }));
|
||||
|
||||
@@ -24,6 +24,7 @@ const HeaderCell = (props) => {
|
||||
const {
|
||||
text,
|
||||
sort,
|
||||
sortCaret,
|
||||
filter,
|
||||
filterRenderer,
|
||||
headerTitle,
|
||||
@@ -49,6 +50,7 @@ const HeaderCell = (props) => {
|
||||
|
||||
if (headerStyle) {
|
||||
cellStyle = _.isFunction(headerStyle) ? headerStyle(column, index) : headerStyle;
|
||||
cellStyle = cellStyle ? { ...cellStyle } : cellStyle;
|
||||
}
|
||||
|
||||
if (headerTitle) {
|
||||
@@ -68,7 +70,7 @@ const HeaderCell = (props) => {
|
||||
cellAttrs.className = cs(cellAttrs.className, 'sortable');
|
||||
|
||||
if (sorting) {
|
||||
sortSymbol = <SortCaret order={ sortOrder } />;
|
||||
sortSymbol = sortCaret ? sortCaret(sortOrder, column) : <SortCaret order={ sortOrder } />;
|
||||
|
||||
// append customized classes or style if table was sorting based on the current column.
|
||||
cellClasses = cs(
|
||||
@@ -85,7 +87,7 @@ const HeaderCell = (props) => {
|
||||
: headerSortingStyle
|
||||
};
|
||||
} else {
|
||||
sortSymbol = <SortSymbol />;
|
||||
sortSymbol = sortCaret ? sortCaret(undefined, column) : <SortSymbol />;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +116,7 @@ HeaderCell.propTypes = {
|
||||
column: PropTypes.shape({
|
||||
dataField: PropTypes.string.isRequired,
|
||||
text: PropTypes.string.isRequired,
|
||||
isDummyField: PropTypes.bool,
|
||||
hidden: PropTypes.bool,
|
||||
headerFormatter: PropTypes.func,
|
||||
formatter: PropTypes.func,
|
||||
@@ -149,6 +152,7 @@ HeaderCell.propTypes = {
|
||||
onSort: PropTypes.func,
|
||||
sorting: PropTypes.bool,
|
||||
sortOrder: PropTypes.oneOf([Const.SORT_ASC, Const.SORT_DESC]),
|
||||
sortCaret: PropTypes.func,
|
||||
isLastSorting: PropTypes.bool,
|
||||
onFilter: PropTypes.func,
|
||||
onExternalFilter: PropTypes.func
|
||||
|
||||
@@ -5,7 +5,8 @@ const events = [
|
||||
'onClick',
|
||||
'onDoubleClick',
|
||||
'onMouseEnter',
|
||||
'onMouseLeave'
|
||||
'onMouseLeave',
|
||||
'onContextMenu'
|
||||
];
|
||||
|
||||
export default ExtendBase =>
|
||||
|
||||
@@ -27,6 +27,7 @@ export default class SelectionHeaderCell extends Component {
|
||||
mode: PropTypes.string.isRequired,
|
||||
checkedStatus: PropTypes.string,
|
||||
onAllRowsSelect: PropTypes.func,
|
||||
hideSelectAll: PropTypes.bool,
|
||||
selectionHeaderRenderer: PropTypes.func
|
||||
}
|
||||
|
||||
@@ -63,7 +64,10 @@ export default class SelectionHeaderCell extends Component {
|
||||
CHECKBOX_STATUS_CHECKED, CHECKBOX_STATUS_INDETERMINATE, ROW_SELECT_MULTIPLE
|
||||
} = Const;
|
||||
|
||||
const { mode, checkedStatus, selectionHeaderRenderer } = this.props;
|
||||
const { mode, checkedStatus, selectionHeaderRenderer, hideSelectAll } = this.props;
|
||||
if (hideSelectAll) {
|
||||
return <th data-row-selection />;
|
||||
}
|
||||
|
||||
const checked = checkedStatus === CHECKBOX_STATUS_CHECKED;
|
||||
|
||||
|
||||
@@ -177,6 +177,7 @@ describe('Cell', () => {
|
||||
let props;
|
||||
let nextProps;
|
||||
|
||||
describe('if column.isDummyField is false', () => {
|
||||
describe('when content is change', () => {
|
||||
const column = { dataField: 'name', text: 'Product Name' };
|
||||
beforeEach(() => {
|
||||
@@ -195,6 +196,28 @@ describe('Cell', () => {
|
||||
expect(wrapper.instance().shouldComponentUpdate(nextProps)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('if column.isDummyField is true', () => {
|
||||
describe('when content is change', () => {
|
||||
const column = { dataField: '', text: 'Product Name', isDummyField: true };
|
||||
beforeEach(() => {
|
||||
props = {
|
||||
row,
|
||||
columnIndex: 1,
|
||||
rowIndex: 1,
|
||||
column
|
||||
};
|
||||
wrapper = shallow(
|
||||
<Cell { ...props } />);
|
||||
});
|
||||
|
||||
it('should return true', () => {
|
||||
nextProps = { ...props, row: { id: 1, name: 'CDE', test: 'This is new Field' } };
|
||||
expect(wrapper.instance().shouldComponentUpdate(nextProps)).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when column.hidden is change', () => {
|
||||
const column = { dataField: 'name', text: 'Product Name' };
|
||||
|
||||
@@ -220,21 +220,6 @@ describe('DataContext', () => {
|
||||
it('should set state.selected correctly', () => {
|
||||
expect(wrapper.state('selected')).toEqual(data.map(d => d[keyField]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('when isUnSelect argument is true', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(shallowContext({
|
||||
...defaultSelectRow,
|
||||
selected: data.map(d => d[keyField])
|
||||
}));
|
||||
wrapper.instance().handleAllRowsSelect(e, true);
|
||||
});
|
||||
|
||||
it('should set state.selected correctly', () => {
|
||||
expect(wrapper.state('selected')).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when selectRow.onSelectAll is defined', () => {
|
||||
const onSelectAll = jest.fn();
|
||||
@@ -255,4 +240,39 @@ describe('DataContext', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when isUnSelect argument is true', () => {
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(shallowContext({
|
||||
...defaultSelectRow,
|
||||
selected: data.map(d => d[keyField])
|
||||
}));
|
||||
wrapper.instance().handleAllRowsSelect(e, true);
|
||||
});
|
||||
|
||||
it('should set state.selected correctly', () => {
|
||||
expect(wrapper.state('selected')).toEqual([]);
|
||||
});
|
||||
|
||||
describe('when selectRow.onSelectAll is defined', () => {
|
||||
const onSelectAll = jest.fn();
|
||||
beforeEach(() => {
|
||||
wrapper = shallow(shallowContext({
|
||||
...defaultSelectRow,
|
||||
selected: data.map(d => d[keyField]),
|
||||
onSelectAll
|
||||
}));
|
||||
wrapper.instance().handleAllRowsSelect(e, true);
|
||||
});
|
||||
|
||||
it('should call selectRow.onSelectAll correctly', () => {
|
||||
expect(onSelectAll).toHaveBeenCalledWith(
|
||||
false,
|
||||
dataOperator.getSelectedRows(data, keyField, data.map(d => d[keyField])),
|
||||
e
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -403,6 +403,24 @@ describe('HeaderCell', () => {
|
||||
it('header should render SortSymbol as default', () => {
|
||||
expect(wrapper.find(SortSymbol).length).toBe(1);
|
||||
});
|
||||
|
||||
describe('when sortCaret is defined ', () => {
|
||||
beforeEach(() => {
|
||||
column = { ...column, sortCaret: jest.fn() };
|
||||
wrapper = shallow(
|
||||
<HeaderCell column={ column } index={ index } onSort={ onSortCallBack } />
|
||||
);
|
||||
});
|
||||
|
||||
it('header should not render SortSymbol', () => {
|
||||
expect(wrapper.find(SortSymbol).length).toBe(0);
|
||||
});
|
||||
|
||||
it('should call column.sortCaret correctly', () => {
|
||||
expect(column.sortCaret).toHaveBeenCalledTimes(1);
|
||||
expect(column.sortCaret).toHaveBeenCalledWith(undefined, column);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('and sorting prop is true', () => {
|
||||
@@ -420,6 +438,30 @@ describe('HeaderCell', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('when sortCaret is defined ', () => {
|
||||
beforeEach(() => {
|
||||
column = { ...column, sortCaret: jest.fn() };
|
||||
wrapper = shallow(
|
||||
<HeaderCell
|
||||
column={ column }
|
||||
index={ index }
|
||||
onSort={ onSortCallBack }
|
||||
sortOrder={ Const.SORT_ASC }
|
||||
sorting
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
it('header should not render SortSymbol', () => {
|
||||
expect(wrapper.find(SortSymbol).length).toBe(0);
|
||||
});
|
||||
|
||||
it('should call column.sortCaret correctly', () => {
|
||||
expect(column.sortCaret).toHaveBeenCalledTimes(1);
|
||||
expect(column.sortCaret).toHaveBeenCalledWith(Const.SORT_ASC, column);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when headerSortingClasses is defined ', () => {
|
||||
const classes = 'foo';
|
||||
const order = Const.SORT_DESC;
|
||||
|
||||
@@ -104,6 +104,22 @@ describe('<SelectionHeaderCell />', () => {
|
||||
});
|
||||
|
||||
describe('render', () => {
|
||||
describe('when props.hideSelectAll is true', () => {
|
||||
beforeEach(() => {
|
||||
const checkedStatus = Const.CHECKBOX_STATUS_CHECKED;
|
||||
|
||||
wrapper = shallow(
|
||||
<SelectionHeaderCell mode="checkbox" checkedStatus={ checkedStatus } hideSelectAll />
|
||||
);
|
||||
});
|
||||
|
||||
it('should render empty th element', () => {
|
||||
expect(wrapper.find('th').length).toBe(1);
|
||||
expect(wrapper.find('th[data-row-selection]').length).toBe(1);
|
||||
expect(wrapper.find(CheckBox).length).toBe(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when props.mode is radio', () => {
|
||||
beforeEach(() => {
|
||||
const checkedStatus = Const.CHECKBOX_STATUS_CHECKED;
|
||||
|
||||
Reference in New Issue
Block a user