diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 8ab6c897fb0..6bac3fa39e6 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -1043,19 +1043,27 @@ openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.W }, on_inserted: function(element, widget) {}, /** - * Renders the element. The default implementation renders the widget using QWeb, - * `this.template` must be defined. The context given to QWeb contains the "widget" - * key that references `this`. + * Renders the element and insert the result of the render() method in this.$element. */ render_element: function() { - var rendered = null; - if (this.template) - rendered = openerp.web.qweb.render(this.template, {widget: this}); + var rendered = this.render(); if (rendered) { var elem = $(rendered); this.$element.replaceWith(elem); this.$element = elem; } + return this; + }, + /** + * Renders the widget using QWeb, `this.template` must be defined. + * The context given to QWeb contains the "widget" key that references `this`. + * + * @param {Object} additional Additional context arguments to pass to the template. + */ + render: function (additional) { + if (this.template) + return openerp.web.qweb.render(this.template, _.extend({widget: this}, additional || {})); + return null; }, /** * Method called after rendering. Mostly used to bind actions, perform asynchronous @@ -1133,20 +1141,6 @@ openerp.web.OldWidget = openerp.web.Widget.extend({ this.element_id = this.element_id || _.uniqueId('widget-'); var tmp = document.getElementById(this.element_id); this.$element = tmp ? $(tmp) : $(document.createElement(this.tag_name)); - }, - render_element: function() { - var rendered = this.render(); - if (rendered) { - var elem = $(rendered); - this.$element.replaceWith(elem); - this.$element = elem; - } - return this; - }, - render: function (additional) { - if (this.template) - return openerp.web.qweb.render(this.template, _.extend({widget: this}, additional || {})); - return null; } }); diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index ca1c2c29e6e..f4749717a6b 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -90,21 +90,17 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView# }, on_loaded: function(data) { var self = this; - if (!data) { - throw "No data provided."; - } - if (this.root_frame) { - throw "Form view does not support multiple calls to on_loaded"; - } - this.fields_order = []; - this.fields_view = data; + if (data) { + this.fields_order = []; + this.fields_view = data; + var frame = new (this.registry.get_object('frame'))(this, this.fields_view.arch); - this.rendered = QWeb.render(this.form_template, {'widget': this}); + this.rendered = QWeb.render(this.form_template, { 'frame': frame, 'widget': this }); + } this.$element.html(this.rendered); - - this.root_frame = instanciate_widget(this.registry.get_object('frame'), this, this.fields_view.arch); - this.root_frame.appendTo($(".oe_form_header", this.$element)); - + _.each(this.widgets, function(w) { + w.start(); + }); this.$form_header = this.$element.find('.oe_form_header:first'); this.$form_header.find('div.oe_form_pager button[data-pager-action]').click(function() { var action = $(this).data('pager-action'); @@ -791,7 +787,7 @@ openerp.web.form.compute_domain = function(expr, fields) { }; openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.form.Widget# */{ - form_template: 'Widget', + template: 'Widget', /** * @constructs openerp.web.form.Widget * @extends openerp.web.OldWidget @@ -806,9 +802,13 @@ openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.fo this.always_invisible = (this.modifiers.invisible && this.modifiers.invisible === true); this.type = this.type || node.tag; this.element_name = this.element_name || this.type; + this.element_class = [ + 'formview', this.view.view_id, this.element_name, + this.view.widgets_counter++].join("_"); this._super(view); + this.view.widgets[this.element_class] = this; this.children = node.children; this.colspan = parseInt(node.attrs.colspan || 1, 10); this.decrease_max_width = 0; @@ -827,8 +827,13 @@ openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.fo this.align = 'center'; } + this.width = this.node.attrs.width; }, + start: function() { + this.$element = this.view.$element.find( + '.' + this.element_class.replace(/[^\r\n\f0-9A-Za-z_-]/g, "\\$&")); + }, stop: function() { this._super.apply(this, arguments); $('div.tipsy').stop().remove(); @@ -842,8 +847,9 @@ openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.fo update_dom: function() { this.$element.toggle(!this.invisible); }, - render_element: function() { - this.$element.html(QWeb.render(this.form_template, { "widget": this })); + render: function() { + var template = this.template; + return QWeb.render(template, { "widget": this }); }, do_attach_tooltip: function(widget, trigger, options) { widget = widget || this; @@ -853,7 +859,7 @@ openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.fo delayOut: 0, fade: true, title: function() { - var template = widget.form_template + '.tooltip'; + var template = widget.template + '.tooltip'; if (!QWeb.has_template(template)) { template = 'WidgetLabel.tooltip'; } @@ -918,7 +924,7 @@ openerp.web.form.Widget = openerp.web.OldWidget.extend(/** @lends openerp.web.fo }); openerp.web.form.WidgetFrame = openerp.web.form.Widget.extend({ - form_template: 'WidgetFrame', + template: 'WidgetFrame', init: function(view, node) { this._super(view, node); this.columns = parseInt(node.attrs.col || 4, 10); @@ -936,23 +942,6 @@ openerp.web.form.WidgetFrame = openerp.web.form.Widget.extend({ } this.set_row_cells_with(this.table[this.table.length - 1]); }, - render_element: function() { - this._super(); - var self = this; - _.each(this.table, function(row) { - _.each(row, function(td) { - td.$element = self.$element.find('.' + td.element_class); - td.render_element(); - }); - }); - }, - start: function() { - _.each(this.table, function(row) { - _.each(row, function(td) { - td.start(); - }); - }); - }, add_row: function(){ if (this.table.length) { this.set_row_cells_with(this.table[this.table.length - 1]); @@ -1000,14 +989,14 @@ openerp.web.form.WidgetFrame = openerp.web.form.Widget.extend({ node.attrs.nolabel = '1'; } } - var widget = instanciate_widget(this.view.registry.get_any( - [node.attrs.widget, type.type, node.tag]), this.view, node); + var widget = new (this.view.registry.get_any( + [node.attrs.widget, type.type, node.tag])) (this.view, node); if (node.tag == 'field') { if (!this.view.default_focus_field || node.attrs.default_focus == '1') { this.view.default_focus_field = widget; } if (node.attrs.nolabel != '1') { - var label = instanciate_widget(this.view.registry.get_object('label'), this.view, node); + var label = new (this.view.registry.get_object('label')) (this.view, node); label["for"] = widget; this.add_widget(label, widget.colspan + 1); } @@ -1029,31 +1018,23 @@ openerp.web.form.WidgetFrame = openerp.web.form.Widget.extend({ }); openerp.web.form.WidgetGroup = openerp.web.form.WidgetFrame.extend({ - form_template: 'WidgetGroup' + template: 'WidgetGroup' }), openerp.web.form.WidgetNotebook = openerp.web.form.Widget.extend({ - form_template: 'WidgetNotebook', + template: 'WidgetNotebook', init: function(view, node) { this._super(view, node); this.pages = []; for (var i = 0; i < node.children.length; i++) { var n = node.children[i]; if (n.tag == "page") { - var page = instanciate_widget(this.view.registry.get_object('notebookpage'), + var page = new (this.view.registry.get_object('notebookpage'))( this.view, n, this, this.pages.length); this.pages.push(page); } } }, - render_element: function() { - this._super(); - var self = this; - _.each(this.pages, function(page) { - page.$element = self.$element.find('.' + page.element_class); - page.render_element(); - }); - }, start: function() { var self = this; this._super.apply(this, arguments); @@ -1073,9 +1054,6 @@ openerp.web.form.WidgetNotebook = openerp.web.form.Widget.extend({ gravity: 's' }); } - _.each(this.pages, function(page) { - page.start(); - }); }, do_select_first_visible_tab: function() { for (var i = 0; i < this.pages.length; i++) { @@ -1089,7 +1067,7 @@ openerp.web.form.WidgetNotebook = openerp.web.form.Widget.extend({ }); openerp.web.form.WidgetNotebookPage = openerp.web.form.WidgetFrame.extend({ - form_template: 'WidgetNotebookPage', + template: 'WidgetNotebookPage', init: function(view, node, notebook, index) { this.notebook = notebook; this.index = index; @@ -1111,7 +1089,7 @@ openerp.web.form.WidgetNotebookPage = openerp.web.form.WidgetFrame.extend({ }); openerp.web.form.WidgetSeparator = openerp.web.form.Widget.extend({ - form_template: 'WidgetSeparator', + template: 'WidgetSeparator', init: function(view, node) { this._super(view, node); this.orientation = node.attrs.orientation || 'horizontal'; @@ -1123,7 +1101,7 @@ openerp.web.form.WidgetSeparator = openerp.web.form.Widget.extend({ }); openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({ - form_template: 'WidgetButton', + template: 'WidgetButton', init: function(view, node) { this._super(view, node); this.force_disabled = false; @@ -1213,14 +1191,14 @@ openerp.web.form.WidgetButton = openerp.web.form.Widget.extend({ }); openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({ - form_template: 'WidgetLabel', + template: 'WidgetLabel', init: function(view, node) { this.element_name = 'label_' + node.attrs.name; this._super(view, node); if (this.node.tag == 'label' && (this.align === 'left' || this.node.attrs.colspan || (this.string && this.string.length > 32))) { - this.form_template = "WidgetParagraph"; + this.template = "WidgetParagraph"; this.colspan = parseInt(this.node.attrs.colspan || 1, 10); // Widgets default to right-aligned, but paragraph defaults to // left-aligned @@ -1234,15 +1212,12 @@ openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({ this.nowrap = true; } }, - render_element: function() { - var rendered; + render: function () { if (this['for'] && this.type !== 'label') { - rendered = QWeb.render(this.form_template, {widget: this['for']}); - } else { - // Actual label widgets should not have a false and have type label - rendered = QWeb.render(this.form_template, {widget: this}); + return QWeb.render(this.template, {widget: this['for']}); } - this.$element.html(rendered); + // Actual label widgets should not have a false and have type label + return QWeb.render(this.template, {widget: this}); }, start: function() { this._super(); @@ -1372,7 +1347,7 @@ openerp.web.form.Field = openerp.web.form.Widget.extend(/** @lends openerp.web.f }); openerp.web.form.FieldChar = openerp.web.form.Field.extend({ - form_template: 'FieldChar', + template: 'FieldChar', init: function (view, node) { this._super(view, node); this.password = this.node.attrs.password === 'True' || this.node.attrs.password === '1'; @@ -1417,7 +1392,7 @@ openerp.web.form.FieldID = openerp.web.form.FieldChar.extend({ }); openerp.web.form.FieldEmail = openerp.web.form.FieldChar.extend({ - form_template: 'FieldEmail', + template: 'FieldEmail', start: function() { this._super.apply(this, arguments); this.$element.find('button').click(this.on_button_clicked); @@ -1432,7 +1407,7 @@ openerp.web.form.FieldEmail = openerp.web.form.FieldChar.extend({ }); openerp.web.form.FieldUrl = openerp.web.form.FieldChar.extend({ - form_template: 'FieldUrl', + template: 'FieldUrl', start: function() { this._super.apply(this, arguments); this.$element.find('button').click(this.on_button_clicked); @@ -1555,7 +1530,7 @@ openerp.web.DateWidget = openerp.web.DateTimeWidget.extend({ }); openerp.web.form.FieldDatetime = openerp.web.form.Field.extend({ - form_template: "EmptyComponent", + template: "EmptyComponent", build_widget: function() { return new openerp.web.DateTimeWidget(this); }, @@ -1592,7 +1567,7 @@ openerp.web.form.FieldDate = openerp.web.form.FieldDatetime.extend({ }); openerp.web.form.FieldText = openerp.web.form.Field.extend({ - form_template: 'FieldText', + template: 'FieldText', start: function() { this._super.apply(this, arguments); this.$element.find('textarea').change(this.on_ui_change); @@ -1653,7 +1628,7 @@ openerp.web.form.FieldText = openerp.web.form.Field.extend({ }); openerp.web.form.FieldBoolean = openerp.web.form.Field.extend({ - form_template: 'FieldBoolean', + template: 'FieldBoolean', start: function() { var self = this; this._super.apply(this, arguments); @@ -1677,7 +1652,7 @@ openerp.web.form.FieldBoolean = openerp.web.form.Field.extend({ }); openerp.web.form.FieldProgressBar = openerp.web.form.Field.extend({ - form_template: 'FieldProgressBar', + template: 'FieldProgressBar', start: function() { this._super.apply(this, arguments); this.$element.find('div').progressbar({ @@ -1701,7 +1676,7 @@ openerp.web.form.FieldTextXml = openerp.web.form.Field.extend({ }); openerp.web.form.FieldSelection = openerp.web.form.Field.extend({ - form_template: 'FieldSelection', + template: 'FieldSelection', init: function(view, node) { var self = this; this._super(view, node); @@ -1807,7 +1782,7 @@ openerp.web.form.dialog = function(content, options) { }; openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({ - form_template: 'FieldMany2One', + template: 'FieldMany2One', init: function(view, node) { this._super(view, node); this.limit = 7; @@ -2176,7 +2151,7 @@ var commands = { } }; openerp.web.form.FieldOne2Many = openerp.web.form.Field.extend({ - form_template: 'FieldOne2Many', + template: 'FieldOne2Many', multi_selection: false, init: function(view, node) { this._super(view, node); @@ -2543,7 +2518,7 @@ openerp.web.form.One2ManyFormView = openerp.web.FormView.extend({ }); openerp.web.form.FieldMany2Many = openerp.web.form.Field.extend({ - form_template: 'FieldMany2Many', + template: 'FieldMany2Many', multi_selection: false, init: function(view, node) { this._super(view, node); @@ -2992,7 +2967,7 @@ openerp.web.form.FormOpenDataset = openerp.web.ProxyDataSet.extend({ }); openerp.web.form.FieldReference = openerp.web.form.Field.extend({ - form_template: 'FieldReference', + template: 'FieldReference', init: function(view, node) { this._super(view, node); this.fields_view = { @@ -3147,7 +3122,7 @@ openerp.web.form.FieldBinary = openerp.web.form.Field.extend({ }); openerp.web.form.FieldBinaryFile = openerp.web.form.FieldBinary.extend({ - form_template: 'FieldBinaryFile', + template: 'FieldBinaryFile', update_dom: function() { this._super.apply(this, arguments); this.$element.find('.oe-binary-file-set, .oe-binary-file-clear').toggle(!this.readonly); @@ -3185,7 +3160,7 @@ openerp.web.form.FieldBinaryFile = openerp.web.form.FieldBinary.extend({ }); openerp.web.form.FieldBinaryImage = openerp.web.form.FieldBinary.extend({ - form_template: 'FieldBinaryImage', + template: 'FieldBinaryImage', start: function() { this._super.apply(this, arguments); this.$image = this.$element.find('img.oe-binary-image'); @@ -3220,7 +3195,7 @@ openerp.web.form.FieldBinaryImage = openerp.web.form.FieldBinary.extend({ }); openerp.web.form.FieldStatus = openerp.web.form.Field.extend({ - form_template: "EmptyComponent", + template: "EmptyComponent", start: function() { this._super(); this.selected_value = null; @@ -3285,11 +3260,10 @@ openerp.web.form.FieldStatus = openerp.web.form.Field.extend({ }); openerp.web.form.WidgetHtml = openerp.web.form.Widget.extend({ - render_element: function () { + render: function () { var $root = $('