summaryrefslogtreecommitdiff
path: root/addons/web/static/src
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src')
-rw-r--r--addons/web/static/src/js/fields/abstract_field.js11
-rw-r--r--addons/web/static/src/js/fields/relational_fields.js132
-rw-r--r--addons/web/static/src/js/views/basic/basic_model.js51
-rw-r--r--addons/web/static/src/js/views/field_manager_mixin.js76
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_controller.js13
5 files changed, 125 insertions, 158 deletions
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 "<strong>%s</strong>"'),
- $('<span />').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 "<strong>%s</strong>"'),
+ $('<span />').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;
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 4413168cc73..e28daffc587 100644
--- a/addons/web/static/src/js/views/basic/basic_model.js
+++ b/addons/web/static/src/js/views/basic/basic_model.js
@@ -614,42 +614,6 @@ var BasicModel = AbstractModel.extend({
return record.id;
},
/**
- * This method just does a name_create call to the server.
- *
- * @todo Maybe this method should also create a local record...
- *
- * @param {string} model the name of the model
- * @param {string} name the desired name of the created record
- * @param {Object} context the context to be passed to the rpc
- * @returns {Deferred}
- */
- nameCreate: function (model, name, context) {
- return this.performModelRPC(model, 'name_create', [name], {
- context: _.extend({}, session.user_context, context),
- });
- },
- /**
- * Do a name_search. I think that it should be done directly by the widget
- * @todo remove this
- * @deprecated
- *
- * @param {any} model
- * @param {any} name
- * @param {any} domain
- * @param {any} operator
- * @param {any} limit
- * @returns
- */
- nameSearch: function (model, name, domain, operator, limit) {
- // fixme: correctly handle context
- return this.performModelRPC(model, 'name_search', [], {
- name: name || '',
- args: domain || [],
- operator: operator || 'ilike',
- limit: limit || 0,
- });
- },
- /**
* This is an extremely important method. All changes in any field go
* through this method. It will then apply them in the local state, check
* if onchanges needs to be applied, actually do them if necessary, then
@@ -909,6 +873,20 @@ var BasicModel = AbstractModel.extend({
});
}
},
+ /**
+ * Every RPC done by the model need to add some context, which is a
+ * combination of the context of the session, of the record/list, and/or of
+ * the concerned field. This method combines all these contexts and evaluate
+ * them with the proper evalcontext.
+ *
+ * @param {string} recordID - the id of an element from the localData
+ * @see _getContext for the options parameter
+ * @returns {Object} the evaluated context
+ */
+ getContext: function (recordID, options) {
+ var record = this.localData[recordID];
+ return this._getContext(record, options);
+ },
//--------------------------------------------------------------------------
// Private
@@ -2039,4 +2017,3 @@ var BasicModel = AbstractModel.extend({
return BasicModel;
});
-
diff --git a/addons/web/static/src/js/views/field_manager_mixin.js b/addons/web/static/src/js/views/field_manager_mixin.js
index 92c3da6a1fc..e2cfa681116 100644
--- a/addons/web/static/src/js/views/field_manager_mixin.js
+++ b/addons/web/static/src/js/views/field_manager_mixin.js
@@ -14,13 +14,11 @@ var core = require('web.core');
var qweb = core.qweb;
-return {
+var FieldManagerMixin = {
custom_events: {
field_changed: '_onFieldChanged',
- name_create: '_onNameCreate',
- name_get: '_onNameGet',
- name_search: '_onNameSearch',
load: '_onLoad',
+ call_service: '_onCallService',
},
/**
* A FieldManagerMixin can be initialized with an instance of a basicModel.
@@ -123,52 +121,36 @@ return {
});
},
/**
- * When a name_create event arrives, the nameCreate method from the model
- * should be called.
+ * Some widgets perform model RPCs. These are intercepted so that the
+ * context can be automatically added according to the given dataPointID
+ * option the AbstractField implementation automatically adds.
*
- * @param {OdooEvent} event
- */
- _onNameCreate: function (event) {
- var data = event.data;
- if (!data.on_success) { return; }
- this.model
- .nameCreate(data.model, data.name)
- .then(data.on_success)
- .fail(function () {
- if (data.on_fail) {
- data.on_fail();
- }
- });
- },
- /**
- * When a name_get event arrives, the name_get method from the model should
- * be called.
- *
- * @param {OdooEvent} event
- */
- _onNameGet: function (event) {
- var data = event.data;
- if (!data.on_success) { return; }
- this.model.name_get(data.model, data.ids)
- .then(data.on_success); // fixme: handle context
- },
- /**
- * Some field widgets need to perform a namesearch. For example, a many2one
- * widget when it needs to fetch its autocompletion data.
- *
- * @todo Note: I think that this is wrong, the field widget should just perform
- * a name_search rpc on its own, no need for this.
- *
- * @deprecated Just do a regular name_search
- * @param {OdooEvent} event
+ * @param {OdooEvent} e
+ * @param {string} e.data.service - the service called, here we are only
+ * interested in the "ajax" service
+ * @param {string} e.data.method - the service method called, here we are
+ * only interested by the "rpc" method
+ * @param {Array} e.data.args
+ * the args parameters contains the route, the route arguments and
+ * the RPC call options. This method purpose is to check the RPC
+ * call options for the dataPointID (and field name) and merge the
+ * appropriate context with the route arguments' one.
*/
- _onNameSearch: function (event) {
- var data = event.data;
- if (!data.on_success) { return; }
- this.model
- .nameSearch(data.model, data.search_val, data.domain, data.operator, data.limit)
- .then(data.on_success);
+ _onCallService: function (e) {
+ if (e.data.service !== "ajax" || e.data.method !== "rpc") return;
+
+ var args = e.data.args[1];
+ var options = e.data.args[2];
+ if (args.kwargs && options.dataPointID) {
+ args.kwargs.context = _.extend(
+ this.model.getContext(options.dataPointID, {
+ fieldName: options.fieldName || false,
+ }),
+ args.kwargs.context || {}
+ );
+ }
},
};
+return FieldManagerMixin;
});
diff --git a/addons/web/static/src/js/views/kanban/kanban_controller.js b/addons/web/static/src/js/views/kanban/kanban_controller.js
index 7ea09f38eb5..b8010c97899 100644
--- a/addons/web/static/src/js/views/kanban/kanban_controller.js
+++ b/addons/web/static/src/js/views/kanban/kanban_controller.js
@@ -299,10 +299,12 @@ var KanbanController = BasicController.extend({
});
}
data.context['default_' + data.groupedBy[0]] = column.id;
- this.model
- .nameCreate(data.model, event.data.value, data.context)
- .then(add_record)
- .fail(function (event) {
+
+ this.performModelRPC(data.model, "name_create", [event.data.value], {
+ context: data.context,
+ }).then(
+ add_record,
+ function (event) {
event.preventDefault();
var popup = new form_common.SelectCreatePopup(this);
popup.select_element(
@@ -316,7 +318,8 @@ var KanbanController = BasicController.extend({
{ default_name: event.data.value }
);
popup.on("elements_selected", null, add_record);
- });
+ }
+ );
},
/**
* @param {OdooEvent} event