From cd6bba33c2b0b5960c596784dbfcc44b2c9f32d1 Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Thu, 23 Feb 2017 17:52:23 +0100 Subject: [IMP] web: auto-context for fields model RPC calls Some fields need to do some model RPC calls (name_search, name_create, ...). Before this commit, they did not use the performModelRPC method but an explicit trigger_up so that the BasicController (the FieldManagerMixin) catches it and ask the BasicModel to perform the RPC. This was designed to let the BasicModel handle the context. This commit makes the context be automatically binded without the need to explicitely call the BasicModel for each route in the FieldManagerMixin. It also ensures that the field own context is properly merged with the user/action/search contexts. Now, the fields use the performModelRPC method and the FieldManagerMixin catches the associated "call_service" event. Then, it can get the full context from the BasicModel instance and let the event continue its propagation. To know which field context has to be fetched, the performModelRPC method is overriden by AbstractField to automatically add the dataPointID and the field name in the options parameter. --- addons/web/static/src/js/fields/abstract_field.js | 11 ++ .../web/static/src/js/fields/relational_fields.js | 132 ++++++++++----------- 2 files changed, 74 insertions(+), 69 deletions(-) (limited to 'addons/web/static/src/js/fields') diff --git a/addons/web/static/src/js/fields/abstract_field.js b/addons/web/static/src/js/fields/abstract_field.js index 3d7a827ff13..d50fd493521 100644 --- a/addons/web/static/src/js/fields/abstract_field.js +++ b/addons/web/static/src/js/fields/abstract_field.js @@ -207,6 +207,17 @@ var AbstractField = Widget.extend({ this._reset(record, event); return this._render(); }, + /** + * @override performModelRPC from ServicesMixin + * Adds the dataPointID to the option parameter so that the BasicController + * (the FieldManagerMixin) knows the context to bind to the rpc call. + */ + performModelRPC: function (model, method, args, kwargs, options) { + return this._super(model, method, args, kwargs, _.extend({ + dataPointID: this.dataPointID, + fieldName: this.name, + }, options || {})); + }, //-------------------------------------------------------------------------- // Private diff --git a/addons/web/static/src/js/fields/relational_fields.js b/addons/web/static/src/js/fields/relational_fields.js index 02c41c8c9e5..de46740bcce 100644 --- a/addons/web/static/src/js/fields/relational_fields.js +++ b/addons/web/static/src/js/fields/relational_fields.js @@ -224,21 +224,18 @@ var FieldMany2One = AbstractRelationalField.extend({ */ _quickCreate: function (name) { var self = this; - var slow_create = this._searchCreatePopup.bind(this, "form", false, this._createContext(name)); + var slowCreate = this._searchCreatePopup.bind(this, "form", false, this._createContext(name)); if (this.nodeOptions.quick_create) { - this.trigger_up('name_create', { - model: this.field.relation, - name: name, - context: data.build_context(this.record, this.context), - on_success: function (result) { + this.performModelRPC(this.field.relation, "name_create", [name]).then( + function (result) { if (self.mode === "edit") { self.reinitialize({id: result[0], display_name: result[1]}); } }, - on_fail: slow_create, - }); + slowCreate + ); } else { - slow_create(); + slowCreate(); } }, /** @@ -296,69 +293,66 @@ var FieldMany2One = AbstractRelationalField.extend({ exclusion_domain.push(['id', 'not in', blacklisted_ids]); } var domain = new data.CompoundDomain(data.build_domain(this.record, this.domain), exclusion_domain); - this.trigger_up('name_search', { - model: this.field.relation, - search_val: search_val, - domain: pyeval.eval('domain', domain), - operator: 'ilike', + + this.performModelRPC(this.field.relation, "name_search", [], { + name: search_val, + args: pyeval.eval("domain", domain), + operator: "ilike", limit: this.limit + 1, - on_success: function (result) { - // possible selections for the m2o - var values = _.map(result, function (x) { - x[1] = x[1].split("\n")[0]; - return { - label: _.str.escapeHTML(x[1].trim()) || data.noDisplayContent, - value: x[1], - name: x[1], - id: x[0], - }; - }); + }).then(function (result) { + // possible selections for the m2o + var values = _.map(result, function (x) { + x[1] = x[1].split("\n")[0]; + return { + label: _.str.escapeHTML(x[1].trim()) || data.noDisplayContent, + value: x[1], + name: x[1], + id: x[0], + }; + }); - // search more... if more results than limit - if (values.length > self.limit) { - values = values.slice(0, self.limit); - values.push({ - label: _t("Search More..."), - action: function () { - self.trigger_up('name_search', { - model: self.field.relation, - search_val: search_val, - domain: pyeval.eval('domain', domain), - operator: 'ilike', - limit: 160, - on_success: self._searchCreatePopup.bind(self, "search"), - }); - }, - classname: 'o_m2o_dropdown_option', - }); - } - var create_enabled = self.can_create && !self.nodeOptions.no_create; - // quick create - var raw_result = _.map(result, function (x) { return x[1]; }); - if (create_enabled && !self.nodeOptions.no_quick_create && - search_val.length > 0 && !_.contains(raw_result, search_val)) { - values.push({ - label: _.str.sprintf(_t('Create "%s"'), - $('').text(search_val).html()), - action: self._quickCreate.bind(self, search_val), - classname: 'o_m2o_dropdown_option' - }); - } - // create and edit ... - if (create_enabled && !self.nodeOptions.no_create_edit) { - values.push({ - label: _t("Create and Edit..."), - action: self._searchCreatePopup.bind(self, "form", false, self._createContext(search_val)), - classname: 'o_m2o_dropdown_option', - }); - } else if (values.length === 0) { - values.push({ - label: _t("No results to show..."), - }); - } + // search more... if more results than limit + if (values.length > self.limit) { + values = values.slice(0, self.limit); + values.push({ + label: _t("Search More..."), + action: function () { + self.performModelRPC(self.field.relation, "name_search", { + name: search_val, + args: pyeval.eval('domain', domain), + operator: "ilike", + limit: 160, + }).then(self._searchCreatePopup.bind(self, "search")); + }, + classname: 'o_m2o_dropdown_option', + }); + } + var create_enabled = self.can_create && !self.nodeOptions.no_create; + // quick create + var raw_result = _.map(result, function (x) { return x[1]; }); + if (create_enabled && !self.nodeOptions.no_quick_create && + search_val.length > 0 && !_.contains(raw_result, search_val)) { + values.push({ + label: _.str.sprintf(_t('Create "%s"'), + $('').text(search_val).html()), + action: self._quickCreate.bind(self, search_val), + classname: 'o_m2o_dropdown_option' + }); + } + // create and edit ... + if (create_enabled && !self.nodeOptions.no_create_edit) { + values.push({ + label: _t("Create and Edit..."), + action: self._searchCreatePopup.bind(self, "form", false, self._createContext(search_val)), + classname: 'o_m2o_dropdown_option', + }); + } else if (values.length === 0) { + values.push({ + label: _t("No results to show..."), + }); + } - def.resolve(values); - }, + def.resolve(values); }); return def; -- cgit v1.2.3