diff --git a/addons/web/static/src/js/corelib.js b/addons/web/static/src/js/corelib.js index e9fd4e1fedf..73fa6839607 100644 --- a/addons/web/static/src/js/corelib.js +++ b/addons/web/static/src/js/corelib.js @@ -716,7 +716,11 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { if (this.className) { attrs['class'] = this.className; } $el = $(this.make(this.tagName, attrs)) } + var $oldel = this.$el; this.setElement($el); + if ($oldel && !$oldel.is(this.$el)) { + $oldel.replaceWith(this.$el); + } }, /** @@ -734,7 +738,6 @@ instance.web.Widget = instance.web.Class.extend(instance.web.WidgetMixin, { setElement: function (element) { if (this.$el) { this.undelegateEvents(); - this.$el.replaceWith(element); } this.$element = this.$el = (element instanceof $) ? element : $(element); diff --git a/addons/web/static/test/Widget.js b/addons/web/static/test/Widget.js index 36d6795ff7c..b50dd233a13 100644 --- a/addons/web/static/test/Widget.js +++ b/addons/web/static/test/Widget.js @@ -6,15 +6,21 @@ $(document).ready(function () { window.openerp.web.corelib(instance); instance.web.qweb = new QWeb2.Engine(); - instance.web.qweb.add_template('' + - '
    ' + - '
  1. ' + - '' + - '' + - '
  2. ' + - '
' + - '
'); + instance.web.qweb.add_template( + '' + + '' + + '
    ' + + '
  1. ' + + '' + + '' + + '
  2. ' + + '
' + + '
' + + '' + + '

' + + '
' + + '
'); } }; var instance; @@ -221,4 +227,22 @@ $(document).ready(function () { ok(!clicked, "undelegate should unbind events delegated"); ok(newclicked, "undelegate should only unbind events it created"); }); + + module('Widget.renderElement', mod); + test('repeated', function () { + var w = new (instance.web.Widget.extend({ + template: 'test.widget.template-value' + })); + w.value = 42; + w.appendTo($fix) + .always(start) + .done(function () { + equal($fix.find('p').text(), '42', "DOM fixture should contain initial value"); + equal(w.$el.text(), '42', "should set initial value"); + w.value = 36; + w.renderElement(); + equal($fix.find('p').text(), '36', "DOM fixture should use new value"); + equal(w.$el.text(), '36', "should set new value"); + }); + }); }); diff --git a/doc/widget.rst b/doc/widget.rst index 9868e4030e0..b29260c5882 100644 --- a/doc/widget.rst +++ b/doc/widget.rst @@ -95,7 +95,17 @@ The DOM root can also be defined programmatically by overridding Any override to :js:func:`~openerp.web.Widget.renderElement` which does not call its ``_super`` **must** call :js:func:`~openerp.web.Widget.setElement` with whatever it - generated or the widget's behavior is undefined. + generated or the widget's behavior is undefined.r + + .. note:: + + The default :js:func:`~openerp.web.Widget.renderElement` can + be called repeatedly, it will *replace* the previous DOM root + (using ``replaceWith``). However, this requires that the + widget correctly sets and unsets its events (and children + widgets). Generally, + :js:func:`~openerp.web.Widget.renderElement` should not be + called repeatedly unless the widget advertizes this feature. Accessing DOM content ~~~~~~~~~~~~~~~~~~~~~