实践环境

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>

Odoo 自定义form表单按钮点击事件处理程序的更多相关文章

  1. 利用 ajax自定义Form表单的提交方式

    需求场景:有时候单纯的form表单无法向后端传递额外的参数 比如需要action传递js异步生成的参数 ,form表单默认的action就无法满足需求,这时就需要我们自定义form表单的提交方式. h ...

  2. python26:自定义form表单验证

    一.自定义Form的原理 1.1 各种form表单验证比较 只有python提供了form表单验证,其他的都没有提供.django提供的功能还不够强大.最强大的是微软的ASP.NET!我们可以自己写一 ...

  3. iview form表单数值类型校验「iview自定义form表单校验器」

    摘录iview表单验证 Form 组件基于 sync-validator 实现的数据验证,给 Form 设置属性 rules,同时给需要验证的 FormItem 设置属性 prop 指向对应字段即可. ...

  4. web前端框架之自定义form表单验证

    自定义form验证初试 .在后端创建一个类MainForm,并且在类中自定义host ip port phone等,然后写入方法,在post方法中创建MainForm对象,并且把post方法中的sel ...

  5. tornado之自定义form表单验证

    直接上链接吧:银角的地址 源码下载链接:点我点我点我...

  6. DuiLib笔记之自定义标题栏以及响应按钮点击事件

    在博文DuiLib笔记,基于WindowImplBase的基础模板的基础上,修改皮肤文件如下 <?xml version="1.0" encoding="utf-8 ...

  7. form表单的字符串进行utf-8编码

    <form>表单有assept-charset属性.该属性规定字符的编码方式,默认是"unknown",与文档的字符集相同. 该属性除了Internet explore ...

  8. 提交Form表单,submit之前做js判断处理

    效果: 在点击提交按钮时,首先进行js判断, 如果不符合条件,则alert出提示信息,并return false. 主要点就在于给form表单添加一个onsubmit事件. 在onsubmit事件中定 ...

  9. form 表单提交返回值问题

    form不比ajax,即使后台返回值后,在页面也不知道怎么去取值判断提交状态.所以前几天结合网上资料整了一个小案例,需要用到ajaxSubmit,即通过ajax来提交表单,好处在于可以在任何情况下进行 ...

  10. 看用Tornado如何自定义实现表单验证

    我们知道,平时在登陆某个网站或软件时,网站对于你输入的内容是有要求的,并且会对你输入的错误内容有提示,对于Django这种大而全的web框架,是提供了form表单验证功能,但是对于Tornado而言, ...

随机推荐

  1. 卸载vsto插件的方法

    现在发布博客园的博客已经可以直接在word上进行,word上的代码高亮插件也安装起了,不过,因为有源码的原因,我就对插件进行了更改,安装之后需要重新安装,有时候在再次安装得时候会提示已经安装过了,我就 ...

  2. RocketMQ阅读源码前的准备

    本文将讲解如何在IDEA中导入 RocketMQ 源码,并运行 Broker 和 NameServer,编写一个消息发送与消息消费的示例. 一. 源码导入及调试 1.1 导入源码 RocketMQ 原 ...

  3. dotnet c# samples core nativeaot NativeLibrary

    如何在 System.Text.Json 中使用源生成 https://learn.microsoft.com/zh-cn/dotnet/standard/serialization/system-t ...

  4. NOIP模拟62

    T1 Set 解题思路 抽屉原理 发现对于前缀和向 \(n\) 取模之后一定是右两个值相等的(包括什么都不选的 0 ). 假设 \(pre_j=pre_i\) 那么 \([j+1,i]\) 之间这一段 ...

  5. C#笔记(1)窗体

    1. 隐藏TabPage 在使用TabControl控件时,希望隐藏其中某个选项卡(即TabPage).设置该TabPage的父容器为null 即可,如TabPage.Parent = null .如 ...

  6. 一文了解JVM(中)

    HotSpot 虚拟机对象探秘 对象的创建 Header 解释 使用 new 关键字 调用了构造函数 使用 Class 的 newInstance 方法 调用了构造函数 使用 Constructor ...

  7. Matlab打印运行进度

      在运行matlab程序的过程中,有时候需要实时地掌握程序运行的进度,尤其对于一些耗时较长的循环操作,能够及时地输出运行进度,显得非常有必要.   打印进度条的实现方式就是不断地退格.输出.   退 ...

  8. P6259

    problem 考虑使用 dfs 模拟. 由于一个程序可能在不进入无限循环的情况下运行很多步,这将会非常缓慢.因此,接下来要加速模拟,可以用记忆化搜索. 在网格中,机器人的可能状态(位置和朝向)只有 ...

  9. vm ware cent os 共享文件夹

    1.VM中安装vm-tools 2.在VM 虚拟机设置中添加共享文件夹. 3.重启虚拟机 4.在/mnt/ 里新建一个名为"win"的文件夹 5.在cent os 中执行: vmw ...

  10. C# WINFORM 获取上级目录

    MessageBox.Show(Application.StartupPath); DirectoryInfo di = new DirectoryInfo(string.Format(@" ...