Login Register

dojo.qery does not work on imported nodes

So I finally tracked down the issue I was seeing when I made my initial erroneous post (http://dojotoolkit.org/forum/dojo-core-dojo-0-9/dojo-core-development-di...). Basically if you use import node to import some html from another document dojo.query can not find those nodes. The standard document.getElementById can though, so I'm not sure where the bug is. I have written a simple test case to reproduce this, which uses dojo.parser to show that the parser can not find/query for the inserted node. When you run this test, you will see that the first two buttons parse fine, the 3rd button, however, does not. Note: it will only work on FF, as DOMParser is not supported in IE.

<html>
<html>
  <head>
    <title>Dojo: Hello World!</title>
   
    <link rel="stylesheet" type="text/css" href="js/dojo/dijit/themes/tundra/tundra.css"/>
    <script type="text/javascript" src="js/dojo/dojo/dojo.js" djConfig="parseOnLoad: true">
    </script>
    <script type="text/javascript">

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

        function onPageLoad()
        {
            // Create a separate document             var text = "<doc xmlns=\"http://www.w3.org/1999/xhtml\"><button dojoType=\"dijit.form.Button\" id=\"test3\">Test3</button></doc>";
            var parser = new DOMParser();
            var doc = parser.parseFromString(text, "text/xml");

            // Get the button from the document
            var button_element = doc.getElementById("test3");

            // Import the button node into our document
            var import_button = document.importNode(button_element, true);
           
            // Insert it into our document   
            var dom_insert_node = document.getElementById("dominsert");
            dom_insert_node.appendChild(import_button);   
 
            // The parser can not find it    
            dojo.parser.parse();

            // Look it up in the document. Get element by id can find it just fine
            var lookup = document.getElementById("test3");
               
            // Choose your output method
            console.log(lookup);
            //alert(lookup);
        }
    </script>
  </head>

  <body onload="onPageLoad()">

    <button dojoType="dijit.form.Button" id="test1">Test1</button>
    <div>
        <button dojoType="dijit.form.Button" id="test2">Test2</button>
    </div>
    <div id="dominsert">
    </div>
  </body>
</html>

</html>

Ticket

A ticket has been field for this issue: http://trac.dojotoolkit.org/ticket/3849

hmmmm

didn't notice it before, but you have body onLoad="onPageLoad" ... you cannot rely on body onLoad to init, especially wrt to dojo, because dojo may not be fully loaded. Not saying that's why dojo.query doesn't work in this case, but it might be.

try adding after your onPageLoad function(){} :

dojo.addOnLoad(onPageLoad);

instead of body="onPageLoad"

That's actually wrong...

...but you should move any onload functions to dojo.addOnLoad. In general, it tries to fire with DOMContentLoaded (before body.onLoad) but if it doesn't, it will fire onload.

I doubt that has anything to do with the imported nodes issue; it's more likely that a caching mechanism is in effect in order to speed up querying, or something similar.

On a related note, using importNode may not work as entirely expected cross browser, so if you can actually avoid using that mechanism, you probably should. There's a reason why most toolkits prefer injection via innerHTML...

I agree

"On a related note, using importNode may not work as entirely expected cross browser, so if you can actually avoid using that mechanism, you probably should. There's a reason why most toolkits prefer injection via innerHTML..."

I agree that innerHTML is often better, however I'm attempting to integrate Dojo with an existing framework that already does things via inportNode (and has its own implementation for browsers that don't support it natively). Therefore, unfortunately I have to do it this way.

Probably Not

Considering the parser finds the buttons "Test1" and "Test2" just fine, I kind of doubt it, but I'll give it a try.

Nope

Just tired it, and it didn't make a difference. The buttons "Test1" and "Test2" still load just fine. The button "Test3" (which is imported) does not.