在odoo13 实现from视图按钮的一些定制化开发

854 阅读3分钟

需求说明:

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"/>