gen_Eric
gen_Eric

Reputation: 227240

RadioGroup not updating bound value

I am using a radiogroup in my form, and I noticed that when I select one of the radio buttons, the value (bound value) is not updated.

Here's a small example:

Ext.create({
    xtype: 'container',
    renderTo: Ext.getBody(),
    items: [{
        xtype: 'formpanel',
        viewModel: {
            data: {
                myValue: 3
            }
        },
        items: [{
            xtype: 'displayfield',
            label: 'This is the value of myValue:',
            bind: '{myValue}'
        }, {
            xtype: 'textfield',
            label: 'Update myValue:',
            bind: '{myValue}'
        }, {
            xtype: 'radiogroup',
            vertical: true,
            label: 'Click a radio button:',
            bind: '{myValue}',
            items: [{
                label: 'One',
                value: 1
            }, {
                label: 'Two',
                value: 2
            }, {
                label: 'Three',
                value: 3
            }, ]
        }]
    }]
});

I created a simple viewModel with one data value: myValue: 3. This is bound to all of the form elements: the radiogroup, a textfield, and a displayfield.

I'd expect that when I click one of the radio buttons, that the displayfield would update its value. The displayfield value is updated when you type into the textfield, but the radiogroup is not updated.

It seems like the radiogroup is only using its bound value when it initializes, but it doesn't notice when it gets updated nor does it update it on its own.

What am I doing wrong? Why doesn't the bound value get updated when I click on a radio button?

Here's an example over on Sencha Fiddle: https://fiddle.sencha.com/#view/editor&fiddle/389i


UPDATE: I found a solution adding a change listener to the radiogroup. Well, this fixes updating myValue wen you click on a radio button. I'd need another listener to update the radiogroup when myValue is updated elsewhere (like in the textfield).

This works for my needs, but why should I need to add a change listener? Why doesn't the radiogroup bind to {myValue} correctly?

listeners: {
    change: function(field, val) {
        let vm = field.lookupViewModel();
        vm.set('myValue', val);
    }
}

Here's a fiddle with this update applied: https://fiddle.sencha.com/#view/editor&fiddle/389k

Upvotes: 1

Views: 1162

Answers (3)

gen_Eric
gen_Eric

Reputation: 227240

I've contacted Sencha support (of behalf of the company I work for; we have "premium support"). They said that there is already an opened bug report for this (EXTJS-28689) and they provided an "unofficial" override that fixes the issue.

Ext.define(null, {
    override: 'Ext.field.FieldGroupContainer',

    onGroupChange: function () {
        var me = this,
            newVal, oldVal, isValid;

        if (me.isConfiguring || me.isDestructing() || me.suspendCheckChange) {
            return;
        }

        newVal = me.getValue();
        oldVal = me.lastValue || me.originalValue;

        if (!me.isEqual(newVal, oldVal)) {
            me.lastValue = newVal;
            me.fireEvent('change', me, newVal, oldVal);
            isValid = me.validate();

            if (isValid) {
                me.publishState('value', newVal);
            }
        }
    }
});

Fiddle with this override applied: https://fiddle.sencha.com/#fiddle/38as

Upvotes: 2

incutonez
incutonez

Reputation: 3331

I ran into this issue earlier this year, but I don't think I ever reported it to Sencha because I was using the Community Edition. Anyway, from what I recall, I had tracked it down to some issue in the getValue method, believe it or not, and overrode that to the following (Fiddle here):

Ext.define('MyOverride', {
    override: 'Ext.field.RadioGroup',

    getValue: function () {
        var value = this.callParent(arguments);
        var bind = this.getBind()
        var bindValue = bind && bind.value;
        if (bindValue) {
            if (Ext.isEmpty(value) && !Ext.isEmpty(bindValue.getValue())) {
                value = bindValue.getValue()
            }
            bindValue.setValue(value)
        }
        return value
    }
});

I'm sure this isn't the right method for this override, but it unblocked me for the time being. Not sure if it's useful for you, but I wanted to share.

Upvotes: 2

Arthur Rubens
Arthur Rubens

Reputation: 4706

The problem is in typing, the text field returns string and the radiogroup working with numbers.. for vise versa you will have to use dirty hack.. :-/

Ext.create({
    xtype: 'container',
    renderTo: Ext.getBody(),
    items: [{
        xtype: 'formpanel',
        viewModel: {
            data: {
                myValue: "3" // type string
            }
        },
        items: [{
            xtype: 'displayfield',
            label: 'This is the value of myValue:',
            bind: '{myValue}'
        }, {
            xtype: 'textfield',
            label: 'Update myValue:',
            bind: '{myValue}'
        }, {
            xtype: 'radiogroup',
            vertical: true,
            label: 'Click a radio button:',
            bind: '{myValue}',
            simpleValue: true,
            items: [{
                label: 'One',
                value: "1" // type string
            }, {
                label: 'Two',
                value: "2" // type string
            }, {
                label: 'Three',
                value: "3" // type string
            }],
            listeners: {
                change: function(radioGroup, newValue, oldValue) {
                    this.up('formpanel').getViewModel().set('myValue', newValue); // Dirty hack
                } 
            }
        }]
    }]
});

Upvotes: 1

Related Questions