summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js/views
diff options
context:
space:
mode:
authorMichael Mattiello (mcm) <mcm@odoo.com>2020-02-03 10:40:52 +0000
committeraab-odoo <aab@odoo.com>2020-02-03 11:08:04 +0000
commit3fd7b2009ec1f16c56c6d0ae87004011c90e204c (patch)
tree85f041055d81938c694263fe082f490d0f0e8446 /addons/web/static/src/js/views
parent6bdcf054fdeef1b02cbb20bdb00fcba648725f36 (diff)
[ADD] web: add owl AbstractField
This commit adds the new AbstractField class written in owl, meant to be extended by specific Field owl implementations. Note that its API is not complete yet, but it is enough for basic usecases. This commit also adapts the BasicRenderer to instantiate the future new fields that will be written in owl. closes odoo/odoo#43759 Related: odoo/enterprise#7872 Signed-off-by: Aaron Bohy (aab) <aab@odoo.com>
Diffstat (limited to 'addons/web/static/src/js/views')
-rw-r--r--addons/web/static/src/js/views/basic/basic_renderer.js75
-rw-r--r--addons/web/static/src/js/views/form/form_renderer.js8
2 files changed, 70 insertions, 13 deletions
diff --git a/addons/web/static/src/js/views/basic/basic_renderer.js b/addons/web/static/src/js/views/basic/basic_renderer.js
index 07edeae343a..046d10a741f 100644
--- a/addons/web/static/src/js/views/basic/basic_renderer.js
+++ b/addons/web/static/src/js/views/basic/basic_renderer.js
@@ -13,9 +13,12 @@ var core = require('web.core');
var dom = require('web.dom');
var widgetRegistry = require('web.widget_registry');
+const { WidgetAdapterMixin } = require('web.OwlCompatibility');
+const FieldWrapper = require('web.FieldWrapper');
+
var qweb = core.qweb;
-var BasicRenderer = AbstractRenderer.extend({
+var BasicRenderer = AbstractRenderer.extend(WidgetAdapterMixin, {
custom_events: {
navigation_move: '_onNavigationMove',
},
@@ -36,6 +39,30 @@ var BasicRenderer = AbstractRenderer.extend({
this.handleField = null;
},
/**
+ * @override
+ */
+ destroy: function () {
+ this._super.apply(this, arguments);
+ WidgetAdapterMixin.destroy.call(this);
+ },
+ /**
+ * Called each time the renderer is attached into the DOM.
+ */
+ on_attach_callback: function () {
+ WidgetAdapterMixin.on_attach_callback.call(this);
+ },
+ /**
+ * Called each time the renderer is detached from the DOM.
+ */
+ on_detach_callback: function () {
+ WidgetAdapterMixin.on_detach_callback.call(this);
+ },
+
+ //--------------------------------------------------------------------------
+ // Public
+ //--------------------------------------------------------------------------
+
+ /**
* This method has two responsabilities: find every invalid fields in the
* current view, and making sure that they are displayed as invalid, by
* toggling the o_form_invalid css class. It has to be done both on the
@@ -625,10 +652,21 @@ var BasicRenderer = AbstractRenderer.extend({
// Initialize and register the widget
// Readonly status is known as the modifiers have just been registered
var Widget = record.fieldsInfo[this.viewType][fieldName].Widget;
- var widget = new Widget(this, fieldName, record, {
+ const legacy = !(Widget.prototype instanceof owl.Component);
+ const widgetOptions = {
mode: modifiers.readonly ? 'readonly' : mode,
viewType: this.viewType,
- });
+ };
+ let widget;
+ if (legacy) {
+ widget = new Widget(this, fieldName, record, widgetOptions);
+ } else {
+ widget = new FieldWrapper(this, Widget, {
+ fieldName,
+ record,
+ options: widgetOptions,
+ });
+ }
// Register the widget so that it can easily be found again
if (this.allFieldWidgets[record.id] === undefined) {
@@ -639,8 +677,13 @@ var BasicRenderer = AbstractRenderer.extend({
widget.__node = node; // TODO get rid of this if possible one day
// Prepare widget rendering and save the related promise
- var def = widget._widgetRenderAndInsert(function () {});
var $el = $('<div>');
+ let def;
+ if (legacy) {
+ def = widget._widgetRenderAndInsert(function () {});
+ } else {
+ def = widget.mount(document.createDocumentFragment());
+ }
this.defs.push(def);
@@ -746,13 +789,23 @@ var BasicRenderer = AbstractRenderer.extend({
_rerenderFieldWidget: function (widget, record, options) {
// Render the new field widget
var $el = this._renderFieldWidget(widget.__node, record, options);
- widget.$el.replaceWith($el);
-
- // Destroy the old widget and position the new one at the old one's
- var oldIndex = this._destroyFieldWidget(record.id, widget);
- var recordWidgets = this.allFieldWidgets[record.id];
- var newWidget = recordWidgets.pop();
- recordWidgets.splice(oldIndex, 0, newWidget);
+ const def = this.defs[this.defs.length - 1]; // this is the widget's def, resolved when it is ready
+ const $div = $('<div>');
+ $div.append($el); // $el will be replaced when widget is ready (see _renderFieldWidget)
+ def.then(() => {
+ widget.$el.replaceWith($div.children());
+
+ // Destroy the old widget and position the new one at the old one's
+ var oldIndex = this._destroyFieldWidget(record.id, widget);
+ var recordWidgets = this.allFieldWidgets[record.id];
+ let newWidget = recordWidgets.pop();
+ recordWidgets.splice(oldIndex, 0, newWidget);
+
+ // Mount new widget if necessary (mainly for Owl components)
+ if (this._isInDom && newWidget.on_attach_callback) {
+ newWidget.on_attach_callback();
+ }
+ });
},
/**
* Unregisters an element of the modifiers data associated to the given
diff --git a/addons/web/static/src/js/views/form/form_renderer.js b/addons/web/static/src/js/views/form/form_renderer.js
index e393f22dba4..89972e700aa 100644
--- a/addons/web/static/src/js/views/form/form_renderer.js
+++ b/addons/web/static/src/js/views/form/form_renderer.js
@@ -1060,11 +1060,15 @@ var FormRenderer = BasicRenderer.extend({
_onNavigationMove: function (ev) {
ev.stopPropagation();
var index;
+ let target = ev.data.target || ev.target;
+ if (target.__owl__) {
+ target = target.__owl__.parent; // Owl fields are wrapped by the FieldWrapper
+ }
if (ev.data.direction === "next") {
- index = this.allFieldWidgets[this.state.id].indexOf(ev.data.target || ev.target);
+ index = this.allFieldWidgets[this.state.id].indexOf(target);
this._activateNextFieldWidget(this.state, index);
} else if (ev.data.direction === "previous") {
- index = this.allFieldWidgets[this.state.id].indexOf(ev.data.target);
+ index = this.allFieldWidgets[this.state.id].indexOf(target);
this._activatePreviousFieldWidget(this.state, index);
}
},