From 11c0136907b0b5bd96fd4e53e481c5542f0be7f4 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Mon, 16 Apr 2012 16:45:42 +0200 Subject: [PATCH] [ADD] Add support for QWeb templates in form view bzr revid: fme@openerp.com-20120416144542-modz8goodot8yr7b --- addons/web/static/src/js/view_form.js | 67 +++++++++++++++++++++++++-- addons/web/static/src/js/views.js | 20 ++++++++ 2 files changed, 84 insertions(+), 3 deletions(-) diff --git a/addons/web/static/src/js/view_form.js b/addons/web/static/src/js/view_form.js index e5824d64f59..27905ee4e73 100644 --- a/addons/web/static/src/js/view_form.js +++ b/addons/web/static/src/js/view_form.js @@ -55,6 +55,7 @@ openerp.web.FormView = openerp.web.View.extend({ this.reload_mutex = new $.Mutex(); this.mode = null; this.rendering_engine = new openerp.web.form.FormRenderingEngineReadonly(this); + this.qweb = null; // A QWeb instance will be created if the view is a QWeb template }, destroy: function() { _.each(this.get_widgets(), function(w) { @@ -73,11 +74,13 @@ openerp.web.FormView = openerp.web.View.extend({ this.fields_order = []; this.fields_view = data; - this.rendering_engine.set_fields_view(data); this.rendering_engine.set_fields_registry(this.fields_registry); this.rendering_engine.set_tags_registry(this.tags_registry); - var $dest = this.$element.hasClass("oe_form_container") ? this.$element : this.$element.find('.oe_form_container'); - this.rendering_engine.render_to($dest); + if (!this.extract_qweb_template(data)) { + this.rendering_engine.set_fields_view(data); + var $dest = this.$element.hasClass("oe_form_container") ? this.$element : this.$element.find('.oe_form_container'); + this.rendering_engine.render_to($dest); + } this.$sidebar = this.options.$sidebar || this.$element.find('.oe_form_sidebar'); @@ -124,6 +127,56 @@ openerp.web.FormView = openerp.web.View.extend({ this.has_been_loaded.resolve(); return $.when(); }, + extract_qweb_template: function(fvg) { + for (var i=0, ii=fvg.arch.children.length; i < ii; i++) { + var child = fvg.arch.children[i]; + if (child.tag === "templates") { + this.qweb = new QWeb2.Engine(); + this.qweb.add_template(openerp.web.json_node_to_xml(child)); + if (!this.qweb.has_template('form')) { + throw new Error("No QWeb template found for form view"); + } + return true; + } + } + this.qweb = null; + return false; + }, + get_fvg_from_qweb: function(record) { + var view = this.qweb.render('form', this.get_qweb_context(record)); + var fvg = _.clone(this.fields_view); + fvg.arch = openerp.web.xml_to_json(openerp.web.str_to_xml(view).firstChild); + return fvg; + }, + get_qweb_context: function(record) { + var self = this, + new_record = {}; + _.each(record, function(value, name) { + var r = _.clone(self.fields_view.fields[name] || {}); + if ((r.type === 'date' || r.type === 'datetime') && value) { + r.raw_value = openerp.web.auto_str_to_date(value); + } else { + r.raw_value = value; + } + r.value = openerp.web.format_value(value, r); + new_record[name] = r; + }); + return { + record : new_record, + new_record : !record.id + }; + }, + kill_current_form: function() { + _.each(this.getChildren(), function(el) { + el.destroy(); + }); + this.fields = {}; + this.fields_order = []; + this.default_focus_field = null; + this.default_focus_button = null; + this.translatable_fields = []; + this.$element.find('.oe_form_container').empty(); + }, do_load_state: function(state, warm) { if (state.id && this.datarecord.id != state.id) { if (!this.dataset.get_id_index(state.id)) { @@ -185,6 +238,13 @@ openerp.web.FormView = openerp.web.View.extend({ } this.datarecord = record; + if (this.qweb) { + this.kill_current_form(); + this.rendering_engine.set_fields_view(this.get_fvg_from_qweb(record)); + var $dest = this.$element.hasClass("oe_form_container") ? this.$element : this.$element.find('.oe_form_container'); + this.rendering_engine.render_to($dest); + } + _(this.fields).each(function (field, f) { field.reset(); var result = field.set_value(self.datarecord[f] || false); @@ -863,6 +923,7 @@ openerp.web.form.FormRenderingEngine = openerp.web.Class.extend({ var w = new (obj)(self.view, openerp.web.xml_to_json($elem[0])); w.replace($elem); }) + // TODO: return a deferred }, render_element: function(template, layout/* dictionaries */) { var dicts = [].slice.call(arguments).slice(2); diff --git a/addons/web/static/src/js/views.js b/addons/web/static/src/js/views.js index de9ff55758c..78f365c1a16 100644 --- a/addons/web/static/src/js/views.js +++ b/addons/web/static/src/js/views.js @@ -1247,6 +1247,26 @@ session.web.xml_to_str = function(node) { return (new XMLSerializer()).serializeToString(node); } } +session.web.str_to_xml = function(s) { + if (window.DOMParser) { + var dp = new DOMParser(); + var r = dp.parseFromString(s, "text/xml"); + if (r.body && r.body.firstChild && r.body.firstChild.nodeName == 'parsererror') { + throw new Error("Could not parse string to xml"); + } + return r; + } + var xDoc; + try { + xDoc = new ActiveXObject("MSXML2.DOMDocument"); + } catch (e) { + throw new Error("Could not find a DOM Parser: " + e.message); + } + xDoc.async = false; + xDoc.preserveWhiteSpace = true; + xDoc.loadXML(s); + return xDoc; +} /** * Registry for all the client actions key: tag value: widget