diff options
| author | Yosua Nicolaus <yoni@odoo.com> | 2024-09-10 08:07:26 +0000 |
|---|---|---|
| committer | AllePilli <peal@odoo.com> | 2025-02-06 16:44:12 +0000 |
| commit | 32ec059f5fe7325a7e2607d6349d9259357be1c4 (patch) | |
| tree | d0fd77775ddf3bbc68f5f24d442db5514442f068 | |
| parent | c7a60568d3ef77dc628e0534f5066157ffda2ba5 (diff) | |
[IMP] account: add dynamic selection field
This commit creates a new widget "dynamic_selection", that enables us to
create selection fields with dynamic options on the views.
To make it possible, we need 2 fields; one as the string of available
options separated by comma, and the other as the actual selection field
we want to make dynamic.
The available field are passed in the xml through the options of the
widget. Of course, the mentioned available must also be present (usually
with invisible=1) for this field to function. Otherwise, it will just
show an empty selection.
Task-id: 3358316
X-original-commit: 0dcbfe13a2da634bc5bbd2e8862820387b090d22
Part-of: odoo/odoo#196201
Signed-off-by: Laurent Smet (las) <las@odoo.com>
Signed-off-by: Allesio Pellicciotta (peal) <peal@odoo.com>
| -rw-r--r-- | addons/account/static/src/components/dynamic_selection/dynamic_selection.js | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/addons/account/static/src/components/dynamic_selection/dynamic_selection.js b/addons/account/static/src/components/dynamic_selection/dynamic_selection.js new file mode 100644 index 00000000000..1a85d567b9e --- /dev/null +++ b/addons/account/static/src/components/dynamic_selection/dynamic_selection.js @@ -0,0 +1,63 @@ +/** @odoo-module **/ + +import { registry } from "@web/core/registry"; +import { SelectionField, selectionField } from "@web/views/fields/selection/selection_field"; + +export class DynamicSelectionField extends SelectionField { + + static props = { + ...SelectionField.props, + available_field: { type: String }, + } + + get availableOptions() { + return this.props.record.data[this.props.available_field]?.split(",") || []; + } + + /** + * Filter the options with the accepted available options. + * @override + */ + get options() { + const availableOptions = this.availableOptions; + return super.options.filter(x => availableOptions.includes(x[0])); + } + + /** + * In dynamic selection field, sometimes we can have no options available. + * This override handles that case by adding optional chaining when accessing the found options. + * @override + */ + get string() { + if (this.type === "selection") { + return this.props.record.data[this.props.name] !== false + ? this.options.find((o) => o[0] === this.props.record.data[this.props.name])?.[1] + : ""; + } + return super.string; + } + +} + +/* +EXAMPLE USAGE: + +In python: +the_available_field = fields.Char() # string of comma separated available selection field keys +the_selection_field = fields.Selection([ ... ]) + +In the views: +<field name="the_available_field" column_invisible="1"/> +<field name="the_selection_field" + widget="dynamic_selection" + options="{'available_field': 'the_available_field'}"/> + */ + +registry.category("fields").add("dynamic_selection", { + ...selectionField, + component: DynamicSelectionField, + extractProps: (fieldInfo, dynamicInfo) => ({ + ...selectionField.extractProps(fieldInfo, dynamicInfo), + available_field: fieldInfo.options.available_field, + }), +}) |
