Odoo:JSON:继承视图,有条件地隐藏编辑按钮

时间:2015-09-23 08:28:18

标签: javascript json xml xpath openerp

我试图在Odoo中隐藏物料清单中的编辑按钮,具体取决于布尔值的状态。

我设法通过以下代码永久删除编辑按钮:

<xpath expr="//form[@string='Bill of Material']" position="attributes">
    <attribute name="edit">false</attribute>
</xpath>

现在我尝试使用这样的布尔值使其成为条件:

<xpath expr="//form[@string='Bill of Material']" position="attributes">
    <attribute name="edit">true:realman==True;false:realman==False;</attribute>
</xpath>

这会出错:

  

SyntaxError:JSON.parse:后面的意外非空格字符   JSON数据的第1行第5列的JSON数据

当我查找javascript文件时,我发现这是处理编辑属性的代码:

/**
 * Return whether the user can perform the action ('create', 'edit', 'delete') in this view.
 * An action is disabled by setting the corresponding attribute in the view's main element,
 * like: <form string="" create="false" edit="false" delete="false">
 */
is_action_enabled: function(action) {
    var attrs = this.fields_view.arch.attrs;
    return (action in attrs) ? JSON.parse(attrs[action]) : true;
},

我想当我的表单中的布尔falsevar attrs时,我需要在realman中获得False

我已经尝试用大括号写出来,就像这个问题中的答案一样:JSON.parse unexpected character error

这也给了我错误。

为什么我会收到此错误以及如何解决此问题?这只是语法错误还是有更多问题?

3 个答案:

答案 0 :(得分:1)

我通过使用field_view_get成功地解决了类似的问题,但仅当“realman”传递到上下文中时

GET /api/home

如果realman是一个字段,你需要启用/禁用编辑按钮,那么我担心这是不可能的。 AFAIK。

答案 1 :(得分:0)

正如Alessandro Ruffolo所述,他的解决方案不适用于按钮/操作,具体取决于型号的字段。我已经用Javascript编写了解决方案。它适用于ODOO 10(也应该在9中,但我还没有测试过它)。

示例是检查模型的字段&#34; state&#34;。如果它有价值&#34; noEditable&#34;编辑和删除按钮会隐藏。覆盖is_action_enabled是不够的,因为当没有加载datarecord时ODOO正在调用该方法。因此,在方法do_show和reload后,需要再次检查它。

// modify default form view for custom model my.custom.model
odoo.define('my.custom_model_form', function (require) {
    "use strict";

    var FormView = require('web.FormView');

    FormView.include({
        is_action_enabled: function(action) {
            if (this.model == "my.custom.model" && this.datarecord && this.datarecord.state == "noEditable" &&
                (action == 'delete' || action == 'edit')) {
                // don't allow edit nor delete
                return false;
            }
            // call default is_action_enabled method
            return this._super.apply(this, arguments);
        },
        deleteItem: null,
        deleteItemIdx: null,
        deleteItemShown: true,
        reinit_actions: function() {
            // apply for my custom model only
            if (this.model == "my.custom.model") {
                // hide/show edit button
                if (this.is_action_enabled('edit')) {
                    this.$buttons.find(".o_form_button_edit").show();
                } else {
                    this.$buttons.find(".o_form_button_edit").hide();
                }

                // find delete item in sidebar's items
                if (!this.deleteItem) {
                    // form view is adding it to "other"
                    if (this.sidebar && this.sidebar.items && this.sidebar.items.other) {
                        for (var i = 0; i < this.sidebar.items.other.length; i++) {
                            // on_button_delete is used as callback for delete button
                            // it's ugly way to find out which one is delete button, haven't found better way
                            if (this.sidebar.items.other[i].callback == this.on_button_delete) {
                                this.deleteItem = this.sidebar.items.other[i];
                                this.deleteItemIdx = i;
                                break;
                            }
                        }
                    }
                }
                // hide/show delete button
                if (this.is_action_enabled('delete')) {
                    if (!this.deleteItemShown) {
                        this.deleteItemShown = true;
                        // add delete item to sidebar's items
                        this.sidebar.items.other.splice(this.deleteItemIdx, 0, this.deleteItem);
                    }
                } else
                if (this.deleteItemShown) {
                    this.deleteItemShown = false;
                    // remove delete item from sidebar's items
                    this.sidebar.items.other.splice(this.deleteItemIdx, 1);
                }
            }
        },
        reload: function() {
            var self = this;
            // run reinit_actions after reload finish
            return this._super.apply(this, arguments).done(function() {
                 self.reinit_actions();
            });
        },
        do_show: function() {
            var self = this;
            // run reinit_actions after do_show finish
            return this._super.apply(this, arguments).done(function() {
                 self.reinit_actions();
            });
        }
    });

});

答案 2 :(得分:0)

我相信具有计算字段的解决方案可以简化这些情况。

您可以继承物料清单表格并将其覆盖。将不可见条件指向要在其中创建验证的计算字段。请注意,即使将计算的字段隐藏起来,也必须将其添加到窗体中。

<xpath expr="//form[@string='Bill of Material']" position="attributes">
    <attribute name="attrs">
        {'invisible': [('show_bm_button', '=', False)]}
    </attribute>
    <field name="show_bm_button" invisible="1"/>
</xpath>

然后在python中覆盖该对象并添加新的计算字段。

class ProductTemplate(models.Model):
    _inherit = 'product.template'

    show_bm_button = fields.Boolean(
            compute='_compute_show_bm_button', 
            readonly=False, store=False
        )

    # @api.depends('realman') #Just as a sample, if you have this field in this Model
    def _compute_show_bm_button(self):
        for record in self:
            realman = self._context.get('realman') or True
            if realman:
                record.show_bm_button = True
            else:
                record.show_bm_button = False