需求说明:
odoo form视图的所有button按钮都会触发保存操作,而odoo默认的保存操作会触发验证,就是说odoo会先验证保存完表单,再去执行按钮对应的方法,但是有时我们只是想单纯的实现按钮功能,不需要保存操作,所以针对以上场景,我们对odoo的按钮事件进行了二次开发,以实现一下更常规的操作。
实现方式说明:
以下改造都是在重写odoo 的 form_controller.js的基础上进行,重写方式如下:
odoo.define('changeformcontroller', function (require) {
"use strict";
var FormController = require('web.FormController');
var Dialog = require('web.Dialog');
var core = require('web.core');
var dialogs = require('web.view_dialogs');
var Sidebar = require('web.Sidebar');
var _t = core._t;
var qweb = core.qweb;
var clickDataAction = ''; // 用来保存触发按钮的data-actionState属性值
FormController.include({
...... 后续内容写在此处
})
1. 实现按钮不触发odoo 保存操作
重写 saveAndExecuteAction 方法
function saveAndExecuteAction() {
/**
(说明)在原方法上新增的部分
*/
// 保存从dom上获取的data属性
var evData = clickDataAction = ev.data.attrs['data-actionState']
// 根据值类型,判断后续的逻辑
if (evData && evData === 'm-noSave') { // 如果为"m-noSave", 则不进行后续的保存和验证
var record = self.model.get(ev.data.record.id);
// 直接调用按钮对应的方法
return self._callButtonAction(attrs, record);
} else {
// 原逻辑
return self.saveRecord(self.handle, {
stayInEdit: true,
}).then(function () {
var record = self.model.get(ev.data.record.id);
return self._callButtonAction(attrs, record);
});
}
在xml 视图需要实现功能的按钮上增加自定义属性
<button name="change_contract" type="object" string="变更合同" confirm="确认变更申请?" data-actionState="m-noSave"/>
2. 实现取消按钮功能,点击按钮后关闭页面
if (evData && evData === 'm-cancel') { // 取消按钮
var record = self.model.get(ev.data.record.id);
self._discardChanges(); // 关闭视图
return self._callButtonAction(attrs, record);
}
在xml 视图需要实现功能的按钮上增加自定义属性
<button name="cancel" type="object" string="取消" data-actionState="m-cancel"/>
3. 切换视图只读或者编辑模式
- 说明:odoo 的from表单页,查看和编辑是公用一个页面,查看页面所有字段是不可以编辑的,默认是保存后页面变更为只读状态,有时需要手动切换页面的编辑状态
if (evData && evData === 'm-toggle-mode') { // 如果为切换视图状态
var isEdit = self.mode === 'edit'; // 判断是否为编辑状态
self._setMode(isEdit ? 'readonly' : 'edit') // 设置视图类型
self.initialState.context['form_state'] = isEdit ? 'readonly' : 'edit'
return self._callButtonAction(attrs, record); // 返回按钮事件(目前看,是必须要返回的)
在xml 添加自定义属性 m-toggle-mode
<button class="m-form-edit-hidden" type="object" string="编辑" data-actionState="m-toggle-mode"/>
4. 根据form视图模式显示或者隐藏按钮
- 说明:此功能主要是配合视图模式切换使用,例如,当视图处于只读模式时,隐藏某个按钮,甚至某个字段
// 更新按钮状态
_updateButtons: function () {
if (this.$buttons) {
if (this.footerToButtons) {
var $footer = this.renderer.$('footer');
if ($footer.length) {
this.$buttons.empty().append($footer);
}
}
var edit_mode = (this.mode === 'edit');
this.$buttons.find('.o_form_buttons_edit')
.toggleClass('o_hidden', !edit_mode);
this.$buttons.find('.o_form_buttons_view')
.toggleClass('o_hidden', edit_mode);
// 需要等到dom加载完在执行逻辑
$(document).ready(() => {
// 新增条件,用来切换自定义按钮的显示和隐藏
[].forEach.call(document.querySelectorAll('.m-form-edit-hidden'), element => {
$(element).toggleClass('o_hidden', edit_mode);
});
[].forEach.call($('.m-form-view-hidden'), element => {
$(element).toggleClass('o_hidden', !edit_mode);
})
});
}
},
在xml视图需要根据视图模式隐藏或显示的按钮或字段,增加自定义的样式类 m-form-view-hidden m-form-edit-hidden
// 只读模式隐藏 m-form-view-hidden
<button name="go_to_list" class="m-form-view-hidden" type="object" string="取消" data-actionState="m-noSave"/>
// 编辑模式隐藏 m-form-edit-hidden
<button name="go_to_list" class="m-form-edit-hidden" type="object" string="返回" data-actionState="m-noSave"/>
5. 实现保存但不验证功能
- 说明:在有些时候是需要odoo保存数据,但是不想进行验证数据,例如保存草稿,这就不需要对必填字段进行验证,这时就需要跳过odoo 的验证直接保存
canBeSaved: function (recordID) {
var fieldNames = this.renderer.canBeSaved(recordID || this.handle);
// 新增属性判断,用来跳过验证,直接保存
fieldNames.length = clickDataAction === 'm-no-valid' ? 0 : fieldNames.length
if (fieldNames.length) {
this._notifyInvalidFields(fieldNames);
return false;
}
return true;
},
在xml 增加自定义属性 m-no-valid
<button name="save_contract" class="m-form-view-hidden" type="object" string="保存草稿" data-actionState="m-no-valid"/>