odoo14 动态改变进度条颜色(widget=“progressbar“)底色,边框,进度颜色

在odoo14中当时使用:widget="progressbar" 时默认表现为:
 


 

但我想在不同的比例展示不同的颜色,和其他的样式颜色:
tree视图

form视图 也一样:
 

说明:进度0-30为蓝色,31-80为黄色,81-100为紫色、边框为红色,底色为绿色

这个组件 拥有普通组件widget=“progressbar“的所有功能,换言之 在widget=“progressbar“组件的js文件和模板文件的基础上进行改进,使其有更好的可移植性和可造性。


 这是一个单独模块:

js文件

odoo.define('progressbar_dynamic_color.progressbar_dynamic', function (require) {
    'use strict';
    var AbstractField = require('web.AbstractField');
    let fieldRegistry = require("web.field_registry");
    var core = require('web.core');
    var utils = require('web.utils');
    var field_utils = require('web.field_utils');

    require("web.zoomodoo");

    var _t = core._t;
    var _lt = core._lt;

    var CustomProgressBarColorWidget = AbstractField.extend({
        description: _lt("进度条"),
        template: "Custom_ProgressBar",
        events: {
            'change input': 'on_change_input',
            'input input': 'on_change_input',
            'keyup input': function (e) {
                if (e.which === $.ui.keyCode.ENTER) {
                    this.on_change_input(e);
                }
            },
        },
        supportedFieldTypes: ['integer', 'float'],
        init: function () {
            this._super.apply(this, arguments);


            if (this.recordData[this.nodeOptions.current_value]) {
                this.value = this.recordData[this.nodeOptions.current_value];
            }

            this.editable_readonly = !!this.nodeOptions.editable_readonly;
            this.readonly = this.nodeOptions.readonly || !this.nodeOptions.editable;
            this.canWrite = !this.readonly && (
                this.mode === 'edit' ||
                (this.editable_readonly && this.mode === 'readonly') ||
                (this.viewType === 'kanban') // Keep behavior before commit
            );

            this.edit_max_value = !!this.nodeOptions.edit_max_value;
            this.max_value = this.recordData[this.nodeOptions.max_value] || 100;
            this.title = _t(this.attrs.title || this.nodeOptions.title) || '';
            this.enableBarAsInput = false;
            this.edit_on_click = this.enableBarAsInput && this.mode === 'readonly' && !this.edit_max_value;
            this.write_mode = false;
        },
        _render: function () {
            var self = this;
            this._render_value();

            if (this.canWrite) {
                if (this.edit_on_click) {
                    this.$el.on('click', '.o_progress', function (e) {
                        var $target = $(e.currentTarget);
                        var numValue = Math.floor((e.pageX - $target.offset().left) / $target.outerWidth() * self.max_value);
                        self.on_update(numValue);
                        self._render_value();
                    });
                } else {
                    this.$el.on('click', function () {
                        if (!self.write_mode) {
                            var $input = $('<input>', {type: 'text', class: 'o_custom_progressbar_value o_input'});
                            $input.on('blur', self.on_change_input.bind(self));
                            self.$('.o_custom_progressbar_value').replaceWith($input);
                            self.write_mode = true;
                            self._render_value();
                        }
                    });
                }
            }
            return this._super();
        },
        on_update: function (value) {
            if (this.edit_max_value) {
                this.max_value = value;
                this._isValid = true;
                var changes = {};
                changes[this.nodeOptions.max_value] = this.max_value;
                this.trigger_up('field_changed', {
                    dataPointID: this.dataPointID,
                    changes: changes,
                });
            } else {
                // _setValues accepts string and will parse it
                var formattedValue = this._formatValue(value);
                this._setValue(formattedValue);
            }
        },
        on_change_input: function (e) {
            var $input = $(e.target);
            if (e.type === 'change' && !$input.is(':focus')) {
                return;
            }

            var parsedValue;
            try {
                // Cover all numbers with parseFloat
                parsedValue = field_utils.parse.float($input.val());
            } catch (error) {
                this.do_warn(false, _t("Please enter a numerical value"));
            }

            if (parsedValue !== undefined) {
                if (e.type === 'input') { // ensure what has just been typed in the input is a number
                    // returns NaN if not a number
                    this._render_value(parsedValue);
                    if (parsedValue === 0) {
                        $input.select();
                    }
                } else { // Implicit type === 'blur': we commit the value
                    if (this.edit_max_value) {
                        parsedValue = parsedValue || 100;
                    }

                    var $div = $('<div>', {class: 'o_custom_progressbar_value'});
                    this.$('.o_custom_progressbar_value').replaceWith($div);
                    this.write_mode = false;

                    this.on_update(parsedValue);
                    this._render_value();
                }
            }
        },
        _render_value: function (v) {
            var value = this.value;
            var max_value = this.max_value;
            if (!isNaN(v)) {
                if (this.edit_max_value) {
                    max_value = v;
                } else {
                    value = v;
                }
            }
            value = value || 0;
            max_value = max_value || 0;

            var widthComplete;
            if (value <= max_value) {
                widthComplete = value / max_value * 100;
            } else {
                widthComplete = 100;
            }


            var color_value = '#34c38f'
            try {
                if (this.attrs.options.colors) {
                    var colorJudgmentValue = this.attrs.options.colors
                    for (var key in this.attrs.options.colors) {
                        if (colorJudgmentValue.hasOwnProperty(key)) {
                            var range = colorJudgmentValue[key];
                            if (value >= range[0] && value < range[1]) {
                                color_value = key;
                                break;  // 如果找到匹配的值,可以提前结束循环
                            }
                        }
                    }

                }
            } catch (error) {
            }

            var bordercolor = "white";
            try {
                if (this.attrs.options.bordercolor) {
                    var borderColorValue = this.attrs.options.bordercolor
                    if (borderColorValue) {
                        if (borderColorValue.color) {
                            bordercolor = borderColorValue.color
                        }
                    }

                }
                ;
            } catch (error) {
                console.log("边框颜色动态改变输入的值有错误", error)
            }

            var basercolor = "white";
            try {
                if (this.attrs.options.basercolor) {
                    var baseColorValue = this.attrs.options.basercolor
                    if (baseColorValue) {
                        if (baseColorValue.color) {
                            basercolor = baseColorValue.color
                        }
                    }

                }
                ;
            } catch (error) {
                console.log("边框底板颜色动态改变输入的值有错误", error)
            }


            var progressBarComplete = this.$('.o_custom_progressbar_complete');
            progressBarComplete.css('background-color', color_value);


            this.$('.o_custom_progress').toggleClass('o_custom_progress_overflow', value > max_value)
                .attr('aria-valuemin', '0')
                .attr('aria-valuemax', max_value)
                .attr('aria-valuenow', value);

            var progressBorderComplete = this.$('.o_custom_progress');
            progressBorderComplete.css('border', `1px solid ${bordercolor}`);
            progressBorderComplete.css('background-color', basercolor);

            this.$('.o_custom_progressbar_complete').css('width', widthComplete + '%')

            if (!this.write_mode) {
                if (max_value !== 100) {
                    this.$('.o_custom_progressbar_value').text(utils.human_number(value) + " / " + utils.human_number(max_value));
                } else {
                    this.$('.o_custom_progressbar_value').text(utils.human_number(value) + "%");
                }
            } else if (isNaN(v)) {
                this.$('.o_custom_progressbar_value').val(this.edit_max_value ? max_value : value);
                this.$('.o_custom_progressbar_value').focus().select();
            }
        },
        _reset: function () {
            this._super.apply(this, arguments);
            var new_max_value = this.recordData[this.nodeOptions.max_value];
            this.max_value = new_max_value !== undefined ? new_max_value : this.max_value;
        },
        isSet: function () {
            return true;
        },
    });

    // 注册widget
    fieldRegistry.add('progressbar_dynamic_color', CustomProgressBarColorWidget);

    return CustomProgressBarColorWidget;
});

scss文件:
 

.o_custom_progressbar {

    > div {
        display: inline-block;
    }

    .o_custom_progressbar_title {
        white-space: nowrap;
        padding-right: 10px;
    }

    .o_custom_progress {
        width: 100px;
        height: 15px;
        vertical-align: middle;

        //border: 1px solid lighten(white, 25%);
        overflow: hidden;

        //background-color: firebrick;
        &.o_custom_progress_overflow {
            background-color: white;
        }

        .o_custom_progressbar_complete {
            //background-color: lawngreen;
            height: 100%;
        }
    }

    .o_custom_progressbar_value {
        width: 100px;
        white-space: nowrap;
        padding-left: 10px;
    }
}

progress_bar_template.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
    <t t-name="Custom_ProgressBar">
    <div class="o_custom_progressbar" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
        <div t-if="widget.title" class="o_custom_progressbar_title"><t t-esc="widget.title"/></div><div class="o_custom_progress">
            <div class="o_custom_progressbar_complete"/>
        </div><div class="o_custom_progressbar_value"/>
    </div>
</t>
</templates>

temaple.xml 和 __manifest__.py  加载这些文件和模板

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奔跑的蜗牛..

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值