mirror of
https://github.com/gosticks/react-bootstrap-table2.git
synced 2025-10-16 11:55:39 +00:00
refine remote cell edit
This commit is contained in:
parent
fcf7800f96
commit
a50a12426a
@ -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 }));
|
||||
}
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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 (
|
||||
<Base
|
||||
{ ...this.props }
|
||||
isDataChanged={ isDataChanged }
|
||||
data={ this.props.store.data }
|
||||
onCellUpdate={ this.handleCellUpdate }
|
||||
onStartEditing={ this.startEditing }
|
||||
onEscapeEditing={ this.escapeEditing }
|
||||
currEditCell={ { ...this.state } }
|
||||
currEditCell={ { ...rest } }
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
39
packages/react-bootstrap-table2/src/container.js
vendored
39
packages/react-bootstrap-table2/src/container.js
vendored
@ -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() {
|
||||
|
||||
@ -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 }));
|
||||
}
|
||||
};
|
||||
|
||||
@ -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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user