Login Register

Combining Dijit with Standard DOM - I Think

I think this is an issue with combining the standard page DOM with creating dijit elements in the DOM, or I could be way off track. Here is a complete sample of some code that is similar to what I am trying to do.


Dojo Test


	@import "dojo/dijit/themes/tundra/tundra.css";
	@import "dojo/dojo/resources/dojo.css";





//





The output from this is 6 buttons. Each is labeled 'A Button n', Where n is a number from 0 to 5. On the left of each button is the word corresponding to the number. However, when you click on any of the buttons, what is returned is a javascript alert dialog with the text 'Button 6'. This seems like an error. What am I doing wrong?

Newbie

I should point out that I am a newbie to DOJO, only having used it for a few days.

It's a closure problem...

...and has nothing to do with Dojo, and everything to do with JS. The function definition you use to create the alert captures the last state of the variable "i", which means it will always be the last number value.

What you'd be better off doing is alerting the label of the button:

...onClick=function(){ alert this.label }

Quick response

Thanks for the quick response, and the clarification!

The actual functionality that I want for the button is to have it open to a new web page, not display a number. I just used that as a simple example of the problem I was having. On the actual implementation of this I have several button that all do the same thing as the last button. Not the behavior that I want.

How do I properly handle closure in this code example?

slightly modified:

dojo.require("dojo.parser");
        dojo.require("dijit.form.Button");
       
        function createTable() {
                var table = document.createElement("table");
               
                var strings = new Array("Zero", "One", "Two", "Three", "Four", "Five");
                
              //  for ( var i = 0; i < strings.length; i++ ) {
             var i = 0;
             dojo.forEach(strings,function(str){ 

                        var row = table.insertRow(i);
                       
                        var cell = row.insertCell(0);
                        cell.innerHTML = str;
                       
                        var cell2 = row.insertCell(1);
                        var aButton = new dijit.form.Button({
                            label: "A Button " + i, 
                            onClick: function(){alert("button " + i);} 
                        });
                        cell2.appendChild(aButton.domNode);
                });
               
                document.getElementById("placeholder").appendChild(table);
        }
        dojo.addOnLoad(createTable); 
        //window.onload = createTable;

that may help.

(using dojo.forEach and a function creates the closure i think, by the function() being run)

One fix.

dojo.forEach(strings, function(item, idx){ ... }

Replace "str" with "item", and use idx (the current index) instead of trying to count it on your own (plus dante's code doesn't increment the i variable at all).

nice tip. another spot i

nice tip. another spot i want to tag. I always forget about the idx in forEach, and realized after i'd posted i was doing nothing with the "i", but i think he got the point :)

yay.

Thank you

Separating the work of creating the button and adding it to the DOM through a function was the key. At least that appears to have worked.

I noticed that the i was not being incremented ;-)

I have been using Dojo for 4 days now and I am impressed by it. I am starting to find all kinds of places in my code where I can use it to really enhance the user experience and feedback.

To the Dojo developer community, Thank you for all your hard work on this!

To the Dojo support community, Thank you for being there!