前言
我們通常在form檢視中可以很簡單地在header裡面新增按鈕,但是在某些情況下,我們也需要在Tree檢視中新增按鈕,但是odoo官方目前沒有給我們提供相應的介面,因此,我們嘗試自己來實現它。最終效果如下:
按鈕顯示擴充
首先,我們需要先把按鈕的樣子給它做出來,我們需要在專案路徑下(/xxx/static/src/xml/file_name.xml)新增如下模板:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <template xml:space="preserve"> 3 <t t-extend="ListView.buttons"> 4 <t t-jquery="button.o_list_button_add" t-operation="after"> 5 <button class="btn btn-primary oe_action_button_picking o_hidden" type="button" 6 accesskey="f">揀貨</button> 7 </t> 8 </t> 9 </template>
繼承修改ListView檢視的buttons,新增“揀貨”按鈕,然後在__manifest__的'qweb'中引用它,升級模組後發現所有模組下都已經成功新增按鈕。
通常情況下,我們只需要在特定的模組下顯示按鈕,我們只需要稍作修改,指定模型名即可:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <template xml:space="preserve"> 3 <t t-extend="ListView.buttons"> 4 <t t-jquery="button.o_list_button_add" t-operation="after"> 5 <button t-if="widget.modelName == 'MODEL_NAME'" 6 class="btn btn-primary oe_action_button_picking o_hidden" type="button" 7 accesskey="f">揀貨</button> 8 </t> 9 </t> 10 </template>
按鈕方法邏輯
我們簡單完成了按鈕的顯示,按鈕的目的就是需要繫結執行特定的方法,因此,我們接下來需要為按鈕繫結對應的python方法。
首先在目錄下(/static/src/js/file_name.js)建立一個js檔案,繼承修改ListController:
1 odoo.define('ModelName.action_picking_button', function (require) { 2 "use strict"; 3 var core = require('web.core'); 4 var ListController = require('web.ListController'); 5 var rpc = require('web.rpc'); 6 var session = require('web.session'); 7 var _t = core._t; 8 ListController.include({ 9 renderButtons: function ($node) { 10 this._super.apply(this, arguments); 11 if (this.$buttons) { 12 this.$picking_button = this.$buttons.find('.oe_action_button_picking'); 13 this.$picking_button.click(this.proxy('action_def')); 14 } 15 }, 16 action_def: function () { 17 var self = this; 18 var user = session.uid; 19 rpc.query({ 20 model: 'ModelName', 21 method: 'do_picking', 22 args: [[user], self.getSelectedIds()], 23 }).then(function (result) { 24 self.do_notify('揀貨通知', '銷售訂單(%s)已成功生成揀貨單,你可以開始揀貨啦' % result.codes); 25 self.update({}); 26 }); 27 } 28 }); 29 });
注意上面的oe_action_button_picking 需要和上面qweb templates中的button class對應,以繫結方法。
action_def 方法就是button繫結的方法,在方法中呼叫了model類中的do_picking方法。
因此,我們只需要在python類中新增do_picking方法,並新增相應的邏輯即可。
擴充彩蛋
我需要有相應行選定的時候顯示按鈕,沒有的時候隱藏,如下圖。該如何實現呢?
在JS中覆蓋_toggleSidebar方法,在selectedRecords大於0時顯示按鈕,如下邏輯:
_toggleSidebar: function () { this._super.apply(this, arguments); if (this.$picking_button) { this.do_picking_button_toggle(this.selectedRecords.length > 0); } }, do_picking_button_toggle: function (display) { if (_.isBoolean(display)) { display ? this.do_show_picking_button() : this.do_hide_picking_button(); } else { this.$el.hasClass('o_hidden') ? this.do_show_picking_button() : this.do_hide_picking_button(); } }, do_show_picking_button: function() { this.$picking_button.removeClass('o_hidden'); }, do_hide_picking_button: function() { this.$picking_button.addClass('o_hidden'); }
當然,你也可以見仁見智,修改不同的邏輯以滿足你的業務。