Skip to content

Commit a50a124

Browse files
committed
refine remote cell edit
1 parent fcf7800 commit a50a124

File tree

6 files changed

+57
-63
lines changed

6 files changed

+57
-63
lines changed

packages/react-bootstrap-table2-filter/src/wrapper.js

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
/* eslint no-param-reassign: 0 */
2+
13
import React, { Component } from 'react';
24
import PropTypes from 'prop-types';
35
import { filters } from './filter';
@@ -15,14 +17,20 @@ export default (Base, {
1517

1618
constructor(props) {
1719
super(props);
18-
this.state = { currFilters: {}, isDataChanged: false };
20+
this.state = { currFilters: {}, isDataChanged: props.isDataChanged || false };
1921
this.onFilter = this.onFilter.bind(this);
2022
}
2123

22-
componentWillReceiveProps(nextProps) {
24+
componentWillReceiveProps({ isDataChanged, store, columns }) {
2325
// consider to use lodash.isEqual
24-
if (JSON.stringify(this.state.currFilters) !== JSON.stringify(nextProps.store.filters)) {
25-
this.setState(() => ({ isDataChanged: true, currFilters: nextProps.store.filters }));
26+
if (JSON.stringify(this.state.currFilters) !== JSON.stringify(store.filters)) {
27+
this.setState(() => ({ isDataChanged: true, currFilters: store.filters }));
28+
} else if (isDataChanged) {
29+
if (!(this.isRemoteFiltering() || this.isRemotePagination()) &&
30+
Object.keys(this.state.currFilters).length > 0) {
31+
store.filteredData = filters(store, columns, _)(this.state.currFilters);
32+
}
33+
this.setState(() => ({ isDataChanged }));
2634
} else {
2735
this.setState(() => ({ isDataChanged: false }));
2836
}

packages/react-bootstrap-table2/src/bootstrap-table.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -130,13 +130,11 @@ BootstrapTable.propTypes = {
130130
filter: PropTypes.object,
131131
cellEdit: PropTypes.shape({
132132
mode: PropTypes.oneOf([Const.CLICK_TO_CELL_EDIT, Const.DBCLICK_TO_CELL_EDIT]).isRequired,
133-
onUpdate: PropTypes.func,
134133
onErrorMessageDisappear: PropTypes.func,
135134
blurToSave: PropTypes.bool,
136135
beforeSaveCell: PropTypes.func,
137136
afterSaveCell: PropTypes.func,
138137
nonEditableRows: PropTypes.func,
139-
editing: PropTypes.bool,
140138
timeToCloseMessage: PropTypes.number,
141139
errorMessage: PropTypes.string
142140
}),
@@ -146,8 +144,7 @@ BootstrapTable.propTypes = {
146144
currEditCell: PropTypes.shape({
147145
ridx: PropTypes.number,
148146
cidx: PropTypes.number,
149-
message: PropTypes.string,
150-
editing: PropTypes.bool
147+
message: PropTypes.string
151148
}),
152149
selectRow: PropTypes.shape({
153150
mode: PropTypes.oneOf([Const.ROW_SELECT_SINGLE, Const.ROW_SELECT_MULTIPLE]).isRequired,

packages/react-bootstrap-table2/src/cell-edit/wrapper.js

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,54 @@
11
/* eslint react/prop-types: 0 */
22
import React, { Component } from 'react';
33
import _ from '../utils';
4+
import remoteResolver from '../props-resolver/remote-resolver';
45

5-
export default (Base, parentProps) =>
6-
class CellEditWrapper extends Component {
6+
export default Base =>
7+
class CellEditWrapper extends remoteResolver(Component) {
78
constructor(props) {
89
super(props);
910
this.startEditing = this.startEditing.bind(this);
1011
this.escapeEditing = this.escapeEditing.bind(this);
1112
this.completeEditing = this.completeEditing.bind(this);
1213
this.handleCellUpdate = this.handleCellUpdate.bind(this);
13-
this.updateEditingWithErr = this.updateEditingWithErr.bind(this);
1414
this.state = {
1515
ridx: null,
1616
cidx: null,
1717
message: null,
18-
editing: false
18+
isDataChanged: false
1919
};
2020
}
2121

2222
componentWillReceiveProps(nextProps) {
23-
if (nextProps.cellEdit) {
24-
if (nextProps.cellEdit.editing) {
23+
if (nextProps.cellEdit && this.isRemoteCellEdit()) {
24+
if (nextProps.cellEdit.errorMessage) {
2525
this.setState(() => ({
26-
...this.state,
26+
isDataChanged: false,
2727
message: nextProps.cellEdit.errorMessage
2828
}));
2929
} else {
30+
this.setState(() => ({
31+
isDataChanged: true
32+
}));
3033
this.escapeEditing();
3134
}
35+
} else {
36+
this.setState(() => ({
37+
isDataChanged: false
38+
}));
3239
}
3340
}
3441

3542
handleCellUpdate(row, column, newValue) {
36-
const { keyField, cellEdit } = this.props;
43+
const { keyField, cellEdit, store } = this.props;
3744
const { beforeSaveCell, afterSaveCell } = cellEdit;
3845
const oldValue = _.get(row, column.dataField);
3946
const rowId = _.get(row, keyField);
4047
if (_.isFunction(beforeSaveCell)) beforeSaveCell(oldValue, newValue, row, column);
41-
if (parentProps.onUpdateCell(rowId, column.dataField, newValue)) {
48+
if (this.isRemoteCellEdit()) {
49+
this.handleCellChange(rowId, column.dataField, newValue);
50+
} else {
51+
store.edit(rowId, column.dataField, newValue);
4252
if (_.isFunction(afterSaveCell)) afterSaveCell(oldValue, newValue, row, column);
4353
this.completeEditing();
4454
}
@@ -49,7 +59,7 @@ export default (Base, parentProps) =>
4959
ridx: null,
5060
cidx: null,
5161
message: null,
52-
editing: false
62+
isDataChanged: true
5363
}));
5464
}
5565

@@ -58,7 +68,7 @@ export default (Base, parentProps) =>
5868
this.setState(() => ({
5969
ridx,
6070
cidx,
61-
editing: true
71+
isDataChanged: false
6272
}));
6373
};
6474

@@ -69,27 +79,21 @@ export default (Base, parentProps) =>
6979
escapeEditing() {
7080
this.setState(() => ({
7181
ridx: null,
72-
cidx: null,
73-
editing: false
74-
}));
75-
}
76-
77-
updateEditingWithErr(message) {
78-
this.setState(() => ({
79-
...this.state,
80-
message
82+
cidx: null
8183
}));
8284
}
8385

8486
render() {
87+
const { isDataChanged, ...rest } = this.state;
8588
return (
8689
<Base
8790
{ ...this.props }
91+
isDataChanged={ isDataChanged }
8892
data={ this.props.store.data }
8993
onCellUpdate={ this.handleCellUpdate }
9094
onStartEditing={ this.startEditing }
9195
onEscapeEditing={ this.escapeEditing }
92-
currEditCell={ { ...this.state } }
96+
currEditCell={ { ...rest } }
9397
/>
9498
);
9599
}

packages/react-bootstrap-table2/src/container.js

Lines changed: 4 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,10 @@ const withDataStore = Base =>
1616
this.store = new Store(props.keyField);
1717
this.store.data = props.data;
1818
this.wrapComponents();
19-
this.handleUpdateCell = this.handleUpdateCell.bind(this);
2019
}
2120

2221
componentWillReceiveProps(nextProps) {
23-
this.store.data = nextProps.data;
22+
this.store.setAllData(nextProps.data);
2423
}
2524

2625
wrapComponents() {
@@ -45,41 +44,13 @@ const withDataStore = Base =>
4544
});
4645
}
4746

48-
if (selectRow) {
49-
this.BaseComponent = withSelection(this.BaseComponent);
50-
}
51-
5247
if (cellEdit) {
53-
this.BaseComponent = withCellEdit(this.BaseComponent, {
54-
ref: node => this.cellEditWrapper = node,
55-
onUpdateCell: this.handleUpdateCell
56-
});
48+
this.BaseComponent = withCellEdit(this.BaseComponent);
5749
}
58-
}
5950

60-
handleUpdateCell(rowId, dataField, newValue) {
61-
const { cellEdit } = this.props;
62-
// handle cell editing internal
63-
if (!cellEdit.onUpdate) {
64-
this.store.edit(rowId, dataField, newValue);
65-
return true;
66-
}
67-
68-
// handle cell editing external
69-
const aPromise = cellEdit.onUpdate(rowId, dataField, newValue);
70-
if (_.isDefined(aPromise) && aPromise !== false) { // TODO: should be a promise here
71-
aPromise.then((result = true) => {
72-
const response = result === true ? {} : result;
73-
if (_.isObject(response)) {
74-
const { value } = response;
75-
this.store.edit(rowId, dataField, value || newValue);
76-
this.cellEditWrapper.completeEditing();
77-
}
78-
}).catch((e) => {
79-
this.cellEditWrapper.updateEditingWithErr(e.message);
80-
});
51+
if (selectRow) {
52+
this.BaseComponent = withSelection(this.BaseComponent);
8153
}
82-
return false;
8354
}
8455

8556
render() {

packages/react-bootstrap-table2/src/props-resolver/remote-resolver.js

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export default ExtendBase =>
1010
filters: store.filters,
1111
sortField: store.sortField,
1212
sortOrder: store.sortOrder,
13-
data: store.data,
13+
data: store.getAllData(),
1414
...state
1515
};
1616
}
@@ -30,6 +30,11 @@ export default ExtendBase =>
3030
return remote === true || (_.isObject(remote) && remote.sort);
3131
}
3232

33+
isRemoteCellEdit() {
34+
const { remote } = this.props;
35+
return remote === true || (_.isObject(remote) && remote.cellEdit);
36+
}
37+
3338
handleRemotePageChange() {
3439
this.props.onTableChange('pagination', this.getNewestState());
3540
}
@@ -46,4 +51,9 @@ export default ExtendBase =>
4651
handleSortChange() {
4752
this.props.onTableChange('sort', this.getNewestState());
4853
}
54+
55+
handleCellChange(rowId, dataField, newValue) {
56+
const cellEdit = { rowId, dataField, newValue };
57+
this.props.onTableChange('cellEdit', this.getNewestState({ cellEdit }));
58+
}
4959
};

packages/react-bootstrap-table2/src/store/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ export default class Store {
3434
return this._data;
3535
}
3636

37+
setAllData(data) {
38+
this._data = data;
39+
}
40+
3741
get data() {
3842
if (Object.keys(this._filters).length > 0) {
3943
return this._filteredData;

0 commit comments

Comments
 (0)