summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/views/basic/basic_model.js
diff options
context:
space:
mode:
authorMartin Geubelle <mge@odoo.com>2017-09-07 17:19:38 +0200
committerMartin Geubelle <mge@odoo.com>2017-09-08 12:27:43 +0200
commit14cb9af0d672e544484d6dc7b3432722217f4e10 (patch)
tree5a7e2cd2525d7657d52de3b4dc59d7f44780e961 /addons/web/static/src/js/views/basic/basic_model.js
parentb2c916de836d55e2c6deb0c0f344de51de86ba63 (diff)
[FIX] web: only send changed fields on one2many after onchange
The server response to an `onchange` on a one2many is a list of commands. In case of one2many update (command 1), the server returns all fields (and not only the modified ones). When saving the record, this is the client responsability to specify which fields really changed. Before this commit, all fields were sent at `write` and not only the changed ones. This was causing issues when the user couldn't write on the field ; an error was triggered even though the user didn't change anything. To fix this, we only tag as changed (in the datapoint `_changes` attribute) the fields that have a different value after the onchange.
Diffstat (limited to 'addons/web/static/src/js/views/basic/basic_model.js')
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js91
1 files changed, 61 insertions, 30 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_model.js b/addons/web/static/src/js/views/basic/basic_model.js
index 202545c2c8f..cf5a18488a6 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -1234,6 +1234,7 @@ var BasicModel = AbstractModel.extend({
record._rawChanges[name] = val;
return;
}
+ var oldValue = record._changes[name] || record.data[name];
var id;
if (field.type === 'many2one') {
id = false;
@@ -1246,29 +1247,42 @@ var BasicModel = AbstractModel.extend({
var data = _.isArray(val) ?
{id: val[0], display_name: val[1]} :
{id: val};
- rec = self._makeDataPoint({
- context: record.context,
- data: data,
- modelName: field.relation,
- parentID: record.id,
- });
- id = rec.id;
+ if (!oldValue || (self.localData[oldValue].res_id !== data.id)) {
+ // only register a change if the value has changed
+ rec = self._makeDataPoint({
+ context: record.context,
+ data: data,
+ modelName: field.relation,
+ parentID: record.id,
+ });
+ id = rec.id;
+ record._changes[name] = id;
+ }
+ } else {
+ record._changes[name] = false;
}
- record._changes[name] = id;
} else if (field.type === 'reference') {
id = false;
if (val) {
var ref = val.split(',');
- rec = self._makeDataPoint({
- context: record.context,
- data: {id: parseInt(ref[1])},
- modelName: ref[0],
- parentID: record.id,
- });
- defs.push(self._fetchNameGet(rec));
- id = rec.id;
+ var modelName = ref[0];
+ var resID = parseInt(ref[1]);
+ if (!oldValue || self.localData[oldValue].res_id !== resID ||
+ self.localData[oldValue].model !== modelName) {
+ // only register a change if the value has changed
+ rec = self._makeDataPoint({
+ context: record.context,
+ data: {id: parseInt(ref[1])},
+ modelName: modelName,
+ parentID: record.id,
+ });
+ defs.push(self._fetchNameGet(rec));
+ id = rec.id;
+ record._changes[name] = id;
+ }
+ } else {
+ record._changes[name] = id;
}
- record._changes[name] = id;
} else if (field.type === 'one2many' || field.type === 'many2many') {
var listId = record._changes[name] || record.data[name];
var list;
@@ -1288,25 +1302,39 @@ var BasicModel = AbstractModel.extend({
viewType: fieldInfo.viewType,
});
}
+ // TODO: before registering the changes, verify that the x2many
+ // value has changed
record._changes[name] = list.id;
var shouldLoad = false;
list._changes = list._changes || [];
_.each(val, function (command) {
+ var rec;
if (command[0] === 0 || command[0] === 1) {
// CREATE or UPDATE
- var params = {
- context: list.context,
- fields: list.fields,
- fieldsInfo: list.fieldsInfo,
- modelName: list.model,
- parentID: list.id,
- viewType: list.viewType,
- };
- if (command[0] === 1) {
- params.res_id = command[1];
+ if (command[0] === 1 && command[1]) {
+ // updating an existing record
+ var recID = _.find(list.data, function (childID) {
+ var child = self.localData[childID];
+ return child.res_id === command[1];
+ });
+ rec = self.localData[recID];
+ }
+ if (!rec) {
+ var params = {
+ context: list.context,
+ fields: list.fields,
+ fieldsInfo: list.fieldsInfo,
+ modelName: list.model,
+ parentID: list.id,
+ viewType: list.viewType,
+ };
+ if (command[0] === 1) {
+ params.res_id = command[1];
+ }
+ rec = self._makeDataPoint(params);
+ list._cache[rec.res_id] = rec.id;
}
- rec = self._makeDataPoint(params);
- list._cache[rec.res_id] = rec.id;
+
list._changes.push({operation: 'ADD', id: rec.id});
if (command[0] === 1) {
list._changes.push({operation: 'UPDATE', id: rec.id});
@@ -1327,7 +1355,10 @@ var BasicModel = AbstractModel.extend({
defs.push(self._readUngroupedList(list));
}
} else {
- record._changes[name] = self._parseServerValue(field, val);
+ var newValue = self._parseServerValue(field, val);
+ if (newValue !== oldValue) {
+ record._changes[name] = newValue;
+ }
}
});
return $.when.apply($, defs);