override widget in odoo stock - javascript

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

Related

Javascript: Use "new Function()" to run code in a string and have it access class definitions

My actual code is dense, so I'm trying to reduce this to a minimal example.
I have MainUI.js which contains:
var MainUI = function(){
'use strict';
var singleton = null;
class MainUI {
makeSomethingHappen(){
console.log("MAGIC!");
}
}
return {
getSingleton: function(){
if (singleton == null) singleton = new MainUI();
return singleton;
}
};
}();
Then I have test.js which contains:
function test(code){
var uis = MainUI.getSingleton();
retValue = new Function("ui", "use strict'" + code)(uis);
}
This is all run from index.html which contains:
<html>
<script type="text/javascript" src="MainUI.js"></script>
<script type="text/javascript" src="test.js"></script>
<body onload="test('ui.makeSomethingHappen();');">
</body>
</html>
But when I call
test("ui.makeSomethingHappen();");
or even
test("console.log('NARF!');");
I get an exception with the message
MainUI is not defined
The singleton accessor and the MainUI works in all my code outside of "new Function()", so I know it's working (even if I made typographical error producing the minimal test).
So I'm hoping someone can tell me how I can give the code inside the Function access to the class definitions outside.
Make sure that the MainUI.js script is referenced correctly and that it is referenced prior to the test.js script that will use it.

How to inherit or override js file in odoo?

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

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

Pass angular value to common JavaScript

I am trying to pass a value from angular scope to common JavaScript.
The JavaScript is like this
<script type="text/javascript">
var epaycode = null;
var epaybuysum = null;
paymentwindow = new PaymentWindow({
'merchantnumber': epaycode,
'amount': epaybuysum,
'currency': "DKK",
'windowstate': "4",
'paymentcollection': "1",
'iframeheight': "250",
'iframewidth': "500"
});
paymentwindow.append('payment-div');
setTimeout(function(){
paymentwindow.open();
}, 1000);
The angular controller code is like this
$scope.showpay = function () {
$window.epaybuysum = $scope.buysum * 100;
$window.epaycode = $scope.ePayCode;
};
The Angular showpay() function is called after the common JavaScript is initialized. The buysum and ePayCode is set earlier in the program. They have value and is tested with console.log().
Why doesn't the epaybuysum and epaycode getting transferred to the common JavaScript?
Is there any other solutions to passing values to common JavaScript from Angular controllers?
Have a look at this plunker: http://plnkr.co/edit/lQiXpObbWuG84CNbcZt2?p=preview
<div ng-controller="MainCtrl">
<input ng-model="buyCode">
<input ng-model="buySum">
<p>{{buyCode}} ... {{buySum}}</p>
<button ng-click="showPay()">call showPay</button>
</div>
<button onclick="buttonClick()">Console.log</button>
The first button calls your showPay function(the one on scope). The second button calls console.log (outside the angular controller, simple js). For this simple usecase it seems to work as expected. How are you calling showPay function?
Try this:
(function (angular, epaycode) {
'use strict';
var module = angular.module('abc', []);
//Your controller etc.
}
})(angular, epaycode);
Updated
The plunker in the comments section shows how you can do this.

Backbone: getting the html code of a view?

In order to write the HTML code of social icons (Twitter, Linkedin, etc) to a textarea so that the user can use that code elsewhere, I would like to get the HTML code of the view element, but I'm having some issues. To help illustrate this better, here is the code that creates the view:
define(function(require, exports, module) {
var _ = require('underscore');
var GridControlView = require('pb/views/grid-control');
var SocialiconsControlDialog = require('pb/views/socialicons-control-dialog');
var template = require('text!pb/templates/socialicons-grid-control.html');
var SocialiconsGridControlView = GridControlView.extend({
template: _.template(template)
,templateVars: {
partials: {
facebook: require('text!pb/templates/socialicons-grid-control-facebook.html')
,twitter: require('text!pb/templates/socialicons-grid-control-twitter.html')
,googleplus: require('text!pb/templates/socialicons-grid-control-googleplus.html')
,pinterest: require('text!pb/templates/socialicons-grid-control-pinterest.html')
,linkedin: require('text!pb/templates/socialicons-grid-control-linkedin.html')
}
}
,control_dialog: SocialiconsControlDialog
});
return SocialiconsGridControlView;
});
And, for example, the Linkedin template looks like this:
<script src="//platform.linkedin.com/in.js?<%- t.cache_buster %>" type="text/javascript">lang: en_US</script>
<script type="IN/Share" data-counter="<%- t.linkedin_option_countmode %>"></script>
What I would like to retrieve, is the parsed template code as text, something such as:
<script type="text/javascript" src="//platform.linkedin.com/in.js?0.4670609195438331">
<script data-counter="top" type="IN/Share+init">
But using something such as:
control_view.render().$el.innerHTML;, control_view.render().$el.html().text() or control_view.render().$el.html().replace(/<\/?[a-z][a-z0-9]*[^<>]*>/ig, ""); doesn't return text; it returns the full HTML, and produces a Linkedin icon (when I just want the text to be written to a textarea).
Any thoughts?
Update **
I noticed that the code control_view.render().$el is working correctly on other places of the application, and returning HTML code, but for some reason in this view where I'm trying it doesn't. The code seems to break at:
$control = control_view.render().el;
and in the console I get an error which is:
TypeError: t is undefined - underscore-min.js (line 3)
Use the .outerHTML property of the $el.
var html = $('<script type="text/javascript" src="//platform.linkedin.com/in.js?0.4670609195438331">' +
'<script data-counter="top" type="IN/Share+init">');
var text = html[0].outerHTML;
$('textarea').val(text);
jsFiddle

Categories

Resources