odoo的编辑功能是一直存在的,当用户想在某种条件下不允许编辑字段,只能在fields上或者view上添加readonly的条件,但是当字段或者条件一多时控制难度就会变得很大,所以作为一个伸手党在网上去找是否有对应的js,可以控制前端的编辑按钮,但是很遗憾,虽然可以找到一些,但是在odoo15中并不适用,所以只能自己看看能不能搞出来;
通过debug调试获取定位到了web.FormController中的updateButtons函数,该函数是控制视图中的按钮的显示的,通过继承这个函数添加我们的隐藏逻辑;
odoo的js中有Domain的计算方法,通过调用对应的函数可以计算出我们的条件的真假
代码:
odoo.define('a_module.hide_edit_btn', function (require) {
"use strict";
var FormController = require('web.FormController');
var FormRenderer = require('web.FormRenderer');
var Domain = require('web.Domain');
FormController.include({
/**
* @private
*/
updateButtons: function () {
try {
this._super.apply(this, arguments);
var no_edit = this.controlPanelProps.action.context.form_no_edit
if (no_edit !== undefined) {
var result = new Domain(no_edit).compute(this.renderer.state.evalContext)
if (result === true) {
this.$buttons.find('.o_form_buttons_edit')
.toggleClass('o_hidden', result);
this.$buttons.find('.o_form_buttons_view')
.toggleClass('o_hidden', result);
}
this.activeActions.edit = !result
this.activeActions.create = !result
}
} catch (e) {
console.log(e)
}
},
});
FormRenderer.include({
_renderFieldWidget: function (node, record, options) {
if (!this.renderInvisible && node.attrs.modifiers.invisible === true) {
return $();
}
options = options || {};
var fieldName = node.attrs.name;
// Register the node-associated modifiers
var mode = options.mode || this.mode;
var modifiers = this._registerModifiers(node, record, null, options);
// Initialize and register the widget
// Readonly status is known as the modifiers have just been registered
var Widget = record.fieldsInfo[this.viewType][fieldName].Widget;
const legacy = !(Widget.prototype instanceof owl.Component);
const widgetOptions = {
// Distinct readonly from renderer and readonly from modifier,
// renderer can be readonly while modifier not.
// This is needed as modifiers are set after first render
hasReadonlyModifier: modifiers.readonly || this.viewEditable === false || this._getViewMode(),
mode: modifiers.readonly ? 'readonly' : mode,
viewType: this.viewType,
};
let widget;
if (legacy) {
widget = new Widget(this, fieldName, record, widgetOptions);
} else {
widget = new FieldWrapper(this, Widget, {
fieldName,
record,
options: widgetOptions,
});
}
// Register the widget so that it can easily be found again
if (this.allFieldWidgets[record.id] === undefined) {
this.allFieldWidgets[record.id] = [];
}
this.allFieldWidgets[record.id].push(widget);
widget.__node = node; // TODO get rid of this if possible one day
// Prepare widget rendering and save the related promise
var $el = $('<div>');
let def;
if (legacy) {
def = widget._widgetRenderAndInsert(function () {
});
} else {
def = widget.mount(document.createDocumentFragment());
}
this.defs.push(def);
// Update the modifiers registration by associating the widget and by
// giving the modifiers options now (as the potential callback is
// associated to new widget)
var self = this;
def.then(function () {
// when the caller of renderFieldWidget uses something like
// this.renderFieldWidget(...).addClass(...), the class is added on
// the temporary div and not on the actual element that will be
// rendered. As we do not return a promise and some callers cannot
// wait for this.defs, we copy those classnames to the final element.
widget.$el.addClass($el.attr('class'));
$el.replaceWith(widget.$el);
self._registerModifiers(node, record, widget, {
callback: function (element, modifiers, record) {
element.$el.toggleClass('o_field_empty', !!(
record.data.id &&
(modifiers.readonly || mode === 'readonly') &&
element.widget.isEmpty()
));
},
keepBaseMode: !!options.keepBaseMode,
mode: mode,
});
self._postProcessField(widget, node);
});
return $el;
},
_getViewMode: function () {
if (this.state.context.form_no_edit) {
var result = new Domain(this.state.context.form_no_edit).compute(this.state.evalContext);
if (result === true) {
return true
}
}
return false
},
})
});
通过在action的context中定义{"form_no_edit": 条件}就能实现隐藏编辑按钮,将所有的widget置为不可快速编辑

2. 由于odoo明细行中会在非编辑状态下出现“添加明细”/“添加节"等快捷按钮,看起来有点不舒服,所以也改动了一下,在非编辑状态下,明细行不出现快捷添加等按钮
odoo.define('a_module.HideListRenderer', function (require) {
"use strict";
var ListRenderer = require('web.ListRenderer');
ListRenderer.include({
_render: function () {
if (this.editable === false){
this.addCreateLine = false
this.addCreateLineInGroups = false
this.addTrashIcon = false
}
return this._super.apply(this, arguments);
},
});
});
白嫖多了,偶然也要被嫖一下才行,学暴龙哥话斋:整天想着自己一个人爽怎么行呢,要给别人爽一下嘛