extending javascript and qweb template in Odoo 15? - odoo-15

I am trying to tweak the odoo wysiwyg web_editor in Odoo 15, just adding a few font sizes as an example. But it does not seem to work.
What i have tried: I created a module to isolate the problem:
https://github.com/jwaes/jt_webeditor_extras
Manifest:
'assets' : {
'web.assets_qweb': [
'jt_webeditor_extras/static/src/xml/editor.xml',
],
'website.assets_wysiwyg': [
'jt_webeditor_extras/static/src/js/editor.js',
],
xml:
<!-- fiddling with https://github.com/odoo/odoo/blob/15.0/addons/web_editor/static/src/xml/editor.xml -->
<t t-extend="web_editor.toolbar">
<t t-jquery="#font-size ul li:nth-child(7)" t-operation="after">
<li>
<a class="dropdown-item" href="#" data-call="setFontSize" data-arg1="16px">16</a>
</li>
</t>
<t t-jquery="#font-size ul" t-operation="append">
<li>
<a class="dropdown-item" href="#" data-call="setFontSize" data-arg1="99px">99</a>
</li>
</t>
<!-- perhaps my jquery was wrong... so trying with a drastic one -->
<t t-jquery="#font" t-operation="replace" />
</t>
js:
odoo.define('jt_webeditor_extras.toolbar_extras', function (require) {
'use strict';
const weToolbar = require('web_editor.toolbar');
weToolbar.include({
xmlDependencies: (weToolbar.prototype.xmlDependencies || []).concat(
['/jt_webeditor_extras/static/src/xml/editor.xml']),
});
console.log(weToolbar.prototype.xmlDependencies);
});
The javascript console message was logged. so it was loaded.
There is a http call to the template xml from the frontend.
But the resulting UI is not altered.
Any idea what i am doing wrong ?

Remove the odoo tag and add web_editor to module depends entry.

Related

How to render data from the external model in divs of a view?

I need your help, I have some divs in a view in odoo 13, I need to bring the data from an external model "maintenance.stage" render them in those divs, can someone give me an example of how to do it with a controller to bring those logs and be able to display them in those divs? every time i add a new record it should render in those divs.
enter image description here
enter image description here
I hope this helps,
This is a controller exemple:
class ControllerExemple(http.Controller):
#http.route('/path/', auth='public', type='http',
methods=["GET","POST"], website=True)
def function_exemple(self):
obj = request.env['maintenance.stage'].browse(<id>)
return request.render("module.your_view_id", {'object': obj})
There is a exemple view :
<template id="your_view_id" name="Something">
<t t-call="website.layout">
<div class="container">
<div><span t-out="object.the_field_you_need"/></div>
</div>
</t>
</template>
It seems that you have several values to display, so use the foreach in your template :
<template id="your_view_id" name="Something">
<t t-call="website.layout">
<t t-foreach="object.the_field_you_need" t-as="value">
<div class="container">
<div><span t-out="value"/></div>
</div>
</t>
</t>
</template>
https://odoo-master.readthedocs.io/en/master/reference/qweb.html

MissingError Template: web.external_layout

I am trying to create a report in Odoo 12. But I come across an issue.
<template id="applicant_contract_offering_document">
<t t-call="web.external_layout">
<div class="header tahoma underline_bold center font_size_11">
<p>OFFICIAL OFFERING LETTER</p>
</div>
</t>
</template>
<template id="applicant_contract_offering">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="fhid_recruitment.applicant_contract_offering_document" />
</t>
</t>
</template>
Odoo always gives me
Error to render compiling AST
MissingError: ('Record does not exist or has been deleted.\n\n(Records: [4], User:2)', None)
Template: web.external_layout
What am I missing? I can print without web.external_layout but it seems the CSS is not applied to the body of the report.
At the file manifest.py add web in the list of dependencies.
This error message is very misleading. I urge every developer who encounter this kind of error message to try to check their codes again.
In my case, it was caused by empty record id.

Materialize: Cannot set property 'tabIndex' of null at Dropdown._makeDropdownFocusable

I am trying to test my vuejs component via jest that contains materialize select.
When performing a component test, I get the following error in materialize.js:
TypeError: Cannot set property 'tabIndex' of null at Dropdown._makeDropdownFocusable
How fix this error?
This problem can happen when the input field is not wrapped inside a div with the class input-field:
<div class="input-field">
<input type="text" class="autocomplete"></input>
</div>
Adding a div with the class "input-field might solve this problem.
use id selector instead class selector. for example call dropdown like this :
html :
<a class='dropdown-trigger' id="dropdowner" href='#' data-target='dropdown1'>Drop Me!</a>
<!-- Dropdown Structure -->
<ul id='dropdown1' class='dropdown-content'>
<li>one</li>
<li>two</li>
<li class="divider" tabindex="-1"></li>
<li>three</li>
<li><i class="material-icons">view_module</i>four</li>
<li><i class="material-icons">cloud</i>five</li>
</ul>
js:
$('#dropdowner').dropdown();
Can only be used once.
data-target="name_target" must not be repeated
Exam1.❌
<nav>
<div class="nav-wrapper">
<ul class="right hide-on-med-and-down">
<li><a class="dropdown-trigger" href="#!" data-target="name_target1">Dropdown<i class="material-icons right">arrow_drop_down</i></a></li>
<li><a class="dropdown-trigger" href="#!" data-target="name_target1">Dropdown<i class="material-icons right">arrow_drop_down</i></a></li>
</ul>
</div>
</nav>
<!-- Dropdown Structure -->
<ul id="name_target1" class="dropdown-content">
<li>one</li>
<li>two</li>
</ul>
Exam2.✔️
<nav> <div class="nav-wrapper">
Logo
<ul class="right hide-on-med-and-down">
<li><a class="dropdown-trigger" href="#!" data-target="name_target2">Dropdown<i enter code here class="material-icons right">arrow_drop_down</i></a></li>
</ul> </div> </nav> <ul id="name_target2" class="dropdown-content"> <li>one</li> <li>two</li> </ul>
When I ran into this issue I was trying to create the whole dropdown list dynamically in JS. The fix for me was creating the list and any default list elements in HTML:
<div id="select1" class=\"input-field col s12\">
<select>
<option value="" selected>Default</option>
</select>
<label>Test</label>
</div>
Then appending any dynamic values in JS:
contents.forEach(function(content) {
var buffer = "<option></option>";
var template = $(buffer);
$(template).text(content);
$("select1").find("select").append(template);
});
$("select").formSelect();
pre 1.0.0 you would use data-activates, if data-target is not specified you will get this error
My problem was, that jQuery object was not attached to the DOM yet, so inner materialise code could not init element due to inability to find element by ID:
// materializecss initing dropdown (in my case for input autocomplete), where `t` is the input element
i.id = M.getIdFromTrigger(t),
i.dropdownEl = document.getElementById(i.id),
i.$dropdownEl = h(i.dropdownEl),
M.getIdFromTrigger(t) returned some random ID (not the one I provided) and dropdownEl was inited with null, and later method _makeDropdownFocusable failed on using it `this.dropdownEl.tabIndex = 0
So my problem code looked like this:
let root = $('#root'); // root in the DOM already
let wrapper = $('<div>'); // wrapper is just created and NOT attached to the DOM yet
let input = $('<input>').appendTo(wrapper); // creating input and attaching to the wrapper, but still not in DOM
initAutocomplete(input) // M.Autocomplete.init logic here FAILS
root.append(wrapper) // too late, error above
So the quick fix is to append elements first and only than do M.Autocomplete.init
I just stumbled this issue too while using Materializecss for my Vue project. As mentioned by sajjad, using id selector instead of class works. However, this is problem for initializing multiple dropdown, since each dropdown must have unique ID.
The way I solve this is just by selecting all the elements with the '.dropdown-trigger' class, and initialize every each of those. It works for me.
$.each($('.dropdown-trigger'), function(index, value) {
$(value).dropdown();
});

OpenERP - QWeb report

I'm writing a module on Odoo (OpenERP) v.8 to allow timesheet's print.
I'm using QWeb report type, but I can't use the fields that I need to use.
If I call a field from res_company module, it works correctly.
<template id="report_timesheet_document">
<t t-call="report.external_layout">
<div class="page">
<div class="row">
<div>
<span t-esc="res_company.name"/>
</div>
</div>
If I call a field from other modules, like res_partner, it doesn't work.
I can't use fields from the current object (timesheet, inherited from hr_timesheet_sheet.sheet).
If I use t-esc:
<span t-esc="o.date_from"/>
QWebException: "'NoneType' object has no attribute 'date_from'" while
evaluating 'o.date_from'
If I use t-field
<span t-field="o.date_from"/>
QWebException: 'NoneType' object has no attribute '_all_columns'
How can I resolve? Thanks.
Fixed:
<template id="report_timesheet">
<t t-call="report.html_container">
<t t-foreach="doc_ids" t-as="doc_id">
<t t-raw="translate_doc(doc_id, doc_model, 'user_id.partner_id.lang', 'hr_timesheet_print.report_timesheet_document')"/>
</t>
</t>
</template>

Dojo loading templated widget into data-dojo-type

I've created a very simple HTML templated widget.
<div class="tool">
<a href="" id="freehand">
<i class="flaticon-writing9"></i>
</a>
</div>
<div class="tool">
<a href="" id="polygon">
<i class="flaticon-constellation"></i>
</a>
</div>
My widget declaration looks like this:
define([
"dojo/_base/declare",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dojo/text!./templates/DrawingToolsWidget.html",
"dojo/parser",
"dojo/ready"
],
function(declare, _WidgetBase, _TemplatedMixin, template, parser, ready) {
return declare("DrawingToolsWidget",[_WidgetBase, _TemplatedMixin], {
templateString: template,
constructor: function() {
console.log(this);
}
});
ready(function(){
parser.parse();
});
}
);
I try to attach it to a point in my main DOM with a data-dojo-type attribute:
<div id="drawing-tools-container" data-dojo-type="DrawingToolsWidget"></div>
But I keep getting a generic dojo/parser::parse() error Error {} which is completely useless for debugging.
My directory structure is: /index.html(main DOM) /app/DrawingToolWidget/templates/DrawingToolsWidget.html(template) /app/DrawingToolWidget/DrawingToolWidget.js(declaration)
I've also tried to attach "app/DrawingToolWidget/DrawingToolWidget" just in case it wanted the path to the widget declaration. Nope.
What am I doing wrong? Why is it so hard just to attach a fragment of markup to the DOM?
Your template is invalid because you can only have 1 root element. I'm not sure if that's the main problem, but this might solve certain things. A quote from the documentation:
Note that when you define a template, it can only have one root
node definition ( just like with XML documents). Multiple nodes at the
top level is not allowed.
The article: http://dojotoolkit.org/documentation/tutorials/1.9/templated/
A working template would be:
<div>
<div class="tool">
<a href="" id="freehand">
<i class="flaticon-writing9"></i>
</a>
</div>
<div class="tool">
<a href="" id="polygon">
<i class="flaticon-constellation"></i>
</a>
</div>
</div>
The working example can be found here.
About your debugging problem, do you use Google Chrome? When encountering an error, you should try to close and open the developer tools/console, if you do that, there should be a small arrow next to the Error, for example:
As you can see here, there are 2 arrows, the left one gives you the stacktrace, while the right one (almost at the end of the error line), will give you detailed information about the error (if you click/expand it).