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 React, { Component } from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { filters } from './filter';
|
import { filters } from './filter';
|
||||||
@ -15,14 +17,20 @@ export default (Base, {
|
|||||||
|
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { currFilters: {}, isDataChanged: false };
|
this.state = { currFilters: {}, isDataChanged: props.isDataChanged || false };
|
||||||
this.onFilter = this.onFilter.bind(this);
|
this.onFilter = this.onFilter.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps({ isDataChanged, store, columns }) {
|
||||||
// consider to use lodash.isEqual
|
// consider to use lodash.isEqual
|
||||||
if (JSON.stringify(this.state.currFilters) !== JSON.stringify(nextProps.store.filters)) {
|
if (JSON.stringify(this.state.currFilters) !== JSON.stringify(store.filters)) {
|
||||||
this.setState(() => ({ isDataChanged: true, currFilters: nextProps.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 {
|
} else {
|
||||||
this.setState(() => ({ isDataChanged: false }));
|
this.setState(() => ({ isDataChanged: false }));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -130,13 +130,11 @@ BootstrapTable.propTypes = {
|
|||||||
filter: PropTypes.object,
|
filter: PropTypes.object,
|
||||||
cellEdit: PropTypes.shape({
|
cellEdit: PropTypes.shape({
|
||||||
mode: PropTypes.oneOf([Const.CLICK_TO_CELL_EDIT, Const.DBCLICK_TO_CELL_EDIT]).isRequired,
|
mode: PropTypes.oneOf([Const.CLICK_TO_CELL_EDIT, Const.DBCLICK_TO_CELL_EDIT]).isRequired,
|
||||||
onUpdate: PropTypes.func,
|
|
||||||
onErrorMessageDisappear: PropTypes.func,
|
onErrorMessageDisappear: PropTypes.func,
|
||||||
blurToSave: PropTypes.bool,
|
blurToSave: PropTypes.bool,
|
||||||
beforeSaveCell: PropTypes.func,
|
beforeSaveCell: PropTypes.func,
|
||||||
afterSaveCell: PropTypes.func,
|
afterSaveCell: PropTypes.func,
|
||||||
nonEditableRows: PropTypes.func,
|
nonEditableRows: PropTypes.func,
|
||||||
editing: PropTypes.bool,
|
|
||||||
timeToCloseMessage: PropTypes.number,
|
timeToCloseMessage: PropTypes.number,
|
||||||
errorMessage: PropTypes.string
|
errorMessage: PropTypes.string
|
||||||
}),
|
}),
|
||||||
@ -146,8 +144,7 @@ BootstrapTable.propTypes = {
|
|||||||
currEditCell: PropTypes.shape({
|
currEditCell: PropTypes.shape({
|
||||||
ridx: PropTypes.number,
|
ridx: PropTypes.number,
|
||||||
cidx: PropTypes.number,
|
cidx: PropTypes.number,
|
||||||
message: PropTypes.string,
|
message: PropTypes.string
|
||||||
editing: PropTypes.bool
|
|
||||||
}),
|
}),
|
||||||
selectRow: PropTypes.shape({
|
selectRow: PropTypes.shape({
|
||||||
mode: PropTypes.oneOf([Const.ROW_SELECT_SINGLE, Const.ROW_SELECT_MULTIPLE]).isRequired,
|
mode: PropTypes.oneOf([Const.ROW_SELECT_SINGLE, Const.ROW_SELECT_MULTIPLE]).isRequired,
|
||||||
|
|||||||
@ -1,44 +1,54 @@
|
|||||||
/* eslint react/prop-types: 0 */
|
/* eslint react/prop-types: 0 */
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import _ from '../utils';
|
import _ from '../utils';
|
||||||
|
import remoteResolver from '../props-resolver/remote-resolver';
|
||||||
|
|
||||||
export default (Base, parentProps) =>
|
export default Base =>
|
||||||
class CellEditWrapper extends Component {
|
class CellEditWrapper extends remoteResolver(Component) {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
this.startEditing = this.startEditing.bind(this);
|
this.startEditing = this.startEditing.bind(this);
|
||||||
this.escapeEditing = this.escapeEditing.bind(this);
|
this.escapeEditing = this.escapeEditing.bind(this);
|
||||||
this.completeEditing = this.completeEditing.bind(this);
|
this.completeEditing = this.completeEditing.bind(this);
|
||||||
this.handleCellUpdate = this.handleCellUpdate.bind(this);
|
this.handleCellUpdate = this.handleCellUpdate.bind(this);
|
||||||
this.updateEditingWithErr = this.updateEditingWithErr.bind(this);
|
|
||||||
this.state = {
|
this.state = {
|
||||||
ridx: null,
|
ridx: null,
|
||||||
cidx: null,
|
cidx: null,
|
||||||
message: null,
|
message: null,
|
||||||
editing: false
|
isDataChanged: false
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
if (nextProps.cellEdit) {
|
if (nextProps.cellEdit && this.isRemoteCellEdit()) {
|
||||||
if (nextProps.cellEdit.editing) {
|
if (nextProps.cellEdit.errorMessage) {
|
||||||
this.setState(() => ({
|
this.setState(() => ({
|
||||||
...this.state,
|
isDataChanged: false,
|
||||||
message: nextProps.cellEdit.errorMessage
|
message: nextProps.cellEdit.errorMessage
|
||||||
}));
|
}));
|
||||||
} else {
|
} else {
|
||||||
|
this.setState(() => ({
|
||||||
|
isDataChanged: true
|
||||||
|
}));
|
||||||
this.escapeEditing();
|
this.escapeEditing();
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.setState(() => ({
|
||||||
|
isDataChanged: false
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleCellUpdate(row, column, newValue) {
|
handleCellUpdate(row, column, newValue) {
|
||||||
const { keyField, cellEdit } = this.props;
|
const { keyField, cellEdit, store } = this.props;
|
||||||
const { beforeSaveCell, afterSaveCell } = cellEdit;
|
const { beforeSaveCell, afterSaveCell } = cellEdit;
|
||||||
const oldValue = _.get(row, column.dataField);
|
const oldValue = _.get(row, column.dataField);
|
||||||
const rowId = _.get(row, keyField);
|
const rowId = _.get(row, keyField);
|
||||||
if (_.isFunction(beforeSaveCell)) beforeSaveCell(oldValue, newValue, row, column);
|
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);
|
if (_.isFunction(afterSaveCell)) afterSaveCell(oldValue, newValue, row, column);
|
||||||
this.completeEditing();
|
this.completeEditing();
|
||||||
}
|
}
|
||||||
@ -49,7 +59,7 @@ export default (Base, parentProps) =>
|
|||||||
ridx: null,
|
ridx: null,
|
||||||
cidx: null,
|
cidx: null,
|
||||||
message: null,
|
message: null,
|
||||||
editing: false
|
isDataChanged: true
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +68,7 @@ export default (Base, parentProps) =>
|
|||||||
this.setState(() => ({
|
this.setState(() => ({
|
||||||
ridx,
|
ridx,
|
||||||
cidx,
|
cidx,
|
||||||
editing: true
|
isDataChanged: false
|
||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -69,27 +79,21 @@ export default (Base, parentProps) =>
|
|||||||
escapeEditing() {
|
escapeEditing() {
|
||||||
this.setState(() => ({
|
this.setState(() => ({
|
||||||
ridx: null,
|
ridx: null,
|
||||||
cidx: null,
|
cidx: null
|
||||||
editing: false
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
updateEditingWithErr(message) {
|
|
||||||
this.setState(() => ({
|
|
||||||
...this.state,
|
|
||||||
message
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
const { isDataChanged, ...rest } = this.state;
|
||||||
return (
|
return (
|
||||||
<Base
|
<Base
|
||||||
{ ...this.props }
|
{ ...this.props }
|
||||||
|
isDataChanged={ isDataChanged }
|
||||||
data={ this.props.store.data }
|
data={ this.props.store.data }
|
||||||
onCellUpdate={ this.handleCellUpdate }
|
onCellUpdate={ this.handleCellUpdate }
|
||||||
onStartEditing={ this.startEditing }
|
onStartEditing={ this.startEditing }
|
||||||
onEscapeEditing={ this.escapeEditing }
|
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 = new Store(props.keyField);
|
||||||
this.store.data = props.data;
|
this.store.data = props.data;
|
||||||
this.wrapComponents();
|
this.wrapComponents();
|
||||||
this.handleUpdateCell = this.handleUpdateCell.bind(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentWillReceiveProps(nextProps) {
|
componentWillReceiveProps(nextProps) {
|
||||||
this.store.data = nextProps.data;
|
this.store.setAllData(nextProps.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
wrapComponents() {
|
wrapComponents() {
|
||||||
@ -45,41 +44,13 @@ const withDataStore = Base =>
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cellEdit) {
|
||||||
|
this.BaseComponent = withCellEdit(this.BaseComponent);
|
||||||
|
}
|
||||||
|
|
||||||
if (selectRow) {
|
if (selectRow) {
|
||||||
this.BaseComponent = withSelection(this.BaseComponent);
|
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() {
|
render() {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ export default ExtendBase =>
|
|||||||
filters: store.filters,
|
filters: store.filters,
|
||||||
sortField: store.sortField,
|
sortField: store.sortField,
|
||||||
sortOrder: store.sortOrder,
|
sortOrder: store.sortOrder,
|
||||||
data: store.data,
|
data: store.getAllData(),
|
||||||
...state
|
...state
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -30,6 +30,11 @@ export default ExtendBase =>
|
|||||||
return remote === true || (_.isObject(remote) && remote.sort);
|
return remote === true || (_.isObject(remote) && remote.sort);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isRemoteCellEdit() {
|
||||||
|
const { remote } = this.props;
|
||||||
|
return remote === true || (_.isObject(remote) && remote.cellEdit);
|
||||||
|
}
|
||||||
|
|
||||||
handleRemotePageChange() {
|
handleRemotePageChange() {
|
||||||
this.props.onTableChange('pagination', this.getNewestState());
|
this.props.onTableChange('pagination', this.getNewestState());
|
||||||
}
|
}
|
||||||
@ -46,4 +51,9 @@ export default ExtendBase =>
|
|||||||
handleSortChange() {
|
handleSortChange() {
|
||||||
this.props.onTableChange('sort', this.getNewestState());
|
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;
|
return this._data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setAllData(data) {
|
||||||
|
this._data = data;
|
||||||
|
}
|
||||||
|
|
||||||
get data() {
|
get data() {
|
||||||
if (Object.keys(this._filters).length > 0) {
|
if (Object.keys(this._filters).length > 0) {
|
||||||
return this._filteredData;
|
return this._filteredData;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user