mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-06-29 13:40:07 +00:00
Compare commits
22 Commits
react-boot
...
react-boot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
497bf44192 | ||
|
|
fcefcf8c84 | ||
|
|
04e3af0bbb | ||
|
|
9f47fa009c | ||
|
|
0edf9c8891 | ||
|
|
df5024892c | ||
|
|
4448c3f28c | ||
|
|
196ae33295 | ||
|
|
7f1b7a6c97 | ||
|
|
a6ccafcc75 | ||
|
|
06d87299a3 | ||
|
|
5891ec1b93 | ||
|
|
c5d9e04c2c | ||
|
|
dba3da28c1 | ||
|
|
a0e09cd804 | ||
|
|
d0e70f7246 | ||
|
|
b93c683f17 | ||
|
|
f80e1ea66c | ||
|
|
7642bfa1a3 | ||
|
|
8f304a849f | ||
|
|
33c026c7e2 | ||
|
|
d84fd5c801 |
@@ -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
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -132,7 +132,7 @@ const columns = [
|
||||
if (typeof cell !== 'object') {
|
||||
dateObj = new Date(cell);
|
||||
}
|
||||
return `${('0' + dateObj.getDate()).slice(-2)}/${('0' + (dateObj.getMonth() + 1)).slice(-2)}/${dateObj.getFullYear()}`;
|
||||
return `${('0' + dateObj.getUTCDate()).slice(-2)}/${('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/${dateObj.getUTCFullYear()}`;
|
||||
},
|
||||
editor: {
|
||||
type: Type.DATE
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-editor",
|
||||
"version": "1.2.2",
|
||||
"version": "1.2.3",
|
||||
"description": "it's the editor addon for react-bootstrap-table2",
|
||||
"main": "./lib/index.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -23,7 +23,7 @@ const columns = [{
|
||||
if (typeof cell !== 'object') {
|
||||
dateObj = new Date(cell);
|
||||
}
|
||||
return `${('0' + dateObj.getDate()).slice(-2)}/${('0' + (dateObj.getMonth() + 1)).slice(-2)}/${dateObj.getFullYear()}`;
|
||||
return `${('0' + dateObj.getUTCDate()).slice(-2)}/${('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/${dateObj.getUTCFullYear()}`;
|
||||
},
|
||||
editor: {
|
||||
type: Type.DATE
|
||||
@@ -48,7 +48,7 @@ const columns = [{
|
||||
if (typeof cell !== 'object') {
|
||||
dateObj = new Date(cell);
|
||||
}
|
||||
return \`$\{('0' + dateObj.getDate()).slice(-2)}/$\{('0' + (dateObj.getMonth() + 1)).slice(-2)}/$\{dateObj.getFullYear()}\`;
|
||||
return \`$\{('0' + dateObj.getUTCDate()).slice(-2)}/$\{('0' + (dateObj.getUTCMonth() + 1)).slice(-2)}/$\{dateObj.getUTCFullYear()}\`;
|
||||
},
|
||||
editor: {
|
||||
type: Type.DATE
|
||||
|
||||
@@ -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 }
|
||||
|
||||
102
packages/react-bootstrap-table2-example/examples/csv/export-only-filtered.js
vendored
Normal file
102
packages/react-bootstrap-table2-example/examples/csv/export-only-filtered.js
vendored
Normal 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>
|
||||
);
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-example",
|
||||
"version": "1.0.20",
|
||||
"version": "1.0.23",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"private": true,
|
||||
|
||||
@@ -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 />)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table2-filter",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.8",
|
||||
"description": "it's a column filter addon for react-bootstrap-table2",
|
||||
"main": "./lib/index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -18,7 +18,7 @@ const legalComparators = [
|
||||
];
|
||||
|
||||
function dateParser(d) {
|
||||
return `${d.getFullYear()}-${('0' + (d.getMonth() + 1)).slice(-2)}-${('0' + d.getDate()).slice(-2)}`;
|
||||
return `${d.getUTCFullYear()}-${('0' + (d.getUTCMonth() + 1)).slice(-2)}-${('0' + d.getUTCDate()).slice(-2)}`;
|
||||
}
|
||||
|
||||
class DateFilter extends Component {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -98,9 +98,9 @@ export const filterByDate = _ => (
|
||||
customFilterValue
|
||||
) => {
|
||||
if (!date || !comparator) return data;
|
||||
const filterDate = date.getDate();
|
||||
const filterMonth = date.getMonth();
|
||||
const filterYear = date.getFullYear();
|
||||
const filterDate = date.getUTCDate();
|
||||
const filterMonth = date.getUTCMonth();
|
||||
const filterYear = date.getUTCFullYear();
|
||||
|
||||
return data.filter((row) => {
|
||||
let valid = true;
|
||||
@@ -114,9 +114,9 @@ export const filterByDate = _ => (
|
||||
cell = new Date(cell);
|
||||
}
|
||||
|
||||
const targetDate = cell.getDate();
|
||||
const targetMonth = cell.getMonth();
|
||||
const targetYear = cell.getFullYear();
|
||||
const targetDate = cell.getUTCDate();
|
||||
const targetMonth = cell.getUTCMonth();
|
||||
const targetYear = cell.getUTCFullYear();
|
||||
|
||||
|
||||
switch (comparator) {
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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 if (totalPages > 1 || alwaysShowAllBtns) {
|
||||
pages = [prePageText];
|
||||
} else {
|
||||
pages = [];
|
||||
pages = [prePageText];
|
||||
}
|
||||
}
|
||||
|
||||
if (startPage !== pageStartIndex &&
|
||||
totalPages > paginationSize &&
|
||||
withFirstAndLast &&
|
||||
pages.length === 0
|
||||
) {
|
||||
pages = [firstPageText, prePageText];
|
||||
} else if (totalPages > 1 && pages.length === 0) {
|
||||
pages = [prePageText];
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
})
|
||||
])
|
||||
|
||||
@@ -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": {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-bootstrap-table-next",
|
||||
"version": "3.0.1",
|
||||
"version": "3.1.0",
|
||||
"description": "Next generation of react-bootstrap-table",
|
||||
"main": "./lib/index.js",
|
||||
"repository": {
|
||||
@@ -37,6 +37,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"classnames": "2.2.5",
|
||||
"react-transition-group": "2.5.3",
|
||||
"underscore": "1.9.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
|
||||
2
packages/react-bootstrap-table2/src/cell.js
vendored
2
packages/react-bootstrap-table2/src/cell.js
vendored
@@ -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 ||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,18 +10,31 @@ class RowExpandProvider extends React.Component {
|
||||
children: PropTypes.node.isRequired,
|
||||
data: PropTypes.array.isRequired,
|
||||
keyField: PropTypes.string.isRequired
|
||||
}
|
||||
};
|
||||
|
||||
state = { expanded: this.props.expandRow.expanded || [] };
|
||||
state = { expanded: this.props.expandRow.expanded || [],
|
||||
isClosing: this.props.expandRow.isClosing || [] };
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
if (nextProps.expandRow) {
|
||||
const isClosing = this.state.expanded.reduce((acc, cur) => {
|
||||
if (!nextProps.expandRow.expanded.includes(cur)) {
|
||||
acc.push(cur);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
this.setState(() => ({ expanded: nextProps.expandRow.expanded, isClosing }));
|
||||
} else {
|
||||
this.setState(() => ({
|
||||
expanded: nextProps.expandRow.expanded || this.state.expanded
|
||||
expanded: this.state.expanded
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
onClosed = (closedRow) => {
|
||||
this.setState({ isClosing: this.state.isClosing.filter(value => value !== closedRow) });
|
||||
};
|
||||
|
||||
handleRowExpand = (rowKey, expanded, rowIndex, e) => {
|
||||
const { data, keyField, expandRow: { onExpand, onlyOneExpanding, nonExpandable } } = this.props;
|
||||
if (nonExpandable && nonExpandable.includes(rowKey)) {
|
||||
@@ -29,11 +42,15 @@ class RowExpandProvider extends React.Component {
|
||||
}
|
||||
|
||||
let currExpanded = [...this.state.expanded];
|
||||
let isClosing = [...this.state.isClosing];
|
||||
|
||||
if (expanded) {
|
||||
if (onlyOneExpanding) currExpanded = [rowKey];
|
||||
else currExpanded.push(rowKey);
|
||||
if (onlyOneExpanding) {
|
||||
isClosing = isClosing.concat(currExpanded);
|
||||
currExpanded = [rowKey];
|
||||
} else currExpanded.push(rowKey);
|
||||
} else {
|
||||
isClosing.push(rowKey);
|
||||
currExpanded = currExpanded.filter(value => value !== rowKey);
|
||||
}
|
||||
|
||||
@@ -41,8 +58,8 @@ class RowExpandProvider extends React.Component {
|
||||
const row = dataOperator.getRowByRowId(data, keyField, rowKey);
|
||||
onExpand(row, expanded, rowIndex, e);
|
||||
}
|
||||
this.setState(() => ({ expanded: currExpanded }));
|
||||
}
|
||||
this.setState(() => ({ expanded: currExpanded, isClosing }));
|
||||
};
|
||||
|
||||
handleAllRowExpand = (e, expandAll) => {
|
||||
const {
|
||||
@@ -68,7 +85,7 @@ class RowExpandProvider extends React.Component {
|
||||
}
|
||||
|
||||
this.setState(() => ({ expanded: currExpanded }));
|
||||
}
|
||||
};
|
||||
|
||||
render() {
|
||||
const { data, keyField } = this.props;
|
||||
@@ -78,6 +95,8 @@ class RowExpandProvider extends React.Component {
|
||||
...this.props.expandRow,
|
||||
nonExpandable: this.props.expandRow.nonExpandable,
|
||||
expanded: this.state.expanded,
|
||||
isClosing: this.state.isClosing,
|
||||
onClosed: this.onClosed,
|
||||
isAnyExpands: dataOperator.isAnyExpands(data, keyField, this.state.expanded),
|
||||
onRowExpand: this.handleRowExpand,
|
||||
onAllRowExpand: this.handleAllRowExpand
|
||||
|
||||
@@ -1,18 +1,37 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { CSSTransition } from 'react-transition-group';
|
||||
|
||||
const ExpandRow = ({ children, ...rest }) => (
|
||||
<tr className="expanding-row">
|
||||
<td { ...rest }>{ children }</td>
|
||||
const ExpandRow = ({ children, expanded, onClosed, ...rest }) => (
|
||||
<tr>
|
||||
<td className="reset-expansion-style" { ...rest }>
|
||||
<CSSTransition
|
||||
appear
|
||||
in={ expanded }
|
||||
timeout={ 400 }
|
||||
classNames="row-expand-slide"
|
||||
onExited={ onClosed }
|
||||
>
|
||||
<div>
|
||||
<div className="row-expansion-style">
|
||||
{ children }
|
||||
</div>
|
||||
</div>
|
||||
</CSSTransition>
|
||||
</td>
|
||||
</tr>
|
||||
);
|
||||
|
||||
ExpandRow.propTypes = {
|
||||
children: PropTypes.node
|
||||
children: PropTypes.node,
|
||||
expanded: PropTypes.bool,
|
||||
onClosed: PropTypes.func
|
||||
};
|
||||
|
||||
ExpandRow.defaultProps = {
|
||||
children: null
|
||||
children: null,
|
||||
expanded: false,
|
||||
onClosed: null
|
||||
};
|
||||
|
||||
export default ExpandRow;
|
||||
|
||||
@@ -8,8 +8,8 @@ export default (Component) => {
|
||||
const key = props.value;
|
||||
|
||||
const expanded = expandRow.expanded.includes(key);
|
||||
const isClosing = expandRow.isClosing.includes(key);
|
||||
const expandable = !expandRow.nonExpandable || !expandRow.nonExpandable.includes(key);
|
||||
|
||||
return [
|
||||
<Component
|
||||
{ ...props }
|
||||
@@ -18,9 +18,11 @@ export default (Component) => {
|
||||
expandable={ expandable }
|
||||
expandRow={ { ...expandRow } }
|
||||
/>,
|
||||
expanded ? <ExpandRow
|
||||
expanded || isClosing ? <ExpandRow
|
||||
key={ `${key}-expanding` }
|
||||
colSpan={ props.visibleColumnSize }
|
||||
expanded={ expanded }
|
||||
onClosed={ () => expandRow.onClosed(key) }
|
||||
>
|
||||
{ expandRow.renderer(props.row) }
|
||||
</ExpandRow> : null
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -68,10 +68,6 @@
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
tr.expanding-row {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
td.react-bootstrap-table-editing-cell {
|
||||
.animated {
|
||||
animation-fill-mode: both;
|
||||
@@ -161,4 +157,26 @@
|
||||
animation-name: bounceOut;
|
||||
}
|
||||
}
|
||||
.reset-expansion-style{
|
||||
padding: 0;
|
||||
}
|
||||
.row-expansion-style{
|
||||
padding: 8px;
|
||||
}
|
||||
.row-expand-slide-appear{
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
.row-expand-slide-appear-active{
|
||||
max-height: 1000px;
|
||||
transition: max-height 3s linear;
|
||||
}
|
||||
.row-expand-slide-exit{
|
||||
max-height: 1000px;
|
||||
}
|
||||
.row-expand-slide-exit-active{
|
||||
max-height: 0;
|
||||
overflow: hidden;
|
||||
transition: max-height 400ms cubic-bezier(0, 0.95, 0, 0.95)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user