OpenERP(查看) - 改变选择字段的外观? (又名单选按钮)

时间:2014-03-24 14:21:22

标签: python view field selection openerp

有没有办法改变selection字段的外观?我需要将其更改为看起来像一堆布尔字段(技术上它将是一个字段,而不是多个布尔字段。只有外观会改变)?

它应该看起来像这样(看起来有多个字段,但从技术上讲它应该只有一个):

enter image description here

它应该像选择字段一样起作用 - 你只能选择一个值。有可能吗?

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

似乎可以在OpenERP 8上使用小部件(使用无线电小部件作为选择字段)。所以我认为可以在OpenERP 7中移动这样的功能。

2 个答案:

答案 0 :(得分: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> 

P.S。您可以在OpenERP主干版本中找到原始代码。

答案 1 :(得分:0)

是。这是可能的。你可以在openerp本身看到一个类似的例子。转到settings / users /access rights tab。在那里,您可以看到用于添加组的所有布尔和选择字段列表。实际上,它是一个与res.groups相关的many2many字段,并且它的视图被修改为以下方式:所有被继承且属于同一类别的组将被视为选择列表,而所有其他组将被视为布尔值。请检查base/ res/res_users.py文件中的代码。希望它对你有所帮助。