This commit is contained in:
Allen
2019-02-16 16:18:33 +08:00
committed by GitHub
parent 3cd8efffb9
commit 052284a163
8 changed files with 416 additions and 13 deletions
@@ -0,0 +1,70 @@
/* eslint react/prop-types: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
import { productsGenerator } from 'utils/common';
const ProductList = (props) => {
const columns = [
{
dataField: 'id',
text: 'Product ID'
},
{
dataField: 'name',
text: 'Product Name',
filter: textFilter({
defaultValue: '1'
})
},
{
dataField: 'price',
text: 'Product Price',
filter: textFilter()
}
];
return (
<div style={ { paddingTop: '20px' } }>
<h1 className="h2">Products</h1>
<BootstrapTable
keyField="id"
data={ props.products }
columns={ columns }
filter={ filterFactory() }
/>
</div>
);
};
export default class DataContainer extends React.Component {
state = {
products: productsGenerator(3)
};
loadData = () => {
this.setState({
products: productsGenerator(14)
});
}
render() {
return (
<div>
<button
onClick={ this.loadData }
style={ {
fontSize: '20px',
position: 'absolute',
left: '200px',
top: '40px'
} }
>
Load Data
</button>
<ProductList products={ this.state.products } />
</div>
);
}
}
@@ -0,0 +1,80 @@
/* 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 { productsGenerator } from 'utils/common';
const { SearchBar } = Search;
const ProductList = (props) => {
const columns = [
{
dataField: 'id',
text: 'Product ID'
},
{
dataField: 'name',
text: 'Product Name'
},
{
dataField: 'price',
text: 'Product Price'
}
];
return (
<div style={ { paddingTop: '20px' } }>
<h1 className="h2">Products</h1>
<ToolkitProvider
keyField="id"
data={ props.products }
columns={ columns }
search={ { defaultSearch: '2101' } }
>
{
toolkitprops => (
<div>
<SearchBar { ...toolkitprops.searchProps } />
<BootstrapTable
striped
hover
{ ...toolkitprops.baseProps }
/>
</div>
)
}
</ToolkitProvider>
</div>
);
};
export default class DataContainer extends React.Component {
state = {
products: productsGenerator(3)
};
loadData = () => {
this.setState({
products: productsGenerator(14)
});
}
render() {
return (
<div>
<button
onClick={ this.loadData }
style={ {
fontSize: '20px',
position: 'absolute',
left: '200px',
top: '40px'
} }
>
Load Data
</button>
<ProductList products={ this.state.products } />
</div>
);
}
}
@@ -0,0 +1,68 @@
/* eslint react/prop-types: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
import { productsGenerator } from 'utils/common';
const ProductList = (props) => {
const columns = [
{
dataField: 'id',
text: 'Product ID'
},
{
dataField: 'name',
text: 'Product Name',
filter: textFilter()
},
{
dataField: 'price',
text: 'Product Price',
filter: textFilter()
}
];
return (
<div style={ { paddingTop: '20px' } }>
<h1 className="h2">Products</h1>
<BootstrapTable
keyField="id"
data={ props.products }
columns={ columns }
filter={ filterFactory() }
/>
</div>
);
};
export default class DataContainer extends React.Component {
state = {
products: []
};
loadData = () => {
this.setState({
products: productsGenerator()
});
}
render() {
return (
<div>
<button
onClick={ this.loadData }
style={ {
fontSize: '20px',
position: 'absolute',
left: '200px',
top: '40px'
} }
>
Load Data
</button>
<ProductList products={ this.state.products } />
</div>
);
}
}
@@ -0,0 +1,72 @@
/* eslint react/prop-types: 0 */
import React from 'react';
import BootstrapTable from 'react-bootstrap-table-next';
import filterFactory, { textFilter } from 'react-bootstrap-table2-filter';
import paginationFactory from 'react-bootstrap-table2-paginator';
import { productsGenerator } from 'utils/common';
const ProductList = (props) => {
const columns = [
{
dataField: 'id',
text: 'Product ID'
},
{
dataField: 'name',
text: 'Product Name',
filter: textFilter({
defaultValue: '6'
})
},
{
dataField: 'price',
text: 'Product Price',
filter: textFilter()
}
];
return (
<div style={ { paddingTop: '20px' } }>
<h1 className="h2">Products</h1>
<BootstrapTable
keyField="id"
data={ props.products }
columns={ columns }
filter={ filterFactory() }
pagination={ paginationFactory() }
/>
</div>
);
};
export default class DataContainer extends React.Component {
state = {
products: productsGenerator(60)
};
loadData = () => {
this.setState({
products: productsGenerator(14)
});
}
render() {
return (
<div>
<button
onClick={ this.loadData }
style={ {
fontSize: '20px',
position: 'absolute',
left: '200px',
top: '40px'
} }
>
Load Data
</button>
<ProductList products={ this.state.products } />
</div>
);
}
}
@@ -0,0 +1,80 @@
/* 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 { productsGenerator } from 'utils/common';
const { SearchBar } = Search;
const ProductList = (props) => {
const columns = [
{
dataField: 'id',
text: 'Product ID'
},
{
dataField: 'name',
text: 'Product Name'
},
{
dataField: 'price',
text: 'Product Price'
}
];
return (
<div style={ { paddingTop: '20px' } }>
<h1 className="h2">Products</h1>
<ToolkitProvider
keyField="id"
data={ props.products }
columns={ columns }
search
>
{
toolkitprops => (
<div>
<SearchBar { ...toolkitprops.searchProps } />
<BootstrapTable
striped
hover
{ ...toolkitprops.baseProps }
/>
</div>
)
}
</ToolkitProvider>
</div>
);
};
export default class DataContainer extends React.Component {
state = {
products: []
};
loadData = () => {
this.setState({
products: productsGenerator()
});
}
render() {
return (
<div>
<button
onClick={ this.loadData }
style={ {
fontSize: '20px',
position: 'absolute',
left: '200px',
top: '40px'
} }
>
Load Data
</button>
<ProductList products={ this.state.products } />
</div>
);
}
}
@@ -205,6 +205,13 @@ import RemoteSearch from 'examples/remote/remote-search';
import RemoteCellEdit from 'examples/remote/remote-celledit';
import RemoteAll from 'examples/remote/remote-all';
// data
import LoadDataWithFilter from 'examples/data/load-data-on-the-fly-with-filter';
import LoadDataWithDefaultFilter from 'examples/data/load-data-on-the-fly-with-default-filter';
import LoadDataWithSearch from 'examples/data/load-data-on-the-fly-with-search';
import LoadDataWithDefaultSearch from 'examples/data/load-data-on-the-fly-with-default-search';
import LoadDataWithPaginationAndFilter from 'examples/data/load-data-on-the-fly-with-pagination-and-filter';
// css style
import 'stories/stylesheet/tomorrow.min.css';
import 'stories/stylesheet/storybook.scss';
@@ -433,3 +440,11 @@ storiesOf('Remote', module)
.add('Remote Search', () => <RemoteSearch />)
.add('Remote Cell Editing', () => <RemoteCellEdit />)
.add('Remote All', () => <RemoteAll />);
storiesOf('Data', module)
.addDecorator(bootstrapStyle())
.add('Load data with Filter', () => <LoadDataWithFilter />)
.add('Load data with Default Filter', () => <LoadDataWithDefaultFilter />)
.add('Load data with Search', () => <LoadDataWithSearch />)
.add('Load data with Default Search', () => <LoadDataWithDefaultSearch />)
.add('Load data with Filter and Pagination', () => <LoadDataWithPaginationAndFilter />);
+19 -9
View File
@@ -25,6 +25,7 @@ export default (
super(props);
this.currFilters = {};
this.onFilter = this.onFilter.bind(this);
this.doFilter = this.doFilter.bind(this);
this.onExternalFilter = this.onExternalFilter.bind(this);
this.state = {
data: props.data
@@ -38,11 +39,13 @@ export default (
}
componentWillReceiveProps(nextProps) {
if (isRemoteFiltering()) {
this.setState({
data: nextProps.data
});
let nextData = nextProps.data;
if (!isRemoteFiltering() && !_.isEqual(nextProps.data, this.props.data)) {
nextData = this.doFilter(nextProps);
}
this.setState({
data: nextData
});
}
onFilter(column, filterType, initialize = false) {
@@ -81,11 +84,7 @@ export default (
result = filter.props.onFilter(filterVal);
}
const { dataChangeListener, data } = this.props;
result = result || filters(data, this.props.columns, _)(this.currFilters);
if (dataChangeListener) {
dataChangeListener.emit('filterChanged', result.length);
}
result = this.doFilter(this.props, result);
this.setState({ data: result });
};
}
@@ -96,6 +95,17 @@ export default (
};
}
doFilter(props, customResult) {
let result = customResult;
const { dataChangeListener, data, columns } = props;
result = result || filters(data, columns, _)(this.currFilters);
if (dataChangeListener) {
dataChangeListener.emit('filterChanged', result.length);
}
return result;
}
render() {
return (
<FilterContext.Provider value={ {
@@ -2,6 +2,7 @@
/* eslint react/require-default-props: 0 */
/* eslint no-continue: 0 */
/* eslint no-lonely-if: 0 */
/* eslint class-methods-use-this: 0 */
import React from 'react';
import PropTypes from 'prop-types';
@@ -28,7 +29,7 @@ export default (options = {
if (isRemoteSearch() && this.props.searchText !== '') {
handleRemoteSearchChange(this.props.searchText);
} else {
initialData = this.search(props.searchText.toLowerCase());
initialData = this.search(props);
this.triggerListener(initialData);
}
this.state = { data: initialData };
@@ -39,7 +40,7 @@ export default (options = {
if (isRemoteSearch()) {
handleRemoteSearchChange(nextProps.searchText);
} else {
const result = this.search(nextProps.searchText.toLowerCase());
const result = this.search(nextProps);
this.triggerListener(result);
this.setState({
data: result
@@ -48,6 +49,12 @@ export default (options = {
} else {
if (isRemoteSearch()) {
this.setState({ data: nextProps.data });
} else if (!_.isEqual(nextProps.data, this.props.data)) {
const result = this.search(nextProps);
this.triggerListener(result);
this.setState({
data: result
});
}
}
}
@@ -58,8 +65,9 @@ export default (options = {
}
}
search(searchText) {
const { data, columns } = this.props;
search(props) {
const { data, columns } = props;
const searchText = props.searchText.toLowerCase();
return data.filter((row, ridx) => {
for (let cidx = 0; cidx < columns.length; cidx += 1) {
const column = columns[cidx];