Javascript developers can create complex interfaces for the applets easily, using the flexibility introduced by the AMD (Asynchronous Module Definition) specifications.
More information about AMD: http://wiki.commonjs.org/wiki/Modules/AsynchronousDefinition .
Using Dojo classes is preferred since it will keep the size small and probably reducing the network traffic and time since many dependencies will be loaded already in the browser, but this is not a strict requirement (JQuery should work too - to be confirmed).
The main thing to keep in mind is to make modules compatible with the AMD specifications, since they will be loaded by a require call.
Note
Currently the Dojo build process does not include the compression of applets’ static files. This will be included in a near future.
Javascript sources should be located in the applet’s static directory. Files located in this directory are accessible from a (relative) URL of the form: /static/hanji/applet/applet_id/some_module.js.
Since the hanji prefix is present in the AMD path definitions (by djConfig), require statements need to refer to hanji/applet/applet_id/some_module.
When an applet is loaded in the browser, the modules defined by the optional require_js array of the applet’s WebUI class.
It is however a good practice to limit the number of modules defined in require_js. The technique given in the example below shows how to load more modules.
static/MyWidget.js:
require([
'dijit/form/Button',
// You can add modules that will be loaded immediately here
],
function(Button) {
dojo.declare("hanji.applet.my_applet.MyWidget",
Button,
{
myFirstParam: "Something silly", // Default value
mySecondParam: 0,
startup: function() {
this.set('label', this.myFirstParam);
this.inherited(arguments);
},
onClick: function() {
console.log("Loading another module");
require(['hanji/applet/my_applet/SmartModule']);
SmartModule.doSomethingSmart(this, mySecondParam);
}
}
);
return hanji.applet.my_applet.MyWidget;
}
);
static/SmartModule.js:
var SmartModule = {
doSomethingSmart: function(button, param) {
console.log("I'm super duper smart, and just loaded.");
button.set('label', param);
}
}
/*
* This example suppose that `SmartModule` is registered in the global scope
* (see the code in the onClick function in `MyWidget.js`).
* Since Dojo has a restriction mechanism, we need a workaround:
*/
window.SmartModule = SmartModule;
templates/content.html:
<div dojoType="hanji.applet.my_applet.MyWidget"
myFirstParam="Do something smart"
mySecondParam="{{ applet.webUI.second_param|safe }}">
</div>
interfaces.py:
class WebUI(applet.WebUI):
require_js = [
'hanji/applet/my_applet/MyWidget',
]
def on_activate(self):
second_param = "Done"
In this example, the MyWidget.js file is downloaded by the browser when the applet loads (depending on the layout, the applet status, it can be when the main page loads, only when the applet is activated, or only when it is displayed).
The SmartModule is loaded only on demand. Note that SmartModule does not need to be AMD compatible.