diff --git a/docs/README.md b/docs/README.md
index d622a8848..9bc4ff181 100644
--- a/docs/README.md
+++ b/docs/README.md
@@ -39,11 +39,36 @@
* [onDataSizeChange](#onDataSizeChange)
### keyField(**required**) - [String]
-Tells `react-bootstrap-table2` which column is unique.
+Tells `react-bootstrap-table2` which column of the data is unique. This should be the name of a property that is unique for each item in your dataset
### data(**required**) - [Array]
Provides data for your table. It accepts a single Array object.
+Each item in this array is an object that represents a row in the table. Each "Row" object should have a key-value pair for each column in the table, whose key matches that column's dataField value.
+
+For example, if your column definitions look like:
+
+```js
+columns = [
+ { dataField: 'id', text: 'Id' },
+ { dataField: 'name', text: 'Name' },
+ { dataField: 'animal', text: 'Animal' },
+]
+```
+
+Then your data might look like:
+
+```js
+data = [
+ { id: 1, name: 'George', animal: 'Monkey' }
+ { id: 2, name: 'Jeffrey', animal: 'Giraffe' }
+ { id: 3, name: 'Alice', animal: 'Giraffe' }
+ { id: 4, name: 'Alice', animal: 'Tiger' }
+]
+```
+
+And your "keyField" would be `id`
+
### columns(**required**) - [Object]
Accepts a single Array object, please see [columns definition](./columns.md) for more detail.
diff --git a/packages/react-bootstrap-table2-example/examples/search/search-hook.js b/packages/react-bootstrap-table2-example/examples/search/search-hook.js
new file mode 100644
index 000000000..3abbe3bca
--- /dev/null
+++ b/packages/react-bootstrap-table2-example/examples/search/search-hook.js
@@ -0,0 +1,91 @@
+/* eslint react/prop-types: 0 */
+import React from 'react';
+
+import BootstrapTable from 'react-bootstrap-table-next';
+import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
+import Code from 'components/common/code-block';
+import { productsGenerator } from 'utils/common';
+
+const { SearchBar } = Search;
+const products = productsGenerator();
+
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price'
+}];
+
+const sourceCode = `\
+import BootstrapTable from 'react-bootstrap-table-next';
+import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
+
+const { SearchBar } = Search;
+const columns = [{
+ dataField: 'id',
+ text: 'Product ID'
+}, {
+ dataField: 'name',
+ text: 'Product Name'
+}, {
+ dataField: 'price',
+ text: 'Product Price'
+}];
+
+const afterSearch = (newResult) => {
+ console.log(newResult);
+};
+
+
+ {
+ props => (
+
+
Input something at below input field:
+
+
+
+
+ )
+ }
+
+`;
+
+const afterSearch = (newResult) => {
+ console.log(newResult);
+};
+
+export default () => (
+
+
+ {
+ props => (
+
+
Input something at below input field:
+
+
+
+
+ )
+ }
+
+
{ sourceCode }
+
+);
diff --git a/packages/react-bootstrap-table2-example/stories/index.js b/packages/react-bootstrap-table2-example/stories/index.js
index 9bca826bf..757cbad18 100644
--- a/packages/react-bootstrap-table2-example/stories/index.js
+++ b/packages/react-bootstrap-table2-example/stories/index.js
@@ -197,6 +197,7 @@ import CustomePaginationWithSearch from 'examples/pagination/custom-page-list-wi
import SearchTable from 'examples/search';
import ClearSearchButton from 'examples/search/clear-search-button';
import DefaultSearch from 'examples/search/default-search';
+import SearchHooks from 'examples/search/search-hook';
import DefaultCustomSearch from 'examples/search/default-custom-search';
import FullyCustomSearch from 'examples/search/fully-custom-search';
import SearchFormattedData from 'examples/search/search-formatted';
@@ -464,6 +465,7 @@ storiesOf('Table Search', module)
.add('Clear Search Button', () => )
.add('Default Search Table', () => )
.add('Default Custom Search', () => )
+ .add('Search Hooks', () => )
.add('Searchable Column', () => )
.add('Fully Custom Search', () => )
.add('Search Formatted Value', () => )
diff --git a/packages/react-bootstrap-table2-filter/README.md b/packages/react-bootstrap-table2-filter/README.md
index 697aa9f99..70f45914f 100644
--- a/packages/react-bootstrap-table2-filter/README.md
+++ b/packages/react-bootstrap-table2-filter/README.md
@@ -2,7 +2,7 @@
`react-bootstrap-table2` separate the filter core code base to [`react-bootstrap-table2-filter`](https://github.com/react-bootstrap-table/react-bootstrap-table2/tree/develop/packages/react-bootstrap-table2-filter), so there's a little bit different when you use column filter than `react-bootstrap-table`. In the following, we are going to show you how to enable the column filter:
-**[Live Demo For Column Filter](https://github.com/react-bootstrap-table/react-bootstrap-table2/blob/gh-pages-src/storybook/index.html?selectedKind=Column%20Filter)**
+**[Live Demo For Column Filter](https://react-bootstrap-table.github.io/react-bootstrap-table2/storybook/index.html?selectedKind=Column%20Filter)**
**[API&Props Definitation](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/filter-props.html)**
@@ -385,4 +385,4 @@ export default () => (
/>
);
-```
\ No newline at end of file
+```
diff --git a/packages/react-bootstrap-table2-filter/src/filter.js b/packages/react-bootstrap-table2-filter/src/filter.js
index 7aad77bc3..924e00982 100644
--- a/packages/react-bootstrap-table2-filter/src/filter.js
+++ b/packages/react-bootstrap-table2-filter/src/filter.js
@@ -39,55 +39,36 @@ export const filterByNumber = _ => (
) => (
data.filter((row) => {
if (number === '' || !comparator) return true;
- let valid = true;
let cell = _.get(row, dataField);
+
if (customFilterValue) {
cell = customFilterValue(cell, row);
}
switch (comparator) {
case EQ: {
- if (cell != number) {
- valid = false;
- }
- break;
+ return cell == number;
}
case GT: {
- if (cell <= number) {
- valid = false;
- }
- break;
+ return cell > number;
}
case GE: {
- if (cell < number) {
- valid = false;
- }
- break;
+ return cell >= number;
}
case LT: {
- if (cell >= number) {
- valid = false;
- }
- break;
+ return cell < number;
}
case LE: {
- if (cell > number) {
- valid = false;
- }
- break;
+ return cell <= number;
}
case NE: {
- if (cell == number) {
- valid = false;
- }
- break;
+ return cell != number;
}
default: {
console.error('Number comparator provided is not supported');
- break;
+ return true;
}
}
- return valid;
})
);
@@ -208,25 +189,19 @@ export const filterByArray = _ => (
};
export const filterFactory = _ => (filterType) => {
- let filterFn;
switch (filterType) {
- case FILTER_TYPE.TEXT:
- case FILTER_TYPE.SELECT:
- filterFn = filterByText(_);
- break;
case FILTER_TYPE.MULTISELECT:
- filterFn = filterByArray(_);
- break;
+ return filterByArray(_);
case FILTER_TYPE.NUMBER:
- filterFn = filterByNumber(_);
- break;
+ return filterByNumber(_);
case FILTER_TYPE.DATE:
- filterFn = filterByDate(_);
- break;
+ return filterByDate(_);
+ case FILTER_TYPE.TEXT:
+ case FILTER_TYPE.SELECT:
default:
- filterFn = filterByText(_);
+ // Use `text` filter as default filter
+ return filterByText(_);
}
- return filterFn;
};
export const filters = (data, columns, _) => (currFilters, clearFilters = {}) => {
diff --git a/packages/react-bootstrap-table2-filter/test/context.test.js b/packages/react-bootstrap-table2-filter/test/context.test.js
index eccef3063..248ed88d1 100644
--- a/packages/react-bootstrap-table2-filter/test/context.test.js
+++ b/packages/react-bootstrap-table2-filter/test/context.test.js
@@ -55,11 +55,13 @@ describe('FilterContext', () => {
jest.fn().mockReturnValue(enableRemote),
handleFilterChange
);
+ const filterOptions = {};
return (
diff --git a/packages/react-bootstrap-table2-toolkit/README.md b/packages/react-bootstrap-table2-toolkit/README.md
index 84b24445b..948f34eb6 100644
--- a/packages/react-bootstrap-table2-toolkit/README.md
+++ b/packages/react-bootstrap-table2-toolkit/README.md
@@ -80,6 +80,9 @@ Custom the style on input element.
#### delay = [number]
milionsecond for debounce user input.
+#### srText = [string]
+Customize the screen reader text for the search input. (Default: "Search this table")
+
### Search Options
#### defaultSearch - [string]
@@ -141,6 +144,22 @@ If you want to search on the formatted data, you are supposed to enable this pro
```
+#### afterSearch - [Function]
+After search done, this callback function will be called with newest result.
+
+```js
+ console.log(newResult)
+ } }
+>
+ // ...
+
+```
+
### Clear Search Button
We have a built-in clear search function which allow user clear search status via clicking button:
diff --git a/packages/react-bootstrap-table2-toolkit/src/search/SearchBar.js b/packages/react-bootstrap-table2-toolkit/src/search/SearchBar.js
index 9bef75f32..fac666a8e 100644
--- a/packages/react-bootstrap-table2-toolkit/src/search/SearchBar.js
+++ b/packages/react-bootstrap-table2-toolkit/src/search/SearchBar.js
@@ -56,7 +56,8 @@ class SearchBar extends React.Component {
className,
style,
placeholder,
- tableId
+ tableId,
+ srText
} = this.props;
return (
@@ -64,13 +65,15 @@ class SearchBar extends React.Component {
htmlFor={ `search-bar-${tableId}` }
className="search-label"
>
- Search this table
+
+ { srText }
+
this.input = n }
id={ `search-bar-${tableId}` }
type="text"
style={ style }
- aria-label="enter text you want to search"
+ aria-labelledby={ `search-bar-${tableId}-label` }
onKeyUp={ () => this.onKeyup() }
onChange={ this.onChangeValue }
className={ `form-control ${className}` }
@@ -89,7 +92,8 @@ SearchBar.propTypes = {
style: PropTypes.object,
delay: PropTypes.number,
searchText: PropTypes.string,
- tableId: PropTypes.string
+ tableId: PropTypes.string,
+ srText: PropTypes.string
};
SearchBar.defaultProps = {
@@ -98,7 +102,8 @@ SearchBar.defaultProps = {
placeholder: 'Search',
delay: 250,
searchText: '',
- tableId: '0'
+ tableId: '0',
+ srText: 'Search this table'
};
export default SearchBar;
diff --git a/packages/react-bootstrap-table2-toolkit/src/search/context.js b/packages/react-bootstrap-table2-toolkit/src/search/context.js
index ec94da7a3..9f34c92ab 100644
--- a/packages/react-bootstrap-table2-toolkit/src/search/context.js
+++ b/packages/react-bootstrap-table2-toolkit/src/search/context.js
@@ -9,6 +9,7 @@ import PropTypes from 'prop-types';
export default (options = {
searchFormatted: false,
+ afterSearch: null,
onColumnMatch: null
}) => (
_,
@@ -32,7 +33,7 @@ export default (options = {
handleRemoteSearchChange(this.props.searchText);
} else {
initialData = this.search(props);
- this.triggerListener(initialData);
+ this.triggerListener(initialData, true);
}
this.state = { data: initialData };
}
@@ -41,7 +42,10 @@ export default (options = {
return this.state.data;
}
- triggerListener(result) {
+ triggerListener(result, skipInit) {
+ if (options.afterSearch && !skipInit) {
+ options.afterSearch(result);
+ }
if (this.props.dataChangeListener) {
this.props.dataChangeListener.emit('filterChanged', result.length);
}
diff --git a/packages/react-bootstrap-table2/src/contexts/row-expand-context.js b/packages/react-bootstrap-table2/src/contexts/row-expand-context.js
index fb1aed05a..7b7172a5e 100644
--- a/packages/react-bootstrap-table2/src/contexts/row-expand-context.js
+++ b/packages/react-bootstrap-table2/src/contexts/row-expand-context.js
@@ -23,13 +23,16 @@ class RowExpandProvider extends React.Component {
UNSAFE_componentWillReceiveProps(nextProps) {
if (nextProps.expandRow) {
- const nextExpanded = nextProps.expandRow.expanded || this.state.expanded;
+ let nextExpanded = [...(nextProps.expandRow.expanded || this.state.expanded)];
+ const { nonExpandable = [] } = nextProps.expandRow;
+ nextExpanded = nextExpanded.filter(rowId => !_.contains(nonExpandable, rowId));
const isClosing = this.state.expanded.reduce((acc, cur) => {
if (!_.contains(nextExpanded, cur)) {
acc.push(cur);
}
return acc;
}, []);
+
this.setState(() => ({
expanded: nextExpanded,
isClosing
diff --git a/packages/react-bootstrap-table2/src/row-selection/selection-cell.js b/packages/react-bootstrap-table2/src/row-selection/selection-cell.js
index f53753cff..ff20f1eca 100644
--- a/packages/react-bootstrap-table2/src/row-selection/selection-cell.js
+++ b/packages/react-bootstrap-table2/src/row-selection/selection-cell.js
@@ -92,7 +92,8 @@ export default class SelectionCell extends Component {
mode: inputType,
checked: selected,
disabled,
- rowIndex
+ rowIndex,
+ rowKey
}) : (
', () => {
mode,
checked: selected,
disabled: wrapper.prop('disabled'),
- rowIndex
+ rowIndex,
+ rowKey: 1
});
});
});