How to inherit or override js file in odoo? - javascript

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
});

Related

How to inherit and modify nv.d3.js javascript file from web module odoo 10

I am using Odoo 10. Trying to inherit and modify nv.d3.js file in web module but no effect and no error is showing. Please check what I am doing wrong here.
my .js file:
odoo.define('budget_management.graph', function(require){
"use strict";
var WebClient = require('web.nv.d3');
var Model = require('web.Model');
var utils = require('web.utils');
WebClient.contentGenerator.include({
trowEnter.append("td")
.classed("value",true)
.html(function(p, i) {
var myval = valueFormatter(p.value, i)
//alert(myval)
return myval+'%'
});
var html = table.node().outerHTML;
if (d.footer !== undefined)
html += "<div class='footer'>" + d.footer + "</div>";
return html;
});
});
And my xml file contains:
<template id="assets_backend" name="extend_web_nvd3js assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/budget_management/static/src/js/inherit.nv.d3.js"></script>
</xpath>
</template>
if I change the code from the core module it is working but unable to inherit and implement this.

Testing a simple javascript function in odoo

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

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" />

override widget in odoo stock

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();
....

Access Firefox extension XPCOM object from Javascript inside an HTML page

I'm trying to get the most basic XPCOM javascript object to be accessible to the javascript I load into my webpage. I'm using the example code from this tutorial:
https://developer.mozilla.org/en-US/docs/How_to_Build_an_XPCOM_Component_in_Javascript
Here is my set up:
install.rdf:
<?xml version="1.0"?>
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
<Description about="urn:mozilla:install-manifest">
<em:id>helloworld#thellamatesting.com</em:id>
<em:name>Hello World</em:name>
<em:version>1.0</em:version>
<em:type>2</em:type>
<em:creator>The Llama</em:creator>
<em:description>Testing</em:description>
<em:targetApplication>
<Description>
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
<em:minVersion>2.0</em:minVersion>
<em:maxVersion>20.0</em:maxVersion>
</Description>
</em:targetApplication>
</Description>
</RDF>
chrome.manifest
content helloworld chrome/content/
content helloworld chrome/content/ contentaccessible=yes
overlay chrome://browser/content/browser.xul chrome://helloworld/content/browser.xul
component {4762b5c0-5b32-11e2-bcfd-0800200c9a66} components/HelloWorld.js
contract #thellamatesting.com/helloworld;1 {4762b5c0-5b32-11e2-bcfd-0800200c9a66}
locale helloworld en-US locale/en-US/
components/HelloWorld.js
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function HelloWorld() {
// If you only need to access your component from Javascript, uncomment the following line:
this.wrappedJSObject = this;
}
HelloWorld.prototype = {
classDescription: "My Hello World Javascript XPCOM Component",
classID: Components.ID("{4762b5c0-5b32-11e2-bcfd-0800200c9a66}"),
//Also tried
//classID: Components.ID("4762b5c0-5b32-11e2-bcfd-0800200c9a66"),
contractID: "#thellamatesting.com/helloworld;1",
QueryInterface: XPCOMUtils.generateQI(),
// Also tried
//QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIHelloWorld]),
hello: function() {
return "Hello World!";
}
};
var components = [HelloWorld];
if ("generateNSGetFactory" in XPCOMUtils)
var NSGetFactory = XPCOMUtils.generateNSGetFactory(components); // Firefox 4.0 and higher
else
var NSGetModule = XPCOMUtils.generateNSGetModule(components); // Firefox 3.x
Testing HTML:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script type="application/javascript">
function go() {
try {
var coms = Components;
alert(Components.classes);
var myComponent = Components.classes['#thellamatesting.com/helloworld;1'].getService().wrappedJSObject;
alert(myComponent.hello());
} catch (anError) {
dump("ERROR: " + anError);
}
};
</script>
</head>
<body>
<button onclick="javascript:go()">Click to go</button>
</body>
</html>
After all this, I end up with "Components.classes is undefined". Does anyone know what I'm doing wrong here?
Thanks so much!
In order to gain access to the Components object from a javascript context, you need to have extended capabilities, that is, run from a chrome:// URL. There used to be a way for a regular web page (served from http://) to request extended capabilities (called UniversalXPConnect) but it has been removed out of security concerns.
I think you should tell us a little more about what it is you're trying to achieve. If you're trying to export data from your addon into a webpage, the AddonSDK (see https://addons.mozilla.org/en-US/developers/docs/sdk/latest/dev-guide/) has a very good protocol for doing that called page-mod; it allows you to inject data into web pages.
Thanks to Jonathan's advice I was able to come up with a great solution to this problem. Here is the code I'm using:
main.js:
var data = require("self").data;
var pageMod = require("page-mod");
const {Cc,Ci} = require("chrome");
pageMod.PageMod({
include: "*",
contentScriptFile: data.url("copy-helper.js"),
onAttach: function(worker) {
worker.port.on("handleCopy", function(copyInfo) {
var gClipboardHelper = Cc["#mozilla.org/widget/clipboardhelper;1"].getService(Ci.nsIClipboardHelper);
gClipboardHelper.copyString(copyInfo.dataToCopy);
});
}
});
copy-helper.js:
window.addEventListener("copyEvent", function (event) {
self.port.emit('handleCopy', event.detail.copyInfo);
}, false);
in my apps javascript
var event = new CustomEvent("copyEvent", {
detail:{
copyInfo: {dataToCopy:"my string"}
}
});
window.dispatchEvent(event);
Hope this helps anyone else who's ran into this issue!

Categories

Resources