7

I am trying to modify the web_tree_image widget. Instead of just showing a small image in the column, I would like a larger image to appear when hovering or clicking. In order to achieve this, I am trying to add a callback after the widget is rendered, by overriding the start function, as explained in the documentation.

I therefore added the following code to web_tree_image.js:

openerp.web_tree_image = function (instance) {
    instance.web.list.Image = instance.web.list.Column.extend({
        // [...]
        start: function() {
            console.log("start called");
            // [... add callbacks ...]
        },
        // [...]
    });
};

However, the start function is never called, so this does not work.

I haven't fully understood the code path that usually leads to start being called, but it seems that it is somehow different for web.list.Column.

Should start be called and I am doing something wrong? Or is there another way of executing code after the DOM elements have been created?

ValarDohaeris
  • 6,064
  • 5
  • 31
  • 43
  • Try with `include` instead of `extend` – ChesuCR Nov 06 '15 at 18:53
  • It doesn't work with `include` either; also, the [documentation](https://www.odoo.com/documentation/8.0/reference/javascript.html#subclassing-widget) clearly states that it should work with `extend`. – ValarDohaeris Nov 10 '15 at 13:14
  • I am not familiar with Odoo but according to documentation you have to *Create the instance* with `var my_widget = new MyWidget(this);` and *Render and insert into DOM* with `my_widget.appendTo(".some-div");` – Anonymous0day Nov 13 '15 at 10:55

2 Answers2

-1

While I still don't know why the start function is not called, this is a workaround:

openerp.web_tree_image = function (instance) {
    instance.web.list.Image = instance.web.list.Column.extend({
        // ...
        format: function (row_data, options) {
            // ...
            window.setTimeout(function() {
                console.log("DOM ready");
                // ... add callbacks ...
            }, 0);
            // ...
        },
        // ...
    });
};

By adding to the event queue with timeout 0, execution can be deferred until the relevant DOM elements have been created as explained here.

Community
  • 1
  • 1
ValarDohaeris
  • 6,064
  • 5
  • 31
  • 43
-1

According documentation :

The new class can then be used in the following manner:

// Create the instance
var my_widget = new MyWidget(this);
// Render and insert into DOM
my_widget.appendTo(".some-div");

After these two lines have executed (and any promise returned by appendTo() has been resolved if needed), the widget is ready to be used.


Note

the insertion methods will start the widget themselves, and will return the result of start().

If for some reason you do not want to call these methods, you will have to >first call render() on the widget, then insert it into your DOM and start it.

Anonymous0day
  • 3,012
  • 1
  • 14
  • 16
  • In the case described in my question, the widget is instantiated as part of a tree view that is defined in xml (and will indeed call the `appendTo` function under the hood). Note that I do not have a problem instantiating and seeing the widget, the problem is really just that `start` is not called. – ValarDohaeris Nov 16 '15 at 08:05