Question

I've written a class that extends dijit.Tree to include a radio button alongside each node. I'm using it in a form to show a folder tree from which the user can select a folder. Here is the code:

define("my/Tree/RadioButton",
    ['dojo/_base/declare', 'dijit/Tree', 'dijit/form/RadioButton', 'dojo/dom-construct', 'dojo/_base/connect', 'dojo/on', 'dojo/_base/lang'],
    function (declare, Tree, RadioButton, domConstruct, connect, on, lang){

    var TreeNode = declare(Tree._TreeNode, {
        _radiobutton: null,

        postCreate: function(){
            this._createRadioButton();

            this.inherited(arguments);
        },

        _createRadioButton: function(){
            this._radiobutton = new RadioButton({
                name: this.tree.name,
                value: this.tree.model.store.getIdentity(this.item) + '',
                checked: false
            });
            domConstruct.place(this._radiobutton.domNode, this.iconNode, 'before');

            if (this.tree.model.store.hasAttribute(this.item, 'checked')) {
                var attrValue = this.tree.model.store.getValue(this.item, 'checked');
                if (attrValue === true) {
                    this._radiobutton.set('checked', true);
                }
            }

            connect.connect(this._radiobutton, 'onClick', this, function(){
                // set any checked items as unchecked in the store
                this.tree.model.store.fetch({
                    query: {checked: true},
                    onItem: lang.hitch(this.tree.model.store, function(item){
                        console.log('found checked item ' + this.getValue(item, 'name'));
                        this.setValue(item, 'checked', false);
                    })
                });

                // check the one that was clicked on
                var radioValue = this._radiobutton.get('value');
                this.tree.model.store.setValue(this.item, 'checked', true);
            });
        }
    });

    return declare(Tree, {
        _createTreeNode: function(/*Object*/ args){
            return new TreeNode(args);
        }
    });
});

The issue is that when the form is submitted, the value that is submitted is always the value of the first radio button that was selected, even if other radio buttons are subsequently clicked on.

I can see by inspecting the dom that the value attribute for the checked radio button has the correct value. But what gets submitted is always the initially selected value.

I have a similar class that uses the checkbox widget instead and that one works fine.

Edit based on some feedback I created an even simpler version of this class that doesn't track the checked state using attribute in the store:

define("my/Tree/RadioButton",
    ['dojo/_base/declare', 'dijit/Tree', 'dijit/form/RadioButton', 'dojo/dom-construct'],
    function (declare, Tree, RadioButton, domConstruct){

    var TreeNode = declare(Tree._TreeNode, {
        _radiobutton: null,

        postCreate: function(){
            this._createRadioButton();

            this.inherited(arguments);
        },

        _createRadioButton: function(){
            this._radiobutton = new RadioButton({
                name: this.tree.name,
                value: this.tree.model.store.getIdentity(this.item) + '',
                checked: false
            });
            domConstruct.place(this._radiobutton.domNode, this.iconNode, 'before');
        }
    });

    return declare(Tree, {
        _createTreeNode: function(/*Object*/ args){
            return new TreeNode(args);
        }
    });
});

but even this still has the same issue - whichever radio button the user clicks on first is the value that will be submitted, regardless of what other buttons are subsequently clicked.

Was it helpful?

Solution

I managed to workaround this issue by hooking on to the onchange event for the radio buttons. The hook explicitly sets checked to false on the unchecked radio button, which seems to fix the problem. I'm unsure why this is required though.

OTHER TIPS

I have this exact same problem. It used to work in older Dojos. Specifically, ALL of the radioButtons incorrectly return true on "dijit.byId("whatever").checked" during the onClicked function. When checked manually after the onClicked function finishes using FireBug console, the above property returns the correct values. I think it is a bug, and I only worked around it by having a different onClicked function for each button, like so:

<form id="locateForm">
<label for="locate">Locate:</label><br />
<input type="radio" dojoType="dijit.form.RadioButton" name="locate" id="locateAddress" value="Address" checked="checked" onClick="enableLocate1();" />
<label for="locateAddress">Address</label>
<input type="radio" dojoType="dijit.form.RadioButton" name="locate" id="locatePlace" value="Place" onClick="enableLocate2();" />
<label for="locatePlace">Place</label>
</form>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top