0

I need to add events in some buttons in qweb template or maybe make a widget for this template. But I can't load js in this template, even if I add js file in web.assets_backend or web.assets_frontend.

controller.py

from odoo import http
class LogData(http.Controller):
    @http.route("/log_data", type="http", auth="user")
    def log_data_view(self, **kwargs):
        return http.request.render(
            "table_relation.log_data_template"
        )

log_data_template.xml

<odoo>

  <template id="log_data_template" name="Log Data">
    <t t-call="web.layout">
      <t t-set="head">
        <t t-call-asssets="web.assets_common" t-js="false"/>
        <t t-call-asssets="web.assets_frontend" t-js="false"/>
      </t>

      <div id="wrap" class="container">
        <h1>Log Data</h1>
        <div class="o_log_data">
          <button id="start-log">日志</button>
          <button id="cancel-log">停止</button>
          <div id="log-content" style="height:500px;overflow: scroll;"/>
        </div>
        <button type="button" class="demo-btn">demo button</button>
      </div>
    </t>
  </template>


</odoo>


log_data.js

odoo.define('log_data', function (require){
'use strict';
var publicWidget = require('web.public.widget');

console.log('==========')

publicWidget.registry.LogData = publicWidget.Widget.extend({
    selector: '.o_log_data',
    events: {
        'click #start-log': '_startLog',
        'click #cancel-log': '_cancelLog',
    },

    init: function () {
        console.log('o_log_data')
    },
    start: function () {
        console.log('o_log_data')
    },
    _startLog: function () {
        console.log('_startLog')
    },
});

publicWidget.registry.DemoBtn = publicWidget.Widget.extend({
    selector: '.demo-btn',
    events: {
        click: '_onClick'
    },
    _onClick: function (e) {
        console.log('_onClick')
    },
});
})

manifest.py

'assets': {
        'web.assets_backend': [
         ...
         'table_relation/static/src/js/log_data.js',
        ]
        'web.assets_frontend': [
         ...
         'table_relation/static/src/js/log_data.js',
        ]
         ...
}

enter image description here

It seems not to load assets_backend bundle on this page, and log_data.js is not working.

holydragon
  • 6,158
  • 6
  • 39
  • 62
Kyle
  • 5
  • 5

2 Answers2

0

As per the code you have mentioned above, it seems like you are trying to create a controller i.e a route that can be accessed by the User only but from the website side like the portal or eCommerce part.

So if that is the case, then you need to add your js files to web.assets_frontend instead of web.assets_backend in manifest.py file.

  • I have tried to add js to web.assets_frontend but still not working. – Kyle Jul 25 '22 at 06:14
  • Can you add your code/screenshot of the JS that you've created? – Krutarth Patel Jul 25 '22 at 06:30
  • I have tried to replicate your code. It seems that your JS is loading. There is no issue in loading. `web.assets_frontend` loads your JS, but to use that JS in your view, you need to include the Odoo Layout i.e web.layout before your webpage design. Like `` or something like that. The issue is, when we include the JS/CSS/SCSS files in assets, layout templates are the once that execute these includes files. – Krutarth Patel Jul 25 '22 at 08:20
  • As your template is simply a container that does not inherit from Odoo layouts (web or portal), Odoo simply does not know that it needs to load the assets on that route. Hope you understand what I am trying to explain. – Krutarth Patel Jul 25 '22 at 08:26
  • I added t-call="web.layout" and t-call-assets="web.assets_frontend" in template, but still not working. I edited the code in my question. – Kyle Jul 26 '22 at 08:36
  • try using `t-call="website.layout"` – Krutarth Patel Jul 27 '22 at 04:33
0

The answer is late but in case you still need this you can try the following code. It works in Odoo14 and should definitely work in Odoo15 as well since class Widget still have this statement:

 // Now this class can simply be used with the following syntax::
 // var myWidget = new MyWidget(this);
 // myWidget.appendTo($(".some-div"));

You can find the reference here: https://github.com/odoo/odoo/blob/f1f3fcef6cc471fc01da574da26712e643315da6/addons/web/static/src/legacy/js/core/widget.js#L49-L52

And your code refactored by following those instructions.

odoo.define('log_data', function (require){
'use strict';
var publicWidget = require('web.public.widget');

console.log('==========')

publicWidget.registry.LogData = publicWidget.Widget.extend({
    selector: '.o_log_data',
    events: {
        'click #start-log': '_startLog',
        'click #cancel-log': '_cancelLog',
    },

    init: function () {
        console.log('o_log_data')
    },
    start: function () {
        console.log('o_log_data')
    },
    _startLog: function () {
        console.log('_startLog')
    },
});

var LogData = new publicWidget.registry.LogData(this);
LogData.appendTo($(".o_log_data"));

publicWidget.registry.DemoBtn = publicWidget.Widget.extend({
    selector: '.demo-btn',
    events: {
        click: '_onClick'
    },
    _onClick: function (e) {
        console.log('_onClick')
    },
});

var DemoBtn = new publicWidget.registry.DemoBtn(this);
DemoBtn.appendTo($(".demo-btn"));

});

I think that publicWidget are only rendered, as Krutarth Patel said, in the scope of some layout like 'website.layout'. I cannot provide much info about this because I still have to figure out the layouts, for example 'portal.layout' scope was not rendering the publicWidget extension for me.

But the Widget class is designed in a way that allows to 'force' render of the widget by inserting it into the dom, render, bound to specific selector and events.

So you can (probably?) automatically render by wrapping your template with the proper t-call, otherwise you can use the 'appendTo' syntax and append the widget to the DOM, make an istance out of it and use that istance. I've been struggling with this for a couple of days before I could make it work, and I found a couple of post like this. I hope this will help you, or other users to figure out some of the use you can make of odoo widgets.

Fra B
  • 13
  • 4