diff --git a/packages/react-bootstrap-table2-example/examples/loading-overlay/empty-table-overlay.js b/packages/react-bootstrap-table2-example/examples/loading-overlay/empty-table-overlay.js
index 6366f16..aa62c20 100644
--- a/packages/react-bootstrap-table2-example/examples/loading-overlay/empty-table-overlay.js
+++ b/packages/react-bootstrap-table2-example/examples/loading-overlay/empty-table-overlay.js
@@ -116,7 +116,7 @@ class EmptyTableOverlay extends React.Component {
};
}
- handleTableChange = ({ page, sizePerPage }) => {
+ handleTableChange = (type, { page, sizePerPage }) => {
const currentIndex = (page - 1) * sizePerPage;
setTimeout(() => {
this.setState(() => ({
diff --git a/packages/react-bootstrap-table2-example/examples/loading-overlay/table-overlay.js b/packages/react-bootstrap-table2-example/examples/loading-overlay/table-overlay.js
index b0dca04..c3c9546 100644
--- a/packages/react-bootstrap-table2-example/examples/loading-overlay/table-overlay.js
+++ b/packages/react-bootstrap-table2-example/examples/loading-overlay/table-overlay.js
@@ -127,7 +127,7 @@ class Container extends React.Component {
};
}
- handleTableChange = ({ page, sizePerPage }) => {
+ handleTableChange = (type, { page, sizePerPage }) => {
const currentIndex = (page - 1) * sizePerPage;
setTimeout(() => {
this.setState(() => ({
diff --git a/packages/react-bootstrap-table2-filter/src/index.js b/packages/react-bootstrap-table2-filter/src/index.js
index 4bba49d..4b38550 100644
--- a/packages/react-bootstrap-table2-filter/src/index.js
+++ b/packages/react-bootstrap-table2-filter/src/index.js
@@ -1,9 +1,9 @@
import TextFilter from './components/text';
-import FilterWrapper from './wrapper';
+import wrapperFactory from './wrapper';
import * as Comparison from './comparison';
export default (options = {}) => ({
- FilterWrapper,
+ wrapperFactory,
options
});
diff --git a/packages/react-bootstrap-table2-filter/src/wrapper.js b/packages/react-bootstrap-table2-filter/src/wrapper.js
index 48e4d73..780c4d8 100644
--- a/packages/react-bootstrap-table2-filter/src/wrapper.js
+++ b/packages/react-bootstrap-table2-filter/src/wrapper.js
@@ -1,76 +1,66 @@
-/* eslint react/prop-types: 0 */
-import { Component } from 'react';
+import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { filters } from './filter';
import { LIKE } from './comparison';
-export default class FilterWrapper extends Component {
- static propTypes = {
- store: PropTypes.object.isRequired,
- columns: PropTypes.array.isRequired,
- baseElement: PropTypes.func.isRequired,
- onRemoteFilterChange: PropTypes.func.isRequired,
- // refactoring later
- _: PropTypes.object.isRequired
- }
-
- constructor(props) {
- super(props);
- this.state = { currFilters: {}, isDataChanged: false };
- this.onFilter = this.onFilter.bind(this);
- }
-
- componentWillReceiveProps(nextProps) {
- // consider to use lodash.isEqual
- if (JSON.stringify(this.state.currFilters) !== JSON.stringify(nextProps.store.filters)) {
- this.setState(() => ({ isDataChanged: true, currFilters: nextProps.store.filters }));
- } else {
- this.setState(() => ({ isDataChanged: false }));
- }
- }
-
- onFilter(column, filterVal, filterType) {
- const { store, columns, _, onRemoteFilterChange } = this.props;
- const currFilters = Object.assign({}, this.state.currFilters);
- const { dataField, filter } = column;
-
- if (!_.isDefined(filterVal) || filterVal === '') {
- delete currFilters[dataField];
- } else {
- const { comparator = LIKE } = filter.props;
- currFilters[dataField] = { filterVal, filterType, comparator };
- }
- store.filters = currFilters;
-
- if (this.isRemote() || this.isPaginationRemote()) {
- onRemoteFilterChange(this.isPaginationRemote());
- // when remote filtering is enable, dont set currFilters state
- // in the componentWillReceiveProps, it's the key point that we can know the filter is changed
- return;
+export default (Base, {
+ _,
+ remoteResolver
+}) =>
+ class FilterWrapper extends remoteResolver(Component) {
+ static propTypes = {
+ store: PropTypes.object.isRequired,
+ columns: PropTypes.array.isRequired
}
- store.filteredData = filters(store, columns, _)(currFilters);
- this.setState(() => ({ currFilters, isDataChanged: true }));
- }
+ constructor(props) {
+ super(props);
+ this.state = { currFilters: {}, isDataChanged: false };
+ this.onFilter = this.onFilter.bind(this);
+ }
- // refactoring later
- isRemote() {
- const { remote } = this.props;
- return remote === true || (typeof remote === 'object' && remote.filter);
- }
+ componentWillReceiveProps(nextProps) {
+ // consider to use lodash.isEqual
+ if (JSON.stringify(this.state.currFilters) !== JSON.stringify(nextProps.store.filters)) {
+ this.setState(() => ({ isDataChanged: true, currFilters: nextProps.store.filters }));
+ } else {
+ this.setState(() => ({ isDataChanged: false }));
+ }
+ }
- // refactoring later
- isPaginationRemote() {
- const { remote } = this.props;
- return remote === true || (typeof remote === 'object' && remote.pagination);
- }
+ onFilter(column, filterVal, filterType) {
+ const { store, columns } = this.props;
+ const currFilters = Object.assign({}, this.state.currFilters);
+ const { dataField, filter } = column;
- render() {
- return this.props.baseElement({
- ...this.props,
- key: 'table',
- onFilter: this.onFilter,
- isDataChanged: this.state.isDataChanged
- });
- }
-}
+ if (!_.isDefined(filterVal) || filterVal === '') {
+ delete currFilters[dataField];
+ } else {
+ const { comparator = LIKE } = filter.props;
+ currFilters[dataField] = { filterVal, filterType, comparator };
+ }
+ store.filters = currFilters;
+
+ if (this.isRemoteFiltering() || this.isRemotePagination()) {
+ this.handleRemoteFilterChange();
+ // when remote filtering is enable, dont set currFilters state
+ // in the componentWillReceiveProps,
+ // it's the key point that we can know the filter is changed
+ return;
+ }
+
+ store.filteredData = filters(store, columns, _)(currFilters);
+ this.setState(() => ({ currFilters, isDataChanged: true }));
+ }
+
+ render() {
+ return (
+
+ );
+ }
+ };
diff --git a/packages/react-bootstrap-table2-filter/test/wrapper.test.js b/packages/react-bootstrap-table2-filter/test/wrapper.test.js
index 9541c8d..f250c46 100644
--- a/packages/react-bootstrap-table2-filter/test/wrapper.test.js
+++ b/packages/react-bootstrap-table2-filter/test/wrapper.test.js
@@ -3,10 +3,11 @@ import sinon from 'sinon';
import { shallow } from 'enzyme';
import _ from 'react-bootstrap-table2/src/utils';
+import remoteResolver from 'react-bootstrap-table2/src/props-resolver/remote-resolver';
import BootstrapTable from 'react-bootstrap-table2/src/bootstrap-table';
import Store from 'react-bootstrap-table2/src/store';
import filter, { textFilter } from '../src';
-import FilterWrapper from '../src/wrapper';
+import wrapperFactory from '../src/wrapper';
import { FILTER_TYPE } from '../src/const';
const data = [];
@@ -21,10 +22,10 @@ for (let i = 0; i < 20; i += 1) {
describe('Wrapper', () => {
let wrapper;
let instance;
- const onRemoteFilterChangeCB = sinon.stub();
+ const onTableChangeCB = sinon.stub();
afterEach(() => {
- onRemoteFilterChangeCB.reset();
+ onTableChangeCB.reset();
});
const createTableProps = () => {
@@ -46,16 +47,19 @@ describe('Wrapper', () => {
filter: filter(),
_,
store: new Store('id'),
- onRemoteFilterChange: onRemoteFilterChangeCB
+ onTableChange: onTableChangeCB
};
tableProps.store.data = data;
return tableProps;
};
- const pureTable = props => ();
+ const FilterWrapper = wrapperFactory(BootstrapTable, {
+ _,
+ remoteResolver
+ });
const createFilterWrapper = (props, renderFragment = true) => {
- wrapper = shallow();
+ wrapper = shallow();
instance = wrapper.instance();
if (renderFragment) {
const fragment = instance.render();
@@ -177,7 +181,7 @@ describe('Wrapper', () => {
});
it('should calling props.onRemoteFilterChange correctly', () => {
- expect(onRemoteFilterChangeCB.calledOnce).toBeTruthy();
+ expect(onTableChangeCB.calledOnce).toBeTruthy();
});
});
diff --git a/packages/react-bootstrap-table2-paginator/src/index.js b/packages/react-bootstrap-table2-paginator/src/index.js
index 375f1fa..fd468cb 100644
--- a/packages/react-bootstrap-table2-paginator/src/index.js
+++ b/packages/react-bootstrap-table2-paginator/src/index.js
@@ -1,6 +1,6 @@
-import PaginationWrapper from './wrapper';
+import wrapperFactory from './wrapper';
export default (options = {}) => ({
- PaginationWrapper,
+ wrapperFactory,
options
});
diff --git a/packages/react-bootstrap-table2-paginator/src/page.js b/packages/react-bootstrap-table2-paginator/src/page.js
index 1ea54e5..aa3085a 100644
--- a/packages/react-bootstrap-table2-paginator/src/page.js
+++ b/packages/react-bootstrap-table2-paginator/src/page.js
@@ -1,12 +1,12 @@
-export const getByCurrPage = store => (page, sizePerPage, pageStartIndex) => {
+export const getByCurrPage = (store, pageStartIndex) => {
const dataSize = store.data.length;
if (!dataSize) return [];
const getNormalizedPage = () => {
const offset = Math.abs(1 - pageStartIndex);
- return page + offset;
+ return store.page + offset;
};
- const end = (getNormalizedPage() * sizePerPage) - 1;
- const start = end - (sizePerPage - 1);
+ const end = (getNormalizedPage() * store.sizePerPage) - 1;
+ const start = end - (store.sizePerPage - 1);
const result = [];
for (let i = start; i <= end; i += 1) {
diff --git a/packages/react-bootstrap-table2-paginator/src/wrapper.js b/packages/react-bootstrap-table2-paginator/src/wrapper.js
index e01cd51..5393a79 100644
--- a/packages/react-bootstrap-table2-paginator/src/wrapper.js
+++ b/packages/react-bootstrap-table2-paginator/src/wrapper.js
@@ -1,6 +1,4 @@
/* eslint react/prop-types: 0 */
-/* eslint arrow-body-style: 0 */
-
import React, { Component } from 'react';
import PropTypes from 'prop-types';
@@ -8,172 +6,154 @@ import Const from './const';
import Pagination from './pagination';
import { getByCurrPage } from './page';
-class PaginationWrapper extends Component {
- static propTypes = {
- store: PropTypes.object.isRequired,
- baseElement: PropTypes.func.isRequired,
- onRemotePageChange: PropTypes.func.isRequired
- }
-
- constructor(props) {
- super(props);
- this.handleChangePage = this.handleChangePage.bind(this);
- this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this);
-
- let currPage;
- let currSizePerPage;
- const { options } = props.pagination;
- const sizePerPageList = options.sizePerPageList || Const.SIZE_PER_PAGE_LIST;
-
- // initialize current page
- if (typeof options.page !== 'undefined') {
- currPage = options.page;
- } else if (typeof options.pageStartIndex !== 'undefined') {
- currPage = options.pageStartIndex;
- } else {
- currPage = Const.PAGE_START_INDEX;
+export default (Base, {
+ remoteResolver
+}) =>
+ class PaginationWrapper extends remoteResolver(Component) {
+ static propTypes = {
+ store: PropTypes.object.isRequired
}
- // initialize current sizePerPage
- if (typeof options.sizePerPage !== 'undefined') {
- currSizePerPage = options.sizePerPage;
- } else if (typeof sizePerPageList[0] === 'object') {
- currSizePerPage = sizePerPageList[0].value;
- } else {
- currSizePerPage = sizePerPageList[0];
- }
+ constructor(props) {
+ super(props);
+ this.handleChangePage = this.handleChangePage.bind(this);
+ this.handleChangeSizePerPage = this.handleChangeSizePerPage.bind(this);
- this.state = { currPage, currSizePerPage };
- this.saveToStore(currPage, currSizePerPage);
- }
+ let currPage;
+ let currSizePerPage;
+ const { options } = props.pagination;
+ const sizePerPageList = options.sizePerPageList || Const.SIZE_PER_PAGE_LIST;
- componentWillReceiveProps(nextProps) {
- let needNewState = false;
- let { currPage, currSizePerPage } = this.state;
- const { page, sizePerPage, pageStartIndex, onPageChange } = nextProps.pagination.options;
-
- if (typeof page !== 'undefined' && currPage !== page) { // user defined page
- currPage = page;
- needNewState = true;
- } else if (nextProps.isDataChanged) { // user didn't defined page but data change
- currPage = typeof pageStartIndex !== 'undefined' ? pageStartIndex : Const.PAGE_START_INDEX;
- needNewState = true;
- }
-
- if (typeof sizePerPage !== 'undefined') {
- currSizePerPage = sizePerPage;
- needNewState = true;
- }
-
- this.saveToStore(currPage, currSizePerPage);
-
- if (needNewState) {
- if (onPageChange) {
- onPageChange(currPage, currSizePerPage);
+ // initialize current page
+ if (typeof options.page !== 'undefined') {
+ currPage = options.page;
+ } else if (typeof options.pageStartIndex !== 'undefined') {
+ currPage = options.pageStartIndex;
+ } else {
+ currPage = Const.PAGE_START_INDEX;
}
- this.setState(() => ({ currPage, currSizePerPage }));
+
+ // initialize current sizePerPage
+ if (typeof options.sizePerPage !== 'undefined') {
+ currSizePerPage = options.sizePerPage;
+ } else if (typeof sizePerPageList[0] === 'object') {
+ currSizePerPage = sizePerPageList[0].value;
+ } else {
+ currSizePerPage = sizePerPageList[0];
+ }
+
+ this.state = { currPage, currSizePerPage };
+ this.saveToStore(currPage, currSizePerPage);
}
- }
- saveToStore(page, sizePerPage) {
- this.props.store.page = page;
- this.props.store.sizePerPage = sizePerPage;
- }
+ componentWillReceiveProps(nextProps) {
+ let needNewState = false;
+ let { currPage, currSizePerPage } = this.state;
+ const { page, sizePerPage, pageStartIndex, onPageChange } = nextProps.pagination.options;
- isRemote() {
- const { remote } = this.props;
- return remote === true || (typeof remote === 'object' && remote.pagination);
- }
+ if (typeof page !== 'undefined' && currPage !== page) { // user defined page
+ currPage = page;
+ needNewState = true;
+ } else if (nextProps.isDataChanged) { // user didn't defined page but data change
+ currPage = typeof pageStartIndex !== 'undefined' ? pageStartIndex : Const.PAGE_START_INDEX;
+ needNewState = true;
+ }
- handleChangePage(currPage) {
- const { currSizePerPage } = this.state;
- const { pagination: { options }, onRemotePageChange } = this.props;
- this.saveToStore(currPage, currSizePerPage);
+ if (typeof sizePerPage !== 'undefined') {
+ currSizePerPage = sizePerPage;
+ needNewState = true;
+ }
- if (options.onPageChange) {
- options.onPageChange(currPage, currSizePerPage);
+ this.saveToStore(currPage, currSizePerPage);
+
+ if (needNewState) {
+ if (onPageChange) {
+ onPageChange(currPage, currSizePerPage);
+ }
+ this.setState(() => ({ currPage, currSizePerPage }));
+ }
}
- if (this.isRemote()) {
- onRemotePageChange();
- return;
- }
- this.setState(() => {
- return {
- currPage
- };
- });
- }
- handleChangeSizePerPage(currSizePerPage, currPage) {
- const { pagination: { options }, onRemotePageChange } = this.props;
- this.saveToStore(currPage, currSizePerPage);
+ saveToStore(page, sizePerPage) {
+ this.props.store.page = page;
+ this.props.store.sizePerPage = sizePerPage;
+ }
- if (options.onSizePerPageChange) {
- options.onSizePerPageChange(currSizePerPage, currPage);
+ handleChangePage(currPage) {
+ const { currSizePerPage } = this.state;
+ const { pagination: { options } } = this.props;
+ this.saveToStore(currPage, currSizePerPage);
+
+ if (options.onPageChange) {
+ options.onPageChange(currPage, currSizePerPage);
+ }
+ if (this.isRemotePagination()) {
+ this.handleRemotePageChange();
+ return;
+ }
+ this.setState(() => ({ currPage }));
}
- if (this.isRemote()) {
- onRemotePageChange();
- return;
- }
- this.setState(() => {
- return {
+
+ handleChangeSizePerPage(currSizePerPage, currPage) {
+ const { pagination: { options } } = this.props;
+ this.saveToStore(currPage, currSizePerPage);
+
+ if (options.onSizePerPageChange) {
+ options.onSizePerPageChange(currSizePerPage, currPage);
+ }
+ if (this.isRemotePagination()) {
+ this.handleRemotePageChange();
+ return;
+ }
+ this.setState(() => ({
currPage,
currSizePerPage
- };
- });
- }
+ }));
+ }
- render() {
- const { pagination: { options }, store, baseElement } = this.props;
- const { currPage, currSizePerPage } = this.state;
- const withFirstAndLast = typeof options.withFirstAndLast === 'undefined' ?
- Const.With_FIRST_AND_LAST : options.withFirstAndLast;
- const alwaysShowAllBtns = typeof options.alwaysShowAllBtns === 'undefined' ?
- Const.SHOW_ALL_PAGE_BTNS : options.alwaysShowAllBtns;
- const hideSizePerPage = typeof options.hideSizePerPage === 'undefined' ?
- Const.HIDE_SIZE_PER_PAGE : options.hideSizePerPage;
- const hidePageListOnlyOnePage = typeof options.hidePageListOnlyOnePage === 'undefined' ?
- Const.HIDE_PAGE_LIST_ONLY_ONE_PAGE : options.hidePageListOnlyOnePage;
- const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
- Const.PAGE_START_INDEX : options.pageStartIndex;
+ render() {
+ const { pagination: { options }, store } = this.props;
+ const { currPage, currSizePerPage } = this.state;
+ const withFirstAndLast = typeof options.withFirstAndLast === 'undefined' ?
+ Const.With_FIRST_AND_LAST : options.withFirstAndLast;
+ const alwaysShowAllBtns = typeof options.alwaysShowAllBtns === 'undefined' ?
+ Const.SHOW_ALL_PAGE_BTNS : options.alwaysShowAllBtns;
+ const hideSizePerPage = typeof options.hideSizePerPage === 'undefined' ?
+ Const.HIDE_SIZE_PER_PAGE : options.hideSizePerPage;
+ const hidePageListOnlyOnePage = typeof options.hidePageListOnlyOnePage === 'undefined' ?
+ Const.HIDE_PAGE_LIST_ONLY_ONE_PAGE : options.hidePageListOnlyOnePage;
+ const pageStartIndex = typeof options.pageStartIndex === 'undefined' ?
+ Const.PAGE_START_INDEX : options.pageStartIndex;
- const data = this.isRemote() ?
- this.props.data :
- getByCurrPage(store)(currPage, currSizePerPage, pageStartIndex);
+ const data = this.isRemotePagination() ?
+ this.props.data :
+ getByCurrPage(store, pageStartIndex);
- const base = baseElement({
- ...this.props,
- key: 'table',
- data
- });
-
- return [
- base,
-
- ];
- }
-}
-
-export default PaginationWrapper;
+ return [
+ ,
+
+ ];
+ }
+ };
diff --git a/packages/react-bootstrap-table2-paginator/test/page.test.js b/packages/react-bootstrap-table2-paginator/test/page.test.js
index f073c86..e4ef53a 100644
--- a/packages/react-bootstrap-table2-paginator/test/page.test.js
+++ b/packages/react-bootstrap-table2-paginator/test/page.test.js
@@ -29,7 +29,9 @@ describe('Page Functions', () => {
it('should always return correct data', () => {
params.forEach(([page, sizePerPage, pageStartIndex]) => {
- const rows = getByCurrPage(store)(page, sizePerPage, pageStartIndex);
+ store.page = page;
+ store.sizePerPage = sizePerPage;
+ const rows = getByCurrPage(store, pageStartIndex);
expect(rows).toBeDefined();
expect(Array.isArray(rows)).toBeTruthy();
expect(rows.every(row => !!row)).toBeTruthy();
@@ -39,7 +41,9 @@ describe('Page Functions', () => {
it('should return empty array when store.data is empty', () => {
store.data = [];
params.forEach(([page, sizePerPage, pageStartIndex]) => {
- const rows = getByCurrPage(store)(page, sizePerPage, pageStartIndex);
+ store.page = page;
+ store.sizePerPage = sizePerPage;
+ const rows = getByCurrPage(store, pageStartIndex);
expect(rows).toHaveLength(0);
});
});
diff --git a/packages/react-bootstrap-table2-paginator/test/wrapper.test.js b/packages/react-bootstrap-table2-paginator/test/wrapper.test.js
index 947971d..661f372 100644
--- a/packages/react-bootstrap-table2-paginator/test/wrapper.test.js
+++ b/packages/react-bootstrap-table2-paginator/test/wrapper.test.js
@@ -4,9 +4,10 @@ import { shallow } from 'enzyme';
import BootstrapTable from 'react-bootstrap-table2/src/bootstrap-table';
+import remoteResolver from 'react-bootstrap-table2/src/props-resolver/remote-resolver';
import Store from 'react-bootstrap-table2/src/store';
import paginator from '../src';
-import PaginationWrapper from '../src/wrapper';
+import wrapperFactory from '../src/wrapper';
import Pagination from '../src/pagination';
import Const from '../src/const';
@@ -21,10 +22,10 @@ for (let i = 0; i < 100; i += 1) {
describe('Wrapper', () => {
let wrapper;
let instance;
- const onRemotePageChangeCB = sinon.stub();
+ const onTableChangeCB = sinon.stub();
afterEach(() => {
- onRemotePageChangeCB.reset();
+ onTableChangeCB.reset();
});
const createTableProps = (props = {}) => {
@@ -40,16 +41,18 @@ describe('Wrapper', () => {
data,
pagination: paginator(props.options),
store: new Store('id'),
- onRemotePageChange: onRemotePageChangeCB
+ onTableChange: onTableChangeCB
};
tableProps.store.data = data;
return tableProps;
};
- const pureTable = props => ();
+ const PaginationWrapper = wrapperFactory(BootstrapTable, {
+ remoteResolver
+ });
const createPaginationWrapper = (props, renderFragment = true) => {
- wrapper = shallow();
+ wrapper = shallow();
instance = wrapper.instance();
if (renderFragment) {
const fragment = instance.render();
@@ -504,7 +507,7 @@ describe('Wrapper', () => {
beforeEach(() => {
props.remote = true;
createPaginationWrapper(props, false);
- onRemotePageChangeCB.reset();
+ onTableChangeCB.reset();
instance.handleChangePage(newPage);
});
@@ -513,7 +516,7 @@ describe('Wrapper', () => {
});
it('should calling props.onRemotePageChange correctly', () => {
- expect(onRemotePageChangeCB.calledOnce).toBeTruthy();
+ expect(onTableChangeCB.calledOnce).toBeTruthy();
});
});
});
@@ -551,7 +554,7 @@ describe('Wrapper', () => {
beforeEach(() => {
props.remote = true;
createPaginationWrapper(props, false);
- onRemotePageChangeCB.reset();
+ onTableChangeCB.reset();
instance.handleChangeSizePerPage(newSizePerPage, newPage);
});
@@ -561,68 +564,7 @@ describe('Wrapper', () => {
});
it('should calling props.onRemotePageChange correctly', () => {
- expect(onRemotePageChangeCB.calledOnce).toBeTruthy();
- });
- });
- });
-
- describe('isRemote', () => {
- let result;
- describe('when options.remote is true', () => {
- const props = createTableProps();
- props.remote = true;
-
- beforeEach(() => {
- createPaginationWrapper(props, false);
- result = instance.isRemote();
- });
-
- it('should return true', () => {
- expect(result).toBeTruthy();
- });
- });
-
- describe('when options.remote is false', () => {
- const props = createTableProps();
- props.remote = false;
-
- beforeEach(() => {
- createPaginationWrapper(props, false);
- result = instance.isRemote();
- });
-
- it('should return false', () => {
- expect(result).toBeFalsy();
- });
- });
-
- describe('when options.remote.pagination is defined as true', () => {
- const props = createTableProps();
- props.remote = {};
- props.remote.pagination = true;
-
- beforeEach(() => {
- createPaginationWrapper(props, false);
- result = instance.isRemote();
- });
-
- it('should return true', () => {
- expect(result).toBeTruthy();
- });
- });
-
- describe('when options.remote.pagination is defined as false', () => {
- const props = createTableProps();
- props.remote = {};
- props.remote.pagination = false;
-
- beforeEach(() => {
- createPaginationWrapper(props, false);
- result = instance.isRemote();
- });
-
- it('should return false', () => {
- expect(result).toBeFalsy();
+ expect(onTableChangeCB.calledOnce).toBeTruthy();
});
});
});
diff --git a/packages/react-bootstrap-table2/src/cell-edit/wrapper.js b/packages/react-bootstrap-table2/src/cell-edit/wrapper.js
index 60e3134..ec62fd2 100644
--- a/packages/react-bootstrap-table2/src/cell-edit/wrapper.js
+++ b/packages/react-bootstrap-table2/src/cell-edit/wrapper.js
@@ -1,112 +1,96 @@
-/* eslint arrow-body-style: 0 */
/* eslint react/prop-types: 0 */
-import { Component } from 'react';
-import PropTypes from 'prop-types';
+import React, { Component } from 'react';
import _ from '../utils';
-import { cellEditElement } from '../table-factory';
-
-class CellEditWrapper extends Component {
- constructor(props) {
- super(props);
- this.startEditing = this.startEditing.bind(this);
- this.escapeEditing = this.escapeEditing.bind(this);
- this.completeEditing = this.completeEditing.bind(this);
- this.handleCellUpdate = this.handleCellUpdate.bind(this);
- this.updateEditingWithErr = this.updateEditingWithErr.bind(this);
- this.state = {
- ridx: null,
- cidx: null,
- message: null,
- editing: false
- };
- }
-
- componentWillReceiveProps(nextProps) {
- if (nextProps.cellEdit) {
- if (nextProps.cellEdit.editing) {
- this.setState(() => {
- return {
- ...this.state,
- message: nextProps.cellEdit.errorMessage
- };
- });
- } else {
- this.escapeEditing();
- }
- }
- }
-
- handleCellUpdate(row, column, newValue) {
- const { keyField, cellEdit, onUpdateCell } = this.props;
- const { beforeSaveCell, afterSaveCell } = cellEdit;
- const oldValue = _.get(row, column.dataField);
- const rowId = _.get(row, keyField);
- if (_.isFunction(beforeSaveCell)) beforeSaveCell(oldValue, newValue, row, column);
- if (onUpdateCell(rowId, column.dataField, newValue)) {
- if (_.isFunction(afterSaveCell)) afterSaveCell(oldValue, newValue, row, column);
- this.completeEditing();
- }
- }
-
- completeEditing() {
- this.setState(() => {
- return {
+export default (Base, parentProps) =>
+ class CellEditWrapper extends Component {
+ constructor(props) {
+ super(props);
+ this.startEditing = this.startEditing.bind(this);
+ this.escapeEditing = this.escapeEditing.bind(this);
+ this.completeEditing = this.completeEditing.bind(this);
+ this.handleCellUpdate = this.handleCellUpdate.bind(this);
+ this.updateEditingWithErr = this.updateEditingWithErr.bind(this);
+ this.state = {
ridx: null,
cidx: null,
message: null,
editing: false
};
- });
- }
+ }
- startEditing(ridx, cidx) {
- const editing = () => {
- this.setState(() => {
- return {
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.cellEdit) {
+ if (nextProps.cellEdit.editing) {
+ this.setState(() => ({
+ ...this.state,
+ message: nextProps.cellEdit.errorMessage
+ }));
+ } else {
+ this.escapeEditing();
+ }
+ }
+ }
+
+ handleCellUpdate(row, column, newValue) {
+ const { keyField, cellEdit } = this.props;
+ const { beforeSaveCell, afterSaveCell } = cellEdit;
+ const oldValue = _.get(row, column.dataField);
+ const rowId = _.get(row, keyField);
+ if (_.isFunction(beforeSaveCell)) beforeSaveCell(oldValue, newValue, row, column);
+ if (parentProps.onUpdateCell(rowId, column.dataField, newValue)) {
+ if (_.isFunction(afterSaveCell)) afterSaveCell(oldValue, newValue, row, column);
+ this.completeEditing();
+ }
+ }
+
+ completeEditing() {
+ this.setState(() => ({
+ ridx: null,
+ cidx: null,
+ message: null,
+ editing: false
+ }));
+ }
+
+ startEditing(ridx, cidx) {
+ const editing = () => {
+ this.setState(() => ({
ridx,
cidx,
editing: true
- };
- });
- };
+ }));
+ };
- const { selectRow } = this.props;
- if (!selectRow || (selectRow.clickToEdit || !selectRow.clickToSelect)) editing();
- }
+ const { selectRow } = this.props;
+ if (!selectRow || (selectRow.clickToEdit || !selectRow.clickToSelect)) editing();
+ }
- escapeEditing() {
- this.setState(() => {
- return {
+ escapeEditing() {
+ this.setState(() => ({
ridx: null,
cidx: null,
editing: false
- };
- });
- }
+ }));
+ }
- updateEditingWithErr(message) {
- this.setState(() => {
- return {
+ updateEditingWithErr(message) {
+ this.setState(() => ({
...this.state,
message
- };
- });
- }
+ }));
+ }
- render() {
- return cellEditElement({
- ...this.props,
- onCellUpdate: this.handleCellUpdate,
- onStartEditing: this.startEditing,
- onEscapeEditing: this.escapeEditing,
- currEditCell: { ...this.state }
- });
- }
-}
-
-CellEditWrapper.propTypes = {
- onUpdateCell: PropTypes.func.isRequired
-};
-
-export default CellEditWrapper;
+ render() {
+ return (
+
+ );
+ }
+ };
diff --git a/packages/react-bootstrap-table2/src/container.js b/packages/react-bootstrap-table2/src/container.js
index 8fb7959..04fb908 100644
--- a/packages/react-bootstrap-table2/src/container.js
+++ b/packages/react-bootstrap-table2/src/container.js
@@ -2,53 +2,59 @@
/* eslint react/prop-types: 0 */
import React, { Component } from 'react';
import Store from './store';
+import withSort from './sort/wrapper';
+import withCellEdit from './cell-edit/wrapper';
+import withSelection from './row-selection/wrapper';
-import {
- wrapWithCellEdit,
- wrapWithSelection,
- wrapWithFilter,
- wrapWithSort,
- wrapWithPagination
-} from './table-factory';
-
+import remoteResolver from './props-resolver/remote-resolver';
import _ from './utils';
const withDataStore = Base =>
- class BootstrapTableContainer extends Component {
+ class BootstrapTableContainer extends remoteResolver(Component) {
constructor(props) {
super(props);
this.store = new Store(props.keyField);
this.store.data = props.data;
+ this.wrapComponents();
this.handleUpdateCell = this.handleUpdateCell.bind(this);
- this.handleRemotePageChange = this.handleRemotePageChange.bind(this);
- this.handleRemoteFilterChange = this.handleRemoteFilterChange.bind(this);
}
componentWillReceiveProps(nextProps) {
this.store.data = nextProps.data;
}
- getNewestState(state = {}) {
- return {
- page: this.store.page,
- sizePerPage: this.store.sizePerPage,
- filters: this.store.filters,
- ...state
- };
- }
-
- handleRemotePageChange() {
- this.props.onTableChange('pagination', this.getNewestState());
- }
-
- // refactoring later for isRemotePagination
- handleRemoteFilterChange(isRemotePagination) {
- const newState = {};
- if (isRemotePagination) {
- const options = this.props.pagination.options || {};
- newState.page = _.isDefined(options.pageStartIndex) ? options.pageStartIndex : 1;
+ wrapComponents() {
+ this.BaseComponent = Base;
+ const { pagination, columns, filter, selectRow, cellEdit } = this.props;
+ if (pagination) {
+ const { wrapperFactory } = pagination;
+ this.BaseComponent = wrapperFactory(this.BaseComponent, {
+ remoteResolver
+ });
+ }
+
+ if (columns.filter(col => col.sort).length > 0) {
+ this.BaseComponent = withSort(this.BaseComponent);
+ }
+
+ if (filter) {
+ const { wrapperFactory } = filter;
+ this.BaseComponent = wrapperFactory(this.BaseComponent, {
+ _,
+ remoteResolver
+ });
+ }
+
+ if (selectRow) {
+ this.BaseComponent = withSelection(this.BaseComponent);
+ }
+
+ if (cellEdit) {
+ this.BaseComponent = withCellEdit(this.BaseComponent, {
+ ref: node => this.cellEditWrapper = node,
+ onUpdateCell: this.handleUpdateCell
+ });
}
- this.props.onTableChange('filter', this.getNewestState(newState));
}
handleUpdateCell(rowId, dataField, newValue) {
@@ -82,30 +88,9 @@ const withDataStore = Base =>
store: this.store
};
- if (this.props.cellEdit) {
- return wrapWithCellEdit({
- ref: node => this.cellEditWrapper = node,
- onUpdateCell: this.handleUpdateCell,
- ...baseProps
- });
- } else if (this.props.selectRow) {
- return wrapWithSelection(baseProps);
- } else if (this.props.filter) {
- return wrapWithFilter({
- ...baseProps,
- onRemoteFilterChange: this.handleRemoteFilterChange,
- onRemotePageChange: this.handleRemotePageChange
- });
- } else if (this.props.columns.filter(col => col.sort).length > 0) {
- return wrapWithSort(baseProps);
- } else if (this.props.pagination) {
- return wrapWithPagination({
- ...baseProps,
- onRemotePageChange: this.handleRemotePageChange
- });
- }
-
- return React.createElement(Base, baseProps);
+ return (
+
+ );
}
};
diff --git a/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js b/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js
new file mode 100644
index 0000000..ddadafc
--- /dev/null
+++ b/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js
@@ -0,0 +1,37 @@
+import _ from '../utils';
+
+export default ExtendBase =>
+ class RemoteResolver extends ExtendBase {
+ getNewestState(state = {}) {
+ const store = this.store || this.props.store;
+ return {
+ page: store.page,
+ sizePerPage: store.sizePerPage,
+ filters: store.filters,
+ ...state
+ };
+ }
+
+ isRemotePagination() {
+ const { remote } = this.props;
+ return remote === true || (_.isObject(remote) && remote.pagination);
+ }
+
+ isRemoteFiltering() {
+ const { remote } = this.props;
+ return remote === true || (_.isObject(remote) && remote.filter);
+ }
+
+ handleRemotePageChange() {
+ this.props.onTableChange('pagination', this.getNewestState());
+ }
+
+ handleRemoteFilterChange() {
+ const newState = {};
+ if (this.isRemotePagination()) {
+ const options = this.props.pagination.options || {};
+ newState.page = _.isDefined(options.pageStartIndex) ? options.pageStartIndex : 1;
+ }
+ this.props.onTableChange('filter', this.getNewestState(newState));
+ }
+ };
diff --git a/packages/react-bootstrap-table2/src/row-selection/wrapper.js b/packages/react-bootstrap-table2/src/row-selection/wrapper.js
index 3a73e95..442cb18 100644
--- a/packages/react-bootstrap-table2/src/row-selection/wrapper.js
+++ b/packages/react-bootstrap-table2/src/row-selection/wrapper.js
@@ -1,8 +1,5 @@
-/* eslint arrow-body-style: 0 */
-/* eslint react/prop-types: 0 */
-import { Component } from 'react';
+import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import { selectionElement } from '../table-factory';
import Const from '../const';
import {
@@ -13,88 +10,90 @@ import {
} from '../store/selection';
import { getRowByRowId } from '../store/rows';
-class RowSelectionWrapper extends Component {
- constructor(props) {
- super(props);
- this.handleRowSelect = this.handleRowSelect.bind(this);
- this.handleAllRowsSelect = this.handleAllRowsSelect.bind(this);
- this.state = {
- selectedRowKeys: props.store.selected
- };
- }
-
- /**
- * row selection handler
- * @param {String} rowKey - row key of what was selected.
- * @param {Boolean} checked - next checked status of input button.
- */
- handleRowSelect(rowKey, checked, rowIndex) {
- const { selectRow: { mode, onSelect }, store } = this.props;
- const { ROW_SELECT_SINGLE } = Const;
-
- let currSelected = [...store.selected];
-
- if (mode === ROW_SELECT_SINGLE) { // when select mode is radio
- currSelected = [rowKey];
- } else if (checked) { // when select mode is checkbox
- currSelected.push(rowKey);
- } else {
- currSelected = currSelected.filter(value => value !== rowKey);
+export default Base =>
+ class RowSelectionWrapper extends Component {
+ static propTypes = {
+ store: PropTypes.object.isRequired,
+ selectRow: PropTypes.object.isRequired
}
- store.selected = currSelected;
-
- if (onSelect) {
- const row = getRowByRowId(store)(rowKey);
- onSelect(row, checked, rowIndex);
+ constructor(props) {
+ super(props);
+ this.handleRowSelect = this.handleRowSelect.bind(this);
+ this.handleAllRowsSelect = this.handleAllRowsSelect.bind(this);
+ this.state = {
+ selectedRowKeys: props.store.selected
+ };
}
- this.setState(() => ({
- selectedRowKeys: currSelected
- }));
- }
+ /**
+ * row selection handler
+ * @param {String} rowKey - row key of what was selected.
+ * @param {Boolean} checked - next checked status of input button.
+ */
+ handleRowSelect(rowKey, checked, rowIndex) {
+ const { selectRow: { mode, onSelect }, store } = this.props;
+ const { ROW_SELECT_SINGLE } = Const;
- /**
- * handle all rows selection on header cell by store.selected or given specific result.
- * @param {Boolean} option - customized result for all rows selection
- */
- handleAllRowsSelect(option) {
- const { store, selectRow: {
- onSelectAll,
- nonSelectable
- } } = this.props;
- const selected = isAnySelectedRow(store)(nonSelectable);
+ let currSelected = [...store.selected];
- // set next status of all row selected by store.selected or customizing by user.
- const result = option || !selected;
+ if (mode === ROW_SELECT_SINGLE) { // when select mode is radio
+ currSelected = [rowKey];
+ } else if (checked) { // when select mode is checkbox
+ currSelected.push(rowKey);
+ } else {
+ currSelected = currSelected.filter(value => value !== rowKey);
+ }
- const currSelected = result ?
- selectableKeys(store)(nonSelectable) :
- unSelectableKeys(store)(nonSelectable);
+ store.selected = currSelected;
+ if (onSelect) {
+ const row = getRowByRowId(store)(rowKey);
+ onSelect(row, checked, rowIndex);
+ }
- store.selected = currSelected;
-
- if (onSelectAll) {
- onSelectAll(result, getSelectedRows(store));
+ this.setState(() => ({
+ selectedRowKeys: currSelected
+ }));
}
- this.setState(() => ({
- selectedRowKeys: currSelected
- }));
- }
+ /**
+ * handle all rows selection on header cell by store.selected or given specific result.
+ * @param {Boolean} option - customized result for all rows selection
+ */
+ handleAllRowsSelect(option) {
+ const { store, selectRow: {
+ onSelectAll,
+ nonSelectable
+ } } = this.props;
+ const selected = isAnySelectedRow(store)(nonSelectable);
- render() {
- return selectionElement({
- ...this.props,
- onRowSelect: this.handleRowSelect,
- onAllRowsSelect: this.handleAllRowsSelect
- });
- }
-}
+ // set next status of all row selected by store.selected or customizing by user.
+ const result = option || !selected;
-RowSelectionWrapper.propTypes = {
- store: PropTypes.object.isRequired
-};
+ const currSelected = result ?
+ selectableKeys(store)(nonSelectable) :
+ unSelectableKeys(store)(nonSelectable);
-export default RowSelectionWrapper;
+
+ store.selected = currSelected;
+
+ if (onSelectAll) {
+ onSelectAll(result, getSelectedRows(store));
+ }
+
+ this.setState(() => ({
+ selectedRowKeys: currSelected
+ }));
+ }
+
+ render() {
+ return (
+
+ );
+ }
+ };
diff --git a/packages/react-bootstrap-table2/src/sort/wrapper.js b/packages/react-bootstrap-table2/src/sort/wrapper.js
index 82f00b2..40486fb 100644
--- a/packages/react-bootstrap-table2/src/sort/wrapper.js
+++ b/packages/react-bootstrap-table2/src/sort/wrapper.js
@@ -1,60 +1,55 @@
-/* eslint arrow-body-style: 0 */
/* eslint react/prop-types: 0 */
-/* eslint no-return-assign: 0 */
-import { Component } from 'react';
+import React, { Component } from 'react';
import PropTypes from 'prop-types';
-import { sortableElement } from '../table-factory';
+export default Base =>
+ class SortWrapper extends Component {
+ static propTypes = {
+ store: PropTypes.object.isRequired
+ }
-class SortWrapper extends Component {
- constructor(props) {
- super(props);
- this.handleSort = this.handleSort.bind(this);
- }
+ constructor(props) {
+ super(props);
+ this.handleSort = this.handleSort.bind(this);
+ }
- componentWillMount() {
- const { columns, defaultSorted, store } = this.props;
- // defaultSorted is an array, it's ready to use as multi / single sort
- // when we start to support multi sort, please update following code to use array.forEach
- if (defaultSorted && defaultSorted.length > 0) {
- const dataField = defaultSorted[0].dataField;
- const order = defaultSorted[0].order;
- const column = columns.filter(col => col.dataField === dataField);
- if (column.length > 0) {
- store.sortBy(column[0], order);
+ componentWillMount() {
+ const { columns, defaultSorted, store } = this.props;
+ // defaultSorted is an array, it's ready to use as multi / single sort
+ // when we start to support multi sort, please update following code to use array.forEach
+ if (defaultSorted && defaultSorted.length > 0) {
+ const dataField = defaultSorted[0].dataField;
+ const order = defaultSorted[0].order;
+ const column = columns.filter(col => col.dataField === dataField);
+ if (column.length > 0) {
+ store.sortBy(column[0], order);
+ }
}
}
- }
- componentWillReceiveProps(nextProps) {
- if (nextProps.isDataChanged) {
- const sortedColumn = nextProps.columns.find(
- column => column.dataField === nextProps.store.sortField);
- if (sortedColumn) {
- nextProps.store.sortBy(sortedColumn, nextProps.store.sortOrder);
+ componentWillReceiveProps(nextProps) {
+ if (nextProps.isDataChanged) {
+ const sortedColumn = nextProps.columns.find(
+ column => column.dataField === nextProps.store.sortField);
+ if (sortedColumn) {
+ nextProps.store.sortBy(sortedColumn, nextProps.store.sortOrder);
+ }
}
}
- }
- handleSort(column) {
- const { store } = this.props;
- store.sortBy(column);
+ handleSort(column) {
+ const { store } = this.props;
+ store.sortBy(column);
+ this.forceUpdate();
+ }
- this.table.setState({ data: store.data });
- }
-
- render() {
- return sortableElement({
- ...this.props,
- ref: node => this.table = node,
- onSort: this.handleSort,
- data: this.props.store.data
- });
- }
-}
-
-SortWrapper.propTypes = {
- store: PropTypes.object.isRequired
-};
-
-export default SortWrapper;
+ render() {
+ return (
+
+ );
+ }
+ };
diff --git a/packages/react-bootstrap-table2/src/table-factory.js b/packages/react-bootstrap-table2/src/table-factory.js
deleted file mode 100644
index 10ff86e..0000000
--- a/packages/react-bootstrap-table2/src/table-factory.js
+++ /dev/null
@@ -1,43 +0,0 @@
-/* eslint react/prop-types: 0 */
-import React from 'react';
-
-import _ from './utils';
-import BootstrapTable from './bootstrap-table';
-import SortWrapper from './sort/wrapper';
-import RowSelectionWrapper from './row-selection/wrapper';
-import CellEditWrapper from './cell-edit/wrapper';
-
-
-export const wrapWithCellEdit = props =>
- React.createElement(CellEditWrapper, { ...props });
-
-export const wrapWithSelection = props =>
- React.createElement(RowSelectionWrapper, { ...props });
-
-export const wrapWithSort = props =>
- React.createElement(SortWrapper, { ...props });
-
-export const pureTable = props =>
- React.createElement(BootstrapTable, { ...props });
-
-export const wrapWithFilter = (props) => {
- if (props.filter) {
- const { FilterWrapper } = props.filter;
- return React.createElement(FilterWrapper, { ...props, baseElement: wrapWithSort, _ });
- }
- return wrapWithSort(props);
-};
-
-export const wrapWithPagination = (props) => {
- if (props.pagination) {
- const { PaginationWrapper } = props.pagination;
- return React.createElement(PaginationWrapper, { ...props, baseElement: pureTable });
- }
- return pureTable(props);
-};
-
-export const sortableElement = props => wrapWithPagination(props);
-
-export const selectionElement = props => wrapWithFilter(props);
-
-export const cellEditElement = props => wrapWithSelection(props);
diff --git a/packages/react-bootstrap-table2/test/cell-edit/wrapper.test.js b/packages/react-bootstrap-table2/test/cell-edit/wrapper.test.js
index c8065b6..8f21f5f 100644
--- a/packages/react-bootstrap-table2/test/cell-edit/wrapper.test.js
+++ b/packages/react-bootstrap-table2/test/cell-edit/wrapper.test.js
@@ -3,8 +3,9 @@ import sinon from 'sinon';
import { shallow } from 'enzyme';
import Store from '../../src/store';
+import Container from '../../src';
import BootstrapTable from '../../src/bootstrap-table';
-import CellEditWrapper from '../../src/cell-edit/wrapper';
+import wrapperFactory from '../../src/cell-edit/wrapper';
describe('CellEditWrapper', () => {
let wrapper;
@@ -30,10 +31,14 @@ describe('CellEditWrapper', () => {
};
const keyField = 'id';
-
+ let onUpdateCellCB = sinon.stub();
const store = new Store(keyField);
store.data = data;
+ const CellEditWrapper = wrapperFactory(Container, {
+ onUpdateCell: onUpdateCellCB
+ });
+
beforeEach(() => {
wrapper = shallow(
{
columns={ columns }
cellEdit={ cellEdit }
store={ store }
- onUpdateCell={ sinon.stub() }
/>
);
});
@@ -82,7 +86,6 @@ describe('CellEditWrapper', () => {
columns={ columns }
cellEdit={ cellEdit }
store={ store }
- onUpdateCell={ sinon.stub() }
/>
);
wrapper.setProps({ cellEdit: { ...cellEdit, editing: false } });
@@ -113,7 +116,6 @@ describe('CellEditWrapper', () => {
columns={ columns }
cellEdit={ cellEdit }
store={ store }
- onUpdateCell={ sinon.stub() }
/>
);
wrapper.setState({ ridx, cidx, editing: true });
@@ -167,7 +169,6 @@ describe('CellEditWrapper', () => {
cellEdit={ cellEdit }
selectRow={ selectRow }
store={ store }
- onUpdateCell={ sinon.stub() }
/>
);
});
@@ -190,7 +191,6 @@ describe('CellEditWrapper', () => {
cellEdit={ cellEdit }
selectRow={ selectRow }
store={ store }
- onUpdateCell={ sinon.stub() }
/>
);
});
@@ -215,13 +215,11 @@ describe('CellEditWrapper', () => {
});
describe('call handleCellUpdate function', () => {
- let onUpdateCellCallBack;
const row = data[0];
const column = columns[1];
const newValue = 'new name';
beforeEach(() => {
- onUpdateCellCallBack = sinon.stub().returns(true);
wrapper = shallow(
{
columns={ columns }
cellEdit={ cellEdit }
store={ store }
- onUpdateCell={ onUpdateCellCallBack }
/>
);
wrapper.instance().handleCellUpdate(row, column, newValue);
});
- afterEach(() => { onUpdateCellCallBack.reset(); });
-
it('should calling onUpdateCell callback correctly', () => {
- expect(onUpdateCellCallBack.callCount).toBe(1);
- expect(onUpdateCellCallBack.calledWith(row.id, column.dataField, newValue)).toBe(true);
+ expect(onUpdateCellCB.callCount).toBe(1);
+ expect(onUpdateCellCB.calledWith(row.id, column.dataField, newValue)).toBe(true);
});
describe('when onUpdateCell function return true', () => {
@@ -260,7 +255,6 @@ describe('CellEditWrapper', () => {
columns={ columns }
cellEdit={ cellEdit }
store={ store }
- onUpdateCell={ onUpdateCellCallBack }
/>
);
wrapper.instance().handleCellUpdate(row, column, newValue);
@@ -279,7 +273,7 @@ describe('CellEditWrapper', () => {
const spy = jest.spyOn(CellEditWrapper.prototype, 'completeEditing');
beforeEach(() => {
- onUpdateCellCallBack = sinon.stub().returns(false);
+ onUpdateCellCB = sinon.stub().returns(false);
wrapper = shallow(
{
columns={ columns }
cellEdit={ cellEdit }
store={ store }
- onUpdateCell={ onUpdateCellCallBack }
/>
);
wrapper.instance().handleCellUpdate(row, column, newValue);
@@ -309,7 +302,6 @@ describe('CellEditWrapper', () => {
columns={ columns }
cellEdit={ cellEdit }
store={ store }
- onUpdateCell={ onUpdateCellCallBack }
/>
);
wrapper.instance().handleCellUpdate(row, column, newValue);
diff --git a/packages/react-bootstrap-table2/test/container.test.js b/packages/react-bootstrap-table2/test/container.test.js
index fd4068a..42c67bf 100644
--- a/packages/react-bootstrap-table2/test/container.test.js
+++ b/packages/react-bootstrap-table2/test/container.test.js
@@ -1,14 +1,14 @@
+/* eslint react/prefer-stateless-function: 0 */
+/* eslint react/no-multi-comp: 0 */
import React from 'react';
import sinon from 'sinon';
import { shallow } from 'enzyme';
-import BootstrapTable from '../src';
-import SortWrapper from '../src/sort/wrapper';
-import CellEditWrapper from '../src/cell-edit/wrapper';
-import RowSelectionWrapper from '../src/row-selection/wrapper';
+import BootstrapTable from '../src/bootstrap-table';
+import Container from '../src';
import { getRowByRowId } from '../src/store/rows';
-describe('withDataStore', () => {
+describe('container', () => {
let wrapper;
const keyField = 'id';
@@ -32,12 +32,16 @@ describe('withDataStore', () => {
describe('initialization', () => {
beforeEach(() => {
wrapper = shallow(
-
+
);
});
+ it('should initialize BaseComponent', () => {
+ expect(wrapper.instance().BaseComponent.name).toBe('BootstrapTable');
+ });
+
it('should render BootstrapTable successfully', () => {
- expect(wrapper.length).toBe(1);
+ expect(wrapper.find(BootstrapTable)).toHaveLength(1);
});
it('should creating store successfully', () => {
@@ -55,7 +59,7 @@ describe('withDataStore', () => {
beforeEach(() => {
wrapper = shallow(
- {
);
});
- it('should render CellEditWrapper component successfully', () => {
- const component = wrapper.find(CellEditWrapper);
- expect(component.length).toBe(1);
+ it('should initialize BaseComponent correctly', () => {
+ expect(wrapper.instance().BaseComponent.name).toBe('CellEditWrapper');
});
- it('should injecting correct props to CellEditWrapper', () => {
- const component = wrapper.find(CellEditWrapper);
- expect(component.props().onUpdateCell).toBeDefined();
+ it('should render CellEditWrapper component successfully', () => {
+ expect(wrapper.find('CellEditWrapper')).toHaveLength(1);
+ });
+
+ it('should render BootstrapTable component successfully', () => {
+ expect(wrapper.dive().find(BootstrapTable)).toHaveLength(1);
});
describe('for handleUpdateCell function', () => {
@@ -100,7 +106,7 @@ describe('withDataStore', () => {
beforeEach(() => {
cellEdit.onUpdate = sinon.stub().returns(false);
wrapper = shallow(
- {
beforeEach(() => {
wrapper = shallow(
- {
);
});
+ it('should initialize BaseComponent correctly', () => {
+ expect(wrapper.instance().BaseComponent.name).toBe('RowSelectionWrapper');
+ });
+
+ it('should render BootstrapTable component successfully', () => {
+ expect(wrapper.dive().find(BootstrapTable)).toHaveLength(1);
+ });
+
it('should render RowSelectionWrapper component successfully', () => {
- expect(wrapper.find(RowSelectionWrapper).length).toBe(1);
+ expect(wrapper.find('RowSelectionWrapper').length).toBe(1);
});
});
describe('when pagination prop is defined', () => {
- const PaginationWrapper = () => test
;
+ const wrapperFactory = Base => class PaginationWrapper extends React.Component {
+ render() { return ; }
+ };
const pagination = {
- PaginationWrapper
+ wrapperFactory
};
beforeEach(() => {
wrapper = shallow(
- {
);
});
- it('should render Pagination wrapper successfully', () => {
- expect(wrapper.find(PaginationWrapper).length).toBe(1);
+ it('should initialize BaseComponent correctly', () => {
+ expect(wrapper.instance().BaseComponent.name).toBe('PaginationWrapper');
});
- it('should injecting correct props to Pagination wrapper', () => {
- const component = wrapper.find(PaginationWrapper);
- expect(component.props().onRemotePageChange).toBeDefined();
- expect(component.props().baseElement).toBeDefined();
+ it('should render BootstrapTable component successfully', () => {
+ expect(wrapper.dive().find(BootstrapTable)).toHaveLength(1);
+ });
+
+ it('should render PaginationWrapper component successfully', () => {
+ expect(wrapper.find('PaginationWrapper').length).toBe(1);
+ });
+ });
+
+ describe('when filter prop is defined', () => {
+ const wrapperFactory = Base => class FilterWrapper extends React.Component {
+ render() { return ; }
+ };
+
+ const filter = { wrapperFactory };
+
+ beforeEach(() => {
+ wrapper = shallow(
+
+ );
+ });
+
+ it('should initialize BaseComponent correctly', () => {
+ expect(wrapper.instance().BaseComponent.name).toBe('FilterWrapper');
+ });
+
+ it('should render BootstrapTable component successfully', () => {
+ expect(wrapper.dive().find(BootstrapTable)).toHaveLength(1);
+ });
+
+ it('should render FilterWrapper component successfully', () => {
+ expect(wrapper.find('FilterWrapper').length).toBe(1);
});
});
@@ -189,7 +238,7 @@ describe('withDataStore', () => {
sort: true
}];
wrapper = shallow(
- {
);
});
+ it('should initialize BaseComponent correctly', () => {
+ expect(wrapper.instance().BaseComponent.name).toBe('SortWrapper');
+ });
+
+ it('should render BootstrapTable component successfully', () => {
+ expect(wrapper.dive().find(BootstrapTable)).toHaveLength(1);
+ });
+
it('should render SortWrapper component successfully', () => {
- expect(wrapper.find(SortWrapper).length).toBe(1);
- });
- });
-
- describe('handleRemotePageChange', () => {
- const onTableChangeCallBack = sinon.stub();
-
- beforeEach(() => {
- wrapper = shallow(
-
- );
- wrapper.instance().handleRemotePageChange();
- });
-
- it('should calling onTableChange correctly', () => {
- expect(onTableChangeCallBack.calledOnce).toBeTruthy();
- expect(onTableChangeCallBack.calledWith('pagination', wrapper.instance().getNewestState())).toBeTruthy();
- });
- });
-
- describe('handleRemoteFilterChange', () => {
- const onTableChangeCallBack = sinon.stub();
-
- beforeEach(() => {
- onTableChangeCallBack.reset();
- wrapper = shallow(
-
- );
- });
-
- describe('when isRemotePagination argument is false', () => {
- beforeEach(() => {
- wrapper.instance().handleRemoteFilterChange(false);
- });
-
- it('should calling onTableChange correctly', () => {
- expect(onTableChangeCallBack.calledOnce).toBeTruthy();
- expect(onTableChangeCallBack.calledWith('filter', wrapper.instance().getNewestState())).toBeTruthy();
- });
- });
-
- describe('when isRemotePagination argument is false', () => {
- describe('and pagination.options.pageStartIndex is defined', () => {
- const options = { pageStartIndex: 0 };
- beforeEach(() => {
- wrapper = shallow(
- {} } }
- onTableChange={ onTableChangeCallBack }
- />
- );
- wrapper.instance().handleRemoteFilterChange(true);
- });
-
- it('should calling onTableChange correctly', () => {
- expect(onTableChangeCallBack.calledOnce).toBeTruthy();
- const newState = wrapper.instance().getNewestState();
- newState.page = options.pageStartIndex;
- expect(onTableChangeCallBack.calledWith('filter', newState)).toBeTruthy();
- });
- });
-
- describe('and pagination.options.pageStartIndex is not defined', () => {
- beforeEach(() => {
- wrapper = shallow(
- {} } }
- onTableChange={ onTableChangeCallBack }
- />
- );
- wrapper.instance().handleRemoteFilterChange(true);
- });
-
- it('should calling onTableChange correctly', () => {
- expect(onTableChangeCallBack.calledOnce).toBeTruthy();
- const newState = wrapper.instance().getNewestState();
- newState.page = 1;
- expect(onTableChangeCallBack.calledWith('filter', newState)).toBeTruthy();
- });
- });
+ expect(wrapper.find('SortWrapper').length).toBe(1);
});
});
});
diff --git a/packages/react-bootstrap-table2/test/props-resolver/remote-resolver.test.js b/packages/react-bootstrap-table2/test/props-resolver/remote-resolver.test.js
new file mode 100644
index 0000000..fa7d8b3
--- /dev/null
+++ b/packages/react-bootstrap-table2/test/props-resolver/remote-resolver.test.js
@@ -0,0 +1,180 @@
+/* eslint react/prefer-stateless-function: 0 */
+import React from 'react';
+import sinon from 'sinon';
+import { shallow } from 'enzyme';
+
+import Container from '../../src/';
+// import remoteResolver from '../../src/props-resolver/remote-resolver';
+
+describe('remoteResolver', () => {
+ let wrapper;
+
+ const keyField = 'id';
+
+ const columns = [{
+ dataField: keyField,
+ text: 'ID'
+ }, {
+ dataField: 'name',
+ text: 'Name'
+ }];
+
+ const data = [{
+ id: 1,
+ name: 'A'
+ }, {
+ id: 2,
+ name: 'B'
+ }];
+
+ const shallowContainer = (props) => {
+ wrapper = shallow(
+
+ );
+ };
+
+ describe('isRemotePagination', () => {
+ describe('when remote is false', () => {
+ beforeEach(() => {
+ shallowContainer();
+ });
+
+ it('should return false', () => {
+ expect(wrapper.instance().isRemotePagination()).toBeFalsy();
+ });
+ });
+
+ describe('when remote is true', () => {
+ beforeEach(() => {
+ shallowContainer({ remote: true });
+ });
+
+ it('should return true', () => {
+ expect(wrapper.instance().isRemotePagination()).toBeTruthy();
+ });
+ });
+
+ describe('when remote.pagination is true', () => {
+ beforeEach(() => {
+ shallowContainer({ remote: { pagination: true } });
+ });
+
+ it('should return true', () => {
+ expect(wrapper.instance().isRemotePagination()).toBeTruthy();
+ });
+ });
+ });
+
+ describe('isRemoteFiltering', () => {
+ describe('when remote is false', () => {
+ beforeEach(() => {
+ shallowContainer();
+ });
+
+ it('should return false', () => {
+ expect(wrapper.instance().isRemoteFiltering()).toBeFalsy();
+ });
+ });
+
+ describe('when remote is true', () => {
+ beforeEach(() => {
+ shallowContainer({ remote: true });
+ });
+
+ it('should return true', () => {
+ expect(wrapper.instance().isRemoteFiltering()).toBeTruthy();
+ });
+ });
+
+ describe('when remote.filter is true', () => {
+ beforeEach(() => {
+ shallowContainer({ remote: { filter: true } });
+ });
+
+ it('should return true', () => {
+ expect(wrapper.instance().isRemoteFiltering()).toBeTruthy();
+ });
+ });
+ });
+
+ describe('handleRemotePageChange', () => {
+ const onTableChangeCB = sinon.stub();
+ beforeEach(() => {
+ onTableChangeCB.reset();
+ shallowContainer({ onTableChange: onTableChangeCB });
+ wrapper.instance().handleRemotePageChange();
+ });
+
+ it('should calling props.onTableChange correctly', () => {
+ expect(onTableChangeCB.calledOnce).toBeTruthy();
+ expect(onTableChangeCB.calledWith('pagination', wrapper.instance().getNewestState())).toBeTruthy();
+ });
+ });
+
+ describe('handleRemoteFilterChange', () => {
+ const onTableChangeCB = sinon.stub();
+
+ beforeEach(() => {
+ onTableChangeCB.reset();
+ shallowContainer({ onTableChange: onTableChangeCB });
+ });
+
+ describe('when remote pagination is disabled', () => {
+ it('should calling props.onTableChange correctly', () => {
+ wrapper.instance().handleRemoteFilterChange();
+ expect(onTableChangeCB.calledOnce).toBeTruthy();
+ expect(onTableChangeCB.calledWith('filter', wrapper.instance().getNewestState())).toBeTruthy();
+ });
+ });
+
+ describe('when remote pagination is enabled', () => {
+ const wrapperFactory = Base => class FilterWrapper extends React.Component {
+ render() { return ; }
+ };
+
+ describe('and pagination.options.pageStartIndex is defined', () => {
+ const options = { pageStartIndex: 0 };
+ beforeEach(() => {
+ shallowContainer({
+ remote: true,
+ onTableChange: onTableChangeCB,
+ pagination: { options, wrapperFactory }
+ });
+ wrapper.instance().store.page = 1;
+ wrapper.instance().store.sizePerPage = 10;
+ wrapper.instance().handleRemoteFilterChange();
+ });
+
+ it('should calling onTableChange correctly', () => {
+ expect(onTableChangeCB.calledOnce).toBeTruthy();
+ const newState = wrapper.instance().getNewestState();
+ newState.page = options.pageStartIndex;
+ expect(onTableChangeCB.calledWith('filter', newState)).toBeTruthy();
+ });
+ });
+
+ describe('and pagination.options.pageStartIndex is not defined', () => {
+ beforeEach(() => {
+ shallowContainer({
+ remote: true,
+ onTableChange: onTableChangeCB,
+ pagination: { wrapperFactory }
+ });
+ wrapper.instance().handleRemoteFilterChange();
+ });
+
+ it('should calling onTableChange correctly', () => {
+ expect(onTableChangeCB.calledOnce).toBeTruthy();
+ const newState = wrapper.instance().getNewestState();
+ newState.page = 1;
+ expect(onTableChangeCB.calledWith('filter', newState)).toBeTruthy();
+ });
+ });
+ });
+ });
+});
diff --git a/packages/react-bootstrap-table2/test/row-selection/wrapper.test.js b/packages/react-bootstrap-table2/test/row-selection/wrapper.test.js
index 84b2c77..fba2c67 100644
--- a/packages/react-bootstrap-table2/test/row-selection/wrapper.test.js
+++ b/packages/react-bootstrap-table2/test/row-selection/wrapper.test.js
@@ -4,7 +4,7 @@ import { shallow } from 'enzyme';
import Store from '../../src/store';
import BootstrapTable from '../../src/bootstrap-table';
-import RowSelectionWrapper from '../../src/row-selection/wrapper';
+import wrapperFactory from '../../src/row-selection/wrapper';
describe('RowSelectionWrapper', () => {
let wrapper;
@@ -35,6 +35,7 @@ describe('RowSelectionWrapper', () => {
const store = new Store(keyField);
store.data = data;
+ const RowSelectionWrapper = wrapperFactory(BootstrapTable);
beforeEach(() => {
wrapper = shallow(
diff --git a/packages/react-bootstrap-table2/test/sort/wrapper.test.js b/packages/react-bootstrap-table2/test/sort/wrapper.test.js
index 733f67d..208058d 100644
--- a/packages/react-bootstrap-table2/test/sort/wrapper.test.js
+++ b/packages/react-bootstrap-table2/test/sort/wrapper.test.js
@@ -1,12 +1,12 @@
import 'jsdom-global/register';
import React from 'react';
import sinon from 'sinon';
-import { shallow, mount } from 'enzyme';
+import { shallow } from 'enzyme';
import Const from '../../src/const';
import Store from '../../src/store';
import BootstrapTable from '../../src/bootstrap-table';
-import SortWrapper from '../../src/sort/wrapper';
+import wrapperFactory from '../../src/sort/wrapper';
describe('SortWrapper', () => {
let wrapper;
@@ -34,6 +34,8 @@ describe('SortWrapper', () => {
let store = new Store(keyField);
store.data = data;
+ const SortWrapper = wrapperFactory(BootstrapTable);
+
beforeEach(() => {
wrapper = shallow(
{
describe('call handleSort function', () => {
const sortColumn = columns[0];
-
beforeEach(() => {
store = new Store(keyField);
store.data = data;
- wrapper = mount(
+ wrapper = shallow(
{
wrapper.instance().handleSort(sortColumn);
});
- it('should sorting data correctly', () => {
- expect(wrapper.instance().table.state.data[0][keyField]).toEqual(data[1][keyField]);
- });
-
it('should operating on store correctly', () => {
expect(store.sortOrder).toEqual(Const.SORT_DESC);
expect(store.sortField).toEqual(sortColumn.dataField);