Compare commits

..

12 Commits

Author SHA1 Message Date
AllenFang
df5024892c Publish
- react-bootstrap-table2-example@1.0.22
 - react-bootstrap-table2-paginator@2.0.5
 - react-bootstrap-table-next@3.0.3
2019-03-26 20:41:04 +08:00
Allen
4448c3f28c Merge pull request #875 from react-bootstrap-table/develop
20190326 release
2019-03-26 20:39:13 +08:00
AllenFang
196ae33295 fix #859 2019-03-25 23:07:22 +08:00
AllenFang
7f1b7a6c97 fix #838 2019-03-24 20:52:26 +08:00
AllenFang
a6ccafcc75 fix #866 2019-03-24 16:55:56 +08:00
AllenFang
06d87299a3 Publish
- react-bootstrap-table2-example@1.0.21
 - react-bootstrap-table2-filter@1.1.7
 - react-bootstrap-table2-toolkit@1.4.0
 - react-bootstrap-table-next@3.0.2
2019-03-18 00:31:24 +08:00
Allen
5891ec1b93 Merge pull request #862 from react-bootstrap-table/develop
20190317 release
2019-03-18 00:28:47 +08:00
AllenFang
c5d9e04c2c fix #817 2019-03-17 16:30:39 +08:00
AllenFang
d0e70f7246 fix #852 2019-03-17 14:43:39 +08:00
henning-kvinnesland
b93c683f17 Fix typo. (#855)
`to cusom the sort caret` => `to customize the sort-caret`
2019-03-17 13:30:35 +08:00
henning-kvinnesland
f80e1ea66c Fix typo. (#856)
`chagne` => `change`
2019-03-17 13:30:21 +08:00
AllenFang
7642bfa1a3 fix #849 2019-03-17 13:29:17 +08:00
19 changed files with 338 additions and 152 deletions

View File

@@ -164,7 +164,7 @@ 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`
Use`column.sortCaret` to customize the sort caret. This callback function accept two arguments: `order` and `column`
```js
{

View File

@@ -2,7 +2,7 @@
# Row expand
`react-bootstrap-table2` supports the row expand feature. By passing prop `expandRow` to enable this functionality.
> Default is click to expand/collapse a row. In addition, we don't support any way to chagne this mechanism!
> Default is click to expand/collapse a row. In addition, we don't support any way to change this mechanism!
## Required
* [renderer (**required**)](#renderer)

View File

@@ -11,141 +11,13 @@ const products = [
{ 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 };
this.state = { products, count: 0 };
}
toggleInStock = () => {
@@ -163,17 +35,96 @@ class ProductList extends React.Component {
};
render() {
const columns = [
{
dataField: 'id',
text: 'Product ID',
formatter: (cell, row, rowIndex, extraData) => (
<div>
<span>ID: {row.id}</span>
<br />
<span>state: {extraData}</span>
</div>
),
formatExtraData: this.state.count
},
{
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>
);
}
}
];
return (
<div>
<h1 className="h2">Products</h1>
<h3>Action 1 and Action 2 are dummy column</h3>
<button onClick={ this.toggleInStock } className="btn btn-primary">
Toggle item 13 stock status
</button>
<button
className="btn btn-success"
onClick={ () => this.setState(() => ({ count: this.state.count + 1 })) }
>
Click me to Increase counter
</button>
<BootstrapTable
keyField="id"
data={ this.state.products }
columns={ columns }
/>
<button onClick={ this.toggleInStock } className="btn btn-primary">
Toggle item 13 stock status
</button>
<Code>{ sourceCode }</Code>
</div>
);
}
@@ -183,7 +134,7 @@ class ProductList extends React.Component {
class ProductList extends React.Component {
constructor(props) {
super(props);
this.state = { products };
this.state = { products, count: 0 };
}
toggleInStock = () => {
@@ -200,13 +151,95 @@ class ProductList extends React.Component {
this.setState(curr => ({ ...curr, products: newProducts }));
};
counter = () => {
this.setState(curr => ({ ...curr, count: this.state.count + 1 }));
}
render() {
const columns = [
{
dataField: 'id',
text: 'Product ID',
formatter: (cell, row, rowIndex, extraData) => (
<div>
<span>ID: {row.id}</span>
<br />
<span>Counter: {extraData}</span>
</div>
),
formatExtraData: this.state.count
},
{
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>
);
}
}
];
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>
<button
className="btn btn-success"
onClick={ this.counter }
>
Click me to Increase counter
</button>
<BootstrapTable
keyField="id"
data={ this.state.products }

View File

@@ -0,0 +1,102 @@
/* eslint react/prop-types: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import ToolkitProvider, { CSVExport, Search } from 'react-bootstrap-table2-toolkit';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
import paginationFactory from 'react-bootstrap-table2-paginator';
import Code from 'components/common/code-block';
import { productsGenerator } from 'utils/common';
const { SearchBar } = Search;
const { ExportCSVButton } = CSVExport;
const products = productsGenerator(150);
const columns = [{
dataField: 'id',
text: 'Product ID'
}, {
dataField: 'name',
text: 'Product Name',
filter: textFilter()
}, {
dataField: 'price',
text: 'Product Price'
}];
const sourceCode = `\
import BootstrapTable from 'react-bootstrap-table-next';
import ToolkitProvider, { CSVExport, Search } from 'react-bootstrap-table2-toolkit';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
const { SearchBar } = Search;
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={ products }
columns={ columns }
exportCSV={ { onlyExportFiltered: true, exportAll: false } }
search
>
{
props => (
<div>
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
<hr />
<SearchBar { ...props.searchProps } />
<BootstrapTable
{ ...props.baseProps }
pagination={ paginationFactory() }
filter={ filterFactory() }
/>
</div>
)
}
</ToolkitProvider>
`;
export default () => (
<div>
<h3>Export all the filtered/searched rows</h3>
<ToolkitProvider
keyField="id"
data={ products }
columns={ columns }
exportCSV={ { onlyExportFiltered: true, exportAll: false } }
search
>
{
props => (
<div>
<ExportCSVButton { ...props.csvProps }>Export CSV!!</ExportCSVButton>
<hr />
<SearchBar { ...props.searchProps } />
<BootstrapTable
{ ...props.baseProps }
pagination={ paginationFactory() }
filter={ filterFactory() }
/>
</div>
)
}
</ToolkitProvider>
<Code>{ sourceCode }</Code>
</div>
);

View File

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

View File

@@ -192,6 +192,7 @@ 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 ExportOnlyFiltered from 'examples/csv/export-only-filtered';
import CSVColumnType from 'examples/csv/csv-column-type';
import CustomCSVButton from 'examples/csv/custom-csv-button';
import ExportCustomData from 'examples/csv/export-custom-data';
@@ -443,6 +444,7 @@ storiesOf('Export CSV', module)
.add('Custom CSV Header', () => <CustomCSVHeader />)
.add('Hide CSV Column', () => <HideCSVColumn />)
.add('Only Export Selected Rows', () => <ExportOnlySelected />)
.add('Only Export Filtered/Searched Rows', () => <ExportOnlyFiltered />)
.add('CSV Column Type', () => <CSVColumnType />)
.add('Custom CSV Button', () => <CustomCSVButton />)
.add('Export Custom Data', () => <ExportCustomData />)

View File

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

View File

@@ -41,6 +41,8 @@ export default (
// let nextData = nextProps.data;
if (!isRemoteFiltering() && !_.isEqual(nextProps.data, this.data)) {
this.doFilter(nextProps, undefined, this.isEmitDataChange);
} else {
this.data = nextProps.data;
}
}
@@ -89,6 +91,10 @@ export default (
};
}
getFiltered() {
return this.data;
}
doFilter(props, customResult, ignoreEmitDataChange = false) {
let result = customResult;

View File

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

View File

@@ -56,7 +56,7 @@ export default ExtendBase =>
alwaysShowAllBtns
} = this.props;
let pages;
let pages = [];
let endPage = totalPages;
if (endPage <= 0) return [];
@@ -68,24 +68,42 @@ export default ExtendBase =>
startPage = endPage - paginationSize + 1;
}
if (startPage !== pageStartIndex && totalPages > paginationSize && withFirstAndLast) {
if (alwaysShowAllBtns) {
if (withFirstAndLast) {
pages = [firstPageText, prePageText];
} else {
pages = [prePageText];
}
}
if (startPage !== pageStartIndex &&
totalPages > paginationSize &&
withFirstAndLast &&
pages.length === 0
) {
pages = [firstPageText, prePageText];
} else if (totalPages > 1 || alwaysShowAllBtns) {
} else if (totalPages > 1 && pages.length === 0) {
pages = [prePageText];
} else {
pages = [];
}
for (let i = startPage; i <= endPage; i += 1) {
if (i >= pageStartIndex) pages.push(i);
}
if (endPage <= lastPage && pages.length > 1) {
if (alwaysShowAllBtns || (endPage <= lastPage && pages.length > 1)) {
pages.push(nextPageText);
}
if (endPage !== lastPage && withFirstAndLast) {
if ((endPage !== lastPage && withFirstAndLast) || (withFirstAndLast && alwaysShowAllBtns)) {
pages.push(lastPageText);
}
// if ((endPage <= lastPage && pages.length > 1) || alwaysShowAllBtns) {
// pages.push(nextPageText);
// }
// if (endPage !== lastPage && withFirstAndLast) {
// pages.push(lastPageText);
// }
return pages;
}

View File

@@ -191,6 +191,11 @@ 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.
#### onlyExportFiltered - [bool]
Default is `false`. `true` will only export the data which is filtered/searched.
>> When you configure this prop as true, you must turn off `exportAll`.
-----
## Column Toggle

View File

@@ -30,6 +30,7 @@ class ToolkitProvider extends statelessDecorator(React.Component) {
ignoreHeader: PropTypes.bool,
noAutoBOM: PropTypes.bool,
exportAll: PropTypes.bool,
onlyExportFiltered: PropTypes.bool,
onlyExportSelection: PropTypes.bool
})
])

View File

@@ -1,6 +1,6 @@
{
"name": "react-bootstrap-table2-toolkit",
"version": "1.3.2",
"version": "1.4.0",
"description": "The toolkit for react-bootstrap-table2",
"main": "./lib/index.js",
"repository": {

View File

@@ -27,19 +27,24 @@ export default Base =>
data = source;
} else if (options.exportAll) {
data = this.props.data;
} else if (options.onlyExportFiltered) {
const payload = {};
this.tableExposedAPIEmitter.emit('get.filtered.rows', payload);
data = payload.result;
} else {
const payload = {};
this.tableExposedAPIEmitter.emit('get.table.data', payload);
data = payload.result;
}
// filter data
// filter data by row selection
if (options.onlyExportSelection) {
const payload = {};
this.tableExposedAPIEmitter.emit('get.selected.rows', payload);
const selections = payload.result;
data = data.filter(row => !!selections.find(sel => row[keyField] === sel));
}
const content = transform(data, meta, this._.get, options);
save(content, options);
}

View File

@@ -59,6 +59,10 @@ export default (options = {
}
}
getSearched() {
return this.state.data;
}
triggerListener(result) {
if (this.props.dataChangeListener) {
this.props.dataChangeListener.emit('filterChanged', result.length);

View File

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

View File

@@ -26,7 +26,7 @@ class Cell extends eventDelegater(Component) {
// if (nextProps.formatter)
shouldUpdate =
nextProps.column.formatter ? !_.isEqual(this.props.row, nextProps.row) : false ||
(nextProps.column.formatter ? !_.isEqual(this.props.row, nextProps.row) : false) ||
this.props.column.hidden !== nextProps.column.hidden ||
this.props.rowIndex !== nextProps.rowIndex ||
this.props.columnIndex !== nextProps.columnIndex ||

View File

@@ -23,6 +23,15 @@ const withContext = Base =>
const exposedAPIEmitter = new EventEmitter();
exposedAPIEmitter.on('get.table.data', payload => payload.result = this.table.getData());
exposedAPIEmitter.on('get.selected.rows', payload => payload.result = this.selectionContext.getSelected());
exposedAPIEmitter.on('get.filtered.rows', (payload) => {
if (this.searchContext) {
payload.result = this.searchContext.getSearched();
} else if (this.filterContext) {
payload.result = this.filterContext.getFiltered();
} else {
payload.result = this.table.getData();
}
});
props.registerExposedAPI(exposedAPIEmitter);
}

View File

@@ -8,7 +8,8 @@ export default ExtendBase =>
return (
nextProps.editingRowIdx === nextProps.rowIndex ||
(this.props.editingRowIdx === nextProps.rowIndex &&
nextProps.editingRowIdx === null)
nextProps.editingRowIdx === null) ||
this.props.editingRowIdx === nextProps.rowIndex
);
}
@@ -26,7 +27,7 @@ export default ExtendBase =>
return true;
}
for (let i = 0; i < this.props.columns.length; i += 1) {
if (this.props.columns[i].hidden !== nextProps.columns[i].hidden) {
if (!_.isEqual(this.props.columns[i], nextProps.columns[i])) {
return true;
}
}