summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/views/field_manager_mixin.js
diff options
context:
space:
mode:
authorGéry Debongnie <ged@odoo.com>2017-03-05 10:05:56 +0100
committerAaron Bohy <aab@odoo.com>2017-04-11 19:44:38 +0200
commit905e01921f3c3ef43ace6fc537d1d8c0d280002c (patch)
tree265c43ab21c5401a5d9f0f3d64d86f1ac417451c /addons/web/static/src/js/views/field_manager_mixin.js
parent54d4c73af4ad05c7640d28c1892247c9538b8017 (diff)
[REF] web, *: redesign all JS views
This commit introduce a full redesign of all JS views. We started basically from scratch. The goal was to unify all the various views under a common framework, to make them testable, to make then usable in different conditions (in studio, or in the frontend), and to make our lives easier. Some important points are: - we introduced new coding guidelines (camelCase, 80 chars width, ...) - we have a brand new testing framework (still QUnit based) - kanban view moved to the web addon - calendar view (formerly web_calender) moved to web as well - the tree view was removed - all new code should be documented We hope that this code is the start of a new era for the Odoo web client, we want to have a high quality codebase, well documented, well tested, well designed. Work done by the framework team: mostly aab, ged, chm, dmo, qsm
Diffstat (limited to 'addons/web/static/src/js/views/field_manager_mixin.js')
-rw-r--r--addons/web/static/src/js/views/field_manager_mixin.js164
1 files changed, 164 insertions, 0 deletions
diff --git a/addons/web/static/src/js/views/field_manager_mixin.js b/addons/web/static/src/js/views/field_manager_mixin.js
new file mode 100644
index 00000000000..f1a238e7316
--- /dev/null
+++ b/addons/web/static/src/js/views/field_manager_mixin.js
@@ -0,0 +1,164 @@
+odoo.define('web.FieldManagerMixin', function (require) {
+"use strict";
+
+/**
+ * The FieldManagerMixin is a mixin, designed to do the plumbing between field
+ * widgets and a basicmodel. Field widgets can be used outside of a view. In
+ * that case, someone needs to listen to events bubbling up from the widgets and
+ * calling the correct methods on the model. This is the field_manager's job.
+ */
+
+var BasicModel = require('web.BasicModel');
+
+return {
+ custom_events: {
+ field_changed: '_onFieldChanged',
+ name_create: '_onNameCreate',
+ name_get: '_onNameGet',
+ name_search: '_onNameSearch',
+ load: '_onLoad',
+ },
+ /**
+ * A FieldManagerMixin can be initialized with an instance of a basicModel.
+ * If not, it will simply uses its own.
+ *
+ * @param {BasicModel} [model]
+ */
+ init: function (model) {
+ this.model = model || new BasicModel(this);
+ },
+
+ //--------------------------------------------------------------------------
+ // Private
+ //--------------------------------------------------------------------------
+
+ /**
+ * This method will be called whenever a field value has changed (and has
+ * been confirmed by the model).
+ *
+ * @abstract
+ * @param {string} id basicModel Id for the changed record
+ * @param {string[]} fields the fields (names) that have been changed
+ * @param {OdooEvent} event the event that triggered the change
+ */
+ _confirmChange: function (id, fields, event) {
+ // to be implemented
+ },
+ /**
+ * This method will be called whenever a save has been triggered by a change
+ * in some controlled field value. For example, when a priority widget is
+ * being changed in a readonly form.
+ *
+ * @see _onFieldChanged
+ * @abstract
+ * @param {string} id The basicModel ID for the saved record
+ */
+ _confirmSave: function (id) {
+ // to be implemented, if necessary
+ },
+
+ //--------------------------------------------------------------------------
+ // Handlers
+ //--------------------------------------------------------------------------
+
+ /**
+ * This is the main job of the FMM: deciding what to do when a controlled
+ * field changes. Most of the time, it notifies the model that a change
+ * just occurred, then confirm the change.
+ *
+ * @param {OdooEvent} event
+ */
+ _onFieldChanged: function (event) {
+ var self = this;
+ // in case of field changed in relational record (e.g. in the form view of a one2many
+ // subrecord), the field_changed event must be stopped as soon as is it handled by a
+ // field_manager (i.e. the one of the subrecord's form view), otherwise it bubbles up to
+ // the main form view but its model doesn't have any data related to the given dataPointID
+ event.stopPropagation();
+ var dataPointID = event.data.dataPointID;
+ this.model.notifyChanges(dataPointID, event.data.changes).then(function (result) { // FIXME if datamodel is not a BasicModel, notifyChanges does not exists
+ if (event.data.force_save) {
+ self.model.save(dataPointID).then(function () {
+ self._confirmSave(dataPointID);
+ });
+ } else {
+ self._confirmChange(dataPointID, result, event);
+ }
+ });
+ },
+ /**
+ * Some widgets need to trigger a reload of their data. For example, a
+ * one2many with a pager needs to be able to fetch the next page. To do
+ * that, it can trigger a load event. This will then ask the model to
+ * actually reload the data, then call the on_success callback.
+ *
+ * @param {OdooEvent} event
+ * @param {number} [event.data.limit]
+ * @param {number} [event.data.offset]
+ * @param {function} [event.data.on_success] callback
+ */
+ _onLoad: function (event) {
+ var self = this;
+ var data = event.data;
+ if (!data.on_success) { return; }
+ var params = {};
+ if ('limit' in data) {
+ params.limit = data.limit;
+ }
+ if ('offset' in data) {
+ params.offset = data.offset;
+ }
+ this.model.reload(data.id, params).then(function (db_id) {
+ data.on_success(self.model.get(db_id));
+ });
+ },
+ /**
+ * When a name_create event arrives, the nameCreate method from the model
+ * should be called.
+ *
+ * @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
+ */
+ _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);
+ },
+};
+
+});