组合框,可自动更正该值

时间:2017-03-02 14:09:43

标签: javascript extjs combobox extjs6-classic

我有一个组合框,可以选择一个特定的时间跨度,例如:

5 minutes
15 minutes
1 hour
2 hours
1 day
2 days
1 week
2 weeks

它始终向服务器传输分钟数,但用户不会理解“10080”的含义(在您尝试计算之前:它是一周)。

新要求是用户应该能够在该框中键入任意值。例如。 “20分钟”,“1小时5分钟”,“2小时5分钟”或“1小时6小时120分钟”;并且,如果该字段以编程方式设置为某个值(例如75),则该字段应显示正确的字符串(1小时15分钟)

所以我编写了一个解析器和一个格式化程序函数(见下文),但是如何让我的组合框使用它们呢?

我已经尝试覆盖rawToValue / valueToRaw函数对,类似于我在datefield代码中找到的内容:

rawToValue:function(rawValue) {
    console.log('rawToValue');
    console.log(rawValue);
    return this.parse(rawValue) || rawValue || null;
},
valueToRaw:function(value) {
    console.log('valueToRaw');
    console.log(value);
    return this.format(value);
},

但是没有调用它们,我没有得到任何控制台日志输出。

这些是解析器/格式化程序函数:

Ext.define('AlarmTimeField',{
    extend:'Ext.form.field.ComboBox',
    format:function(minutes) {
        var a = [];
        Ext.each(this.units, function(unit) {
            if(minutes >= unit.minutes) {
                var unitCount = Math.floor(minutes/unit.minutes);
                console.log(unitCount);
                minutes = minutes-unitCount*unit.minutes;
                a.push("" + unitCount + " " + (unitCount==1?unit.singular:unit.plural));
            }
        });
        return a.join(' ');
    },
    parse:function(input) {
        if(!input) return 0;
        var me=this,
            inputSplit = input.split(' '),
            value = 0,
            lastNum = 0;
        Ext.each(inputSplit,function(input) {
            if(!input) return;
            else if(Ext.isNumeric(input)) lastNum = input;
            else if(Ext.isNumeric(input[0])) {
                var inputUnit = input.slice(-1),
                    inputValue = input.slice(0,-1);
                Ext.each(me.units,function(unit) {
                    if(inputUnit==unit.abbr) {
                        value+=unit.minutes*inputValue;
                    }
                });
            }
            else {
                Ext.each(me.units,function(unit) {
                    if(input==unit.singular || input==unit.plural || input==unit.abbr) {
                        value+=unit.minutes*lastNum;
                    }
                });
            }
        });
        return value;
    },
    units:[{
        minutes:10080,
        abbr:'w',
        singular:'week',
        plural:'weeks'
    },{
        minutes:1440,
        abbr:'d',
        singular:'day',
        plural:'days'
    },{
        minutes:60,
        abbr:'h',
        singular:'hour',
        plural:'hours'
    },{
        minutes:1,
        abbr:'m',
        singular:'minute',
        plural:'minutes'
    }]
});

1 个答案:

答案 0 :(得分:1)

主要思想是Ext.form.field.ComboBox值实际上是Ext.data.Model的实例,因此您的值和显示值只是模型属性值,每次更改值/显示值时都必须更新绑定模型实例(我的愿景,如果我错了,请纠正我。)

我认为Ext.form.field.ComboBox.validator是用于解析手动输入值的好地方(如果输入的值不正确,您可以立即显示错误消息),因此您可以像这样覆盖它:< / p>

                validator: function (value) {
                    // TODO: Add regexp value format validator

                    var minutes = me.parse(value);
                    // Add check for zero / empty values if needed
                    if (minutes === 0)
                    // Add meaningful error message
                        return 'Incorrect input';
                    else {
                        me.setValue(Ext.create('Ext.data.Model', {
                            value: minutes,
                            text: value
                        }));
                        return true;
                    }
                }

这是一个非常原始的例子,但我认为这个想法很明确。

要通过setValue()方法格式化以编程方式设置的值,您可以覆盖此方法,如下所示:

        setValue: function (value) {
            // TODO: Add array of values support
            if (Ext.isNumber(value))
                value = Ext.create('Ext.data.Model', {
                    value: value,
                    text: this.format(value)
                });

            this.callParent([value]);
        }

检查fork of your fiddle。我希望我帮了一下。