I work with odoo 9. In the system exists render_value method for each type of field:
/odoo/addons/web/static/src/js/views/form_widgets.js
/odoo/addons/web/static/src/js/views/form_relational_widgets.js
How I can use my custom method render_value(for example in FieldChar) for all forms? And how I can use specific render_value for one form or one module?
I created form_widgets.js in my module, but I not understand how properly override Field.
odoo.define('my_module.form_widgets', function (require) {
"use strict";
// what I should do here???
});
Can you provide small example? Thank in advance.
I found the solution.
The first thing you need to do it is create static for frontend. JS:
// path_to_your_module/static/src/js/form_widgets.js
odoo.define('your_module.form_widgets', function (require) {
"use strict";
var core = require('web.core');
var form_common = require('web.form_common');
var FieldChar = core.form_widget_registry.get('char');
FieldChar.include({
// this is will be work for all FieldChar in the system
template: 'MyChar', // my template for char fields
// we can create here any logic for render
//render_value: function() {
//}
});
// this is widget for unique CharField
var MyModuleFieldChar = FieldChar.extend({
template: 'MyUniqueChar' // my custom template for unique char field
});
// register unique widget, because Odoo does not know anything about it
core.form_widget_registry.add('my_unique_char', MyModuleFieldChar);
});
Templates for qWeb:
<?xml version="1.0" encoding="UTF-8"?>
<templates xml:space="preserve">
<!-- path_to_your_module/static/src/xml/form_widgets.xml -->
<t t-name="MyChar">
<!-- for example I just added new <span> to all FieldChar -->
<span>my_val</span>
<!-- this is original content for CharField from path_to_odoo/addons/web/static/src/xml/base.xml -->
<span t-att-class="'oe_form_field '+widget.widget_class" t-att-style="widget.node.attrs.style">
<t t-if="!widget.get('effective_readonly')">
<input t-att-type="widget.password ? 'password' : 'text'"
t-att-barcode_events="widget.options.barcode_events"
t-att-id="widget.id_for_label"
t-att-tabindex="widget.node.attrs.tabindex"
t-att-autofocus="widget.node.attrs.autofocus"
t-att-placeholder="widget.node.attrs.placeholder"
t-att-maxlength="widget.field.size"
/><img class="oe_field_translate oe_input_icon" t-if="widget.field.translate" t-att-src='_s + "/web/static/src/img/icons/terp-translate.png"' width="16" height="16" border="0"/>
</t>
<t t-if="widget.get('effective_readonly')">
<span class="oe_form_char_content"></span>
</t>
</span>
</t>
<!-- This is example template for my unique field -->
<t t-name="MyUniqueChar">
<span>unique_char</span>
</t>
</templates>
Second step - include our static files.
Create new view which will be add assets:
<?xml version="1.0" encoding="utf-8"?>
<!-- path_to_your_module/views/assets.xml -->
<openerp>
<data>
<template id="assets_backend" name="mail assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/your_module/static/src/js/form_widgets.js"></script>
</xpath>
</template>
</data>
</openerp>
In openerp.py of your module add next sections:
'data': [
'views/assets.xml',
# other files
],
'qweb': [
'static/src/xml/*.xml',
],
After this will be work our FieldChar for all CHAR fields in the system. If we need to use my_unique_char we need just add attribute widget to field of our from like this:
<field name="name" widget="my_unique_char"/>
I hope it will help someone.
Related
I want to change a function in js file. How to do it? Is there any ways to override the function?
addons/web/static/src/js/views/form_common.js,
i want to change the function-get_search_result: function(search_val){}
dataset.name_search(search_val, self.build_domain(), 'ilike', 160).done(function(_data) {self._search_create_popup("search", _data);}
need to change the value 160 to something else
Thanks in advance
There is a good answer/example on this question, which gives a pretty good overview. That example is actually a bit more in depth than necessary for a global JavaScript change.
If you identify the function you want to override, then it's mostly just a matter of mirroring core and making the override(s) you want. Here's an example overview of how to change the name_search JavaScript behavior:
your_module/manifest.py
...
'data': [
...
'views/assets.xml',
...
],
...
your_module/views/assets.xml
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="assets_backend" name="custom assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/your_module/static/src/js/custom.js"></script>
</xpath>
</template>
</data>
</odoo>
your_module/static/src/js/custom.js
odoo.define('your_module.custom_feature', function(require) {
"use strict";
Class = require('web.Class');
mixins = require('web.mixins');
var DataSet = Class.extend(mixins.PropertiesMixin, {
name_search: function (name, domain, operator, limit) {
/* Custom code to override/extend core */
},
});
return {
DataSet: DataSet,
};
});
You can do it like they did in google_calendar:
odoo.define('youmodule.yourmodule', function (require) {
"use strict";
var CompletionFieldMixin = require('web.CompletionFieldMixin');
var _t = core._t;
var QWeb = core.qweb;
CompletionFieldMixin.include({
// You need to redefine the function here
});
I'm trying to create a simple javascript code in odoo 10. So Under myModule\static\src\js folder I added a test.js file containing this code:
alert("it works!!");
And Under myModule\views I added an xml file containing this code:
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="assets_backend" name="solixy assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/solixyProject/static/src/js/test.js"></script>
</xpath>
</template>
</data>
And it works fine when I update my module and refresh odoo. Now I want this js code to be called when I press a button. So I changed js code like this:
function clickMe(){
alert("it works!!");
};
Then in my form I added this button:
<button name="test_js" string="Test Javascript File" type="object" class="btn-primary" onclick="clickMe()"/>
Now the button is shown but I don't have my alert box!!
Thank you for your help.
It looks like I'm missing many other javascript code so my method can work. We can't just add a method like this:
function clickMe(){
alert("it works!!");
};
This is the correct js code:
odoo.define('solixyProject.kanban_view', function (require){
"use strict";
var form_widget = require('web.form_widgets');
var core = require('web.core');
var _t = core._t;
var QWeb = core.qweb;
form_widget.WidgetButton.include({
on_click: function() {
if(this.node.attrs.custom === "click"){
alert("It works!!");
return;
}
this._super();
},
});
});
And this is the correct xml code:
<button string="Test Javascript Onclick Method" custom="click" />
This question helped me a lot:
Odoo javascript onclick event
How Can I create a simple widget in odoo10?? Corresponding code for
following in odoo10? HOw can i convert this code to odoo10?
local.HomePage = instance.Widget.extend({
start: function() {
this.$el.append("<div>Hello dear Odoo user!</div>");
var greeting = new local.GreetingsWidget(this);
return greeting.appendTo(this.$el);
},
});
Create Widgets and Templates in Odoo-10
Widget:
Widget is different or alternate representation to display a screen, fields and attributes in odoo.
Widget allows to change view using different rendering templates and also allows to design as you want.
Example:
widget_name.js
odoo.define('module.model_name', function(require) {
"use strict";
var Widget = require('web.Widget');
var core = require('web.core');
var Model = require('web.Model');
var QWeb = core.qweb;
var _t = core._t;
// here we are getting the value in an array.
var widget_name = Widget.extend({
//render your template
"template" : "template_name",
//initialize
init : function () {
var self = this;
this._super(parent);
//initialize values to variables
}
//Binding Events
events : {
'click .class_ex': 'method1',
'click .class_ex1': 'method2',
},
start : function() {
var self = this;
this._super(parent);
//your functionality code and logic
},
//creating functions
method1:function(){
//do something when click event fire on class_ex
},
method2:function(){
//do something when click event fire on class_ex
},
});
return widget_name;
});
You need to add this .js & .css files in odoo like this.
assets_backend.xml
<odoo>
<data>
<template id="assets_backend" inherit_id="web.assets_backend">
<xpath expr="script[last()]" position="after">
<script type="text/javascript" src="/module/static/src/js/widget_name.js"></script>
<link href="/module/static/src/css/home.css" rel="stylesheet"></link>
</xpath>
</template>
</data>
</odoo>
Design Widget Template:
Create XML and add xml:space="preserve" as argument in template tag.
t-name is name of your template that is defined in .js file and the same name is used as widget name in XML while you use it.
tmpl.xml
<?xml version="1.0"?>
<templates id="template" xml:space="preserve">
<t t-name="template_name">
<div class=”myclass”>
//design your template here
<div class=”class_ex”>
//body
</div>
<div class=”class_ex1”>
//body
</div>
</div>
</t>
</templates>
NOTE: No need to write odoo tag in tmpl.xml file.
It is important to have the template name to be the same, as given in your in .js (widget_name.js) file.
How to use a widget
Use widget by action or object button.
Shown below we add template_name to action_registry, so now we can use this name to execute using XML.
Example:
<record id="template_id" model="ir.actions.client">
<field name="name">template name</field>
<field name="tag">template_name</field>
<field name="target">new</field>
</record>
Set your "template name" in HERE
You can also write some events on your button, fields and then make a function that handles event and execute function that renders your template. Return this id (template_id) as a result when object button clicked.
You can use your widget like this also.
<field name="mobile" widget="template_name" />
In stock module the Barcode Scanner page is handled by widget.js and picking.xml through qweb.
I need to override the behaviour in order to add functionalities. So far I've been able to override the xml:
<templates id="template" xml:space="preserve">
<t t-extend="PickingEditorWidget">
<t t-jquery="#js_packconf_select" t-operation="after">
<p>Hello World!</p>
</t>
</t>
</templates>
but about the js part I'm stuck.
I need to override the behaviour of some functions inside PickingEditorWidget but in widget.js it is first contained inside the object openerp.stock and then the whole openerp.stock is overwritten with a function:
openerp.stock = function(openerp) {
openerp.stock = openerp.stock || {};
openerp_picking_widgets(openerp);
}
I've seen this kind of code is in every module, then, how could I change how (for example) this function works without have to rewritten the whole stock/widget.js with my small changes?
this.$('.js_pack_configure').click(function(){
....
})
I am not JS expert and I couldn't figure it out...
EDIT:
I put in my module's manifest the stock module in dependances, now I see the PickingEditorWidget object but still I can't make it work my changes
my code (widget.js) is:
function openerp_picking_widgets_extended(instance){
var module = instance.mrp_extended;
module.PickingEditorWidgetExtended = instance.stock.PickingEditorWidget.include({
renderElement: function(){
this.$('.js_pack_configure').click(function(){
<my code>
});
this.$('.js_validate_pack').click(function(){
<my code>
});
this._super();
},
});
}
openerp.mrp_extended = function(openerp) {
openerp.mrp_extended = openerp.mrp_extended || {};
openerp_picking_widgets_extended(openerp);
}
I fixed my code this way:
....
module.PickingEditorWidgetExtended = instance.stock.PickingEditorWidget.include({
renderElement: function(){
this._super();
....
I'm developing a website with Odoo v8. I want to write a snippet that its struct is load by javascript. Bellow are my code ...
Firstly, I have a snippet struct:
<template id="snippet_hello" inherit_id="website2.snippets" name="Snippet Hello">
<xpath expr="//div[#id='snippet_structure']" position="inside">
<div class="oe_snippet">
<div class="oe_snippet_thumbnail">
<img class="oe_snippet_thumbnail_img" src="/path_to_block_icon/block_icon.png"/>
<span class="oe_snippet_thumbnail_title">Hello</span>
</div>
<section class="oe_snippet_body">
<div class="oe_snippet_hello">Hello ...</div>
</section>
</div>
</xpath>
<xpath expr="//div[#id='snippet_options']" position="inside">
<div data-snippet-option-id='snippet_hello'
data-selector=".oe_snippet_hello"
data-selector-siblings="p, h1, h2, h3, blockquote, .well, .panel">
</div>
</xpath>
</template>
Then I have a little javascript code to render snippet content:
(function () {
'use strict';
var website = openerp.website;
qweb = openerp.qweb;
qweb.add_template('/path_to_snippet_qweb_template/snippet_template_filename.xml');
website.snippet.animationRegistry.hello = website.snippet.Animation.extend({
selector: ".oe_snippet_hello",
start: function(){
var $content = $(qweb.render('website.snippet_hello', {a:1}));
$content.appendTo(this.$target);
},
});
})();
Then I have a QWeb template to display my struct content (filename: snippet_template_filename.xml):
<?xml version="1.0" encoding="utf-8"?>
<templates id="template" xml:space="preserve">
<t t-name="website.snippet_hello">
<div contenteditable="false">
<p>Hello snippet</p>
<t t-esc="a"/>
</div>
</t>
</templates>
Problem is this line:
var $content = $(qweb.render('website.snippet_hello', {a:1}));
occurred error that "Template 'website.snippet_hello' not found"
I noticed that when I logged in as Admin (haven't tried another account), it works well. It just occurred error when I logged out on my browser.
Please let me your advice, thanks!
This is an old question related to an obsolete Odoo's version but answer is still relevant today (Odoo v11/12/13) :
Template Not found could occur when:
template is not loaded
template names are not equals between your js and your template's xml files. Templates names are case sensitive.
Loading a template:
Usually you save your templates in your project as /your_module/static/src/xml/snippet_template_filename.xml, and you must load this xml file on /your_module/__manifest__.py by adding:
'qweb': [
"static/src/xml/snippet_template_filename.xml",
],
or shorthand:
'qweb': [
"static/src/xml/*.xml",
],
You install/update your_module in odoo's App menu, then you can verify that your template is loaded by looking at http://localhost:8069/web/webclient/qweb?mods=your_module, it should returns your templates.
You can also look at favorite browser network inspector to check the http://localhost:8069/web/webclient/qweb?mods=[...] request and checks that in mods your_module is loaded properly.
Template can be used in your js like in this (Odoo >= v11):
odoo.define('your_module.NameOfYourJs', function (require) {
"use strict";
var QWeb = core.qweb;
[...]
var result = QWeb.render('website.snippet_hello', {a:1});
});
Note: to debug assets you can use http://localhost:8069/web?debug=assets.
Hope this helps!