Good day!
Is there a way to add a button above the Tree View in Odoo?
I would like to run a function whenever the User Clicks the button.
If this is not possible can you help me with an alternative?
here is my code on view:
'''<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_payment_import_view_tree" model="ir.ui.view">
<field name="name">account.payment.import.view.tree</field>
<field name="model">account.payment.import</field>
<field name="arch" type="xml">
<tree string="Payment Imports" decoration-info="payment_id != False" decoration-danger="error_msg != False">
<field name="transaction_date"/>
<field name="facts_id"/>
<field name="paid_in_lei"/>
<field name="paid_in_euro"/>
<field name="amount"/>
<field name="account"/>
<field name="account_no"/>
<field name="document_no"/>
<field name="details_bk_statement"/>
<field name="error_msg"/>
<field name="invoice_number" invisible="1"/>
<field name="payment_id" widget="many2onebutton" invisible="1"/>
<field name="invoice_id" widget="many2onebutton" invisible="1"/>
<field name="company_id" invisible="1"/>
<field name="currency_id" invisible="1"/>
</tree>
</field>
</record>
<record id="account_payment_import_action" model="ir.actions.act_window">
<field name="name">Payment Imports</field>
<field name="res_model">account.payment.import</field>
<field name="view_mode">tree</field>
<field name="domain">[]</field>
<field name="context">{'edit': 0}</field>
</record>
<menuitem
id="account_payment_import_menu"
name="Payment Imports"
action="account_payment_import_action"
parent="account.menu_finance_receivables"
sequence="160"/>
</odoo>'''
Well, here's my attempt to get the button in the tree view. I'll try to explain you well step by step.
First we have to add the button to the tree view via qweb, inheriting the tree view from the web module.
This will make our new button appear in all tree views, which we don't want. So to avoid that we add a condition t-if='widget.modelName == "account.payment.import"'
which will cause the button to be generated only for the views whose model is the one that interests us. We also add a CSS class oe_new_custom_button
to be able to identify the button from the javascript.
Let's call the file that contains this qweb tree_view_button.xml and place it in your_module_name/static/src/xml.
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-extend="ListView.buttons">
<t t-jquery="div.o_list_buttons" t-operation="append">
<button type="button" t-if='widget.modelName == "account.payment.import"'
class="oe_new_custom_button btn btn-primary">Custom Button
</button>
</t>
</t>
</templates>
Second we must give functionality to the button, we achieve this through javascript.
Here we inherit the tree view controller, called ListController, whose its role is to render and bind all extra buttons/pager in the control panel, among other things.
Let's call the file that contains this javascript tree_view_button.js and place it in your_module_name/static/src/js.
odoo.define('your_module_name.tree_view_button', function (require){
"use strict";
var ajax = require('web.ajax');
var ListController = require('web.ListController');
ListController.include({
renderButtons: function($node) {
this._super.apply(this, arguments);
var self = this;
if (this.$buttons) {
$(this.$buttons).find('.oe_new_custom_button').on('click', function() {
//custom code
});
}
},
});
});
Finally, we add our javascript to the odoo assets and configure the manifest to take all our changes.
Let's call the file that contains the assets assets.xml and place it in your_module_name/views.
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<template id="assets_backend" name="your_module_name_assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/your_module_name/static/src/js/tree_view_button.js"></script>
</xpath>
</template>
</data>
</odoo>
And that's what it should look like manifest.py.
{
'data': [
[ ... ]
'views/assets.xml', # <- important
],
"qweb": ['static/src/xml/*.xml'], # <- important
}
A little bit of everything, but the most important thing would be the following.
odoo.define('your_module_name.tree_view_button', function (require){
"use strict";
var ajax = require('web.ajax');
var ListController = require('web.ListController');
var rpc = require('web.rpc')
ListController.include({
renderButtons: function($node) {
this._super.apply(this, arguments);
var self = this;
if (this.$buttons) {
$(this.$buttons).find('.oe_new_custom_button').on('click', function() {
rpc.query({
model: 'account.payment.import',
method: 'some_method',
args: [],
}).then(function(res){
// console.log(res)
// self.reload();
})
});
}
},
});
});
The first argument of args is a list of the ids you want to appear in the self variable of the some_method.
odoo.define('your_module_name.tree_view_button', function (require){
"use strict";
var ajax = require('web.ajax');
var ListController = require('web.ListController');
ListController.include({
renderButtons: function($node) {
this._super.apply(this, arguments);
var self = this;
if (this.$buttons) {
$(this.$buttons).find('.oe_new_custom_button').on('click', function() {
self.do_action('model_name.action_id', {
additional_context: {},
});
});
}
},
});
});
additional_context should be, for example,
{
'active_id': 1,
}
That's all, I hope it works for you. I attach an image of what the button would look like.