diff options
Diffstat (limited to 'addons/web/static/src/js')
| -rw-r--r-- | addons/web/static/src/js/fields/relational_fields.js | 13 | ||||
| -rw-r--r-- | addons/web/static/src/js/views/list/list_editable_renderer.js | 53 |
2 files changed, 59 insertions, 7 deletions
diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index 7df5b390a2c..90c2b08e1e5 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -681,17 +681,16 @@ var FieldX2Many = AbstractField.extend({ var command = ev.data.changes[this.name]; // Here, we only consider 'UPDATE' commands with data, which occur // with editable list view. In order to keep the current line in - // edition, we call confirmChange which will reset the widgets - // instead of re-rendering the list. 'UPDATE' commands with no data - // can be ignored: they occur in one2manys when the record is - // updated from a dialog and in this case, we can re-render the - // whole subview. + // edition, we call confirmUpdate which will try to reset the widgets + // of the line being edited, and rerender the rest of the list. + // 'UPDATE' commands with no data can be ignored: they occur in + // one2manys when the record is updated from a dialog and in this + // case, we can re-render the whole subview. if (command.operation === 'UPDATE' && command.data) { var state = record.data[this.name]; var fieldNames = state.getFieldNames(); this._reset(record, ev); - this.renderer.confirmChange(state, command.id, fieldNames, ev.initialEvent); - return $.when(); + return this.renderer.confirmUpdate(state, command.id, fieldNames, ev.initialEvent); } } return this._super.apply(this, arguments); diff --git a/addons/web/static/src/js/views/list/list_editable_renderer.js b/addons/web/static/src/js/views/list/list_editable_renderer.js index 7984ebf21e1..8379ab3a891 100644 --- a/addons/web/static/src/js/views/list/list_editable_renderer.js +++ b/addons/web/static/src/js/views/list/list_editable_renderer.js @@ -105,6 +105,59 @@ ListRenderer.include({ }); }, /** + * This is a specialized version of confirmChange, meant to be called when + * the change may have affected more than one line (so, for example, an + * onchange which add/remove a few lines in a x2many. This does not occur + * in a normal list view) + * + * The update is more difficult when other rows could have been changed. We + * need to potentially remove some lines, add some other lines, update some + * other lines and maybe reorder a few of them. This problem would neatly + * be solved by using a virtual dom, but we do not have this luxury yet. + * So, in the meantime, what we do is basically remove every current row + * except the 'main' one (the row which caused the update), then rerender + * every new row and add them before/after the main one. + * + * @param {Object} state + * @param {string} id + * @param {string[]} fields + * @param {OdooEvent} ev + * @returns {Deferred<AbstractField[]>} resolved with the list of widgets + * that have been reset + */ + confirmUpdate: function (state, id, fields, ev) { + var self = this; + var oldRowIndex = _.findIndex(this.state.data, {id: id}); + this.state = state; + return this.confirmChange(state, id, fields, ev).then(function () { + // If no record with 'id' can be found in the state, the + // confirmChange method will have rerendered the whole view already, + // so no further work is necessary. + var record = _.findWhere(state.data, {id: id}); + if (!record) { + return; + } + var $row = self.$('.o_data_row:nth(' + oldRowIndex + ')'); + $row.nextAll('.o_data_row').remove(); + $row.prevAll().remove(); + var newRowIndex = _.findIndex(state.data, {id: id}); + _.each(state.data, function (record, index) { + if (index === newRowIndex) { + return; + } + var $newRow = self._renderRow(record); + if (index < newRowIndex) { + $newRow.insertBefore($row); + } else { + $newRow.insertAfter($row); + } + }); + if (self.currentRow !== null) { + self.currentRow = newRowIndex; + } + }); + }, + /** * Edit a given record in the list * * @param {string} recordID |
