summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYosua Nicolaus <yoni@odoo.com>2024-09-10 08:07:26 +0000
committerAllePilli <peal@odoo.com>2025-02-06 16:44:12 +0000
commit32ec059f5fe7325a7e2607d6349d9259357be1c4 (patch)
treed0fd77775ddf3bbc68f5f24d442db5514442f068
parentc7a60568d3ef77dc628e0534f5066157ffda2ba5 (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.js63
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,
+ }),
+})