odoo12 列表视图新增自定义按钮实现不同的业务需求
场景:
一个神奇的需求吧,算是,列表页创建表单数据的时候,通过type控制数据的不同,但是说为了防止用户误操作,需要把原来odoo自带的创建按钮去掉,做成两个不同的创建入口(入库创建按钮、出库创建按钮)附图一张。
然后就是做成弹窗样式的数据,没有常规操作点击列表数据进入form视图的操作。
思路:
用xml继承模板写按钮,然后通过js来获取按钮的点击与否,再写业务逻辑
按钮添加参考这篇:https://blog.csdn.net/Katherine130/article/details/103457644
js打开form参考这篇:https://www.cnblogs.com/da-tong/p/13029686.html
代码实现:
1. 首先在static下的src文件夹下的xml文件夹里面新建一个按钮的模板out_in_stock_btn_template.xml(记得在__manifest__文件里面引入qweb)
<?xml version="1.0" encoding="UTF-8"?> <templates> <!-- Tree 视图上自定义按钮--> <t t-name="OutInStockBtnView.in_stock_button"> <button type="button" class="btn btn-primary in_stock_btn" style="border-radius: 5px"> 新增入库 </button> </t> <t t-name="OutInStockBtnView.out_stock_button"> <button type="button" class="btn btn-primary out_stock_btn" style="margin-left: 10px;border-radius: 5px"> 新增出库 </button> </t> <t t-name="OutInStockBtnView.carry_last_month_stock"> <button type="button" class="btn btn-primary last_month_stock" style="margin-left: 200px;border-radius: 5px"> 结转上月库存 </button> </t> <t t-extend="ListView.buttons" t-name="OutInStockBtnView.out_in_stock_button"> <t t-jquery="div.o_list_buttons" t-operation="append"> <!-- t-jquery 根据页面布局自行填写 --> <t t-call="OutInStockBtnView.in_stock_button"/> <t t-call="OutInStockBtnView.out_stock_button"/> <t t-call="OutInStockBtnView.carry_last_month_stock"/> </t> </t> </templates>
2. 新建一个瞬时模型和form视图,用来在点击了自定义按钮后弹出页面(记得在__manifest__文件引入)
我的页面就是这样
·弹窗的保存按钮:
<button string="保存" type="object" name="execute" class="oe_highlight"/>
3. 对应瞬时模型对应保存按钮方法
@api.multi def execute(self): """新增入库""" pass
4. static下的src下js文件夹新建out_in_site_usage.js文件(为自定义按钮绑定事件,触发功能)
odoo.define('fr.off.site.usage', function (require) { "use strict"; let Dialog = require('web.Dialog'); let core = require('web.core'); let ListController = require('web.ListController'); let ListView = require('web.ListView'); let rpc = require('web.rpc'); let viewRegistry = require('web.view_registry'); let qweb = core.qweb; let FrOffSiteUsage = ListController.extend({ buttons_template: 'OutInStockBtnView.out_in_stock_button', renderButtons: function () { this._super.apply(this, arguments); if (this.$buttons) { var self = this; this.$buttons.on('click', '.in_stock_btn', this.proxy('create_in_stock')); this.$buttons.on('click', '.out_stock_btn', this.proxy('create_out_stock')); this.$buttons.on('click', '.last_month_stock', this.proxy('carry_last_month_stock')); } },create_in_stock: function () { // this._rpc({ // model: "fr.off.site.in.stock.wizard", # 模型名 // method: "execute", # 方法名 // args: ['in'], # 参数 // }).then(function () { // location.reload(); // }); 这是可以直接出发对应模型的方法 var self = this; this.do_action({ name: "新增入库", //自定义弹出框名称 type: 'ir.actions.act_window', //动作类型 res_model: 'fr.off.site.in.stock.wizard', //视图的model views: [ // [false, 'list'], [false, 'form'], ], view_mode: "form", view_type: 'form', view_id: 'fr_storage_extend.FrOffSiteInStockWizardAction', //视图的id context: "{'stock': 'in'}", // flags: {'initial_mode': 'view',action_buttons:false}, //target: 'new'弹出框默认为编辑模式,需要只读模式的可以加上这句 target: 'new' //打开方式 }) }, create_out_stock: function () { alert('点击了新增出库') },carry_last_month_stock: function () { alert('点击了结转上月库存') } }); let OutInStockBtnView = ListView.extend({ config: _.extend({}, ListView.prototype.config, { Controller: FrOffSiteUsage, }), }); viewRegistry.add('fr_off_site_usage', OutInStockBtnView); });
5. js文件引入(此xml文件也要记得引入)
<?xml version="1.0" encoding="utf-8"?> <odoo> <data> <template id="FrStorageExtend" name="FrStorageExtendReportKanBanExtend assets" inherit_id="web.assets_backend"> <xpath expr="." position="inside"> <script type="text/javascript" src="/fr_storage_extend/static/src/js/out_in_site_usage.js"/> </xpath> </template> </data> </odoo>