diff --git a/packages/react-bootstrap-table2-filter/src/wrapper.js b/packages/react-bootstrap-table2-filter/src/wrapper.js index 780c4d8..ad08b82 100644 --- a/packages/react-bootstrap-table2-filter/src/wrapper.js +++ b/packages/react-bootstrap-table2-filter/src/wrapper.js @@ -1,3 +1,5 @@ +/* eslint no-param-reassign: 0 */ + import React, { Component } from 'react'; import PropTypes from 'prop-types'; import { filters } from './filter'; @@ -15,14 +17,20 @@ export default (Base, { constructor(props) { super(props); - this.state = { currFilters: {}, isDataChanged: false }; + this.state = { currFilters: {}, isDataChanged: props.isDataChanged || false }; this.onFilter = this.onFilter.bind(this); } - componentWillReceiveProps(nextProps) { + componentWillReceiveProps({ isDataChanged, store, columns }) { // consider to use lodash.isEqual - if (JSON.stringify(this.state.currFilters) !== JSON.stringify(nextProps.store.filters)) { - this.setState(() => ({ isDataChanged: true, currFilters: nextProps.store.filters })); + if (JSON.stringify(this.state.currFilters) !== JSON.stringify(store.filters)) { + this.setState(() => ({ isDataChanged: true, currFilters: store.filters })); + } else if (isDataChanged) { + if (!(this.isRemoteFiltering() || this.isRemotePagination()) && + Object.keys(this.state.currFilters).length > 0) { + store.filteredData = filters(store, columns, _)(this.state.currFilters); + } + this.setState(() => ({ isDataChanged })); } else { this.setState(() => ({ isDataChanged: false })); } diff --git a/packages/react-bootstrap-table2/src/bootstrap-table.js b/packages/react-bootstrap-table2/src/bootstrap-table.js index 19e7afa..aeed455 100644 --- a/packages/react-bootstrap-table2/src/bootstrap-table.js +++ b/packages/react-bootstrap-table2/src/bootstrap-table.js @@ -130,13 +130,11 @@ BootstrapTable.propTypes = { filter: PropTypes.object, cellEdit: PropTypes.shape({ mode: PropTypes.oneOf([Const.CLICK_TO_CELL_EDIT, Const.DBCLICK_TO_CELL_EDIT]).isRequired, - onUpdate: PropTypes.func, onErrorMessageDisappear: PropTypes.func, blurToSave: PropTypes.bool, beforeSaveCell: PropTypes.func, afterSaveCell: PropTypes.func, nonEditableRows: PropTypes.func, - editing: PropTypes.bool, timeToCloseMessage: PropTypes.number, errorMessage: PropTypes.string }), @@ -146,8 +144,7 @@ BootstrapTable.propTypes = { currEditCell: PropTypes.shape({ ridx: PropTypes.number, cidx: PropTypes.number, - message: PropTypes.string, - editing: PropTypes.bool + message: PropTypes.string }), selectRow: PropTypes.shape({ mode: PropTypes.oneOf([Const.ROW_SELECT_SINGLE, Const.ROW_SELECT_MULTIPLE]).isRequired, diff --git a/packages/react-bootstrap-table2/src/cell-edit/wrapper.js b/packages/react-bootstrap-table2/src/cell-edit/wrapper.js index ec62fd2..7f21e53 100644 --- a/packages/react-bootstrap-table2/src/cell-edit/wrapper.js +++ b/packages/react-bootstrap-table2/src/cell-edit/wrapper.js @@ -1,44 +1,54 @@ /* eslint react/prop-types: 0 */ import React, { Component } from 'react'; import _ from '../utils'; +import remoteResolver from '../props-resolver/remote-resolver'; -export default (Base, parentProps) => - class CellEditWrapper extends Component { +export default Base => + class CellEditWrapper extends remoteResolver(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 + isDataChanged: false }; } componentWillReceiveProps(nextProps) { - if (nextProps.cellEdit) { - if (nextProps.cellEdit.editing) { + if (nextProps.cellEdit && this.isRemoteCellEdit()) { + if (nextProps.cellEdit.errorMessage) { this.setState(() => ({ - ...this.state, + isDataChanged: false, message: nextProps.cellEdit.errorMessage })); } else { + this.setState(() => ({ + isDataChanged: true + })); this.escapeEditing(); } + } else { + this.setState(() => ({ + isDataChanged: false + })); } } handleCellUpdate(row, column, newValue) { - const { keyField, cellEdit } = this.props; + const { keyField, cellEdit, store } = 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 (this.isRemoteCellEdit()) { + this.handleCellChange(rowId, column.dataField, newValue); + } else { + store.edit(rowId, column.dataField, newValue); if (_.isFunction(afterSaveCell)) afterSaveCell(oldValue, newValue, row, column); this.completeEditing(); } @@ -49,7 +59,7 @@ export default (Base, parentProps) => ridx: null, cidx: null, message: null, - editing: false + isDataChanged: true })); } @@ -58,7 +68,7 @@ export default (Base, parentProps) => this.setState(() => ({ ridx, cidx, - editing: true + isDataChanged: false })); }; @@ -69,27 +79,21 @@ export default (Base, parentProps) => escapeEditing() { this.setState(() => ({ ridx: null, - cidx: null, - editing: false - })); - } - - updateEditingWithErr(message) { - this.setState(() => ({ - ...this.state, - message + cidx: null })); } render() { + const { isDataChanged, ...rest } = this.state; return ( ); } diff --git a/packages/react-bootstrap-table2/src/container.js b/packages/react-bootstrap-table2/src/container.js index 04fb908..30fe195 100644 --- a/packages/react-bootstrap-table2/src/container.js +++ b/packages/react-bootstrap-table2/src/container.js @@ -16,11 +16,10 @@ const withDataStore = Base => this.store = new Store(props.keyField); this.store.data = props.data; this.wrapComponents(); - this.handleUpdateCell = this.handleUpdateCell.bind(this); } componentWillReceiveProps(nextProps) { - this.store.data = nextProps.data; + this.store.setAllData(nextProps.data); } wrapComponents() { @@ -45,41 +44,13 @@ const withDataStore = Base => }); } + if (cellEdit) { + this.BaseComponent = withCellEdit(this.BaseComponent); + } + if (selectRow) { this.BaseComponent = withSelection(this.BaseComponent); } - - if (cellEdit) { - this.BaseComponent = withCellEdit(this.BaseComponent, { - ref: node => this.cellEditWrapper = node, - onUpdateCell: this.handleUpdateCell - }); - } - } - - handleUpdateCell(rowId, dataField, newValue) { - const { cellEdit } = this.props; - // handle cell editing internal - if (!cellEdit.onUpdate) { - this.store.edit(rowId, dataField, newValue); - return true; - } - - // handle cell editing external - const aPromise = cellEdit.onUpdate(rowId, dataField, newValue); - if (_.isDefined(aPromise) && aPromise !== false) { // TODO: should be a promise here - aPromise.then((result = true) => { - const response = result === true ? {} : result; - if (_.isObject(response)) { - const { value } = response; - this.store.edit(rowId, dataField, value || newValue); - this.cellEditWrapper.completeEditing(); - } - }).catch((e) => { - this.cellEditWrapper.updateEditingWithErr(e.message); - }); - } - return false; } render() { diff --git a/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js b/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js index b59c9e3..6a44e57 100644 --- a/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js +++ b/packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js @@ -10,7 +10,7 @@ export default ExtendBase => filters: store.filters, sortField: store.sortField, sortOrder: store.sortOrder, - data: store.data, + data: store.getAllData(), ...state }; } @@ -30,6 +30,11 @@ export default ExtendBase => return remote === true || (_.isObject(remote) && remote.sort); } + isRemoteCellEdit() { + const { remote } = this.props; + return remote === true || (_.isObject(remote) && remote.cellEdit); + } + handleRemotePageChange() { this.props.onTableChange('pagination', this.getNewestState()); } @@ -46,4 +51,9 @@ export default ExtendBase => handleSortChange() { this.props.onTableChange('sort', this.getNewestState()); } + + handleCellChange(rowId, dataField, newValue) { + const cellEdit = { rowId, dataField, newValue }; + this.props.onTableChange('cellEdit', this.getNewestState({ cellEdit })); + } }; diff --git a/packages/react-bootstrap-table2/src/store/index.js b/packages/react-bootstrap-table2/src/store/index.js index 9c6e108..6711c99 100644 --- a/packages/react-bootstrap-table2/src/store/index.js +++ b/packages/react-bootstrap-table2/src/store/index.js @@ -34,6 +34,10 @@ export default class Store { return this._data; } + setAllData(data) { + this._data = data; + } + get data() { if (Object.keys(this._filters).length > 0) { return this._filteredData;