Compare commits

..

16 Commits

Author SHA1 Message Date
AllenFang
72f7333a34 Publish
- react-bootstrap-table2-editor@1.3.0
 - react-bootstrap-table2-example@1.0.28
 - react-bootstrap-table-next@3.1.6
2019-07-22 20:14:49 +08:00
Allen
64c113da26 Merge pull request #1023 from react-bootstrap-table/develop
20190721 release
2019-07-22 20:08:57 +08:00
AllenFang
db22bb9adb fix #1015 2019-07-21 16:52:28 +08:00
AllenFang
d7e1f1dfd0 fix #1014 2019-07-21 16:45:11 +08:00
AllenFang
c277c8139e fix #1007 2019-07-21 16:07:26 +08:00
AllenFang
ec4864da5c fix #993 2019-07-13 16:28:48 +08:00
AllenFang
92f1449177 fix #1004 2019-07-13 15:28:12 +08:00
Gena M
46258b0264 Update README, overlayFactory example (#997)
Update example of usage `overlayFactory` according to "react-loading-overlay" documentation.
2019-07-13 13:57:03 +08:00
AllenFang
5e8bb3426a Publish
- react-bootstrap-table2-example@1.0.27
 - react-bootstrap-table2-filter@1.1.10
 - react-bootstrap-table2-paginator@2.0.7
 - react-bootstrap-table-next@3.1.5
2019-06-25 23:13:31 +08:00
Allen
03f2ce4792 Merge pull request #991 from react-bootstrap-table/develop
20190625 release
2019-06-25 23:12:05 +08:00
AllenFang
7382010822 fix #970 2019-06-22 15:47:21 +08:00
Allen
a1a59f9419 fix #980 (#987) 2019-06-22 15:24:28 +08:00
Allen
59f184d74d fix #971 (#986) 2019-06-22 14:45:53 +08:00
Allen
643b9bca5f Merge pull request #985 from react-bootstrap-table/bugfix/979
Fix #979
2019-06-22 13:56:29 +08:00
AllenFang
31724fec7f add story for #979 2019-06-22 13:51:04 +08:00
AllenFang
4cf6e65abc fix #979 2019-06-22 13:50:50 +08:00
40 changed files with 601 additions and 54 deletions

View File

@@ -98,7 +98,14 @@ import overlayFactory from 'react-bootstrap-table2-overlay';
Actually, `react-bootstrap-table-overlay` is depends on [`react-loading-overlay`](https://github.com/derrickpelletier/react-loading-overlay) and `overlayFactory` just a factory function and you can pass any props which available for `react-loading-overlay`: Actually, `react-bootstrap-table-overlay` is depends on [`react-loading-overlay`](https://github.com/derrickpelletier/react-loading-overlay) and `overlayFactory` just a factory function and you can pass any props which available for `react-loading-overlay`:
```js ```js
overlay={ overlayFactory({ spinner: true, background: 'rgba(192,192,192,0.3)' }) } overlay={
overlayFactory({
spinner: true,
styles: {
overlay: (base) => ({...base, background: 'rgba(255, 0, 0, 0.5)'})
}
})
}
``` ```
### <a name='caption'>caption - [String | Node]</a> ### <a name='caption'>caption - [String | Node]</a>
@@ -334,4 +341,4 @@ handleDataChange = ({ dataSize }) => {
onDataSizeChange={ handleDataChange } onDataSizeChange={ handleDataChange }
.... ....
/> />
``` ```

View File

@@ -11,6 +11,7 @@ Available properties in a column object:
* [hidden](#hidden) * [hidden](#hidden)
* [formatter](#formatter) * [formatter](#formatter)
* [formatExtraData](#formatExtraData) * [formatExtraData](#formatExtraData)
* [type](#type)
* [sort](#sort) * [sort](#sort)
* [sortFunc](#sortFunc) * [sortFunc](#sortFunc)
* [sortCaret](#sortCaret) * [sortCaret](#sortCaret)
@@ -132,6 +133,10 @@ The third argument: `components` have following specified properties:
## <a name='formatExtraData'>column.formatExtraData - [Any]</a> ## <a name='formatExtraData'>column.formatExtraData - [Any]</a>
It's only used for [`column.formatter`](#formatter), you can define any value for it and will be passed as fourth argument for [`column.formatter`](#formatter) callback function. It's only used for [`column.formatter`](#formatter), you can define any value for it and will be passed as fourth argument for [`column.formatter`](#formatter) callback function.
## <a name='type'>column.type - [String]</a>
Specify the data type on column. Available value so far is `string`, `number`, `bool` and `date`. Default is `string`.
`column.type` can be used when you enable the cell editing and want to save your cell data with correct data type.
## <a name='sort'>column.sort - [Bool]</a> ## <a name='sort'>column.sort - [Bool]</a>
Enable the column sort via a `true` value given. Enable the column sort via a `true` value given.

View File

@@ -18,6 +18,7 @@
* [expandColumnPosition](#expandColumnPosition) * [expandColumnPosition](#expandColumnPosition)
* [expandColumnRenderer](#expandColumnRenderer) * [expandColumnRenderer](#expandColumnRenderer)
* [expandHeaderColumnRenderer](#expandHeaderColumnRenderer) * [expandHeaderColumnRenderer](#expandHeaderColumnRenderer)
* [parentClassName](#parentClassName)
### <a name="renderer">expandRow.renderer - [Function]</a> ### <a name="renderer">expandRow.renderer - [Function]</a>
@@ -25,12 +26,13 @@ Specify the content of expand row, `react-bootstrap-table2` will pass a row obje
#### values #### values
* **row** * **row**
* **rowIndex**
#### examples #### examples
```js ```js
const expandRow = { const expandRow = {
renderer: row => ( renderer: (row, rowIndex) => (
<div> <div>
<p>{ `This Expand row is belong to rowKey ${row.id}` }</p> <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>You can render anything here, also you can add additional data on every row object</p>
@@ -165,3 +167,24 @@ const expandRow = {
expandColumnPosition: 'right' expandColumnPosition: 'right'
}; };
``` ```
### <a name='parentClassName'>expandRow.parentClassName - [String | Function]</a>
Apply the custom class name on parent row of expanded row. For example:
```js
const expandRow = {
renderer: (row) => ...,
parentClassName: 'foo'
};
```
Below case is more flexible way to custom the class name:
```js
const expandRow = {
renderer: (row) => ...,
parentClassName: (isExpanded, row, rowIndex) => {
if (rowIndex > 2) return 'foo';
return 'bar';
}
};
```

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-bootstrap-table2-editor", "name": "react-bootstrap-table2-editor",
"version": "1.2.4", "version": "1.3.0",
"description": "it's the editor addon for react-bootstrap-table2", "description": "it's the editor addon for react-bootstrap-table2",
"main": "./lib/index.js", "main": "./lib/index.js",
"scripts": { "scripts": {

View File

@@ -56,12 +56,13 @@ export default (
} }
handleCellUpdate(row, column, newValue) { handleCellUpdate(row, column, newValue) {
const newValueWithType = dataOperator.typeConvert(column.type, newValue);
const { cellEdit } = this.props; const { cellEdit } = this.props;
const { beforeSaveCell } = cellEdit.options; const { beforeSaveCell } = cellEdit.options;
const oldValue = _.get(row, column.dataField); const oldValue = _.get(row, column.dataField);
const beforeSaveCellDone = (result = true) => { const beforeSaveCellDone = (result = true) => {
if (result) { if (result) {
this.doUpdate(row, column, newValue); this.doUpdate(row, column, newValueWithType);
} else { } else {
this.escapeEditing(); this.escapeEditing();
} }
@@ -69,7 +70,7 @@ export default (
if (_.isFunction(beforeSaveCell)) { if (_.isFunction(beforeSaveCell)) {
const result = beforeSaveCell( const result = beforeSaveCell(
oldValue, oldValue,
newValue, newValueWithType,
row, row,
column, column,
beforeSaveCellDone beforeSaveCellDone
@@ -78,7 +79,7 @@ export default (
return; return;
} }
} }
this.doUpdate(row, column, newValue); this.doUpdate(row, column, newValueWithType);
} }
doUpdate(row, column, newValue) { doUpdate(row, column, newValue) {

View File

@@ -0,0 +1,123 @@
/* eslint prefer-template: 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 { stockGenerator } from 'utils/common';
const products = stockGenerator();
const columns = [{
dataField: 'id',
text: 'Stock ID'
}, {
dataField: 'name',
text: 'Stock Name'
}, {
dataField: 'price',
text: 'Price',
type: 'number'
}, {
dataField: 'visible',
text: 'Visible?',
type: 'bool',
editor: {
type: Type.CHECKBOX,
value: 'true:false'
}
}, {
dataField: 'inStockDate',
text: 'Stock Date',
type: 'date',
formatter: (cell) => {
let dateObj = cell;
if (typeof cell !== 'object') {
dateObj = new Date(cell);
}
return `${('0' + dateObj.getUTCDate()).slice(-2)}/${('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/${dateObj.getUTCFullYear()}`;
},
editor: {
type: Type.DATE
}
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import cellEditFactory from 'react-bootstrap-table2-editor';
const columns = [{
dataField: 'id',
text: 'Stock ID'
}, {
dataField: 'name',
text: 'Stock Name'
}, {
dataField: 'price',
text: 'Price',
type: 'number'
}, {
dataField: 'visible',
text: 'Visible?',
type: 'bool',
editor: {
type: Type.CHECKBOX,
value: 'true:false'
}
}, {
dataField: 'inStockDate',
text: 'Stock Date',
type: 'date',
formatter: (cell) => {
let dateObj = cell;
if (typeof cell !== 'object') {
dateObj = new Date(cell);
}
return \`$\{('0' + dateObj.getUTCDate()).slice(-2)}/$\{('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/$\{dateObj.getUTCFullYear()}\`;
},
editor: {
type: Type.DATE
}
}];
function afterSaveCell(oldValue, newValue) {
console.log('--after save cell--');
console.log('New Value was apply as');
console.log(newValue);
console.log(\`and the type is $\{typeof newValue}\`);
}
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({
mode: 'click',
blurToSave: true,
afterSaveCell
}) }
/>
`;
function afterSaveCell(oldValue, newValue) {
console.log('--after save cell--');
console.log('New Value was apply as');
console.log(newValue);
console.log(`and the type is ${typeof newValue}`);
}
export default () => (
<div>
<h3>Save Cell Value with Specified Data Type</h3>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
cellEdit={ cellEditFactory({
mode: 'click',
blurToSave: true,
afterSaveCell
}) }
/>
<Code>{ sourceCode }</Code>
</div>
);

View File

@@ -12,8 +12,12 @@ import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter'; import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
class Table extends React.Component { class Table extends React.Component {
filterByPrice = filterVal => filterByPrice = (filterVal) => {
products.filter(product => product.price == filterVal); if (filterVal) {
return products.filter(product => product.price == filterVal);
}
return products;
}
render() { render() {
const columns = [{ const columns = [{
@@ -46,8 +50,12 @@ class Table extends React.Component {
`; `;
export default class Table extends React.Component { export default class Table extends React.Component {
filterByPrice = filterVal => filterByPrice = (filterVal) => {
products.filter(product => product.price == filterVal); if (filterVal) {
return products.filter(product => product.price == filterVal);
}
return products;
}
render() { render() {
const columns = [{ const columns = [{
@@ -67,7 +75,7 @@ export default class Table extends React.Component {
return ( return (
<div> <div>
<h2>Implement a eq filter on product price column</h2> <h2>Implement Custom Filter</h2>
<BootstrapTable <BootstrapTable
keyField="id" keyField="id"
data={ products } data={ products }

View File

@@ -0,0 +1,188 @@
/* 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 sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
class DummyColumnWithRowExpand extends React.Component {
constructor(props) {
super(props);
this.state = {
hoverIdx: null
};
}
expandRow = {
renderer: () => (
<div style={ { width: '100%', height: '20px' } }>Content</div>
),
showExpandColumn: true,
expandByColumnOnly: true
};
actionFormater = (cell, row, rowIndex, { hoverIdx }) => {
if ((hoverIdx !== null || hoverIdx !== undefined) && hoverIdx === rowIndex) {
return (
<div
style={ { width: '20px', height: '20px', backgroundColor: 'orange' } }
/>
);
}
return (
<div
style={ { width: '20px', height: '20px' } }
/>
);
}
rowEvents = {
onMouseEnter: (e, row, rowIndex) => {
this.setState({ hoverIdx: rowIndex });
},
onMouseLeave: () => {
this.setState({ hoverIdx: null });
}
}
rowStyle = (row, rowIndex) => {
row.index = rowIndex;
const style = {};
if (rowIndex % 2 === 0) {
style.backgroundColor = 'transparent';
} else {
style.backgroundColor = 'rgba(54, 163, 173, .10)';
}
style.borderTop = 'none';
return style;
}
render() {
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price'
}, {
text: '',
isDummyField: true,
formatter: this.actionFormater,
formatExtraData: { hoverIdx: this.state.hoverIdx },
headerStyle: { width: '50px' },
style: { height: '30px' }
}];
return (
<div>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
noDataIndication="There is no data"
classes="table"
rowStyle={ this.rowStyle }
rowEvents={ this.rowEvents }
expandRow={ this.expandRow }
/>
</div>
);
}
}
`;
export default class DummyColumnWithRowExpand extends React.Component {
constructor(props) {
super(props);
this.state = {
hoverIdx: null
};
}
expandRow = {
renderer: () => (
<div style={ { width: '100%', height: '20px' } }>Content</div>
),
showExpandColumn: true,
expandByColumnOnly: true
};
actionFormater = (cell, row, rowIndex, { hoverIdx }) => {
if ((hoverIdx !== null || hoverIdx !== undefined) && hoverIdx === rowIndex) {
return (
<div
style={ { width: '20px', height: '20px', backgroundColor: 'orange' } }
/>
);
}
return (
<div
style={ { width: '20px', height: '20px' } }
/>
);
}
rowEvents = {
onMouseEnter: (e, row, rowIndex) => {
this.setState({ hoverIdx: rowIndex });
},
onMouseLeave: () => {
this.setState({ hoverIdx: null });
}
}
rowStyle = (row, rowIndex) => {
row.index = rowIndex;
const style = {};
if (rowIndex % 2 === 0) {
style.backgroundColor = 'transparent';
} else {
style.backgroundColor = 'rgba(54, 163, 173, .10)';
}
style.borderTop = 'none';
return style;
}
render() {
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name'
}, {
dataField: 'price',
text: 'Product Price'
}, {
isDummyField: true,
text: '',
formatter: this.actionFormater,
formatExtraData: { hoverIdx: this.state.hoverIdx },
headerStyle: { width: '50px' },
style: { height: '30px' }
}];
return (
<div>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
rowStyle={ this.rowStyle }
rowEvents={ this.rowEvents }
expandRow={ this.expandRow }
/>
<Code>{ sourceCode }</Code>
</div>
);
}
}

View File

@@ -36,7 +36,7 @@ const RemotePagination = ({ loading, data, page, sizePerPage, onTableChange, tot
columns={ columns } columns={ columns }
pagination={ paginationFactory({ page, sizePerPage, totalSize }) } pagination={ paginationFactory({ page, sizePerPage, totalSize }) }
onTableChange={ onTableChange } onTableChange={ onTableChange }
overlay={ overlayFactory({ spinner: true, background: 'rgba(192,192,192,0.3)' }) } overlay={ overlayFactory({ spinner: true, styles: { overlay: (base) => ({...base, background: 'rgba(255, 0, 0, 0.5)'}) } }) }
/> />
<Code>{ sourceCode }</Code> <Code>{ sourceCode }</Code>
</div> </div>
@@ -101,7 +101,12 @@ const RemotePagination = ({ loading, data, page, sizePerPage, onTableChange, tot
columns={ columns } columns={ columns }
pagination={ paginationFactory({ page, sizePerPage, totalSize }) } pagination={ paginationFactory({ page, sizePerPage, totalSize }) }
onTableChange={ onTableChange } onTableChange={ onTableChange }
overlay={ overlayFactory({ spinner: true, background: 'rgba(192,192,192,0.3)' }) } overlay={
overlayFactory({
spinner: true,
styles: { overlay: base => ({ ...base, background: 'rgba(255, 0, 0, 0.5)' }) }
})
}
/> />
<Code>{ sourceCode }</Code> <Code>{ sourceCode }</Code>
</div> </div>

View File

@@ -74,7 +74,7 @@ const options = {
// hidePageListOnlyOnePage: true, // Hide the pagination list when only one page // hidePageListOnlyOnePage: true, // Hide the pagination list when only one page
firstPageText: 'First', firstPageText: 'First',
prePageText: 'Back', prePageText: 'Back',
nextPageText: 'Next', nextPageText: <span>Next</span>,
lastPageText: 'Last', lastPageText: 'Last',
nextPageTitle: 'First page', nextPageTitle: 'First page',
prePageTitle: 'Pre page', prePageTitle: 'Pre page',

View File

@@ -18,9 +18,9 @@ const columns = [{
}]; }];
const expandRow = { const expandRow = {
renderer: row => ( renderer: (row, rowIndex) => (
<div> <div>
<p>{ `This Expand row is belong to rowKey ${row.id}` }</p> <p>{ `This Expand row is belong to rowKey ${row.id} and index: ${rowIndex}` }</p>
<p>You can render anything here, also you can add additional data on every row object</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> <p>expandRow.renderer callback will pass the origin row object to you</p>
</div> </div>

View File

@@ -0,0 +1,106 @@
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 expandRow1 = {
parentClassName: 'parent-expand-foo',
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 expandRow2 = {
parentClassName: (isExpanded, row, rowIndex) => {
if (rowIndex > 2) return 'parent-expand-foo';
return 'parent-expand-bar';
},
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 sourceCode1 = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = // omit...
const expandRow = {
parentClassName: 'parent-expand-foo',
renderer: row => (
<div>.....</div>
)
};
<BootstrapTable
keyField='id'
data={ products }
columns={ columns }
expandRow={ expandRow }
/>
`;
const sourceCode2 = `\
import BootstrapTable from 'react-bootstrap-table-next';
const columns = // omit...
const expandRow = {
parentClassName: (isExpanded, row, rowIndex) => {
if (rowIndex > 2) return 'parent-expand-foo';
return 'parent-expand-bar';
},
renderer: row => (
<div>...</div>
)
};
<BootstrapTable
keyField='id'
data={ products }
columns={ columns }
expandRow={ expandRow }
/>
`;
export default () => (
<div>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
expandRow={ expandRow1 }
/>
<Code>{ sourceCode1 }</Code>
<BootstrapTable
keyField="id"
data={ products }
columns={ columns }
expandRow={ expandRow2 }
/>
<Code>{ sourceCode2 }</Code>
</div>
);

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-bootstrap-table2-example", "name": "react-bootstrap-table2-example",
"version": "1.0.26", "version": "1.0.28",
"description": "", "description": "",
"main": "index.js", "main": "index.js",
"private": true, "private": true,

View File

@@ -69,8 +69,9 @@ const endDate = new Date();
export const stockGenerator = (quantity = 5) => export const stockGenerator = (quantity = 5) =>
Array.from({ length: quantity }, (value, index) => ({ Array.from({ length: quantity }, (value, index) => ({
id: index, id: index,
name: `Todo item ${index}`, name: `Stock Name ${index}`,
price: Math.floor((Math.random() * 2) + 1), price: Math.floor((Math.random() * 2) + 1),
visible: Math.random() > 0.5,
inStockDate: inStockDate:
new Date(startDate.getTime() + Math.random() * (endDate.getTime() - startDate.getTime())) new Date(startDate.getTime() + Math.random() * (endDate.getTime() - startDate.getTime()))
})); }));

View File

@@ -35,6 +35,7 @@ import ColumnEventTable from 'examples/columns/column-event-table';
import ColumnHiddenTable from 'examples/columns/column-hidden-table'; import ColumnHiddenTable from 'examples/columns/column-hidden-table';
import ColumnAttrsTable from 'examples/columns/column-attrs-table'; import ColumnAttrsTable from 'examples/columns/column-attrs-table';
import DummyColumnTable from 'examples/columns/dummy-column-table'; import DummyColumnTable from 'examples/columns/dummy-column-table';
import RowExpandWithFormattedDummyColumn from 'examples/columns/row-expand-with-formatted-dummy-column.js';
// work on header columns // work on header columns
import HeaderColumnFormatTable from 'examples/header-columns/column-format-table'; import HeaderColumnFormatTable from 'examples/header-columns/column-format-table';
@@ -130,6 +131,7 @@ import TextareaEditorTable from 'examples/cell-edit/textarea-editor-table';
import CheckboxEditorTable from 'examples/cell-edit/checkbox-editor-table'; import CheckboxEditorTable from 'examples/cell-edit/checkbox-editor-table';
import DateEditorTable from 'examples/cell-edit/date-editor-table'; import DateEditorTable from 'examples/cell-edit/date-editor-table';
import CustomEditorTable from 'examples/cell-edit/custom-editor-table'; import CustomEditorTable from 'examples/cell-edit/custom-editor-table';
import CellEditorWithDataType from 'examples/cell-edit/cell-edit-with-data-type';
// work on row selection // work on row selection
import SingleSelectionTable from 'examples/row-selection/single-selection'; import SingleSelectionTable from 'examples/row-selection/single-selection';
@@ -163,6 +165,7 @@ import ExpandOnlyOne from 'examples/row-expand/expand-only-one';
import CustomExpandColumn from 'examples/row-expand/custom-expand-column'; import CustomExpandColumn from 'examples/row-expand/custom-expand-column';
import ExpandColumnPosition from 'examples/row-expand/expand-column-position'; import ExpandColumnPosition from 'examples/row-expand/expand-column-position';
import ExpandHooks from 'examples/row-expand/expand-hooks'; import ExpandHooks from 'examples/row-expand/expand-hooks';
import ParentRowClassName from 'examples/row-expand/parent-row-classname';
// pagination // pagination
import PaginationTable from 'examples/pagination'; import PaginationTable from 'examples/pagination';
@@ -273,7 +276,8 @@ storiesOf('Work on Columns', module)
.add('Customize Column Class', () => <ColumnClassTable />) .add('Customize Column Class', () => <ColumnClassTable />)
.add('Customize Column Style', () => <ColumnStyleTable />) .add('Customize Column Style', () => <ColumnStyleTable />)
.add('Customize Column HTML attribute', () => <ColumnAttrsTable />) .add('Customize Column HTML attribute', () => <ColumnAttrsTable />)
.add('Dummy Column', () => <DummyColumnTable />); .add('Dummy Column', () => <DummyColumnTable />)
.add('Row Expand with Dummy Column Formatter', () => <RowExpandWithFormattedDummyColumn />);
storiesOf('Work on Header Columns', module) storiesOf('Work on Header Columns', module)
.addDecorator(bootstrapStyle()) .addDecorator(bootstrapStyle())
@@ -375,7 +379,8 @@ storiesOf('Cell Editing', module)
.add('Textarea Editor', () => <TextareaEditorTable />) .add('Textarea Editor', () => <TextareaEditorTable />)
.add('Checkbox Editor', () => <CheckboxEditorTable />) .add('Checkbox Editor', () => <CheckboxEditorTable />)
.add('Date Editor', () => <DateEditorTable />) .add('Date Editor', () => <DateEditorTable />)
.add('Custom Editor', () => <CustomEditorTable />); .add('Custom Editor', () => <CustomEditorTable />)
.add('Cell Editor with Data Type', () => <CellEditorWithDataType />);
storiesOf('Row Selection', module) storiesOf('Row Selection', module)
.addDecorator(bootstrapStyle()) .addDecorator(bootstrapStyle())
@@ -410,7 +415,8 @@ storiesOf('Row Expand', module)
.add('Expand Only One Row at The Same Time', () => <ExpandOnlyOne />) .add('Expand Only One Row at The Same Time', () => <ExpandOnlyOne />)
.add('Custom Expand Indicator', () => <CustomExpandColumn />) .add('Custom Expand Indicator', () => <CustomExpandColumn />)
.add('Expand Column Position', () => <ExpandColumnPosition />) .add('Expand Column Position', () => <ExpandColumnPosition />)
.add('Expand Hooks', () => <ExpandHooks />); .add('Expand Hooks', () => <ExpandHooks />)
.add('Custom Parent Row ClassName', () => <ParentRowClassName />);
storiesOf('Pagination', module) storiesOf('Pagination', module)
.addDecorator(bootstrapStyle()) .addDecorator(bootstrapStyle())

View File

@@ -0,0 +1,7 @@
.parent-expand-foo {
background-color: coral;
}
.parent-expand-bar {
background-color: aqua;
}

View File

@@ -12,3 +12,4 @@
@import "sort/index"; @import "sort/index";
@import "search/index"; @import "search/index";
@import "loading-overlay/index"; @import "loading-overlay/index";
@import "row-expand/index";

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-bootstrap-table2-filter", "name": "react-bootstrap-table2-filter",
"version": "1.1.9", "version": "1.1.10",
"description": "it's a column filter addon for react-bootstrap-table2", "description": "it's a column filter addon for react-bootstrap-table2",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {

View File

@@ -18,8 +18,18 @@ function optionsEquals(currOpts, prevOpts) {
return Object.keys(currOpts).length === Object.keys(prevOpts).length; return Object.keys(currOpts).length === Object.keys(prevOpts).length;
} }
const getSelections = container => const getSelections = (container) => {
Array.from(container.selectedOptions).map(item => item.value); if (container.selectedOptions) {
return Array.from(container.selectedOptions).map(item => item.value);
}
const selections = [];
const totalLen = container.options.length;
for (let i = 0; i < totalLen; i += 1) {
const option = container.options.item(i);
if (option.selected) selections.push(option.value);
}
return selections;
};
class MultiSelectFilter extends Component { class MultiSelectFilter extends Component {
constructor(props) { constructor(props) {

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-bootstrap-table2-paginator", "name": "react-bootstrap-table2-paginator",
"version": "2.0.6", "version": "2.0.7",
"description": "it's the pagination addon for react-bootstrap-table2", "description": "it's the pagination addon for react-bootstrap-table2",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {

View File

@@ -39,7 +39,11 @@ class PageButton extends Component {
PageButton.propTypes = { PageButton.propTypes = {
onPageChange: PropTypes.func.isRequired, onPageChange: PropTypes.func.isRequired,
page: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired, page: PropTypes.oneOfType([
PropTypes.node,
PropTypes.number,
PropTypes.string
]).isRequired,
active: PropTypes.bool.isRequired, active: PropTypes.bool.isRequired,
disabled: PropTypes.bool.isRequired, disabled: PropTypes.bool.isRequired,
className: PropTypes.string, className: PropTypes.string,

View File

@@ -27,7 +27,11 @@ const PaginatonList = props => (
PaginatonList.propTypes = { PaginatonList.propTypes = {
pages: PropTypes.arrayOf(PropTypes.shape({ pages: PropTypes.arrayOf(PropTypes.shape({
page: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), page: PropTypes.oneOfType([
PropTypes.node,
PropTypes.number,
PropTypes.string
]),
active: PropTypes.bool, active: PropTypes.bool,
disable: PropTypes.bool, disable: PropTypes.bool,
title: PropTypes.string title: PropTypes.string

View File

@@ -100,10 +100,10 @@ Pagination.propTypes = {
sizePerPageRenderer: PropTypes.func, sizePerPageRenderer: PropTypes.func,
paginationTotalRenderer: PropTypes.func, paginationTotalRenderer: PropTypes.func,
sizePerPageOptionRenderer: PropTypes.func, sizePerPageOptionRenderer: PropTypes.func,
firstPageText: PropTypes.string, firstPageText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
prePageText: PropTypes.string, prePageText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
nextPageText: PropTypes.string, nextPageText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
lastPageText: PropTypes.string, lastPageText: PropTypes.oneOfType([PropTypes.string, PropTypes.node]),
nextPageTitle: PropTypes.string, nextPageTitle: PropTypes.string,
prePageTitle: PropTypes.string, prePageTitle: PropTypes.string,
firstPageTitle: PropTypes.string, firstPageTitle: PropTypes.string,

View File

@@ -1,6 +1,6 @@
{ {
"name": "react-bootstrap-table-next", "name": "react-bootstrap-table-next",
"version": "3.1.4", "version": "3.1.6",
"description": "Next generation of react-bootstrap-table", "description": "Next generation of react-bootstrap-table",
"main": "./lib/index.js", "main": "./lib/index.js",
"repository": { "repository": {

View File

@@ -189,7 +189,8 @@ BootstrapTable.propTypes = {
expandColumnPosition: PropTypes.oneOf([ expandColumnPosition: PropTypes.oneOf([
Const.INDICATOR_POSITION_LEFT, Const.INDICATOR_POSITION_LEFT,
Const.INDICATOR_POSITION_RIGHT Const.INDICATOR_POSITION_RIGHT
]) ]),
parentClassName: PropTypes.oneOfType([PropTypes.string, PropTypes.func])
}), }),
rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]), rowStyle: PropTypes.oneOfType([PropTypes.object, PropTypes.func]),
rowEvents: PropTypes.object, rowEvents: PropTypes.object,

View File

@@ -1,3 +1,5 @@
import _ from './utils';
const events = [ const events = [
'onClick', 'onClick',
'onDoubleClick', 'onDoubleClick',
@@ -23,7 +25,7 @@ export default ExtendBase =>
delegate(attrs = {}) { delegate(attrs = {}) {
const newAttrs = { ...attrs }; const newAttrs = { ...attrs };
Object.keys(attrs).forEach((attr) => { Object.keys(attrs).forEach((attr) => {
if (events.includes(attr)) { if (_.contains(events, attr)) {
newAttrs[attr] = this.createDefaultEventHandler(attrs[attr]); newAttrs[attr] = this.createDefaultEventHandler(attrs[attr]);
} }
}); });

View File

@@ -8,5 +8,9 @@ export default {
CHECKBOX_STATUS_INDETERMINATE: 'indeterminate', CHECKBOX_STATUS_INDETERMINATE: 'indeterminate',
CHECKBOX_STATUS_UNCHECKED: 'unchecked', CHECKBOX_STATUS_UNCHECKED: 'unchecked',
INDICATOR_POSITION_LEFT: 'left', INDICATOR_POSITION_LEFT: 'left',
INDICATOR_POSITION_RIGHT: 'right' INDICATOR_POSITION_RIGHT: 'right',
TYPE_STRING: 'string',
TYPE_NUMBER: 'number',
TYPE_BOOLEAN: 'bool',
TYPE_DATE: 'date'
}; };

View File

@@ -20,7 +20,7 @@ class RowExpandProvider extends React.Component {
if (nextProps.expandRow) { if (nextProps.expandRow) {
const nextExpanded = nextProps.expandRow.expanded || this.state.expanded; const nextExpanded = nextProps.expandRow.expanded || this.state.expanded;
const isClosing = this.state.expanded.reduce((acc, cur) => { const isClosing = this.state.expanded.reduce((acc, cur) => {
if (!nextExpanded.includes(cur)) { if (!_.contains(nextExpanded, cur)) {
acc.push(cur); acc.push(cur);
} }
return acc; return acc;
@@ -42,7 +42,7 @@ class RowExpandProvider extends React.Component {
handleRowExpand = (rowKey, expanded, rowIndex, e) => { handleRowExpand = (rowKey, expanded, rowIndex, e) => {
const { data, keyField, expandRow: { onExpand, onlyOneExpanding, nonExpandable } } = this.props; const { data, keyField, expandRow: { onExpand, onlyOneExpanding, nonExpandable } } = this.props;
if (nonExpandable && nonExpandable.includes(rowKey)) { if (nonExpandable && _.contains(nonExpandable, rowKey)) {
return; return;
} }

View File

@@ -117,6 +117,12 @@ HeaderCell.propTypes = {
column: PropTypes.shape({ column: PropTypes.shape({
dataField: PropTypes.string.isRequired, dataField: PropTypes.string.isRequired,
text: PropTypes.string.isRequired, text: PropTypes.string.isRequired,
type: PropTypes.oneOf([
Const.TYPE_STRING,
Const.TYPE_NUMBER,
Const.TYPE_BOOLEAN,
Const.TYPE_DATE
]),
isDummyField: PropTypes.bool, isDummyField: PropTypes.bool,
hidden: PropTypes.bool, hidden: PropTypes.bool,
headerFormatter: PropTypes.func, headerFormatter: PropTypes.func,

View File

@@ -22,7 +22,7 @@ export default ExtendBase =>
if (!hiddenRows || hiddenRows.length === 0) return data; if (!hiddenRows || hiddenRows.length === 0) return data;
return data.filter((row) => { return data.filter((row) => {
const key = _.get(row, keyField); const key = _.get(row, keyField);
return !hiddenRows.includes(key); return !_.contains(hiddenRows, key);
}); });
} }
}; };

View File

@@ -1,15 +1,24 @@
/* eslint react/prop-types: 0 */ /* eslint react/prop-types: 0 */
import React from 'react'; import React from 'react';
import cs from 'classnames';
import ExpandRow from './expand-row'; import ExpandRow from './expand-row';
import _ from '../utils';
import ExpansionContext from '../contexts/row-expand-context'; import ExpansionContext from '../contexts/row-expand-context';
export default (Component) => { export default (Component) => {
const renderWithExpansion = (props, expandRow) => { const renderWithExpansion = (props, expandRow) => {
let parentClassName = '';
const key = props.value; const key = props.value;
const expanded = expandRow.expanded.includes(key); const expanded = _.contains(expandRow.expanded, key);
const isClosing = expandRow.isClosing.includes(key); const isClosing = _.contains(expandRow.isClosing, key);
const expandable = !expandRow.nonExpandable || !expandRow.nonExpandable.includes(key); const expandable = !expandRow.nonExpandable || !_.contains(expandRow.nonExpandable, key);
if (expanded) {
parentClassName = _.isFunction(expandRow.parentClassName) ?
expandRow.parentClassName(expanded, props.row, props.rowIndex) :
(expandRow.parentClassName || '');
}
return [ return [
<Component <Component
{ ...props } { ...props }
@@ -17,6 +26,7 @@ export default (Component) => {
expanded={ expanded } expanded={ expanded }
expandable={ expandable } expandable={ expandable }
expandRow={ { ...expandRow } } expandRow={ { ...expandRow } }
className={ cs(props.className, parentClassName) }
/>, />,
expanded || isClosing ? <ExpandRow expanded || isClosing ? <ExpandRow
key={ `${key}-expanding` } key={ `${key}-expanding` }
@@ -24,7 +34,7 @@ export default (Component) => {
expanded={ expanded } expanded={ expanded }
onClosed={ () => expandRow.onClosed(key) } onClosed={ () => expandRow.onClosed(key) }
> >
{ expandRow.renderer(props.row) } { expandRow.renderer(props.row, props.rowIndex) }
</ExpandRow> : null </ExpandRow> : null
]; ];
}; };

View File

@@ -7,8 +7,8 @@ import SelectionContext from '../contexts/selection-context';
export default (Component) => { export default (Component) => {
const renderWithSelection = (props, selectRow) => { const renderWithSelection = (props, selectRow) => {
const key = props.value; const key = props.value;
const selected = selectRow.selected.includes(key); const selected = _.contains(selectRow.selected, key);
const selectable = !selectRow.nonSelectable || !selectRow.nonSelectable.includes(key); const selectable = !selectRow.nonSelectable || !_.contains(selectRow.nonSelectable, key);
let { let {
style, style,

View File

@@ -35,12 +35,13 @@ export default class RowAggregator extends shouldUpdater(eventDelegater(React.Co
this.props.expanded !== nextProps.expanded || this.props.expanded !== nextProps.expanded ||
this.props.expandable !== nextProps.expandable || this.props.expandable !== nextProps.expandable ||
this.props.selectable !== nextProps.selectable || this.props.selectable !== nextProps.selectable ||
this.props.selectRow.hideSelectColumn !== nextProps.selectRow.hideSelectColumn ||
this.shouldUpdatedBySelfProps(nextProps) this.shouldUpdatedBySelfProps(nextProps)
) { ) {
this.shouldUpdateRowContent = this.shouldUpdateChild(nextProps); this.shouldUpdateRowContent = this.shouldRowContentUpdate(nextProps);
return true; return true;
} }
this.shouldUpdateRowContent = this.shouldUpdateChild(nextProps); this.shouldUpdateRowContent = this.shouldRowContentUpdate(nextProps);
return this.shouldUpdateRowContent; return this.shouldUpdateRowContent;
} }

View File

@@ -74,7 +74,7 @@ export default ExtendBase =>
delegate(attrs = {}) { delegate(attrs = {}) {
const newAttrs = { ...attrs }; const newAttrs = { ...attrs };
Object.keys(attrs).forEach((attr) => { Object.keys(attrs).forEach((attr) => {
if (events.includes(attr)) { if (_.contains(events, attr)) {
newAttrs[attr] = this.createDefaultEventHandler(attrs[attr]); newAttrs[attr] = this.createDefaultEventHandler(attrs[attr]);
} }
}); });

View File

@@ -48,4 +48,9 @@ export default ExtendBase =>
return this.shouldUpdateByCellEditing(nextProps) || return this.shouldUpdateByCellEditing(nextProps) ||
this.shouldUpdatedByNormalProps(nextProps); this.shouldUpdatedByNormalProps(nextProps);
} }
shouldRowContentUpdate(nextProps) {
return this.shouldUpdateChild(nextProps) ||
this.shouldUpdateByColumnsForSimpleCheck(nextProps);
}
}; };

View File

@@ -15,8 +15,7 @@ class SimpleRow extends shouldUpdater(eventDelegater(Component)) {
shouldComponentUpdate(nextProps) { shouldComponentUpdate(nextProps) {
this.shouldUpdateRowContent = false; this.shouldUpdateRowContent = false;
this.shouldUpdateRowContent = this.shouldUpdateRowContent = this.shouldRowContentUpdate(nextProps);
this.shouldUpdateChild(nextProps) || this.shouldUpdateByColumnsForSimpleCheck(nextProps);
if (this.shouldUpdateRowContent) return true; if (this.shouldUpdateRowContent) return true;
return this.shouldUpdatedBySelfProps(nextProps); return this.shouldUpdatedBySelfProps(nextProps);

View File

@@ -20,7 +20,7 @@ export const expandableKeys = (data, keyField, skips = []) => {
return data.map(row => _.get(row, keyField)); return data.map(row => _.get(row, keyField));
} }
return data return data
.filter(row => !skips.includes(_.get(row, keyField))) .filter(row => !_.contains(skips, _.get(row, keyField)))
.map(row => _.get(row, keyField)); .map(row => _.get(row, keyField));
}; };

View File

@@ -3,11 +3,13 @@ import * as selection from './selection';
import * as expand from './expand'; import * as expand from './expand';
import * as mutate from './mutate'; import * as mutate from './mutate';
import * as sort from './sort'; import * as sort from './sort';
import * as type from './type';
export default { export default {
...rows, ...rows,
...selection, ...selection,
...expand, ...expand,
...mutate, ...mutate,
...sort ...sort,
...type
}; };

View File

@@ -29,7 +29,7 @@ export const selectableKeys = (data, keyField, skips = []) => {
return data.map(row => _.get(row, keyField)); return data.map(row => _.get(row, keyField));
} }
return data return data
.filter(row => !skips.includes(_.get(row, keyField))) .filter(row => !_.contains(skips, _.get(row, keyField)))
.map(row => _.get(row, keyField)); .map(row => _.get(row, keyField));
}; };
@@ -37,7 +37,7 @@ export const unSelectableKeys = (selected, skips = []) => {
if (skips.length === 0) { if (skips.length === 0) {
return []; return [];
} }
return selected.filter(x => skips.includes(x)); return selected.filter(x => _.contains(skips, x));
}; };
export const getSelectedRows = (data, keyField, selected) => export const getSelectedRows = (data, keyField, selected) =>

View File

@@ -0,0 +1,18 @@
import Const from '../const';
export const typeConvert = (type, value) => {
if (!type || type === Const.TYPE_STRING) {
return String(value);
} else if (type === Const.TYPE_NUMBER) {
return Number(value);
} else if (type === Const.TYPE_BOOLEAN) {
if (typeof value === 'boolean') {
return value;
}
return value === 'true';
} else if (type === Const.TYPE_DATE) {
return new Date(value);
}
return value;
};