I am trying to do a simple task. This task is to load a HTML containg dijit.Form
into a ContentPane
. I don't know which dijits I will need before I load this HTML, but the loaded HTML will contain applicable require
's to load them.
So in order to be able to execute the script from loaded HTML I use dojox.layout.ContentPane
. However when I set parseOnLoad
to true
, the parsing takes place before the script execution, so the dijits aren't available when first loading the content. Also when I try to use onDownloadEnd
callback, when this callback is run, the dijits from require
's are still not loaded.
Only thing I can think of myself is using setTimeout
to defer parsing to a time when these scripts will be executed. I don't like this solution however as it may fail from time to time and it would make the application less responsible.
So how should I perform the parsing so that it happens right after the require
statement from loaded HTML is run?
I can see two possible solutions - both with dijit/layout/ContentPane
:
Use Dojo 1.8.0, as the parser supports auto require, it will load dependencies itself as you can see here: http://jsfiddle.net/phusick/vr4h4/
Put the list of dependencies somewhere into your form template, e.g. in data-config
attribute of your dijit/form/Form
:
<form
data-dojo-type="dijit.form.Form"
data-config='"deps":["dijit/form/Form", "dijit/form/TextBox", "dijit/form/Button"]'>
<input data-dojo-type="dijit.form.TextBox" data-dojo-props="placeholder:'TextBox'">
<button data-dojo-type="dijit.form.Button">Button</button>
</form>
Set parseOnLoad:false
for the dijit/layout/ContentPane
, load the template, get the list of dependencies, require
them and then in the factory function parser.parse()
containerNode
of your ContentPane
(see it in action http://jsfiddle.net/phusick/QA4gH/):
require([
"dojo/ready",
"dojo/dom",
"dojo/query",
"dojo/on",
"dojo/parser",
"dojo/json",
"dijit/layout/ContentPane",
"dojo/domReady!"
], function(ready, dom, query, on, parser, JSON) {
var template, dijits;
ready(function() {
template = dom.byId("template").textContent;
on.once(dom.byId("loadFormButton"), "click", loadForm);
contentPane1.set("parseOnLoad", false);
contentPane1.on("load", parseForm);
});
function loadForm() {
contentPane1.set("content", template);
}
function parseForm() {
// a node to parse
var node = contentPane1.containerNode;
// obtain a list of dependencies
var config = JSON.parse("{" + query("form", node)[0].dataset.config + "}");
// require (AMD load) dependencies
require(config.deps, function() {
// parse ContentPane content when dependencies are resolved
dijits = parser.parse(node);
console.log(dijits); // an array of instantiated dijits
});
}
});
EDIT: I just got this idea that writing an auto require (for Dojo <1.8) is just about adding a short getDependencies()
method, so you don't need to list dependencies as I mentioned in the second option above:
function getDependencies(/*DOMNode*/ containerNode) {
var deps = [];
query("[data-dojo-type]", containerNode).forEach(function(node) {
var dep = node.dataset.dojoType.split(".").join("/");
if(!~array.indexOf(deps, dep)) {
deps.push(dep);
};
});
return deps;
}
See it working at jsFiddle: http://jsfiddle.net/phusick/hnjWt/