Antony Lesuisse (OpenERP) has proposed merging 
lp:~openerp-dev/openerp-web/trunk-simplerendering-niv into lp:openerp-web.

Requested reviews:
  OpenERP R&D Web Team (openerp-dev-web)

For more details, see:
https://code.launchpad.net/~openerp-dev/openerp-web/trunk-simplerendering-niv/+merge/129415
-- 
https://code.launchpad.net/~openerp-dev/openerp-web/trunk-simplerendering-niv/+merge/129415
Your team OpenERP R&D Team is subscribed to branch 
lp:~openerp-dev/openerp-web/trunk-simplerendering-niv.
=== modified file 'addons/web/static/src/js/view_form.js'
--- addons/web/static/src/js/view_form.js	2012-10-12 11:47:11 +0000
+++ addons/web/static/src/js/view_form.js	2012-10-12 12:45:20 +0000
@@ -118,7 +118,6 @@
         this.__clicked_inside = false;
         this.__blur_timeout = null;
         this.rendering_engine = new instance.web.form.FormRenderingEngine(this);
-        this.qweb = null; // A QWeb instance will be created if the view is a QWeb template
         self.set({actual_mode: self.options.initial_mode});
         this.has_been_loaded.then(function() {
             self.on("change:actual_mode", self, self.check_actual_mode);
@@ -157,11 +156,9 @@
         this.rendering_engine.set_fields_registry(this.fields_registry);
         this.rendering_engine.set_tags_registry(this.tags_registry);
         this.rendering_engine.set_widgets_registry(this.widgets_registry);
-        if (!this.extract_qweb_template(data)) {
-            this.rendering_engine.set_fields_view(data);
-            var $dest = this.$el.hasClass("oe_form_container") ? this.$el : this.$el.find('.oe_form_container');
-            this.rendering_engine.render_to($dest);
-        }
+        this.rendering_engine.set_fields_view(data);
+        var $dest = this.$el.hasClass("oe_form_container") ? this.$el : this.$el.find('.oe_form_container');
+        this.rendering_engine.render_to($dest);
 
         this.$el.on('mousedown.formBlur', function () {
             self.__clicked_inside = true;
@@ -214,57 +211,6 @@
 
         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(instance.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 = instance.web.xml_to_json(instance.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 = instance.web.auto_str_to_date(value_);
-            } else {
-                r.raw_value = value_;
-            }
-            r.value = instance.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.$el.find('.oe_form_container').empty();
-    },
-
     widgetFocused: function() {
         // Clear click flag if used to focus a widget
         this.__clicked_inside = false;
@@ -368,13 +314,6 @@
         this._actualize_mode();
         this.set({ 'title' : record.id ? record.display_name : "New" });
 
-        if (this.qweb) {
-            this.kill_current_form();
-            this.rendering_engine.set_fields_view(this.get_fvg_from_qweb(record));
-            var $dest = this.$el.hasClass("oe_form_container") ? this.$el : this.$el.find('.oe_form_container');
-            this.rendering_engine.render_to($dest);
-        }
-
         _(this.fields).each(function (field, f) {
             field._dirty_flag = false;
             field._inhibit_on_change_flag = true;
@@ -395,6 +334,7 @@
                 });
             }
             self.on_form_changed();
+            self.rendering_engine.init_fields();
             self.is_initialized.resolve();
             self.do_update_pager(record.id == null);
             if (self.sidebar) {
@@ -1228,7 +1168,9 @@
 
         this.$form.appendTo(this.$target);
 
-        var ws = _.map(this.fields_to_init, function($elem) {
+        this.to_replace = [];
+
+        _.each(this.fields_to_init, function($elem) {
             var name = $elem.attr("name");
             if (!self.fvg.fields[name]) {
                 throw new Error("Field '" + name + "' specified in view could not be found.");
@@ -1244,24 +1186,28 @@
             }
             self.alter_field(w);
             self.view.register_field(w, $elem.attr("name"));
-            return [w, $elem];
-        });
-        _.each(ws, function(w) {
-            w[0].replace(w[1]);
+            self.to_replace.push([w, $elem]);
         });
         _.each(this.tags_to_init, function($elem) {
             var tag_name = $elem[0].tagName.toLowerCase();
             var obj = self.tags_registry.get_object(tag_name);
             var w = new (obj)(self.view, instance.web.xml_to_json($elem[0]));
-            w.replace($elem);
+            self.to_replace.push([w, $elem]);
         });
         _.each(this.widgets_to_init, function($elem) {
             var widget_type = $elem.attr("type");
             var obj = self.widgets_registry.get_object(widget_type);
             var w = new (obj)(self.view, instance.web.xml_to_json($elem[0]));
-            w.replace($elem);
-        });
-        // TODO: return a deferred
+            self.to_replace.push([w, $elem]);
+        });
+    },
+    init_fields: function() {
+        var defs = [];
+        _.each(this.to_replace, function(el) {
+            defs.push(el[0].replace(el[1]));
+        });
+        this.to_replace = [];
+        return $.when.apply($, defs);
     },
     render_element: function(template /* dictionaries */) {
         var dicts = [].slice.call(arguments).slice(1);
@@ -2010,12 +1956,9 @@
     /**
      * Called by the form view to indicate the value of the field.
      *
-     * set_value() may return an object that can be passed to $.when() that represents the moment when
-     * the field has finished all operations necessary before the user can effectively use the widget.
-     *
      * Multiple calls to set_value() can occur at any time and must be handled correctly by the implementation,
-     * regardless of any asynchronous operation currently running and the status of any promise that a
-     * previous call to set_value() could have returned.
+     * regardless of any asynchronous operation currently running. Calls to set_value() can and will also occur
+     * before the widget is inserted into the DOM.
      *
      * set_value() must be able, at any moment, to handle the syntax returned by the "read" method of the
      * osv class in the OpenERP server as well as the syntax used by the set_value() (see below). It must
@@ -2125,6 +2068,14 @@
         this.field_manager.on("change:display_invalid_fields", this, this._check_css_flags);
         this._check_css_flags();
     },
+    start: function() {
+        var tmp = this._super();
+        this.on("change:value", this, function() {
+            if (! this.no_rerender)
+                this.render_value();
+        });
+        this.render_value();
+    },
     /**
      * Private. Do not use.
      */
@@ -2137,6 +2088,20 @@
     get_value: function() {
         return this.get('value');
     },
+    /**
+        Utility method that all implementations should use to change the
+        value without triggering a re-rendering.
+    */
+    internal_set_value: function(value_) {
+        var tmp = this.no_render;
+        this.no_rerender = true;
+        this.set({'value': value_});
+        this.no_rerender = tmp;
+    },
+    /**
+        This method is called each time the value is modified.
+    */
+    render_value: function() {},
     is_valid: function() {
         return this.is_syntax_valid() && !(this.get('required') && this.is_false());
     },
@@ -2184,8 +2149,8 @@
      * Default implementation of start(), use it or call explicitly initialize_field().
      */
     start: function() {
-        this._super();
         this.initialize_field();
+        this._super();
     },
     initialize_field: function() {
         this.on("change:effective_readonly", this, this.reinitialize);
@@ -2220,10 +2185,6 @@
         instance.web.form.ReinitializeWidgetMixin.reinitialize.call(this);
         this.render_value();
     },
-    /**
-     * Called to render the value. Should also be explicitly called at the end of a set_value().
-     */
-    render_value: function() {},
 });
 
 instance.web.form.FieldChar = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, {
@@ -2237,14 +2198,10 @@
         var self = this;
         var $input = this.$el.find('input');
         $input.change(function() {
-            self.set({'value': self.parse_value($input.val())});
+            self.internal_set_value(self.parse_value($input.val()));
         });
         this.setupFocus($input);
     },
-    set_value: function(value_) {
-        this._super(value_);
-        this.render_value();
-    },
     render_value: function() {
         var show_value = this.format_value(this.get('value'), '');
         if (!this.get("effective_readonly")) {
@@ -2348,7 +2305,7 @@
     widget_class: 'oe_form_field_float',
     init: function (field_manager, node) {
         this._super(field_manager, node);
-        this.set({'value': 0});
+        this.internal_set_value(0);
         if (this.node.attrs.digits) {
             this.digits = this.node.attrs.digits;
         } else {
@@ -2477,17 +2434,18 @@
     initialize_content: function() {
         if (!this.get("effective_readonly")) {
             this.datewidget = this.build_widget();
+<<<<<<< TREE
             this.datewidget.on('datetime_changed', this, _.bind(function() {
                 this.set({'value': this.datewidget.get_value()});
+=======
+            this.datewidget.on_change.add_last(_.bind(function() {
+                this.internal_set_value(this.datewidget.get_value());
+>>>>>>> MERGE-SOURCE
             }, this));
             this.datewidget.appendTo(this.$el);
             this.setupFocus(this.datewidget.$input);
         }
     },
-    set_value: function(value_) {
-        this._super(value_);
-        this.render_value();
-    },
     render_value: function() {
         if (!this.get("effective_readonly")) {
             this.datewidget.set_value(this.get('value'));
@@ -2529,7 +2487,7 @@
         this.default_height = this.$textarea.css('height');
         if (!this.get("effective_readonly")) {
             this.$textarea.change(_.bind(function() {
-                self.set({'value': instance.web.parse_value(self.$textarea.val(), self)});
+                self.internal_set_value(instance.web.parse_value(self.$textarea.val(), self));
             }, this));
         } else {
             this.$textarea.attr('disabled', 'disabled');
@@ -2541,12 +2499,8 @@
         });
         this.setupFocus(this.$textarea);
     },
-    set_value: function(value_) {
-        this._super(value_);
-        this.render_value();
+    render_value: function() {
         $(window).resize();
-    },
-    render_value: function() {
         var show_value = instance.web.format_value(this.get('value'), this, '');
         if (show_value === '') {
             this.$textarea.css('height', parseInt(this.default_height)+"px");
@@ -2606,15 +2560,11 @@
             this.$cleditor.change(function() {
                 if (! self._updating_editor) {
                     self.$cleditor.updateTextArea();
-                    self.set({'value': self.$textarea.val()});
+                    self.internal_set_value(self.$textarea.val());
                 }
             });
         }
     },
-    set_value: function(value_) {
-        this._super.apply(this, arguments);
-        this.render_value();
-    },
     render_value: function() {
         if (! this.get("effective_readonly")) {
             this.$textarea.val(this.get('value') || '');
@@ -2631,21 +2581,20 @@
     template: 'FieldBoolean',
     start: function() {
         var self = this;
-        this._super.apply(this, arguments);
         this.$checkbox = $("input", this.$el);
         this.setupFocus(this.$checkbox);
         this.$el.click(_.bind(function() {
-            this.set({'value': this.$checkbox.is(':checked')});
+            this.internal_set_value(this.$checkbox.is(':checked'));
         }, this));
         var check_readonly = function() {
             self.$checkbox.prop('disabled', self.get("effective_readonly"));
         };
         this.on("change:effective_readonly", this, check_readonly);
         check_readonly.call(this);
-    },
-    set_value: function(value_) {
         this._super.apply(this, arguments);
-        this.$checkbox[0].checked = value_;
+    },
+    render_value: function() {
+        this.$checkbox[0].checked = this.get('value');
     },
     focus: function() {
         this.$checkbox.focus();
@@ -2661,9 +2610,8 @@
             disabled: this.get("effective_readonly")
         });
     },
-    set_value: function(value_) {
-        this._super.apply(this, arguments);
-        var show_value = Number(value_);
+    render_value: function() {
+        var show_value = Number(this.get('value'));
         if (isNaN(show_value)) {
             show_value = 0;
         }
@@ -2701,7 +2649,7 @@
         var ischanging = false;
         var $select = this.$el.find('select')
             .change(_.bind(function() {
-                this.set({'value': this.values[this.$el.find('select')[0].selectedIndex][0]});
+                this.internal_set_value(this.values[this.$el.find('select')[0].selectedIndex][0]);
             }, this))
             .change(function () { ischanging = true; })
             .click(function () { ischanging = false; })
@@ -2716,7 +2664,6 @@
         value_ = value_ === null ? false : value_;
         value_ = value_ instanceof Array ? value_[0] : value_;
         this._super(value_);
-        this.render_value();
     },
     render_value: function() {
         if (!this.get("effective_readonly")) {
@@ -2732,13 +2679,6 @@
             this.$el.text(option ? option[1] : this.values[0][1]);
         }
     },
-    is_syntax_valid: function() {
-        if (this.get("effective_readonly")) {
-            return true;
-        }
-        var value_ = this.values[this.$el.find('select')[0].selectedIndex];
-        return !! value_;
-    },
     focus: function() {
         this.$el.find('select:first').focus();
     }
@@ -2936,26 +2876,28 @@
         this.display_value = {};
         this.last_search = [];
         this.floating = false;
-        this.inhibit_on_change = false;
         this.current_display = null;
+        this.is_started = false;
     },
     start: function() {
-        this._super();
         instance.web.form.ReinitializeFieldMixin.start.call(this);
-        this.on("change:value", this, function() {
-            this.floating = false;
-            this.render_value();
-        });
+        this.is_started = true;
         instance.web.bus.on('click', this, function() {
             if (!this.get("effective_readonly") && this.$input && this.$input.autocomplete('widget').is(':visible')) {
                 this.$input.autocomplete("close");
             }
         });
+        this._super();
+    },
+    reinit_value: function(val) {
+        this.internal_set_value(val);
+        this.floating = false;
+        if (this.is_started)
+            this.render_value();
     },
     initialize_content: function() {
         if (!this.get("effective_readonly"))
             this.render_editable();
-        this.render_value();
     },
     init_error_displayer: function() {
         // nothing
@@ -3006,7 +2948,7 @@
             if (self.current_display !== self.$input.val()) {
                 self.current_display = self.$input.val();
                 if (self.$input.val() === "") {
-                    self.set({value: false});
+                    self.internal_set_value(false);
                     self.floating = false;
                 } else {
                     self.floating = true;
@@ -3038,15 +2980,14 @@
                     if (self.last_search[0][0] != self.get("value")) {
                         self.display_value = {};
                         self.display_value["" + self.last_search[0][0]] = self.last_search[0][1];
-                        self.set({value: self.last_search[0][0]});
+                        self.reinit_value(self.last_search[0][0]);
                     } else {
                         used = true;
                         self.render_value();
                     }
                 } else {
                     used = true;
-                    self.set({value: false});
-                    self.render_value();
+                    self.reinit_value(false);
                 }
                 self.floating = false;
             }
@@ -3101,7 +3042,7 @@
                 if (item.id) {
                     self.display_value = {};
                     self.display_value["" + item.id] = item.name;
-                    self.set({value: item.id});
+                    self.reinit_value(item.id);
                 } else if (item.action) {
                     item.action();
                     // Cancel widget blurring, to avoid form blur event
@@ -3192,16 +3133,14 @@
             value_ = value_[0];
         }
         value_ = value_ || false;
-        this.inhibit_on_change = true;
-        this._super(value_);
-        this.inhibit_on_change = false;
+        this.reinit_value(value_);
     },
     get_displayed: function() {
         return this.display_value["" + this.get("value")];
     },
     add_id: function(id) {
         this.display_value = {};
-        this.set({value: id});
+        this.reinit_value(id);
     },
     is_false: function() {
         return ! this.get("value");
@@ -3274,27 +3213,26 @@
         lazy_build_o2m_kanban_view();
         this.is_loaded = $.Deferred();
         this.initial_is_loaded = this.is_loaded;
-        this.is_setted = $.Deferred();
         this.form_last_update = $.Deferred();
         this.init_form_last_update = this.form_last_update;
-    },
-    start: function() {
-        this._super.apply(this, arguments);
-        this.$el.addClass('oe_form_field oe_form_field_one2many');
-
-        var self = this;
-
+        this.is_started = false;
         this.dataset = new instance.web.form.One2ManyDataSet(this, this.field.relation);
         this.dataset.o2m = this;
         this.dataset.parent_view = this.view;
         this.dataset.child_name = this.name;
+        var self = this;
         this.dataset.on_change.add_last(function() {
             self.trigger_on_change();
         });
-
-        this.is_setted.then(function() {
-            self.load_views();
-        });
+        this.set_value([]);
+    },
+    start: function() {
+        this._super.apply(this, arguments);
+        this.$el.addClass('oe_form_field oe_form_field_one2many');
+
+        var self = this;
+
+        self.load_views();
         this.is_loaded.then(function() {
             self.on("change:effective_readonly", self, function() {
                 self.is_loaded = self.is_loaded.pipe(function() {
@@ -3305,6 +3243,8 @@
                 });
             });
         });
+        this.is_started = true;
+        this.reload_current_view();
     },
     trigger_on_change: function() {
         var tmp = this.doing_on_change;
@@ -3406,10 +3346,8 @@
                 }
             });
         });
-        this.is_setted.then(function() {
-            $.async_when().then(function () {
-                self.viewmanager.appendTo(self.$el);
-            });
+        $.async_when().then(function () {
+            self.viewmanager.appendTo(self.$el);
         });
         return def;
     },
@@ -3489,9 +3427,12 @@
         if (this.dataset.index === null && this.dataset.ids.length > 0) {
             this.dataset.index = 0;
         }
-        self.is_setted.resolve();
         this.trigger_on_change();
-        return self.reload_current_view();
+        if (this.is_started) {
+            return self.reload_current_view();
+        } else {
+            return $.when();
+        }
     },
     get_value: function() {
         var self = this;
@@ -3890,9 +3831,8 @@
         this._drop_shown = false;
     },
     start: function() {
+        instance.web.form.ReinitializeFieldMixin.start.call(this);
         this._super();
-        instance.web.form.ReinitializeFieldMixin.start.call(this);
-        this.on("change:value", this, this.render_value);
     },
     initialize_content: function() {
         if (this.get("effective_readonly"))
@@ -4015,36 +3955,33 @@
     disable_utility_classes: true,
     init: function(field_manager, node) {
         this._super(field_manager, node);
-        this.set({"value": []});
         this.is_loaded = $.Deferred();
         this.initial_is_loaded = this.is_loaded;
-        this.is_setted = $.Deferred();
+        this.dataset = new instance.web.form.Many2ManyDataSet(this, this.field.relation);
+        this.dataset.m2m = this;
+        var self = this;
+        this.dataset.on('unlink', self, function(ids) {
+            self.dataset_changed();
+        });
+        this.set_value([]);
     },
     start: function() {
-        this._super.apply(this, arguments);
         this.$el.addClass('oe_form_field oe_form_field_many2many');
 
         var self = this;
 
-        this.dataset = new instance.web.form.Many2ManyDataSet(this, this.field.relation);
-        this.dataset.m2m = this;
-        this.dataset.on('unlink', self, function(ids) {
-            self.dataset_changed();
-        });
-
-        this.is_setted.then(function() {
-            self.load_view();
-        });
+        self.load_view();
         this.is_loaded.then(function() {
             self.on("change:effective_readonly", self, function() {
                 self.is_loaded = self.is_loaded.pipe(function() {
                     self.list_view.destroy();
                     return $.when(self.load_view()).then(function() {
-                        self.reload_content();
+                        self.render_value();
                     });
                 });
             });
         });
+        this._super.apply(this, arguments);
     },
     set_value: function(value_) {
         value_ = value_ || [];
@@ -4052,17 +3989,12 @@
             value_ = value_[0][2];
         }
         this._super(value_);
-        this.dataset.set_ids(value_);
-        var self = this;
-        self.reload_content();
-        this.is_setted.resolve();
     },
     get_value: function() {
         return [commands.replace_with(this.get('value'))];
     },
-
     is_false: function () {
-        return _(this.dataset.ids).isEmpty();
+        return _(this.get("value")).isEmpty();
     },
     load_view: function() {
         var self = this;
@@ -4089,14 +4021,15 @@
         });
         return loaded;
     },
-    reload_content: function() {
+    render_value: function() {
         var self = this;
+        this.dataset.set_ids(this.get("value"));
         this.is_loaded = this.is_loaded.pipe(function() {
             return self.list_view.reload_content();
         });
     },
     dataset_changed: function() {
-        this.set({'value': this.dataset.ids});
+        this.internal_set_value(this.dataset.ids);
     },
 });
 
@@ -4152,28 +4085,26 @@
         m2m_kanban_lazy_init();
         this.is_loaded = $.Deferred();
         this.initial_is_loaded = this.is_loaded;
-        this.is_setted = $.Deferred();
-    },
-    start: function() {
-        this._super.apply(this, arguments);
 
         var self = this;
-
         this.dataset = new instance.web.form.Many2ManyDataSet(this, this.field.relation);
         this.dataset.m2m = this;
         this.dataset.on('unlink', self, function(ids) {
             self.dataset_changed();
         });
-
-        this.is_setted.then(function() {
-            self.load_view();
-        });
+    },
+    start: function() {
+        this._super.apply(this, arguments);
+
+        var self = this;
+
+        self.load_view();
         this.is_loaded.then(function() {
             self.on("change:effective_readonly", self, function() {
                 self.is_loaded = self.is_loaded.pipe(function() {
                     self.kanban_view.destroy();
                     return $.when(self.load_view()).then(function() {
-                        self.reload_content();
+                        self.render_value();
                     });
                 });
             });
@@ -4185,10 +4116,6 @@
             value_ = value_[0][2];
         }
         this._super(value_);
-        this.dataset.set_ids(value_);
-        var self = this;
-        self.reload_content();
-        this.is_setted.resolve();
     },
     load_view: function() {
         var self = this;
@@ -4215,8 +4142,9 @@
         });
         return loaded;
     },
-    reload_content: function() {
+    render_value: function() {
         var self = this;
+        this.dataset.set_ids(this.get("value"));
         this.is_loaded = this.is_loaded.pipe(function() {
             return self.kanban_view.do_search(self.build_domain(), self.dataset.get_context(), []);
         });
@@ -4243,7 +4171,7 @@
                     if(! _.detect(self.dataset.ids, function(x) {return x == one_id;})) {
                         self.dataset.set_ids([].concat(self.dataset.ids, [one_id]));
                         self.dataset_changed();
-                        self.reload_content();
+                        self.render_value();
                     }
                 });
             });
@@ -4254,7 +4182,7 @@
                 title: _t("Open: ") + self.string,
                 write_function: function(id, data, options) {
                     return self.dataset.write(id, data, {}).then(function() {
-                        self.reload_content();
+                        self.render_value();
                     });
                 },
                 alternative_form_view: self.field.views ? self.field.views["form"] : undefined,
@@ -4684,10 +4612,6 @@
     is_false: function() {
         return typeof(this.get_value()) !== 'string';
     },
-    set_value: function(value_) {
-        this._super(value_);
-        this.render_value();
-    },
     render_value: function() {
         this.reference_ready = false;
         var vals = [], sel_val, m2o_val;
@@ -4707,9 +4631,9 @@
         var model = this.selection.get_value(),
             id = this.m2o.get_value();
         if (typeof(model) === 'string' && typeof(id) === 'number') {
-            this.set({'value': model + ',' + id});
+            this.internal_set_value(model + ',' + id);
         } else {
-            this.set({'value': false});
+            this.internal_set_value(false);
         }
     },
 });
@@ -4808,7 +4732,7 @@
     on_clear: function() {
         if (this.get('value') !== false) {
             this.binary_value = false;
-            this.set({'value': false});
+            this.internal_set_value(false);
         }
         return false;
     }
@@ -4828,10 +4752,6 @@
             });
         }
     },
-    set_value: function(value_) {
-        this._super.apply(this, arguments);
-        this.render_value();
-    },
     render_value: function() {
         if (!this.get("effective_readonly")) {
             var show_value;
@@ -4853,7 +4773,7 @@
     },
     on_file_uploaded_and_valid: function(size, name, content_type, file_base64) {
         this.binary_value = true;
-        this.set({'value': file_base64});
+        this.internal_set_value(file_base64);
         var show_value = name + " (" + this.human_filesize(size) + ")";
         this.$el.find('input').eq(0).val(show_value);
         this.set_filename(name);
@@ -4867,10 +4787,6 @@
 
 instance.web.form.FieldBinaryImage = instance.web.form.FieldBinary.extend({
     template: 'FieldBinaryImage',
-    set_value: function(value_) {
-        this._super.apply(this, arguments);
-        this.render_value();
-    },
     render_value: function() {
         var self = this;
         var url;
@@ -4903,7 +4819,7 @@
         this._super.apply(this, arguments);
     },
     on_file_uploaded_and_valid: function(size, name, content_type, file_base64) {
-        this.set({'value': file_base64});
+        this.internal_set_value(file_base64);
         this.binary_value = true;
         this.render_value();
         this.set_filename(name);
@@ -4921,38 +4837,34 @@
         this._super(field_manager, node);
         this.options.clickable = this.options.clickable || (this.node.attrs || {}).clickable || false;
         this.options.visible = this.options.visible || (this.node.attrs || {}).statusbar_visible || false;
-        this.selected_value = null;
+        this.set({value: false});
     },
     start: function() {
-        this._super();
-        // backward compatibility
-        this.loaded = new $.Deferred();
         if (this.options.clickable) {
             this.$el.on('click','li',this.on_click_stage);
         }
-        // TODO move the following into css :after
         if (this.$el.parent().is('header')) {
             this.$el.after('<div class="oe_clear"/>');
         }
+        this._super();
     },
     set_value: function(value_) {
+        if (value_ instanceof Array) {
+            value_ = value_[0];
+        }
+        this._super(value_);
+    },
+    render_value: function() {
         var self = this;
-        this._super(value_);
-        // find selected value:
-        // - many2one: [2, "New"] -> 2
-        // - selection: new -> new
-        if (this.field.type == "many2one") {
-            this.selected_value = value_[0];
-        } else {
-            this.selected_value = value_;
-        }
-        // trick to be sure all values are loaded in the form, therefore
-        // enabling the evaluation of dynamic domains
-        self.selection = [];
-        $.async_when().then(function() {
-            self.get_selection();
+        self.get_selection().then(function() {
+            var content = QWeb.render("FieldStatus.content", {widget: self});
+            self.$el.html(content);
+            var colors = JSON.parse((self.node.attrs || {}).statusbar_colors || "{}");
+            var color = colors[self.get('value')];
+            if (color) {
+                self.$("oe_active").css("color", color);
+            }
         });
-        return this.loaded;
     },
     /** Get the selection and render it
      *  selection: [[identifier, value_to_display], ...]
@@ -4961,53 +4873,37 @@
      */
     get_selection: function() {
         var self = this;
+        self.selection = [];
         if (this.field.type == "many2one") {
             var domain = [];
             if(!_.isEmpty(this.field.domain) || !_.isEmpty(this.node.attrs.domain)) {
-                domain = new instance.web.CompoundDomain(['|'], self.build_domain(), [['id', '=', self.selected_value]]);
+                domain = new instance.web.CompoundDomain(['|'], self.build_domain(), [['id', '=', self.get('value')]]);
             }
             var ds = new instance.web.DataSetSearch(this, this.field.relation, self.build_context(), domain);
-            ds.read_slice(['name'], {}).done( function (records) {
+            return ds.read_slice(['name'], {}).pipe(function (records) {
                 for(var i = 0; i < records.length; i++) {
                     self.selection.push([records[i].id, records[i].name]);
                 }
-                self.render_elements();
-                self.loaded.resolve();
             });
         } else {
-            this.loaded.resolve();
             // For field type selection filter values according to
             // statusbar_visible attribute of the field. For example:
             // statusbar_visible="draft,open".
             var selection = this.field.selection;
-            for(var i=0; i< selection.length; i++) {
+            for(var i=0; i < selection.length; i++) {
                 var key = selection[i][0];
-                if(key == this.selected_value || !this.options.visible || this.options.visible.indexOf(key) != -1) {
+                if(key == this.get('value') || !this.options.visible || this.options.visible.indexOf(key) != -1) {
                     this.selection.push(selection[i]);
                 }
             }
-            this.render_elements();
-        }
-    },
-    /** Renders the widget. This function also checks for statusbar_colors='{"pending": "blue"}'
-     *  attribute in the widget. This allows to set a given color to a given
-     *  state (given by the key of (key, label)).
-     */
-    render_elements: function () {
-        var self = this;
-        var content = instance.web.qweb.render("FieldStatus.content", {widget: this});
-        this.$el.html(content);
-        var colors = JSON.parse((this.node.attrs || {}).statusbar_colors || "{}");
-        var color = colors[this.selected_value];
-        if (color) {
-            this.$("oe_active").css("color", color);
+            return $.when();
         }
     },
     on_click_stage: function (ev) {
         var self = this;
         var $li = $(ev.currentTarget);
         var val = parseInt($li.data("id"));
-        if (val != self.selected_value) {
+        if (val != self.get('value')) {
             this.view.recursive_save().then(function() {
                 var change = {};
                 change[self.name] = val;

_______________________________________________
Mailing list: https://launchpad.net/~openerp-dev-gtk
Post to     : [email protected]
Unsubscribe : https://launchpad.net/~openerp-dev-gtk
More help   : https://help.launchpad.net/ListHelp

Reply via email to