实践环境
Odoo 14.0-20221212 (Community Edition)
代码实现
方案1
通过研究发现,点击odoo form表单按钮时,会调用odoo14\odoo\addons\web\static\src\js\views\form\form_controller.js
文件中的_onButtonClicked
函数,在该函数中响应点击事件。所以,我们可以通过重写该方法来实现自定义响应点击事件。示例如下
表单视图定义
codePojects\odoo14\custom\estate\wizards\demo_wizard_views.xml
<?xml version="1.0" encoding="UTF-8"?> <odoo> <data> <record id="demo_wizard_view_form" model="ir.ui.view"> <field name="name">demo.wizard.form</field> <field name="model">demo.wizard</field> <field name="arch" type="xml"> <form> //...代码略 <footer> <button name="action_confirm" special="other" type="object" string="确认" class="oe_highlight"/> <button string="关闭" class="oe_link" special="cancel"/> </footer> </form> </field> </record> //...代码略 </data> </odoo>
重定义web.FormController
以实现重写_onButtonClicked
codePojects\odoo14/estate/static/src/js/views/form_controller.js
odoo.define('customModule.FormController', function (require) { "use strict"; var formController = require('web.FormController'); var CustomFormController = formController.extend({ //-------------------------------------------------------------------------- // Handlers //-------------------------------------------------------------------------- /** * @private * @param {OdooEvent} ev */ _onButtonClicked: function (ev) { // stop the event's propagation as a form controller might have other // form controllers in its descendants (e.g. in a FormViewDialog) ev.stopPropagation(); var self = this; var def; this._disableButtons(); function saveAndExecuteAction () { return self.saveRecord(self.handle, { stayInEdit: true, }).then(function () { // we need to reget the record to make sure we have changes made // by the basic model, such as the new res_id, if the record is // new. var record = self.model.get(ev.data.record.id); return self._callButtonAction(attrs, record); }); } var attrs = ev.data.attrs; if (attrs.confirm) { def = new Promise(function (resolve, reject) { Dialog.confirm(self, attrs.confirm, { confirm_callback: saveAndExecuteAction, }).on("closed", null, resolve); }); } else if (attrs.special === 'cancel') { def = this._callButtonAction(attrs, ev.data.record); } else if (attrs.special == 'other') { // 新增自定义事件处理 self._enableButtons(); // 启用按钮(点击后会自动禁用按钮) self.trigger_up('close_dialog'); // 关闭对话框 return; } else if (!attrs.special || attrs.special === 'save') { // save the record but don't switch to readonly mode def = saveAndExecuteAction(); } else { console.warn('Unhandled button event', ev); return; } // Kind of hack for FormViewDialog: button on footer should trigger the dialog closing // if the `close` attribute is set def.then(function () { self._enableButtons(); if (attrs.close) { self.trigger_up('close_dialog'); } }).guardedCatch(this._enableButtons.bind(this)); }, }); odoo.__DEBUG__['services']['web.FormController'] = CustomFormController; });
codePojects\odoo14\custom\estate\views\webclient_templates.xml
<?xml version="1.0" encoding="utf-8"?> <odoo> <template id="assets_common" inherit_id="web.assets_common" name="Backend Assets (used in backend interface)"> <xpath expr="//script[last()]" position="after"> <script type="text/javascript" src="/estate/static/src/js/views/form_controller.js"></script> </xpath> </template> </odoo>
codePojects\odoo14\custom\estate\__manifest__.py
#!/usr/bin/env python # -*- coding:utf-8 -*- { 'name': 'estate', 'depends': ['base'], 'data':[ # ...略 'views/webclient_templates.xml', 'wizards/demo_wizard_views.xml', # ...略 ] }
方案2
研究发现,在不为按钮设置type
属性的情况下,可以为按钮添加onclick
属性,指定点击按钮时需要调用的javascript函数,不过,此时点击按钮,不会再调用web.FormController
中定义的_onButtonClicked
函数。示例如下:
<?xml version="1.0" encoding="UTF-8"?> <odoo> <data> <record id="demo_wizard_view_form" model="ir.ui.view"> <field name="name">demo.wizard.form</field> <field name="model">demo.wizard</field> <field name="arch" type="xml"> <form> //...代码略 <footer> <button name="action_confirm" do_confirm_action('demo.wizard','action_confirm') string="确认" class="oe_highlight"/> <button string="关闭" class="oe_link" special="cancel"/> </footer> </form> </field> </record> //...代码略 </data> </odoo>
codePojects\odoo14/estate/static/src/js/demo_wizard_views.js
function do_confirm_action(modelName, modelMethod){ // do something //... $("button[name='action_confirm']").attr("disabled", true); }
codePojects\odoo14\custom\estate\views\webclient_templates.xml
<?xml version="1.0" encoding="utf-8"?> <odoo> <template id="assets_common" inherit_id="web.assets_common" name="Backend Assets (used in backend interface)"> <xpath expr="//script[last()]" position="after"> <script type="text/javascript" src="/estate/static/src/js/demo_wizard_views.js"></script> </xpath> </template> </odoo>