OpenERP(视图)- 如何更改选择字段的外观?(即单选按钮)

2 投票
2 回答
3244 浏览
提问于 2025-04-17 23:40

有没有办法改变 selection 字段的外观?我想把它改成看起来像一堆布尔字段(技术上来说,它其实还是一个字段,而不是多个布尔字段。只是外观会改变)?

它应该看起来像这样(虽然看起来像有多个字段,但实际上应该只有一个):

在这里输入图片描述

而且它的功能应该和选择字段一样——只能选择一个值。这样做可能吗?

更新: 找到了这个 - http://help.openerp.com/question/29061/how-to-add-radio-button-widget/

看起来在 OpenERP 8 中可以通过小部件实现这个功能(使用单选按钮小部件来处理选择字段)。所以我觉得在 OpenERP 7 中也可能实现这样的功能。

2 个回答

0

是的,这是可能的。你可以在openerp中看到一个类似的例子。去 设置 / 用户 / 权限设置标签。在那里你可以看到所有的布尔值和选择字段的列表,用于添加用户组。实际上,这个字段是一个多对多的字段,和res.groups有关,它的显示方式被修改成这样的:所有继承的组和同一类别下的组会以选择列表的形式展示,而其他的则以布尔值的形式展示。请查看 base/ res/res_users.py 文件中的代码。希望这对你有帮助。

3

我成功把 radio 小部件从 OpenERP 8 移到了 OpenERP 7。现在我来分享一下我是怎么做到的,也许有人会需要这个方法。

其实你只需要两个主要的文件,一个是 js 文件,另一个是 xml 文件(还需要一个空的 __init__.py 文件,因为如果没有这个文件,OpenERP 会报错说找不到这个模块)。

__openerp__.py 文件里:

 'js': ['static/src/js/widget_radio.js'],
'qweb': ['static/src/xml/widget_radio.xml'],

widget_radio.jsweb_widget_radio 是这个插件的名字):

openerp.web_widget_radio = function (instance)
{
    instance.web.form.widgets.add('radio', 'instance.web_widget_radio.FieldRadio');
    instance.web_widget_radio.FieldRadio = instance.web.form.AbstractField.extend(instance.web.form.ReinitializeFieldMixin, {
        template: 'FieldRadio',
        events: {
            'click input': 'click_change_value'
        },
        init: function(field_manager, node) {
            /* Radio button widget: Attributes options:
            * - "horizontal" to display in column
            * - "no_radiolabel" don't display text values
            */
            this._super(field_manager, node);
            this.selection = _.clone(this.field.selection) || [];
            this.domain = false;
        },
        initialize_content: function () {
            this.uniqueId = _.uniqueId("radio");
            this.on("change:effective_readonly", this, this.render_value);
            this.field_manager.on("view_content_has_changed", this, this.get_selection);
            this.get_selection();
        },
        click_change_value: function (event) {
            var val = $(event.target).val();
            val = this.field.type == "selection" ? val : +val;
            if (val == this.get_value()) {
                this.set_value(false);
            } else {
                this.set_value(val);
            }
        },
        /** Get the selection and render it
         *  selection: [[identifier, value_to_display], ...]
         *  For selection fields: this is directly given by this.field.selection
         *  For many2one fields:  perform a search on the relation of the many2one field
         */
        get_selection: function() {
            var self = this;
            var selection = [];
            var def = $.Deferred();
            if (self.field.type == "many2one") {
                var domain = instance.web.pyeval.eval('domain', this.build_domain()) || [];
                if (! _.isEqual(self.domain, domain)) {
                    self.domain = domain;
                    var ds = new instance.web.DataSetStatic(self, self.field.relation, self.build_context());
                    ds.call('search', [self.domain])
                        .then(function (records) {
                            ds.name_get(records).then(function (records) {
                                selection = records;
                                def.resolve();
                            });
                        });
                } else {
                    selection = self.selection;
                    def.resolve();
                }
            }
            else if (self.field.type == "selection") {
                selection = self.field.selection || [];
                def.resolve();
            }
            return def.then(function () {
                if (! _.isEqual(selection, self.selection)) {
                    self.selection = _.clone(selection);
                    self.renderElement();
                    self.render_value();
                }
            });
        },
        set_value: function (value_) {
            if (value_) {
                if (this.field.type == "selection") {
                    value_ = _.find(this.field.selection, function (sel) { return sel[0] == value_;});
                }
                else if (!this.selection.length) {
                    this.selection = [value_];
                }
            }
            this._super(value_);
        },
        get_value: function () {
            var value = this.get('value');
            return value instanceof Array ? value[0] : value;
        },
        render_value: function () {
            var self = this;
            this.$el.toggleClass("oe_readonly", this.get('effective_readonly'));
            this.$("input:checked").prop("checked", false);
            if (this.get_value()) {
                this.$("input").filter(function () {return this.value == self.get_value();}).prop("checked", true);
                this.$(".oe_radio_readonly").text(this.get('value') ? this.get('value')[1] : "");
            }
        }
    });
};

widget_radio.xml

<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
    <t t-name="FieldRadio">
        <span t-attf-class="oe_form_field oe_form_field_radio #{widget.options.horizontal ? 'oe_horizontal' : 'oe_vertical'}" t-att-style="widget.node.attrs.style">
            <span t-if="!widget.get('effective_readonly')">
                <t t-if="widget.options.horizontal">
                    <t t-set="width" t-value="Math.floor(100 / widget.selection.length)"/>
                    <t t-if="!widget.options.no_radiolabel">
                        <t t-foreach="widget.selection" t-as="selection">
                            <label t-att-for="widget.uniqueId + '_' + selection[0]" t-att-style="'width: ' + width + '%;'"><t t-esc="selection[1]"/></label>
                        </t>
                        <br/>
                    </t>
                    <t t-foreach="widget.selection" t-as="selection">
                        <div t-att-style="'width: ' + width + '%;'">
                            <span class="oe_radio_input"><input type="radio" t-att-name="widget.uniqueId" t-att-id="widget.uniqueId + '_' + selection[0]" t-att-value="selection[0]"/></span>
                        </div>
                    </t>
                </t>
                <t t-if="!widget.options.horizontal">
                    <t t-foreach="widget.selection" t-as="selection">
                        <div>
                            <span class="oe_radio_input"><input type="radio" t-att-id="widget.uniqueId + '_' + selection[0]" t-att-name="widget.uniqueId" t-att-value="selection[0]"/></span><label t-if="!widget.options.no_radiolabel" t-att-for="widget.uniqueId + '_' + selection[0]"><t t-esc="selection[1]"/></label>
                        </div>
                    </t>
                </t>
            </span>
            <span t-if="widget.get('effective_readonly')" class="oe_radio_readonly"><t t-esc="widget.get('value')[1]"/></span>
        </span>
    </t>
</templates> 

附注: 你可以在 OpenERP 的主版本中找到原始代码。

撰写回答