mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2026-06-29 21:50:07 +00:00
Compare commits
18 Commits
react-boot
...
react-boot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
06d87299a3 | ||
|
|
5891ec1b93 | ||
|
|
c5d9e04c2c | ||
|
|
d0e70f7246 | ||
|
|
b93c683f17 | ||
|
|
f80e1ea66c | ||
|
|
7642bfa1a3 | ||
|
|
956f1cef4d | ||
|
|
c45deee590 | ||
|
|
2aab4301dd | ||
|
|
43aa280761 | ||
|
|
3af30a0265 | ||
|
|
4b8b8b261e | ||
|
|
e44782f222 | ||
|
|
921e8c7ecc | ||
|
|
a3b3ce0dc4 | ||
|
|
e9f08d278d | ||
|
|
b4973c826c |
@@ -69,7 +69,7 @@ const cellEdit: {
|
|||||||
// omit...
|
// omit...
|
||||||
beforeSaveCell(oldValue, newValue, row, column, done) {
|
beforeSaveCell(oldValue, newValue, row, column, done) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (confirm('Do you want to accep this change?')) {
|
if (confirm('Do you want to accept this change?')) {
|
||||||
done(); // contine to save the changes
|
done(); // contine to save the changes
|
||||||
} else {
|
} else {
|
||||||
done(false); // reject the changes
|
done(false); // reject the changes
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ Enable the column sort via a `true` value given.
|
|||||||
```
|
```
|
||||||
|
|
||||||
## <a name='sortCaret'>column.sortCaret - [Function]</a>
|
## <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
|
```js
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
# Row expand
|
# Row expand
|
||||||
`react-bootstrap-table2` supports the row expand feature. By passing prop `expandRow` to enable this functionality.
|
`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
|
## Required
|
||||||
* [renderer (**required**)](#renderer)
|
* [renderer (**required**)](#renderer)
|
||||||
|
|||||||
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>
|
||||||
|
);
|
||||||
@@ -7,7 +7,7 @@ import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
|
|||||||
import Code from 'components/common/code-block';
|
import Code from 'components/common/code-block';
|
||||||
import { productsGenerator } from 'utils/common';
|
import { productsGenerator } from 'utils/common';
|
||||||
|
|
||||||
const products = productsGenerator(21);
|
const products = productsGenerator(40);
|
||||||
const { SearchBar } = Search;
|
const { SearchBar } = Search;
|
||||||
|
|
||||||
const columns = [{
|
const columns = [{
|
||||||
@@ -24,6 +24,12 @@ import paginationFactory, { PaginationProvider, PaginationListStandalone } from
|
|||||||
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 {
|
||||||
|
state = { products }
|
||||||
|
|
||||||
|
loadData = () => {
|
||||||
|
this.setState({ products: productsGenerator(17) });
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const options = {
|
const options = {
|
||||||
custom: true,
|
custom: true,
|
||||||
@@ -38,70 +44,84 @@ class Table extends React.Component {
|
|||||||
firstPageTitle: 'Next page',
|
firstPageTitle: 'Next page',
|
||||||
lastPageTitle: 'Last page',
|
lastPageTitle: 'Last page',
|
||||||
showTotal: true,
|
showTotal: true,
|
||||||
totalSize: products.length
|
totalSize: this.state.products.length
|
||||||
};
|
|
||||||
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
|
||||||
<div>
|
|
||||||
<PaginationListStandalone { ...paginationProps } />
|
|
||||||
<div>
|
|
||||||
<div>
|
|
||||||
<BootstrapTable
|
|
||||||
striped
|
|
||||||
hover
|
|
||||||
keyField="id"
|
|
||||||
data={ products }
|
|
||||||
columns={ columns }
|
|
||||||
filter={ filterFactory() }
|
|
||||||
cellEdit={ cellEditFactory() }
|
|
||||||
{ ...paginationTableProps }
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<PaginationListStandalone { ...paginationProps } />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h2>PaginationProvider will care the data size change. You dont do anything</h2>
|
|
||||||
<PaginationProvider
|
|
||||||
pagination={
|
|
||||||
paginationFactory(options)
|
|
||||||
}
|
|
||||||
>
|
|
||||||
{ contentTable }
|
|
||||||
</PaginationProvider>
|
|
||||||
<Code>{ sourceCode }</Code>
|
|
||||||
</div >
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
export default class Table extends React.Component {
|
|
||||||
render() {
|
|
||||||
const options = {
|
|
||||||
custom: true,
|
|
||||||
paginationSize: 4,
|
|
||||||
pageStartIndex: 1,
|
|
||||||
firstPageText: 'First',
|
|
||||||
prePageText: 'Back',
|
|
||||||
nextPageText: 'Next',
|
|
||||||
lastPageText: 'Last',
|
|
||||||
nextPageTitle: 'First page',
|
|
||||||
prePageTitle: 'Pre page',
|
|
||||||
firstPageTitle: 'Next page',
|
|
||||||
lastPageTitle: 'Last page',
|
|
||||||
showTotal: true,
|
|
||||||
totalSize: products.length
|
|
||||||
};
|
};
|
||||||
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
||||||
<div>
|
<div>
|
||||||
|
<button className="btn btn-default" onClick={ this.loadData }>Load Another Data</button>
|
||||||
<PaginationListStandalone { ...paginationProps } />
|
<PaginationListStandalone { ...paginationProps } />
|
||||||
<ToolkitProvider
|
<ToolkitProvider
|
||||||
keyField="id"
|
keyField="id"
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
data={ products }
|
data={ this.state.products }
|
||||||
|
search
|
||||||
|
>
|
||||||
|
{
|
||||||
|
toolkitprops => (
|
||||||
|
<div>
|
||||||
|
<SearchBar { ...toolkitprops.searchProps } />
|
||||||
|
<BootstrapTable
|
||||||
|
striped
|
||||||
|
hover
|
||||||
|
{ ...toolkitprops.baseProps }
|
||||||
|
{ ...paginationTableProps }
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
</ToolkitProvider>
|
||||||
|
<PaginationListStandalone { ...paginationProps } />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h2>PaginationProvider will care the data size change. You dont do anything</h2>
|
||||||
|
<PaginationProvider
|
||||||
|
pagination={
|
||||||
|
paginationFactory(options)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{ contentTable }
|
||||||
|
</PaginationProvider>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</div >
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default class Table extends React.Component {
|
||||||
|
state = { products }
|
||||||
|
|
||||||
|
loadData = () => {
|
||||||
|
this.setState({ products: productsGenerator(17) });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const options = {
|
||||||
|
custom: true,
|
||||||
|
paginationSize: 4,
|
||||||
|
pageStartIndex: 1,
|
||||||
|
firstPageText: 'First',
|
||||||
|
prePageText: 'Back',
|
||||||
|
nextPageText: 'Next',
|
||||||
|
lastPageText: 'Last',
|
||||||
|
nextPageTitle: 'First page',
|
||||||
|
prePageTitle: 'Pre page',
|
||||||
|
firstPageTitle: 'Next page',
|
||||||
|
lastPageTitle: 'Last page',
|
||||||
|
showTotal: true,
|
||||||
|
totalSize: this.state.products.length
|
||||||
|
};
|
||||||
|
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
||||||
|
<div>
|
||||||
|
<button className="btn btn-default" onClick={ this.loadData }>Load Another Data</button>
|
||||||
|
<PaginationListStandalone { ...paginationProps } />
|
||||||
|
<ToolkitProvider
|
||||||
|
keyField="id"
|
||||||
|
columns={ columns }
|
||||||
|
data={ this.state.products }
|
||||||
search
|
search
|
||||||
>
|
>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,28 +3,70 @@ import React from 'react';
|
|||||||
|
|
||||||
import BootstrapTable from 'react-bootstrap-table-next';
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
import filterFactory, { textFilter, selectFilter } from 'react-bootstrap-table2-filter';
|
||||||
import Code from 'components/common/code-block';
|
import Code from 'components/common/code-block';
|
||||||
import { productsGenerator } from 'utils/common';
|
import { productsQualityGenerator } from 'utils/common';
|
||||||
|
|
||||||
const products = productsGenerator(21);
|
const products = productsQualityGenerator(21);
|
||||||
|
|
||||||
|
const selectOptions = {
|
||||||
|
0: 'good',
|
||||||
|
1: 'Bad',
|
||||||
|
2: 'unknown'
|
||||||
|
};
|
||||||
|
|
||||||
const columns = [{
|
const columns = [{
|
||||||
dataField: 'id',
|
dataField: 'id',
|
||||||
text: 'Product ID',
|
text: 'Product ID'
|
||||||
filter: textFilter({})
|
|
||||||
}, {
|
}, {
|
||||||
dataField: 'name',
|
dataField: 'name',
|
||||||
text: 'Product Name',
|
text: 'Product Name',
|
||||||
filter: textFilter()
|
filter: textFilter()
|
||||||
|
}, {
|
||||||
|
dataField: 'quality',
|
||||||
|
text: 'Product Quailty',
|
||||||
|
formatter: cell => selectOptions[cell],
|
||||||
|
filter: selectFilter({
|
||||||
|
options: selectOptions,
|
||||||
|
defaultValue: 0
|
||||||
|
})
|
||||||
}];
|
}];
|
||||||
|
|
||||||
const sourceCode = `\
|
const sourceCode = `\
|
||||||
import BootstrapTable from 'react-bootstrap-table-next';
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
import paginationFactory, { PaginationProvider, PaginationListStandalone } from 'react-bootstrap-table2-paginator';
|
||||||
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
|
import filterFactory, { textFilter, selectFilter } from 'react-bootstrap-table2-filter';
|
||||||
|
|
||||||
|
const selectOptions = {
|
||||||
|
0: 'good',
|
||||||
|
1: 'Bad',
|
||||||
|
2: 'unknown'
|
||||||
|
};
|
||||||
|
|
||||||
|
const columns = [{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID'
|
||||||
|
}, {
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name',
|
||||||
|
filter: textFilter()
|
||||||
|
}, {
|
||||||
|
dataField: 'quality',
|
||||||
|
text: 'Product Quailty',
|
||||||
|
formatter: cell => selectOptions[cell],
|
||||||
|
filter: selectFilter({
|
||||||
|
options: selectOptions,
|
||||||
|
defaultValue: 0
|
||||||
|
})
|
||||||
|
}];
|
||||||
|
|
||||||
class Table extends React.Component {
|
class Table extends React.Component {
|
||||||
|
state = { products }
|
||||||
|
|
||||||
|
loadData = () => {
|
||||||
|
this.setState({ products: productsQualityGenerator(40, 7) });
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const options = {
|
const options = {
|
||||||
custom: true,
|
custom: true,
|
||||||
@@ -39,10 +81,11 @@ class Table extends React.Component {
|
|||||||
firstPageTitle: 'Next page',
|
firstPageTitle: 'Next page',
|
||||||
lastPageTitle: 'Last page',
|
lastPageTitle: 'Last page',
|
||||||
showTotal: true,
|
showTotal: true,
|
||||||
totalSize: products.length
|
totalSize: this.state.products.length
|
||||||
};
|
};
|
||||||
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
||||||
<div>
|
<div>
|
||||||
|
<button className="btn btn-default" onClick={ this.loadData }>Load Another Data</button>
|
||||||
<PaginationListStandalone { ...paginationProps } />
|
<PaginationListStandalone { ...paginationProps } />
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
@@ -50,10 +93,9 @@ class Table extends React.Component {
|
|||||||
striped
|
striped
|
||||||
hover
|
hover
|
||||||
keyField="id"
|
keyField="id"
|
||||||
data={ products }
|
data={ this.state.products }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
filter={ filterFactory() }
|
filter={ filterFactory() }
|
||||||
cellEdit={ cellEditFactory() }
|
|
||||||
{ ...paginationTableProps }
|
{ ...paginationTableProps }
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -72,7 +114,6 @@ class Table extends React.Component {
|
|||||||
>
|
>
|
||||||
{ contentTable }
|
{ contentTable }
|
||||||
</PaginationProvider>
|
</PaginationProvider>
|
||||||
<Code>{ sourceCode }</Code>
|
|
||||||
</div >
|
</div >
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -80,6 +121,12 @@ class Table extends React.Component {
|
|||||||
`;
|
`;
|
||||||
|
|
||||||
export default class Table extends React.Component {
|
export default class Table extends React.Component {
|
||||||
|
state = { products }
|
||||||
|
|
||||||
|
loadData = () => {
|
||||||
|
this.setState({ products: productsQualityGenerator(40, 7) });
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const options = {
|
const options = {
|
||||||
custom: true,
|
custom: true,
|
||||||
@@ -94,10 +141,11 @@ export default class Table extends React.Component {
|
|||||||
firstPageTitle: 'Next page',
|
firstPageTitle: 'Next page',
|
||||||
lastPageTitle: 'Last page',
|
lastPageTitle: 'Last page',
|
||||||
showTotal: true,
|
showTotal: true,
|
||||||
totalSize: products.length
|
totalSize: this.state.products.length
|
||||||
};
|
};
|
||||||
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
const contentTable = ({ paginationProps, paginationTableProps }) => (
|
||||||
<div>
|
<div>
|
||||||
|
<button className="btn btn-default" onClick={ this.loadData }>Load Another Data</button>
|
||||||
<PaginationListStandalone { ...paginationProps } />
|
<PaginationListStandalone { ...paginationProps } />
|
||||||
<div>
|
<div>
|
||||||
<div>
|
<div>
|
||||||
@@ -105,7 +153,7 @@ export default class Table extends React.Component {
|
|||||||
striped
|
striped
|
||||||
hover
|
hover
|
||||||
keyField="id"
|
keyField="id"
|
||||||
data={ products }
|
data={ this.state.products }
|
||||||
columns={ columns }
|
columns={ columns }
|
||||||
filter={ filterFactory() }
|
filter={ filterFactory() }
|
||||||
{ ...paginationTableProps }
|
{ ...paginationTableProps }
|
||||||
|
|||||||
150
packages/react-bootstrap-table2-example/examples/pagination/pagination-with-dynamic-data.js
vendored
Normal file
150
packages/react-bootstrap-table2-example/examples/pagination/pagination-with-dynamic-data.js
vendored
Normal file
@@ -0,0 +1,150 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||||
|
import Code from 'components/common/code-block';
|
||||||
|
|
||||||
|
const sourceCode = `\
|
||||||
|
import BootstrapTable from 'react-bootstrap-table-next';
|
||||||
|
import paginationFactory from 'react-bootstrap-table2-paginator';
|
||||||
|
|
||||||
|
class BookList extends React.Component {
|
||||||
|
state = {
|
||||||
|
books: [
|
||||||
|
{ id: '1', name: 'Book 1' },
|
||||||
|
{ id: '2', name: 'Book 2' },
|
||||||
|
{ id: '3', name: 'Book 3' },
|
||||||
|
{ id: '4', name: 'Book 4' },
|
||||||
|
{ id: '5', name: 'Book 5' },
|
||||||
|
{ id: '6', name: 'Book 6' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteBookWithId = () => {
|
||||||
|
const lastOneId = this.state.books.length;
|
||||||
|
const updatedBooks = this.state.books.filter(m => m.id !== lastOneId.toString());
|
||||||
|
this.setState({ books: updatedBooks });
|
||||||
|
};
|
||||||
|
|
||||||
|
addBook = () => {
|
||||||
|
const lastOneId = this.state.books.length + 1;
|
||||||
|
this.setState({ books: [...this.state.books, {
|
||||||
|
id: \`$\{lastOneId}\`, name: \`Book $\{lastOneId}\`
|
||||||
|
}] });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const options = {
|
||||||
|
// pageStartIndex: 0,
|
||||||
|
sizePerPage: 5,
|
||||||
|
hideSizePerPage: true,
|
||||||
|
hidePageListOnlyOnePage: true
|
||||||
|
};
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID',
|
||||||
|
Cell: row => (
|
||||||
|
<div>
|
||||||
|
<span title={ row.value }>{ row.value }</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ this.state.books }
|
||||||
|
columns={ columns }
|
||||||
|
pagination={ paginationFactory(options) }
|
||||||
|
/>
|
||||||
|
<button className="btn btn-default" onClick={ () => this.deleteBookWithId() }>
|
||||||
|
delete last one book
|
||||||
|
</button>
|
||||||
|
<button className="btn btn-default" onClick={ () => this.addBook() }>
|
||||||
|
Add a book to the end
|
||||||
|
</button>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export default class BookList extends React.Component {
|
||||||
|
state = {
|
||||||
|
books: [
|
||||||
|
{ id: '1', name: 'Book 1' },
|
||||||
|
{ id: '2', name: 'Book 2' },
|
||||||
|
{ id: '3', name: 'Book 3' },
|
||||||
|
{ id: '4', name: 'Book 4' },
|
||||||
|
{ id: '5', name: 'Book 5' },
|
||||||
|
{ id: '6', name: 'Book 6' },
|
||||||
|
{ id: '7', name: 'Book 6' },
|
||||||
|
{ id: '8', name: 'Book 6' },
|
||||||
|
{ id: '9', name: 'Book 6' },
|
||||||
|
{ id: '10', name: 'Book 6' },
|
||||||
|
{ id: '11', name: 'Book 6' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
deleteBookWithId = () => {
|
||||||
|
const lastOneId = this.state.books.length;
|
||||||
|
const updatedBooks = this.state.books.filter(m => m.id !== lastOneId.toString());
|
||||||
|
this.setState({ books: updatedBooks });
|
||||||
|
};
|
||||||
|
|
||||||
|
addBook = () => {
|
||||||
|
const lastOneId = this.state.books.length + 1;
|
||||||
|
this.setState({ books: [...this.state.books, {
|
||||||
|
id: `${lastOneId}`, name: `Book ${lastOneId}`
|
||||||
|
}] });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const options = {
|
||||||
|
// pageStartIndex: 0,
|
||||||
|
sizePerPage: 5,
|
||||||
|
hideSizePerPage: true,
|
||||||
|
hidePageListOnlyOnePage: true
|
||||||
|
};
|
||||||
|
const columns = [
|
||||||
|
{
|
||||||
|
dataField: 'id',
|
||||||
|
text: 'Product ID',
|
||||||
|
Cell: row => (
|
||||||
|
<div>
|
||||||
|
<span title={ row.value }>{ row.value }</span>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
dataField: 'name',
|
||||||
|
text: 'Product Name'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<BootstrapTable
|
||||||
|
keyField="id"
|
||||||
|
data={ this.state.books }
|
||||||
|
columns={ columns }
|
||||||
|
pagination={ paginationFactory(options) }
|
||||||
|
/>
|
||||||
|
<button className="btn btn-default" onClick={ () => this.deleteBookWithId() }>
|
||||||
|
delete last one book
|
||||||
|
</button>
|
||||||
|
<button className="btn btn-default" onClick={ () => this.addBook() }>
|
||||||
|
Add a book to the end
|
||||||
|
</button>
|
||||||
|
<Code>{ sourceCode }</Code>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -84,6 +84,7 @@ export default class StandaloneSizePerPage extends React.Component {
|
|||||||
<div>
|
<div>
|
||||||
<SizePerPageDropdownStandalone
|
<SizePerPageDropdownStandalone
|
||||||
{ ...paginationProps }
|
{ ...paginationProps }
|
||||||
|
btnContextual="btn btn-primary"
|
||||||
/>
|
/>
|
||||||
<BootstrapTable
|
<BootstrapTable
|
||||||
keyField="id"
|
keyField="id"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-bootstrap-table2-example",
|
"name": "react-bootstrap-table2-example",
|
||||||
"version": "1.0.19",
|
"version": "1.0.21",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"private": true,
|
"private": true,
|
||||||
|
|||||||
@@ -29,10 +29,10 @@ export const withOnSale = rows => rows.map((row) => {
|
|||||||
return row;
|
return row;
|
||||||
});
|
});
|
||||||
|
|
||||||
export const productsQualityGenerator = (quantity = 5) =>
|
export const productsQualityGenerator = (quantity = 5, factor = 0) =>
|
||||||
Array.from({ length: quantity }, (value, index) => ({
|
Array.from({ length: quantity }, (value, index) => ({
|
||||||
id: index,
|
id: index + factor,
|
||||||
name: `Item name ${index}`,
|
name: `Item name ${index + factor}`,
|
||||||
quality: index % 3
|
quality: index % 3
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -163,6 +163,7 @@ import ExpandHooks from 'examples/row-expand/expand-hooks';
|
|||||||
// pagination
|
// pagination
|
||||||
import PaginationTable from 'examples/pagination';
|
import PaginationTable from 'examples/pagination';
|
||||||
import PaginationHooksTable from 'examples/pagination/pagination-hooks';
|
import PaginationHooksTable from 'examples/pagination/pagination-hooks';
|
||||||
|
import PaginationWithDynamicData from 'examples/pagination/pagination-with-dynamic-data';
|
||||||
import CustomPaginationTable from 'examples/pagination/custom-pagination';
|
import CustomPaginationTable from 'examples/pagination/custom-pagination';
|
||||||
import CustomPageButtonTable from 'examples/pagination/custom-page-button';
|
import CustomPageButtonTable from 'examples/pagination/custom-page-button';
|
||||||
import CustomSizePerPageOptionTable from 'examples/pagination/custom-size-per-page-option';
|
import CustomSizePerPageOptionTable from 'examples/pagination/custom-size-per-page-option';
|
||||||
@@ -191,6 +192,7 @@ import CSVFormatter from 'examples/csv/csv-column-formatter';
|
|||||||
import CustomCSVHeader from 'examples/csv/custom-csv-header';
|
import CustomCSVHeader from 'examples/csv/custom-csv-header';
|
||||||
import HideCSVColumn from 'examples/csv/hide-column';
|
import HideCSVColumn from 'examples/csv/hide-column';
|
||||||
import ExportOnlySelected from 'examples/csv/export-only-selected';
|
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 CSVColumnType from 'examples/csv/csv-column-type';
|
||||||
import CustomCSVButton from 'examples/csv/custom-csv-button';
|
import CustomCSVButton from 'examples/csv/custom-csv-button';
|
||||||
import ExportCustomData from 'examples/csv/export-custom-data';
|
import ExportCustomData from 'examples/csv/export-custom-data';
|
||||||
@@ -404,6 +406,7 @@ storiesOf('Pagination', module)
|
|||||||
.addDecorator(bootstrapStyle())
|
.addDecorator(bootstrapStyle())
|
||||||
.add('Basic Pagination Table', () => <PaginationTable />)
|
.add('Basic Pagination Table', () => <PaginationTable />)
|
||||||
.add('Pagination Hooks', () => <PaginationHooksTable />)
|
.add('Pagination Hooks', () => <PaginationHooksTable />)
|
||||||
|
.add('Pagination with Dynamic Data', () => <PaginationWithDynamicData />)
|
||||||
.add('Custom Pagination', () => <CustomPaginationTable />)
|
.add('Custom Pagination', () => <CustomPaginationTable />)
|
||||||
.add('Custom Page Button', () => <CustomPageButtonTable />)
|
.add('Custom Page Button', () => <CustomPageButtonTable />)
|
||||||
.add('Custom Page List', () => <CustomPageListTable />)
|
.add('Custom Page List', () => <CustomPageListTable />)
|
||||||
@@ -441,6 +444,7 @@ storiesOf('Export CSV', module)
|
|||||||
.add('Custom CSV Header', () => <CustomCSVHeader />)
|
.add('Custom CSV Header', () => <CustomCSVHeader />)
|
||||||
.add('Hide CSV Column', () => <HideCSVColumn />)
|
.add('Hide CSV Column', () => <HideCSVColumn />)
|
||||||
.add('Only Export Selected Rows', () => <ExportOnlySelected />)
|
.add('Only Export Selected Rows', () => <ExportOnlySelected />)
|
||||||
|
.add('Only Export Filtered/Searched Rows', () => <ExportOnlyFiltered />)
|
||||||
.add('CSV Column Type', () => <CSVColumnType />)
|
.add('CSV Column Type', () => <CSVColumnType />)
|
||||||
.add('Custom CSV Button', () => <CustomCSVButton />)
|
.add('Custom CSV Button', () => <CustomCSVButton />)
|
||||||
.add('Export Custom Data', () => <ExportCustomData />)
|
.add('Export Custom Data', () => <ExportCustomData />)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-bootstrap-table2-filter",
|
"name": "react-bootstrap-table2-filter",
|
||||||
"version": "1.1.5",
|
"version": "1.1.7",
|
||||||
"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": {
|
||||||
|
|||||||
@@ -27,9 +27,8 @@ export default (
|
|||||||
this.onFilter = this.onFilter.bind(this);
|
this.onFilter = this.onFilter.bind(this);
|
||||||
this.doFilter = this.doFilter.bind(this);
|
this.doFilter = this.doFilter.bind(this);
|
||||||
this.onExternalFilter = this.onExternalFilter.bind(this);
|
this.onExternalFilter = this.onExternalFilter.bind(this);
|
||||||
this.state = {
|
this.data = props.data;
|
||||||
data: props.data
|
this.isEmitDataChange = false;
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -39,13 +38,12 @@ export default (
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
let nextData = nextProps.data;
|
// let nextData = nextProps.data;
|
||||||
if (!isRemoteFiltering() && !_.isEqual(nextProps.data, this.state.data)) {
|
if (!isRemoteFiltering() && !_.isEqual(nextProps.data, this.data)) {
|
||||||
nextData = this.doFilter(nextProps);
|
this.doFilter(nextProps, undefined, this.isEmitDataChange);
|
||||||
|
} else {
|
||||||
|
this.data = nextProps.data;
|
||||||
}
|
}
|
||||||
this.setState({
|
|
||||||
data: nextData
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onFilter(column, filterType, initialize = false) {
|
onFilter(column, filterType, initialize = false) {
|
||||||
@@ -83,9 +81,7 @@ export default (
|
|||||||
if (filter.props.onFilter) {
|
if (filter.props.onFilter) {
|
||||||
result = filter.props.onFilter(filterVal);
|
result = filter.props.onFilter(filterVal);
|
||||||
}
|
}
|
||||||
|
this.doFilter(this.props, result);
|
||||||
result = this.doFilter(this.props, result);
|
|
||||||
this.setState({ data: result });
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,21 +91,29 @@ export default (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
doFilter(props, customResult) {
|
getFiltered() {
|
||||||
|
return this.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
doFilter(props, customResult, ignoreEmitDataChange = false) {
|
||||||
let result = customResult;
|
let result = customResult;
|
||||||
|
|
||||||
const { dataChangeListener, data, columns } = props;
|
const { dataChangeListener, data, columns } = props;
|
||||||
result = result || filters(data, columns, _)(this.currFilters);
|
result = result || filters(data, columns, _)(this.currFilters);
|
||||||
if (dataChangeListener) {
|
this.data = result;
|
||||||
|
if (dataChangeListener && !ignoreEmitDataChange) {
|
||||||
|
this.isEmitDataChange = true;
|
||||||
dataChangeListener.emit('filterChanged', result.length);
|
dataChangeListener.emit('filterChanged', result.length);
|
||||||
|
} else {
|
||||||
|
this.isEmitDataChange = false;
|
||||||
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<FilterContext.Provider value={ {
|
<FilterContext.Provider value={ {
|
||||||
data: this.state.data,
|
data: this.data,
|
||||||
onFilter: this.onFilter,
|
onFilter: this.onFilter,
|
||||||
onExternalFilter: this.onExternalFilter
|
onExternalFilter: this.onExternalFilter
|
||||||
} }
|
} }
|
||||||
|
|||||||
@@ -283,9 +283,9 @@ describe('FilterContext', () => {
|
|||||||
expect(onFilter).toHaveBeenCalledWith(filterVal);
|
expect(onFilter).toHaveBeenCalledWith(filterVal);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set state.data correctly', () => {
|
it('should set data correctly', () => {
|
||||||
instance.onFilter(customColumns[1], FILTER_TYPE.TEXT)(filterVal);
|
instance.onFilter(customColumns[1], FILTER_TYPE.TEXT)(filterVal);
|
||||||
expect(instance.state.data).toEqual(mockReturn);
|
expect(instance.data).toEqual(mockReturn);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -190,6 +190,19 @@ import paginationFactory, {
|
|||||||
|
|
||||||
That's it!! The benifit for using standalone is you can much easier to render the standalone component in any posistion. In the future, we will implement more featue like applying `style`, `className` etc on standalone components.
|
That's it!! The benifit for using standalone is you can much easier to render the standalone component in any posistion. In the future, we will implement more featue like applying `style`, `className` etc on standalone components.
|
||||||
|
|
||||||
|
##### Customizable props for `PaginationListStandalone`
|
||||||
|
* N/A
|
||||||
|
|
||||||
|
##### Customizable props for `SizePerPageDropdownStandalone`
|
||||||
|
* `open`: `true` to make dropdown show.
|
||||||
|
* `hidden`: `true` to hide the size per page dropdown.
|
||||||
|
* `btnContextual`: Set the button contextual
|
||||||
|
* `variation`: Variation for dropdown, available value is `dropdown` and `dropup`.
|
||||||
|
* `className`: Custom the class on size per page dropdown
|
||||||
|
|
||||||
|
##### Customizable props for `SizePerPageDropdownStandalone`
|
||||||
|
* N/A
|
||||||
|
|
||||||
#### 4.2 Customization Everything
|
#### 4.2 Customization Everything
|
||||||
|
|
||||||
If you choose to custom the pagination component by yourself, the `paginationProps` will be important for you. Becasue you have to know for example how to change page or what's the current page etc. Hence, following is all the props in `paginationProps` object:
|
If you choose to custom the pagination component by yourself, the `paginationProps` will be important for you. Becasue you have to know for example how to change page or what's the current page etc. Hence, following is all the props in `paginationProps` object:
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-bootstrap-table2-paginator",
|
"name": "react-bootstrap-table2-paginator",
|
||||||
"version": "2.0.3",
|
"version": "2.0.4",
|
||||||
"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": {
|
||||||
|
|||||||
@@ -32,7 +32,12 @@ class PaginationDataProvider extends Provider {
|
|||||||
// user should align the page when the page is not fit to the data size when remote enable
|
// user should align the page when the page is not fit to the data size when remote enable
|
||||||
if (!this.isRemotePagination() && !custom) {
|
if (!this.isRemotePagination() && !custom) {
|
||||||
const newPage = alignPage(
|
const newPage = alignPage(
|
||||||
nextProps.data.length, this.currPage, currSizePerPage, pageStartIndex);
|
nextProps.data.length,
|
||||||
|
this.props.data.length,
|
||||||
|
this.currPage,
|
||||||
|
currSizePerPage,
|
||||||
|
pageStartIndex
|
||||||
|
);
|
||||||
|
|
||||||
if (this.currPage !== newPage) {
|
if (this.currPage !== newPage) {
|
||||||
if (onPageChange) {
|
if (onPageChange) {
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import Const from './const';
|
||||||
|
|
||||||
const getNormalizedPage = (
|
const getNormalizedPage = (
|
||||||
page,
|
page,
|
||||||
pageStartIndex
|
pageStartIndex
|
||||||
@@ -19,12 +21,20 @@ const startIndex = (
|
|||||||
|
|
||||||
export const alignPage = (
|
export const alignPage = (
|
||||||
dataSize,
|
dataSize,
|
||||||
|
prevDataSize,
|
||||||
page,
|
page,
|
||||||
sizePerPage,
|
sizePerPage,
|
||||||
pageStartIndex
|
pageStartIndex
|
||||||
) => {
|
) => {
|
||||||
if (page < pageStartIndex || page > (Math.floor(dataSize / sizePerPage) + pageStartIndex)) {
|
if (prevDataSize < dataSize) return page;
|
||||||
return pageStartIndex;
|
if (page < pageStartIndex) return pageStartIndex;
|
||||||
|
if (dataSize <= 0) return pageStartIndex;
|
||||||
|
if ((page >= (Math.floor(dataSize / sizePerPage) + pageStartIndex)) && pageStartIndex === 1) {
|
||||||
|
return Math.ceil(dataSize / sizePerPage);
|
||||||
|
}
|
||||||
|
if (page >= Math.floor(dataSize / sizePerPage) && pageStartIndex === 0) {
|
||||||
|
const newPage = Math.ceil(dataSize / sizePerPage);
|
||||||
|
return newPage - Math.abs((Const.PAGE_START_INDEX - pageStartIndex));
|
||||||
}
|
}
|
||||||
return page;
|
return page;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ const sizePerPageDropdownAdapter = WrappedComponent =>
|
|||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<WrappedComponent
|
<WrappedComponent
|
||||||
|
{ ...this.props }
|
||||||
currSizePerPage={ `${currSizePerPage}` }
|
currSizePerPage={ `${currSizePerPage}` }
|
||||||
options={ this.calculateSizePerPageStatus() }
|
options={ this.calculateSizePerPageStatus() }
|
||||||
optionRenderer={ sizePerPageOptionRenderer }
|
optionRenderer={ sizePerPageOptionRenderer }
|
||||||
|
|||||||
@@ -50,11 +50,17 @@ class StateProvider extends React.Component {
|
|||||||
|
|
||||||
// user should align the page when the page is not fit to the data size when remote enable
|
// user should align the page when the page is not fit to the data size when remote enable
|
||||||
if (this.isRemotePagination() || custom) {
|
if (this.isRemotePagination() || custom) {
|
||||||
|
if (typeof nextProps.pagination.options.page !== 'undefined') {
|
||||||
this.currPage = nextProps.pagination.options.page;
|
this.currPage = nextProps.pagination.options.page;
|
||||||
|
}
|
||||||
|
if (typeof nextProps.pagination.options.sizePerPage !== 'undefined') {
|
||||||
this.currSizePerPage = nextProps.pagination.options.sizePerPage;
|
this.currSizePerPage = nextProps.pagination.options.sizePerPage;
|
||||||
|
}
|
||||||
|
if (typeof nextProps.pagination.options.totalSize !== 'undefined') {
|
||||||
this.dataSize = nextProps.pagination.options.totalSize;
|
this.dataSize = nextProps.pagination.options.totalSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getPaginationProps = () => {
|
getPaginationProps = () => {
|
||||||
const { pagination: { options }, bootstrap4 } = this.props;
|
const { pagination: { options }, bootstrap4 } = this.props;
|
||||||
@@ -117,13 +123,14 @@ class StateProvider extends React.Component {
|
|||||||
const { pagination: { options } } = this.props;
|
const { pagination: { options } } = this.props;
|
||||||
const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
|
const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
|
||||||
Const.PAGE_START_INDEX : options.pageStartIndex;
|
Const.PAGE_START_INDEX : options.pageStartIndex;
|
||||||
this.dataSize = newDataSize;
|
|
||||||
this.currPage = alignPage(
|
this.currPage = alignPage(
|
||||||
newDataSize,
|
newDataSize,
|
||||||
|
this.dataSize,
|
||||||
this.currPage,
|
this.currPage,
|
||||||
this.currSizePerPage,
|
this.currSizePerPage,
|
||||||
pageStartIndex
|
pageStartIndex
|
||||||
);
|
);
|
||||||
|
this.dataSize = newDataSize;
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,18 +43,132 @@ describe('Page Functions', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe('alignPage', () => {
|
describe('alignPage', () => {
|
||||||
const pageStartIndex = 1;
|
let newDataSize;
|
||||||
const sizePerPage = 10;
|
let prevDataSize;
|
||||||
const page = 3;
|
let currPage;
|
||||||
describe('if the page does not fit the pages which calculated from the length of data', () => {
|
let pageStartIndex;
|
||||||
it('should return pageStartIndex argument', () => {
|
let sizePerPage;
|
||||||
expect(alignPage(15, page, sizePerPage, pageStartIndex)).toEqual(pageStartIndex);
|
|
||||||
|
describe('if prevDataSize < newDataSize', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
newDataSize = 10;
|
||||||
|
prevDataSize = 6;
|
||||||
|
currPage = 2;
|
||||||
|
pageStartIndex = 1;
|
||||||
|
sizePerPage = 5;
|
||||||
|
});
|
||||||
|
it('should return same page', () => {
|
||||||
|
expect(alignPage(
|
||||||
|
newDataSize,
|
||||||
|
prevDataSize,
|
||||||
|
currPage,
|
||||||
|
sizePerPage,
|
||||||
|
pageStartIndex
|
||||||
|
)).toEqual(currPage);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('if the length of store.data is large than the end page index', () => {
|
describe('if currPage < newDataSize', () => {
|
||||||
it('should return current page', () => {
|
beforeEach(() => {
|
||||||
expect(alignPage(30, page, sizePerPage, pageStartIndex)).toEqual(page);
|
newDataSize = 10;
|
||||||
|
prevDataSize = 12;
|
||||||
|
currPage = 0;
|
||||||
|
pageStartIndex = 1;
|
||||||
|
sizePerPage = 5;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct page', () => {
|
||||||
|
expect(alignPage(
|
||||||
|
newDataSize,
|
||||||
|
prevDataSize,
|
||||||
|
currPage,
|
||||||
|
sizePerPage,
|
||||||
|
pageStartIndex
|
||||||
|
)).toEqual(pageStartIndex);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if partStartIndex is default 1', () => {
|
||||||
|
describe('and currPage is bigger than newest last page', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
newDataSize = 9;
|
||||||
|
prevDataSize = 12;
|
||||||
|
currPage = 3;
|
||||||
|
pageStartIndex = 1;
|
||||||
|
sizePerPage = 5;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct page', () => {
|
||||||
|
expect(alignPage(
|
||||||
|
newDataSize,
|
||||||
|
prevDataSize,
|
||||||
|
currPage,
|
||||||
|
sizePerPage,
|
||||||
|
pageStartIndex
|
||||||
|
)).toEqual(2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and currPage is short than newest last page', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
newDataSize = 11;
|
||||||
|
prevDataSize = 12;
|
||||||
|
currPage = 3;
|
||||||
|
pageStartIndex = 1;
|
||||||
|
sizePerPage = 5;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct page', () => {
|
||||||
|
expect(alignPage(
|
||||||
|
newDataSize,
|
||||||
|
prevDataSize,
|
||||||
|
currPage,
|
||||||
|
sizePerPage,
|
||||||
|
pageStartIndex
|
||||||
|
)).toEqual(currPage);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('if partStartIndex is default 0', () => {
|
||||||
|
describe('and currPage is bigger than newest last page', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
newDataSize = 8;
|
||||||
|
prevDataSize = 11;
|
||||||
|
currPage = 2;
|
||||||
|
pageStartIndex = 0;
|
||||||
|
sizePerPage = 5;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct page', () => {
|
||||||
|
expect(alignPage(
|
||||||
|
newDataSize,
|
||||||
|
prevDataSize,
|
||||||
|
currPage,
|
||||||
|
sizePerPage,
|
||||||
|
pageStartIndex
|
||||||
|
)).toEqual(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('and currPage is short than newest last page', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
newDataSize = 11;
|
||||||
|
prevDataSize = 12;
|
||||||
|
currPage = 2;
|
||||||
|
pageStartIndex = 0;
|
||||||
|
sizePerPage = 5;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return correct page', () => {
|
||||||
|
expect(alignPage(
|
||||||
|
newDataSize,
|
||||||
|
prevDataSize,
|
||||||
|
currPage,
|
||||||
|
sizePerPage,
|
||||||
|
pageStartIndex
|
||||||
|
)).toEqual(currPage);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -67,6 +67,19 @@ const { SearchBar } = Search;
|
|||||||
|
|
||||||
3. You should render `SearchBar` with `searchProps` as well. The position of `SearchBar` is depends on you.
|
3. You should render `SearchBar` with `searchProps` as well. The position of `SearchBar` is depends on you.
|
||||||
|
|
||||||
|
### `SearchBar` Props
|
||||||
|
#### className - [string]
|
||||||
|
Custom the class on input element.
|
||||||
|
|
||||||
|
#### placeholder - [string]
|
||||||
|
Custom the placeholder on input element.
|
||||||
|
|
||||||
|
#### style - [object]
|
||||||
|
Custom the style on input element.
|
||||||
|
|
||||||
|
#### delay = [number]
|
||||||
|
milionsecond for debounce user input.
|
||||||
|
|
||||||
### Search Options
|
### Search Options
|
||||||
|
|
||||||
#### defaultSearch - [string]
|
#### defaultSearch - [string]
|
||||||
@@ -127,6 +140,8 @@ const { SearchBar, ClearSearchButton } = Search;
|
|||||||
</ToolkitProvider>
|
</ToolkitProvider>
|
||||||
```
|
```
|
||||||
|
|
||||||
|
-----
|
||||||
|
|
||||||
## Export CSV
|
## Export CSV
|
||||||
There are two steps to enable the export CSV functionality:
|
There are two steps to enable the export CSV functionality:
|
||||||
|
|
||||||
@@ -176,6 +191,13 @@ Default is `true`. `false` will only export current data which display on table.
|
|||||||
#### onlyExportSelection - [bool]
|
#### onlyExportSelection - [bool]
|
||||||
Default is `false`. `true` will only export the data which is selected.
|
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
|
## Column Toggle
|
||||||
|
|
||||||
Let's see how to render the column toggle in your react component:
|
Let's see how to render the column toggle in your react component:
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ class ToolkitProvider extends statelessDecorator(React.Component) {
|
|||||||
ignoreHeader: PropTypes.bool,
|
ignoreHeader: PropTypes.bool,
|
||||||
noAutoBOM: PropTypes.bool,
|
noAutoBOM: PropTypes.bool,
|
||||||
exportAll: PropTypes.bool,
|
exportAll: PropTypes.bool,
|
||||||
|
onlyExportFiltered: PropTypes.bool,
|
||||||
onlyExportSelection: PropTypes.bool
|
onlyExportSelection: PropTypes.bool
|
||||||
})
|
})
|
||||||
])
|
])
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-bootstrap-table2-toolkit",
|
"name": "react-bootstrap-table2-toolkit",
|
||||||
"version": "1.3.1",
|
"version": "1.4.0",
|
||||||
"description": "The toolkit for react-bootstrap-table2",
|
"description": "The toolkit for react-bootstrap-table2",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
@@ -27,19 +27,24 @@ export default Base =>
|
|||||||
data = source;
|
data = source;
|
||||||
} else if (options.exportAll) {
|
} else if (options.exportAll) {
|
||||||
data = this.props.data;
|
data = this.props.data;
|
||||||
|
} else if (options.onlyExportFiltered) {
|
||||||
|
const payload = {};
|
||||||
|
this.tableExposedAPIEmitter.emit('get.filtered.rows', payload);
|
||||||
|
data = payload.result;
|
||||||
} else {
|
} else {
|
||||||
const payload = {};
|
const payload = {};
|
||||||
this.tableExposedAPIEmitter.emit('get.table.data', payload);
|
this.tableExposedAPIEmitter.emit('get.table.data', payload);
|
||||||
data = payload.result;
|
data = payload.result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// filter data
|
// filter data by row selection
|
||||||
if (options.onlyExportSelection) {
|
if (options.onlyExportSelection) {
|
||||||
const payload = {};
|
const payload = {};
|
||||||
this.tableExposedAPIEmitter.emit('get.selected.rows', payload);
|
this.tableExposedAPIEmitter.emit('get.selected.rows', payload);
|
||||||
const selections = payload.result;
|
const selections = payload.result;
|
||||||
data = data.filter(row => !!selections.find(sel => row[keyField] === sel));
|
data = data.filter(row => !!selections.find(sel => row[keyField] === sel));
|
||||||
}
|
}
|
||||||
|
|
||||||
const content = transform(data, meta, this._.get, options);
|
const content = transform(data, meta, this._.get, options);
|
||||||
save(content, options);
|
save(content, options);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,6 +59,10 @@ export default (options = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getSearched() {
|
||||||
|
return this.state.data;
|
||||||
|
}
|
||||||
|
|
||||||
triggerListener(result) {
|
triggerListener(result) {
|
||||||
if (this.props.dataChangeListener) {
|
if (this.props.dataChangeListener) {
|
||||||
this.props.dataChangeListener.emit('filterChanged', result.length);
|
this.props.dataChangeListener.emit('filterChanged', result.length);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "react-bootstrap-table-next",
|
"name": "react-bootstrap-table-next",
|
||||||
"version": "3.0.0",
|
"version": "3.0.2",
|
||||||
"description": "Next generation of react-bootstrap-table",
|
"description": "Next generation of react-bootstrap-table",
|
||||||
"main": "./lib/index.js",
|
"main": "./lib/index.js",
|
||||||
"repository": {
|
"repository": {
|
||||||
|
|||||||
3
packages/react-bootstrap-table2/src/body.js
vendored
3
packages/react-bootstrap-table2/src/body.js
vendored
@@ -17,7 +17,6 @@ class Body extends React.Component {
|
|||||||
super(props);
|
super(props);
|
||||||
const {
|
const {
|
||||||
keyField,
|
keyField,
|
||||||
visibleColumnSize,
|
|
||||||
cellEdit,
|
cellEdit,
|
||||||
selectRow,
|
selectRow,
|
||||||
expandRow
|
expandRow
|
||||||
@@ -34,7 +33,7 @@ class Body extends React.Component {
|
|||||||
const expandRowEnabled = !!expandRow.renderer;
|
const expandRowEnabled = !!expandRow.renderer;
|
||||||
|
|
||||||
if (expandRowEnabled) {
|
if (expandRowEnabled) {
|
||||||
RowComponent = withRowExpansion(RowAggregator, visibleColumnSize);
|
RowComponent = withRowExpansion(RowAggregator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectRowEnabled) {
|
if (selectRowEnabled) {
|
||||||
|
|||||||
@@ -23,6 +23,15 @@ const withContext = Base =>
|
|||||||
const exposedAPIEmitter = new EventEmitter();
|
const exposedAPIEmitter = new EventEmitter();
|
||||||
exposedAPIEmitter.on('get.table.data', payload => payload.result = this.table.getData());
|
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.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);
|
props.registerExposedAPI(exposedAPIEmitter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import React from 'react';
|
|||||||
import ExpandRow from './expand-row';
|
import ExpandRow from './expand-row';
|
||||||
import ExpansionContext from '../contexts/row-expand-context';
|
import ExpansionContext from '../contexts/row-expand-context';
|
||||||
|
|
||||||
export default (Component, visibleColumnSize) => {
|
export default (Component) => {
|
||||||
const renderWithExpansion = (props, expandRow) => {
|
const renderWithExpansion = (props, expandRow) => {
|
||||||
const key = props.value;
|
const key = props.value;
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ export default (Component, visibleColumnSize) => {
|
|||||||
/>,
|
/>,
|
||||||
expanded ? <ExpandRow
|
expanded ? <ExpandRow
|
||||||
key={ `${key}-expanding` }
|
key={ `${key}-expanding` }
|
||||||
colSpan={ visibleColumnSize }
|
colSpan={ props.visibleColumnSize }
|
||||||
>
|
>
|
||||||
{ expandRow.renderer(props.row) }
|
{ expandRow.renderer(props.row) }
|
||||||
</ExpandRow> : null
|
</ExpandRow> : null
|
||||||
|
|||||||
@@ -8,7 +8,8 @@ export default ExtendBase =>
|
|||||||
return (
|
return (
|
||||||
nextProps.editingRowIdx === nextProps.rowIndex ||
|
nextProps.editingRowIdx === nextProps.rowIndex ||
|
||||||
(this.props.editingRowIdx === nextProps.rowIndex &&
|
(this.props.editingRowIdx === nextProps.rowIndex &&
|
||||||
nextProps.editingRowIdx === null)
|
nextProps.editingRowIdx === null) ||
|
||||||
|
this.props.editingRowIdx === nextProps.rowIndex
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user