`` element. Since 13.0, the ``colors`` attribute is no
+ longer in the RelaxNG schema of the tree view, so we can't use it anymore.
+ This feature has then been dropped, but could be reimplement in another way.
diff --git a/web_tree_dynamic_colored_field/readme/USAGE.rst b/web_tree_dynamic_colored_field/readme/USAGE.rst
new file mode 100644
index 000000000..2be4517c5
--- /dev/null
+++ b/web_tree_dynamic_colored_field/readme/USAGE.rst
@@ -0,0 +1,55 @@
+* In the tree view declaration, put ``options='{"bg_color": "red: customer==True"}`` attribute in the ``field`` tag::
+
+ ...
+
+
+ ...
+
+ ...
+
+
+ ...
+
+ With this example, column which renders 'name' field will have its background colored in red.
+
+* In the tree view declaration, put ``options='{"fg_color": "white:customer == True"}'`` attribute in the ``field`` tag::
+
+ ...
+
+
+ ...
+
+ ...
+
+
+ ...
+
+ With this example, column which renders 'name' field will have its text colored in white on a customer records.
+
+* If you want to use more than one color, you can split the attributes using ';':
+
+.. code::
+
+ options='{"fg_color": "red:red_color == True; green:green_color == True"}'
+
+Example:
+
+.. code:: xml
+
+ ...
+
+
+ ...
+
+ ...
+
+
+ ...
+
+ With this example, the content of the field named `my_color` will be used to
+ populate the `my_color` CSS value. Use a function field to return whichever
+ color you want depending on the other record values. Note that this
+ overrides the rest of `colors` attributes, and that you need the tree
+ to load your field in the first place by adding it as invisible field.
+
+**Note that you should always use single quotes for fields' ``options`` and wrap nested values in double quotes since ``options`` is a JSON object.**
diff --git a/web_tree_dynamic_colored_field/static/description/icon.png b/web_tree_dynamic_colored_field/static/description/icon.png
new file mode 100644
index 000000000..3a0328b51
Binary files /dev/null and b/web_tree_dynamic_colored_field/static/description/icon.png differ
diff --git a/web_tree_dynamic_colored_field/static/description/index.html b/web_tree_dynamic_colored_field/static/description/index.html
new file mode 100644
index 000000000..d5fcf9a7a
--- /dev/null
+++ b/web_tree_dynamic_colored_field/static/description/index.html
@@ -0,0 +1,497 @@
+
+
+
+
+
+
+Colorize field in tree views
+
+
+
+
+
Colorize field in tree views
+
+
+

+
This module aims to add support for dynamically coloring fields in tree view
+according to data in the record.
+
It provides attributes on fields with the similar syntax as the colors attribute
+in tree tags.
+
Further, it provides a color_field attribute on tree tags’s colors to use
+a field’s value as color.
+
+
Features
+
+- Add attribute bg_color on field’s options to color background of a cell in tree view
+- Add attribute fg_color on field’s options to change text color of a cell in tree view
+- Add attribute color_field on the tree element’s colors to use as color
+
+
Table of contents
+
+
+
Usage
+
+In the tree view declaration, put options='{"bg_color": "red: customer==True"} attribute in the field tag:
+
+...
+<field name="arch" type="xml">
+ <tree string="View name">
+ ...
+ <field name="name" options='{"bg_color": "red: customer == True"}'/>
+ ...
+ </tree>
+</field>
+...
+
+With this example, column which renders 'name' field will have its background colored in red.
+
+
+In the tree view declaration, put options='{"fg_color": "white:customer == True"}' attribute in the field tag:
+
+...
+<field name="arch" type="xml">
+ <tree string="View name">
+ ...
+ <field name="name" options='{"fg_color": "white:customer == True"}'/>
+ ...
+ </tree>
+</field>
+...
+
+With this example, column which renders 'name' field will have its text colored in white on a customer records.
+
+
+In the tree view declaration, use options='"color_field": "my_color"' attribute in the tree tag:
+
+...
+<field name="arch" type="xml">
+ <tree string="View name" colors="color_field: my_color" >
+ ...
+ <field name="my_color" invisible="1"/>
+ ...
+ </tree>
+</field>
+...
+
+
+If you want to use more than one color, you can split the attributes using ‘;’:
+
+
+
+options='{"fg_color": "red:red_color == True; green:green_color == True"}'
+
+
Example:
+
+...
+ <field name="arch" type="xml">
+ <tree string="View name">
+ ...
+ <field name="name" options='{"fg_color": "red:red_color == True; green:green_color == True"}'/>
+ ...
+ </tree>
+ </field>
+ ...
+
+ With this example, the content of the field named `my_color` will be used to
+ populate the `my_color` CSS value. Use a function field to return whichever
+ color you want depending on the other record values. Note that this
+ overrides the rest of `colors` attributes, and that you need the tree
+ to load your field in the first place by adding it as invisible field.
+
+
Note that you should always use single quotes for fields’ ``options`` and wrap nested values in double quotes since ``options`` is a JSON object.
+
+
+
Bug Tracker
+
Bugs are tracked on GitHub Issues.
+In case of trouble, please check there if your issue has already been reported.
+If you spotted it first, help us smashing it by providing a detailed and welcomed
+feedback.
+
Do not contact contributors directly about support or help with technical issues.
+
+
+
Credits
+
+
+
+
Maintainers
+
This module is maintained by the OCA.
+

+
OCA, or the Odoo Community Association, is a nonprofit organization whose
+mission is to support the collaborative development of Odoo features and
+promote its widespread use.
+
This module is part of the OCA/web project on GitHub.
+
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
+
+
+
+
+
diff --git a/web_tree_dynamic_colored_field/static/src/js/web_tree_dynamic_colored_field.js b/web_tree_dynamic_colored_field/static/src/js/web_tree_dynamic_colored_field.js
new file mode 100644
index 000000000..2b9812de5
--- /dev/null
+++ b/web_tree_dynamic_colored_field/static/src/js/web_tree_dynamic_colored_field.js
@@ -0,0 +1,124 @@
+odoo.define("web_tree_dynamic_colored_field", function(require) {
+ "use strict";
+
+ var ListRenderer = require("web.ListRenderer");
+ var pyUtils = require("web.py_utils");
+ var py = window.py;
+
+ ListRenderer.include({
+ /**
+ * Colorize a cell during it's render
+ *
+ * @override
+ */
+ _renderBodyCell: function(record, node) {
+ var $td = this._super.apply(this, arguments);
+ var ctx = this.getEvalContext(record);
+ this.applyColorize($td, record, node, ctx);
+ return $td;
+ },
+
+ /**
+ * Colorize the current cell depending on expressions provided.
+ *
+ * @param {Element} $td a tag inside a table representing a list view
+ * @param {Object} record
+ * @param {Object} node an XML node (must be a )
+ * @param {Object} ctx evaluation context for the record
+ */
+ applyColorize: function($td, record, node, ctx) {
+ if (!node.attrs.options) {
+ return;
+ }
+ if (node.tag !== "field") {
+ return;
+ }
+ var nodeOptions = node.attrs.options;
+ if (!_.isObject(nodeOptions)) {
+ nodeOptions = pyUtils.py_eval(nodeOptions);
+ }
+ this.applyColorizeHelper($td, nodeOptions, node, "fg_color", "color", ctx);
+ this.applyColorizeHelper(
+ $td,
+ nodeOptions,
+ node,
+ "bg_color",
+ "background-color",
+ ctx
+ );
+ },
+ /**
+ * @param {Element} $td a tag inside a table representing a list view
+ * @param {Object} nodeOptions a mapping of nodeOptions parameters to the color itself
+ * @param {Object} node an XML node (must be a )
+ * @param {String} nodeAttribute an attribute of a node to apply a style onto
+ * @param {String} cssAttribute a real CSS-compatible attribute
+ * @param {Object} ctx evaluation context for the record
+ */
+ applyColorizeHelper: function(
+ $td,
+ nodeOptions,
+ node,
+ nodeAttribute,
+ cssAttribute,
+ ctx
+ ) {
+ if (nodeOptions[nodeAttribute]) {
+ var colors = _(nodeOptions[nodeAttribute].split(";"))
+ .chain()
+ .map(this.pairColors)
+ .value()
+ .filter(function CheckUndefined(value) {
+ return value !== undefined;
+ });
+ for (var i = 0, len = colors.length; i < len; ++i) {
+ var pair = colors[i],
+ color = pair[0],
+ expression = pair[1];
+ if (py.evaluate(expression, ctx).toJSON()) {
+ $td.css(cssAttribute, color);
+ }
+ }
+ }
+ },
+
+ /**
+ * Parse `: ` forms to
+ * evaluable expressions
+ *
+ * @param {String} pairColor `color: expression` pair
+ * @returns {Array} undefined or array of color, parsed expression,
+ * original expression
+ */
+ pairColors: function(pairColor) {
+ if (pairColor !== "") {
+ var pairList = pairColor.split(":"),
+ color = pairList[0],
+ // If one passes a bare color instead of an expression,
+ // then we consider that color is to be shown in any case
+ expression = pairList[1] ? pairList[1] : "True";
+ return [color, py.parse(py.tokenize(expression)), expression];
+ }
+ return undefined;
+ },
+ /**
+ * Construct domain evaluation context, mostly by passing
+ * record's fields's values to local scope.
+ *
+ * @param {Object} record a record to build a context from
+ * @returns {Object} evaluation context for the record
+ */
+ getEvalContext: function(record) {
+ var ctx = _.extend({}, record.data, pyUtils.context());
+ for (var key in ctx) {
+ var value = ctx[key];
+ if (ctx[key] instanceof moment) {
+ // Date/datetime fields are represented w/ Moment objects
+ // docs: https://momentjs.com/
+ ctx[key] = value.format("YYYY-MM-DD hh:mm:ss");
+ }
+ }
+ return ctx;
+ },
+ });
+});
diff --git a/web_tree_dynamic_colored_field/views/web_tree_dynamic_colored_field.xml b/web_tree_dynamic_colored_field/views/web_tree_dynamic_colored_field.xml
new file mode 100644
index 000000000..dbd9e43cd
--- /dev/null
+++ b/web_tree_dynamic_colored_field/views/web_tree_dynamic_colored_field.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
| |