OpenERP(视图)- 如何更改选择字段的外观?(即单选按钮)
有没有办法改变 selection
字段的外观?我想把它改成看起来像一堆布尔字段(技术上来说,它其实还是一个字段,而不是多个布尔字段。只是外观会改变)?
它应该看起来像这样(虽然看起来像有多个字段,但实际上应该只有一个):
而且它的功能应该和选择字段一样——只能选择一个值。这样做可能吗?
更新: 找到了这个 - http://help.openerp.com/question/29061/how-to-add-radio-button-widget/
看起来在 OpenERP 8 中可以通过小部件实现这个功能(使用单选按钮小部件来处理选择字段)。所以我觉得在 OpenERP 7 中也可能实现这样的功能。
2 个回答
是的,这是可能的。你可以在openerp中看到一个类似的例子。去 设置 / 用户 / 权限设置标签
。在那里你可以看到所有的布尔值和选择字段的列表,用于添加用户组。实际上,这个字段是一个多对多的字段,和res.groups有关,它的显示方式被修改成这样的:所有继承的组和同一类别下的组会以选择列表的形式展示,而其他的则以布尔值的形式展示。请查看 base/ res/res_users.py
文件中的代码。希望这对你有帮助。
我成功把 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.js
(web_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 的主版本中找到原始代码。