skip to Main Content

I want to change the color of a progress bar that is in a one2many line in an Transient Model.
My idea was to create a custom widget from the progressbar widget and then add a method that gets the color value and the script changes the color.
The color value will be stored in a computed field that is invisible in the line.

So my first try was to create the custom widget, but that didn’t work.

odoo.define('your_module_name.custom_progressbar', function (require) {
"use strict";

var field_registry = require('web.field_registry');
var FieldProgressBar = require('web.basic_fields').FieldProgressBar;

var CustomProgressBar = FieldProgressBar.extend({
    template: FieldProgressBar.prototype.template,
    // Your custom methods and properties here
});

field_registry.add('custom_progressbar', CustomProgressBar);

return CustomProgressBar;

});

I am not very good at Java coding, and the web was no help in that case.
The problem is that I get a message in the browser dev tools:

web.assets_backend.min.js:2970 Missing widget: CustomProgressBar for field of type integer

At this point, I have not tried to make the part with the colors until the original widget is shown in my view.

and the widget is not shown.

And yes the .js is in manifast and will also run

Can someone help me with that?

2

Answers


  1. Chosen as BEST ANSWER

    So this is my latest code:

    /** @odoo-module **/
    
    import { registry } from "@web/core/registry";
    import { ProgressBarField } from "@web/views/fields/progress_bar/progress_bar_field";
    
    console.log("Run CustomProgressBarField");
    
    export class CustomProgressBarField extends ProgressBarField {
        template = 'chn_event_availability_manager.custom_progressbar_template';
    
        constructor() {
               super(...arguments);
               this.color = this.getColorValue(this.props);
               console.log("Run constructor");
               console.log('Color:', this.color);
        }
    
       renderElement() {
            super.renderElement(...arguments);
            this.el.querySelector('.o_progressbar .o_progress .o_progress_bar').style.backgroundColor = this.color;
            const colorFieldInput = this.el.querySelector('.o_field_widget[name="color_field"]');
            if (colorFieldInput) {
                colorFieldInput.addEventListener('change', this._onColorFieldChange.bind(this));
            }
        }
    
        _onColorFieldChange(event) {
            this.color = event.target.value;
            this.renderElement();
        }
    
        getColorValue(p) {
           return p.colorField || '#007bff';  // Standardfarbe ist Blau
        }
    }
    
    CustomProgressBarField.props = {
        ...ProgressBarField.props,
        colorField: { type: String, optional: true },  // Hinzufügen der colorField-Option
    };
    
    CustomProgressBarField.extractProps = ({ attrs }) => {
        const parentProps = ProgressBarField.extractProps({ attrs });  // Extrahieren Sie die Eigenschaften von der übergeordneten Methode
        return {
            ...parentProps,  // Fügen Sie die extrahierten Eigenschaften von der übergeordneten Methode hinzu
            colorField: attrs.options.color_field,  // Extrahieren Sie die neue Eigenschaft 'colorField'
        };
    };
    
    registry.category("fields").add("custom_progressbar", CustomProgressBarField);

    Now the problem I am trying to solve is that the function:

    RenderElement() is not executed, I do not know why, so the color is not transferred to the progress bar.

    But I am getting the correct value in the constructor().

    of the template:

    <?xml version="1.0" encoding="UTF-8"?>
    <odoo>
        <template id="custom_progressbar_template" inherit_id="web.ProgressBarField" name="Custom Progress Bar">
            <xpath expr="//div[@class='o_progress']" position="attributes">
                <attribute name="t-att-style">`'background-color: ' + (record.color_field ? record.color_field : '#007bff')`</attribute>
            </xpath>
        </template>
    </odoo>
    

    and the css to change the color:

    .custom_progressbar .o_progressbar .o_progress .bg-primary {
        background-color: #007bff !important; /* Default color is blue */
        height: 100% !important;
    }
    

    Is there any good explanation for the js. part in odoo 16, thats not easy to understand the framework.

    thanks


  2. Try to inherit the progress bar field

    Example:

    /** @odoo-module **/
    
    import { registry } from "@web/core/registry";
    import { ProgressBarField } from "@web/views/fields/progress_bar/progress_bar_field";
    
    export class CustomProgressBarField extends ProgressBarField {
        
    }
    
    registry.category("fields").add("custom_progressbar", CustomProgressBarField);
    

    You can use a custom template as follows:

    CustomProgressBarField.template = "web.CustomProgressBarField";
    

    To change field color based on a computed field, you can use the t-attf-class attribute:

    <?xml version="1.0" encoding="UTF-8"?>
    <templates xml:space="preserve">
    
        <t t-name="web.CustomProgressBarField" t-inherit="web.ProgressBarField" t-inherit-mode="primary" owl="1">
            <xpath expr="//div[hasclass('o_progress')]/div" position="attributes">
                <attribute name="t-attf-class">{{ props.record.data.color_field < 5 ? 'bg-danger' : 'bg-primary' }} h-100</attribute>
            </xpath>
        </t>
    
    </templates>
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search