summaryrefslogtreecommitdiff
path: root/addons/web/static/src/js
diff options
context:
space:
mode:
Diffstat (limited to 'addons/web/static/src/js')
-rw-r--r--addons/web/static/src/js/views/basic/basic_renderer.js39
-rw-r--r--addons/web/static/src/js/views/basic/widget_registry.js27
-rw-r--r--addons/web/static/src/js/views/form/form_renderer.js23
-rw-r--r--addons/web/static/src/js/views/kanban/kanban_record.js17
-rw-r--r--addons/web/static/src/js/views/list/list_renderer.js4
5 files changed, 96 insertions, 14 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 0e26e2fa19f..ee6e685c3d4 100644
--- a/addons/web/static/src/js/views/basic/basic_renderer.js
+++ b/addons/web/static/src/js/views/basic/basic_renderer.js
@@ -11,6 +11,7 @@ var AbstractRenderer = require('web.AbstractRenderer');
var config = require('web.config');
var core = require('web.core');
var dom = require('web.dom');
+var widgetRegistry = require('web.widget_registry');
var qweb = core.qweb;
@@ -332,6 +333,19 @@ var BasicRenderer = AbstractRenderer.extend({
return _.findWhere(this.allModifiersData, {node: node});
},
/**
+ * @private
+ * @param {jQueryElement} $el
+ * @param {Object} node
+ */
+ _handleAttributes: function ($el, node) {
+ if (node.attrs.class) {
+ $el.addClass(node.attrs.class);
+ }
+ if (node.attrs.style) {
+ $el.attr('style', node.attrs.style);
+ }
+ },
+ /**
* Used by list and kanban renderers to determine whether or not to display
* the no content helper (if there is no data in the state to display)
*
@@ -541,6 +555,31 @@ var BasicRenderer = AbstractRenderer.extend({
return $.when();
},
/**
+ * Instantiate custom widgets
+ *
+ * @private
+ * @param {Object} record
+ * @param {Object} node
+ * @returns {jQueryElement}
+ */
+ _renderWidget: function (record, node) {
+ var Widget = widgetRegistry.get(node.attrs.name);
+ var widget = new Widget(this, record);
+
+ // Prepare widget rendering and save the related deferred
+ var def = widget.__widgetRenderAndInsert(function () {});
+ if (def.state() === 'pending') {
+ this.defs.push(def);
+ }
+
+ // handle other attributes/modifiers
+ this._handleAttributes(widget.$el, node);
+ this._registerModifiers(node, record, widget);
+ widget.$el.addClass('o_widget');
+ return widget.$el;
+ },
+
+ /**
* Rerenders a given widget and make sure the associated data which
* referenced the old one is updated.
*
diff --git a/addons/web/static/src/js/views/basic/widget_registry.js b/addons/web/static/src/js/views/basic/widget_registry.js
new file mode 100644
index 00000000000..470127bd12e
--- /dev/null
+++ b/addons/web/static/src/js/views/basic/widget_registry.js
@@ -0,0 +1,27 @@
+odoo.define('web.widget_registry', function (require) {
+ "use strict";
+
+ // This registry is supposed to contain all custom widgets that will be
+ // available in the basic views, with the tag <widget/>. There are
+ // currently no such widget in the web client, but the functionality is
+ // certainly useful to be able to cleanly add custom behaviour in basic
+ // views (and most notably, the form view)
+ //
+ // The way custom widgets work is that they register themselves to this
+ // registry:
+ //
+ // widgetRegistry.add('some_name', MyWidget);
+ //
+ // Then, they are available with the <widget/> tag (in the arch):
+ //
+ // <widget name="some_name"/>
+ //
+ // Widgets will be then properly instantiated, rendered and destroyed at the
+ // appropriate time, with the current state in second argument.
+ //
+ // For more examples, look at the tests (grep '<widget' in the test folder)
+
+ var Registry = require('web.Registry');
+
+ return new Registry();
+});
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 3cb22af5dfd..7d962e223ce 100644
--- a/addons/web/static/src/js/views/form/form_renderer.js
+++ b/addons/web/static/src/js/views/form/form_renderer.js
@@ -227,19 +227,6 @@ var FormRenderer = BasicRenderer.extend({
},
/**
* @private
- * @param {jQueryElement} $el
- * @param {Object} node
- */
- _handleAttributes: function ($el, node) {
- if (node.attrs.class) {
- $el.addClass(node.attrs.class);
- }
- if (node.attrs.style) {
- $el.attr('style', node.attrs.style);
- }
- },
- /**
- * @private
* @param {Object} node
* @returns {jQueryElement}
*/
@@ -759,6 +746,16 @@ var FormRenderer = BasicRenderer.extend({
return $sheet;
},
/**
+ * Instantiate custom widgets
+ *
+ * @private
+ * @param {Object} node
+ * @returns {jQueryElement}
+ */
+ _renderTagWidget: function (node) {
+ return this._renderWidget(this.state, node);
+ },
+ /**
* Main entry point for the rendering. From here, we call _renderNode on
* the root of the arch, then, when every deferred (from the field widgets)
* are done, it will resolves itself.
diff --git a/addons/web/static/src/js/views/kanban/kanban_record.js b/addons/web/static/src/js/views/kanban/kanban_record.js
index 1dabc93abdb..52597e6ac71 100644
--- a/addons/web/static/src/js/views/kanban/kanban_record.js
+++ b/addons/web/static/src/js/views/kanban/kanban_record.js
@@ -11,6 +11,7 @@ var Domain = require('web.Domain');
var field_utils = require('web.field_utils');
var utils = require('web.utils');
var Widget = require('web.Widget');
+var widgetRegistry = require('web.widget_registry');
var _t = core._t;
var QWeb = core.qweb;
@@ -262,6 +263,21 @@ var KanbanRecord = Widget.extend({
this._setFieldDisplay(widget.$el, field_name);
return widget;
},
+ _processWidgets: function () {
+ var self = this;
+ this.$("widget").each(function () {
+ var $field = $(this);
+ var Widget = widgetRegistry.get($field.attr('name'));
+ var widget = new Widget(self, self.state);
+
+ var def = widget.__widgetRenderAndInsert(function () {});
+ if (def.state() === 'pending') {
+ self.defs.push(def);
+ }
+ widget.$el.addClass('o_widget');
+ $field.replaceWith(widget.$el);
+ });
+ },
/**
* Renders the record
*/
@@ -274,6 +290,7 @@ var KanbanRecord = Widget.extend({
this.$el.on('click', this._onGlobalClick.bind(this));
}
this._processFields();
+ this._processWidgets();
this._setupColor();
this._setupColorPicker();
this._attachTooltip();
diff --git a/addons/web/static/src/js/views/list/list_renderer.js b/addons/web/static/src/js/views/list/list_renderer.js
index 69d56acdbcc..75633629e5e 100644
--- a/addons/web/static/src/js/views/list/list_renderer.js
+++ b/addons/web/static/src/js/views/list/list_renderer.js
@@ -222,7 +222,7 @@ var ListRenderer = BasicRenderer.extend({
var tdClassName = 'o_data_cell';
if (node.tag === 'button') {
tdClassName += ' o_list_button';
- } else {
+ } else if (node.tag === 'field') {
var typeClass = FIELD_CLASSES[this.state.fields[node.attrs.name].type];
if (typeClass) {
tdClassName += (' ' + typeClass);
@@ -245,6 +245,8 @@ var ListRenderer = BasicRenderer.extend({
if (node.tag === 'button') {
return $td.append(this._renderButton(record, node));
+ } else if (node.tag === 'widget') {
+ return $td.append(this._renderWidget(record, node));
}
if (node.attrs.widget || (options && options.renderWidgets)) {
var widget = this._renderFieldWidget(node, record, _.pick(options, 'mode'));