Skip to content

Commit 4d5787a

Browse files
authored
Merge pull request #1378 from react-bootstrap-table/develop
20200517 release
2 parents 52062dd + 4f88591 commit 4d5787a

File tree

12 files changed

+181
-53
lines changed

12 files changed

+181
-53
lines changed

docs/README.md

+26-1
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,36 @@
3939
* [onDataSizeChange](#onDataSizeChange)
4040

4141
### <a name='keyField'>keyField(**required**) - [String]</a>
42-
Tells `react-bootstrap-table2` which column is unique.
42+
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
4343

4444
### <a name='data'>data(**required**) - [Array]</a>
4545
Provides data for your table. It accepts a single Array object.
4646

47+
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.
48+
49+
For example, if your column definitions look like:
50+
51+
```js
52+
columns = [
53+
{ dataField: 'id', text: 'Id' },
54+
{ dataField: 'name', text: 'Name' },
55+
{ dataField: 'animal', text: 'Animal' },
56+
]
57+
```
58+
59+
Then your data might look like:
60+
61+
```js
62+
data = [
63+
{ id: 1, name: 'George', animal: 'Monkey' }
64+
{ id: 2, name: 'Jeffrey', animal: 'Giraffe' }
65+
{ id: 3, name: 'Alice', animal: 'Giraffe' }
66+
{ id: 4, name: 'Alice', animal: 'Tiger' }
67+
]
68+
```
69+
70+
And your "keyField" would be `id`
71+
4772
### <a name='columns'>columns(**required**) - [Object]</a>
4873
Accepts a single Array object, please see [columns definition](./columns.md) for more detail.
4974

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/* eslint react/prop-types: 0 */
2+
import React from 'react';
3+
4+
import BootstrapTable from 'react-bootstrap-table-next';
5+
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
6+
import Code from 'components/common/code-block';
7+
import { productsGenerator } from 'utils/common';
8+
9+
const { SearchBar } = Search;
10+
const products = productsGenerator();
11+
12+
const columns = [{
13+
dataField: 'id',
14+
text: 'Product ID'
15+
}, {
16+
dataField: 'name',
17+
text: 'Product Name'
18+
}, {
19+
dataField: 'price',
20+
text: 'Product Price'
21+
}];
22+
23+
const sourceCode = `\
24+
import BootstrapTable from 'react-bootstrap-table-next';
25+
import ToolkitProvider, { Search } from 'react-bootstrap-table2-toolkit';
26+
27+
const { SearchBar } = Search;
28+
const columns = [{
29+
dataField: 'id',
30+
text: 'Product ID'
31+
}, {
32+
dataField: 'name',
33+
text: 'Product Name'
34+
}, {
35+
dataField: 'price',
36+
text: 'Product Price'
37+
}];
38+
39+
const afterSearch = (newResult) => {
40+
console.log(newResult);
41+
};
42+
43+
<ToolkitProvider
44+
keyField="id"
45+
data={ products }
46+
columns={ columns }
47+
search={ { afterSearch } }
48+
>
49+
{
50+
props => (
51+
<div>
52+
<h3>Input something at below input field:</h3>
53+
<SearchBar { ...props.searchProps } />
54+
<hr />
55+
<BootstrapTable
56+
{ ...props.baseProps }
57+
/>
58+
</div>
59+
)
60+
}
61+
</ToolkitProvider>
62+
`;
63+
64+
const afterSearch = (newResult) => {
65+
console.log(newResult);
66+
};
67+
68+
export default () => (
69+
<div>
70+
<ToolkitProvider
71+
keyField="id"
72+
data={ products }
73+
columns={ columns }
74+
search={ { afterSearch } }
75+
>
76+
{
77+
props => (
78+
<div>
79+
<h3>Input something at below input field:</h3>
80+
<SearchBar { ...props.searchProps } />
81+
<hr />
82+
<BootstrapTable
83+
{ ...props.baseProps }
84+
/>
85+
</div>
86+
)
87+
}
88+
</ToolkitProvider>
89+
<Code>{ sourceCode }</Code>
90+
</div>
91+
);

packages/react-bootstrap-table2-example/stories/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,7 @@ import CustomePaginationWithSearch from 'examples/pagination/custom-page-list-wi
197197
import SearchTable from 'examples/search';
198198
import ClearSearchButton from 'examples/search/clear-search-button';
199199
import DefaultSearch from 'examples/search/default-search';
200+
import SearchHooks from 'examples/search/search-hook';
200201
import DefaultCustomSearch from 'examples/search/default-custom-search';
201202
import FullyCustomSearch from 'examples/search/fully-custom-search';
202203
import SearchFormattedData from 'examples/search/search-formatted';
@@ -464,6 +465,7 @@ storiesOf('Table Search', module)
464465
.add('Clear Search Button', () => <ClearSearchButton />)
465466
.add('Default Search Table', () => <DefaultSearch />)
466467
.add('Default Custom Search', () => <DefaultCustomSearch />)
468+
.add('Search Hooks', () => <SearchHooks />)
467469
.add('Searchable Column', () => <SearchableColumn />)
468470
.add('Fully Custom Search', () => <FullyCustomSearch />)
469471
.add('Search Formatted Value', () => <SearchFormattedData />)

packages/react-bootstrap-table2-filter/README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
`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:
44

5-
**[Live Demo For Column Filter](https://github.com/react-bootstrap-table/react-bootstrap-table2/blob/gh-pages-src/storybook/index.html?selectedKind=Column%20Filter)**
5+
**[Live Demo For Column Filter](https://react-bootstrap-table.github.io/react-bootstrap-table2/storybook/index.html?selectedKind=Column%20Filter)**
66

77
**[API&Props Definitation](https://react-bootstrap-table.github.io/react-bootstrap-table2/docs/filter-props.html)**
88

@@ -385,4 +385,4 @@ export default () => (
385385
/>
386386
</div>
387387
);
388-
```
388+
```

packages/react-bootstrap-table2-filter/src/filter.js

+15-40
Original file line numberDiff line numberDiff line change
@@ -39,55 +39,36 @@ export const filterByNumber = _ => (
3939
) => (
4040
data.filter((row) => {
4141
if (number === '' || !comparator) return true;
42-
let valid = true;
4342
let cell = _.get(row, dataField);
43+
4444
if (customFilterValue) {
4545
cell = customFilterValue(cell, row);
4646
}
4747

4848
switch (comparator) {
4949
case EQ: {
50-
if (cell != number) {
51-
valid = false;
52-
}
53-
break;
50+
return cell == number;
5451
}
5552
case GT: {
56-
if (cell <= number) {
57-
valid = false;
58-
}
59-
break;
53+
return cell > number;
6054
}
6155
case GE: {
62-
if (cell < number) {
63-
valid = false;
64-
}
65-
break;
56+
return cell >= number;
6657
}
6758
case LT: {
68-
if (cell >= number) {
69-
valid = false;
70-
}
71-
break;
59+
return cell < number;
7260
}
7361
case LE: {
74-
if (cell > number) {
75-
valid = false;
76-
}
77-
break;
62+
return cell <= number;
7863
}
7964
case NE: {
80-
if (cell == number) {
81-
valid = false;
82-
}
83-
break;
65+
return cell != number;
8466
}
8567
default: {
8668
console.error('Number comparator provided is not supported');
87-
break;
69+
return true;
8870
}
8971
}
90-
return valid;
9172
})
9273
);
9374

@@ -208,25 +189,19 @@ export const filterByArray = _ => (
208189
};
209190

210191
export const filterFactory = _ => (filterType) => {
211-
let filterFn;
212192
switch (filterType) {
213-
case FILTER_TYPE.TEXT:
214-
case FILTER_TYPE.SELECT:
215-
filterFn = filterByText(_);
216-
break;
217193
case FILTER_TYPE.MULTISELECT:
218-
filterFn = filterByArray(_);
219-
break;
194+
return filterByArray(_);
220195
case FILTER_TYPE.NUMBER:
221-
filterFn = filterByNumber(_);
222-
break;
196+
return filterByNumber(_);
223197
case FILTER_TYPE.DATE:
224-
filterFn = filterByDate(_);
225-
break;
198+
return filterByDate(_);
199+
case FILTER_TYPE.TEXT:
200+
case FILTER_TYPE.SELECT:
226201
default:
227-
filterFn = filterByText(_);
202+
// Use `text` filter as default filter
203+
return filterByText(_);
228204
}
229-
return filterFn;
230205
};
231206

232207
export const filters = (data, columns, _) => (currFilters, clearFilters = {}) => {

packages/react-bootstrap-table2-filter/test/context.test.js

+2
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,13 @@ describe('FilterContext', () => {
5555
jest.fn().mockReturnValue(enableRemote),
5656
handleFilterChange
5757
);
58+
const filterOptions = {};
5859

5960
return (
6061
<FilterContext.Provider
6162
columns={ tableColumns }
6263
data={ data }
64+
filter={ filterOptions }
6365
dataChangeListener={ dataChangeListener }
6466
>
6567
<FilterContext.Consumer>

packages/react-bootstrap-table2-toolkit/README.md

+19
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ Custom the style on input element.
8080
#### delay = [number]
8181
milionsecond for debounce user input.
8282

83+
#### srText = [string]
84+
Customize the screen reader text for the search input. (Default: "Search this table")
85+
8386
### Search Options
8487

8588
#### defaultSearch - [string]
@@ -141,6 +144,22 @@ If you want to search on the formatted data, you are supposed to enable this pro
141144
</ToolkitProvider>
142145
```
143146

147+
#### afterSearch - [Function]
148+
After search done, this callback function will be called with newest result.
149+
150+
```js
151+
<ToolkitProvider
152+
keyField="id"
153+
data={ products }
154+
columns={ columns }
155+
search={ {
156+
afterSearch: (newResult) => console.log(newResult)
157+
} }
158+
>
159+
// ...
160+
</ToolkitProvider>
161+
```
162+
144163
### Clear Search Button
145164
We have a built-in clear search function which allow user clear search status via clicking button:
146165

packages/react-bootstrap-table2-toolkit/src/search/SearchBar.js

+10-5
Original file line numberDiff line numberDiff line change
@@ -56,21 +56,24 @@ class SearchBar extends React.Component {
5656
className,
5757
style,
5858
placeholder,
59-
tableId
59+
tableId,
60+
srText
6061
} = this.props;
6162

6263
return (
6364
<label
6465
htmlFor={ `search-bar-${tableId}` }
6566
className="search-label"
6667
>
67-
<span className="sr-only">Search this table</span>
68+
<span id={ `search-bar-${tableId}-label` } className="sr-only">
69+
{ srText }
70+
</span>
6871
<input
6972
ref={ n => this.input = n }
7073
id={ `search-bar-${tableId}` }
7174
type="text"
7275
style={ style }
73-
aria-label="enter text you want to search"
76+
aria-labelledby={ `search-bar-${tableId}-label` }
7477
onKeyUp={ () => this.onKeyup() }
7578
onChange={ this.onChangeValue }
7679
className={ `form-control ${className}` }
@@ -89,7 +92,8 @@ SearchBar.propTypes = {
8992
style: PropTypes.object,
9093
delay: PropTypes.number,
9194
searchText: PropTypes.string,
92-
tableId: PropTypes.string
95+
tableId: PropTypes.string,
96+
srText: PropTypes.string
9397
};
9498

9599
SearchBar.defaultProps = {
@@ -98,7 +102,8 @@ SearchBar.defaultProps = {
98102
placeholder: 'Search',
99103
delay: 250,
100104
searchText: '',
101-
tableId: '0'
105+
tableId: '0',
106+
srText: 'Search this table'
102107
};
103108

104109
export default SearchBar;

packages/react-bootstrap-table2-toolkit/src/search/context.js

+6-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import PropTypes from 'prop-types';
99

1010
export default (options = {
1111
searchFormatted: false,
12+
afterSearch: null,
1213
onColumnMatch: null
1314
}) => (
1415
_,
@@ -32,7 +33,7 @@ export default (options = {
3233
handleRemoteSearchChange(this.props.searchText);
3334
} else {
3435
initialData = this.search(props);
35-
this.triggerListener(initialData);
36+
this.triggerListener(initialData, true);
3637
}
3738
this.state = { data: initialData };
3839
}
@@ -41,7 +42,10 @@ export default (options = {
4142
return this.state.data;
4243
}
4344

44-
triggerListener(result) {
45+
triggerListener(result, skipInit) {
46+
if (options.afterSearch && !skipInit) {
47+
options.afterSearch(result);
48+
}
4549
if (this.props.dataChangeListener) {
4650
this.props.dataChangeListener.emit('filterChanged', result.length);
4751
}

0 commit comments

Comments
 (0)