From d0e70f72460c807b900d5462c23a8dc8f468c3c8 Mon Sep 17 00:00:00 2001 From: AllenFang Date: Sun, 17 Mar 2019 14:42:33 +0800 Subject: [PATCH] fix #852 --- .../examples/csv/export-only-filtered.js | 102 ++++++++++++++++++ .../stories/index.js | 2 + .../src/context.js | 4 + .../react-bootstrap-table2-toolkit/README.md | 5 + .../react-bootstrap-table2-toolkit/context.js | 1 + .../src/op/csv.js | 7 +- .../src/search/context.js | 4 + .../src/contexts/index.js | 9 ++ 8 files changed, 133 insertions(+), 1 deletion(-) create mode 100644 packages/react-bootstrap-table2-example/examples/csv/export-only-filtered.js diff --git a/packages/react-bootstrap-table2-example/examples/csv/export-only-filtered.js b/packages/react-bootstrap-table2-example/examples/csv/export-only-filtered.js new file mode 100644 index 0000000..b5b9af1 --- /dev/null +++ b/packages/react-bootstrap-table2-example/examples/csv/export-only-filtered.js @@ -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 +}; + + + { + props => ( +
+ Export CSV!! +
+ + +
+ ) + } +
+`; + +export default () => ( +
+

Export all the filtered/searched rows

+ + { + props => ( +
+ Export CSV!! +
+ + +
+ ) + } +
+ { sourceCode } +
+); diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js index cc97704..9fc20d1 100644 --- a/packages/react-bootstrap-table2-example/stories/index.js +++ b/packages/react-bootstrap-table2-example/stories/index.js @@ -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', () => ) .add('Hide CSV Column', () => ) .add('Only Export Selected Rows', () => ) + .add('Only Export Filtered/Searched Rows', () => ) .add('CSV Column Type', () => ) .add('Custom CSV Button', () => ) .add('Export Custom Data', () => ) diff --git a/packages/react-bootstrap-table2-filter/src/context.js b/packages/react-bootstrap-table2-filter/src/context.js index 78b73d1..3fa787b 100644 --- a/packages/react-bootstrap-table2-filter/src/context.js +++ b/packages/react-bootstrap-table2-filter/src/context.js @@ -91,6 +91,10 @@ export default ( }; } + getFiltered() { + return this.data; + } + doFilter(props, customResult, ignoreEmitDataChange = false) { let result = customResult; diff --git a/packages/react-bootstrap-table2-toolkit/README.md b/packages/react-bootstrap-table2-toolkit/README.md index c85accc..a470133 100644 --- a/packages/react-bootstrap-table2-toolkit/README.md +++ b/packages/react-bootstrap-table2-toolkit/README.md @@ -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 diff --git a/packages/react-bootstrap-table2-toolkit/context.js b/packages/react-bootstrap-table2-toolkit/context.js index 322106e..838f634 100644 --- a/packages/react-bootstrap-table2-toolkit/context.js +++ b/packages/react-bootstrap-table2-toolkit/context.js @@ -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 }) ]) diff --git a/packages/react-bootstrap-table2-toolkit/src/op/csv.js b/packages/react-bootstrap-table2-toolkit/src/op/csv.js index 47a6339..76f5135 100644 --- a/packages/react-bootstrap-table2-toolkit/src/op/csv.js +++ b/packages/react-bootstrap-table2-toolkit/src/op/csv.js @@ -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); } diff --git a/packages/react-bootstrap-table2-toolkit/src/search/context.js b/packages/react-bootstrap-table2-toolkit/src/search/context.js index 053b1c4..bfed70d 100644 --- a/packages/react-bootstrap-table2-toolkit/src/search/context.js +++ b/packages/react-bootstrap-table2-toolkit/src/search/context.js @@ -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); diff --git a/packages/react-bootstrap-table2/src/contexts/index.js b/packages/react-bootstrap-table2/src/contexts/index.js index d735c1a..148e805 100644 --- a/packages/react-bootstrap-table2/src/contexts/index.js +++ b/packages/react-bootstrap-table2/src/contexts/index.js @@ -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); }