Core7s
Core7s

Reputation: 147

Function inside of onClick tag out of scope in dojo 1.6

I am making buttons in a forEach loop but when I try to have a function for the onClick tag of a button it says this.foo() is not a function. The code is as follows:

    dojo.forEach(buttonIds, function(btn, i) {
               var button = new dijit.form.Button({
                    id: buttonIds[i]+'.'+widgetId,
                    label: buttonLabel[i],
                    onClick: function () {
                        dojo.hitch(this, this.foo());}
});

Now maybe dojo.connect() is more appropriate here but I don't know how would I get the button ID as the first argument because if I understand correctly then connect would look something like dojo.connect(button.id, 'onClick', this, foo()). Unfortunately this statement also results in the same error. This may be a trivial scoping problem but I am very new at dojo so any help would be appreciated!

EDIT: Sorry for dojo.connect() the error is button is undefined

Upvotes: 0

Views: 1084

Answers (2)

todd
todd

Reputation: 193

I think the connect should look like:

dojo.connect(dijit.byId(buttonIds[i]+'.'+widgetId), 'onclick', this.foo);

notice lower case 'c' in 'onclick' and no '()' after foo.

As for the onClick argument in the button constructor, dojo.hitch takes in and returns a function which is executed in the scope of the first argument so:

onClick:dojo.hitch(this, this.foo);

should work

you were trying to hitch in the execution of the function instead of the function itself (notice no '();' after function name)

Upvotes: 1

phusick
phusick

Reputation: 7352

dojo.forEach accepts actually three parameters (source):

The dojo.forEach method accepts three (3) arguments: an array to iterate over, a function (or callback) to call for each item of the array (including unassigned indexes between assigned ones, as described above), and an optional object to use as the scope in which to call the callback.

Your this in dojo.hitch points to the callback function, add this as third parameter:

dojo.forEach(buttonIds, function(item, index, items) { /*callback*/ }, this);

// or alternatively
var self = this;
dojo.forEach(buttonIds, function(item, index, items) { /*use self instead of this here*/ });

I am not sure what are you about to achieve, but here is my guess:

dojo.require("dijit.form.Button");

dojo.ready(function() {

    dojo.declare("Spam", null, {

        constructor: function() {
            this.buttonIds = ["button1", "button2", "button3"];         
        },

        createButtons: function() {
            dojo.forEach(this.buttonIds, function(item, index, items) {
                var button = new dijit.form.Button({
                    id: item,
                    label: item
                });
                button.onClick = dojo.hitch(this, "foo", button);
                button.placeAt(dojo.body());
            }, this);      
        },

        foo: function(widget, event) {
            console.log(widget.id);
        }
    });

    var spam = new Spam();
    spam.createButtons();

});

See it in action at jsFiddle: http://jsfiddle.net/phusick/mcnjt/

Upvotes: 1

Related Questions