Odoo 提供了多种字段小部件,用于在用户界面中显示不同类型的数据。但是,在某些情况下,您可能需要自定义现有字段小部件或创建新字段小部件以满足您的特定需求。
示例
让我们创建一个名为 boolean_badge 的自定义布尔字段小部件。此小部件将显示带有文本“是”或“否”的徽章,具体取决于字段的值。
要创建小部件,我们首先需要在模块的 static/src/js 目录中创建一个新的 JavaScript 文件。在此文件中,我们将从 @web/views/fields/standard_field_props 模块导入 standardFieldProps 对象。此对象包含一组所有字段小部件通用的标准 props。我们还将从 Owl 库中导入 Component 类。
import { registry } from "@web/core/registry";
import { standardFieldProps } from "@web/views/fields/standard_field_props";
const { Component } = owl;
接下来,我们需要定义一个名为 BooleanBadge 的新类,该类扩展了 Component 类。此类将包含渲染徽章和处理用户交互的逻辑。
类 BooleanBadge 扩展了组件 {
setup(){
this.trueValue = 'Yes'
this.falseValue = 'No'
this.trueColor = 'green'
this.falseColor = 'red'
this.defaultColor = 'white'
}
updateValue(val){
this.props.update(val);
}
}
在 setup() 方法中,我们设置 trueValue、falseValue、trueColor、falseColor 和 defaultColor 属性的默认值。我们还可以使用 setup() 方法来初始化小部件所需的任何其他状态。
当字段的值发生变化时,将调用 updateValue() 方法。此方法更新小部件的状态并重新呈现它。
现在我们已经定义了小部件类,我们需要将其注册到 Odoo。为此,我们将以下代码添加到 JavaScript 文件的末尾。
BoolBadge.template = "BoolBadge"
BoolBadge.props = standardFieldProps
BoolBadge.supportedTypes = ["boolean"]
registry.category("fields").add("boolean_badge",BoolBadge)
template 属性指定将用于呈现小部件的模板文件的名称。 props 属性指定小部件接受的属性。supportedTypes 属性指定小部件可以使用的字段类型。
最后,我们需要为小部件创建模板文件。在模块的 static/src/xml 目录中创建一个名为 BooleanBadge.xml 的新文件。在此文件中添加以下代码:
<?xml version="1.0" encoding="UTF-8" ?>
<templates>
<t t-name="BooleanBadge" owl="1">
<span class="badge rounded-pill m-2 p-2 border"
t-att-class="props.value ? 'text-white' : 'text-black'
t-esc="trueValue"
t-attf-style="background-color: {{ props.value ? trueColor : defaultColor}}"
t-on-click="() => this.updateValue(true)"/>
<span class="badge rounded-pill m-2 p-2 border"
t-att-class="props.value ? 'text-black' : 'text-white'"
t-esc="falseValue"
t-attf-style="background-color: {{ props.value ? defaultColor : falseColor}}"
t-on-click="() => this.updateValue(false)"/>
</t>
</templates>
此模板将根据字段的值显示带有文本“是”或“否”的徽章。徽章的背景颜色将由 trueColor 或 falseColor 属性决定,具体取决于字段的值。
创建小部件的 JavaScript 和 XML 文件后,即可在 Odoo 视图中使用它们。要将小部件添加到字段,只需将以下属性添加到该字段:
widget="boolean_badge"
现在,让我们将这个小部件添加到产品模板页面内的测试字段。
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="product_template_only_form_view" model="ir.ui.view">
<field name="name">product.template.inherit.coc</field>
<field name="model">product.template</field>
<field name="inherit_id"
ref="product.product_template_only_form_view"/>
<field name="arch" type="xml">
<field name="detailed_type" position="after">
<field name="test_field" widget="boolean_badge"/>
</field>
</field>
</record>
</odoo>
现在,该字段如下所示
扩展 BooleanBadge 小部件以添加选项
您可以扩展 BooleanBadge 小部件以添加选项,以便自定义徽章的外观和显示的文本。例如,您可以添加一个选项来更改徽章的大小、徽章文本的字体或徽章的边框。
要扩展 BooleanBadge 小部件以添加选项,您可以在模块的 static/src/js 目录中创建一个新的 JavaScript 文件。然后,从现有模块导入 BooleanBadge 小部件。定义一个扩展 BooleanBadge 小部件的新类。向您的小部件添加一个新 prop 来存储选项的值。为您的选项实现任何自定义行为,并在注册表模块中注册您的新小部件。
例子
/** @odoo-module */
import { registry } from "@web/core/registry";
import { standardFieldProps } from "@web/views/fields/standard_field_props";
import { BoolBadge } from "@custom_widget/js/bool_badge";
export class CustomBoolBadge extends BoolBadge {
setup() {
super.setup();
const options = this.props.options || {};
this.trueValue = options.trueValue || 'Yes';
this.falseValue = options.falseValue || 'No';
this.trueColor = options.trueColor || 'green';
this.falseColor = options.falseColor || 'red';
this.defaultColor = options.defaultColor || 'white';
}
}
CustomBoolBadge.props = {
...standardFieldProps,
options: { type: Object, optional: true}
}
CustomBoolBadge.extractProps = ({attrs}) => {
return {options: attrs.options}
}
registry.category("fields").add("custom_bool_badge", CustomBoolBadge);
要使用 CustomBoolBadge 小部件,您可以像添加任何其他字段小部件一样将其添加到视图中。例如,以下代码会将 CustomBoolBadge 小部件添加到 test_field 字段:
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="product_template_only_form_view" model="ir.ui.view">
<field name="name">product.template.inherit.coc</field>
<field name="model">product.template</field>
<field name="inherit_id"
ref="product.product_template_only_form_view"/>
<field name="arch" type="xml">
<field name="detailed_type" position="after">
<field name="test_field" widget="custom_bool_badge" options="{'trueColor': 'blue', 'trueValue': 'Yes',
'falseColor': 'yellow', 'falseValue': 'No'}"/>
</field>
</field>
</record>
</odoo>
其中,我们给出了 trueColor 为蓝色、falseColor 为黄色以及相应的值。让我们看看结果。
现在我们可以看到颜色分别变成了蓝色和黄色。