diff --git a/docs/columns.md b/docs/columns.md index 3474e6d..55a4003 100644 --- a/docs/columns.md +++ b/docs/columns.md @@ -164,7 +164,7 @@ Enable the column sort via a `true` value given. ``` ## column.sortCaret - [Function] -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 { diff --git a/docs/row-expand.md b/docs/row-expand.md index 025d03d..08198fa 100644 --- a/docs/row-expand.md +++ b/docs/row-expand.md @@ -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) 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 e35711f..3fa787b 100644 --- a/packages/react-bootstrap-table2-filter/src/context.js +++ b/packages/react-bootstrap-table2-filter/src/context.js @@ -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; 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); } diff --git a/packages/react-bootstrap-table2/src/row/should-updater.js b/packages/react-bootstrap-table2/src/row/should-updater.js index 813dbb5..bcef92e 100644 --- a/packages/react-bootstrap-table2/src/row/should-updater.js +++ b/packages/react-bootstrap-table2/src/row/should-updater.js @@ -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 ); }