Skip to content

Instantly share code, notes, and snippets.

@kfranqueiro
Created March 13, 2011 21:37
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kfranqueiro/868470 to your computer and use it in GitHub Desktop.
Save kfranqueiro/868470 to your computer and use it in GitHub Desktop.
Extension of dijit.Menu which fetches its items from a server endpoint outputting widgets in declarative HTML.
dojo.provide('kgf.widget.DeferredDeclarativeMenu');
dojo.require('dojo.parser');
dojo.require('dojo.string');
dojo.require('dijit.Menu');
dojo.requireLocalization('dijit', 'loading');
dojo.declare('kgf.widget._DeferredDeclarativeMenuMixin', null, {
// src: String
// URL to be loaded when this menu is opened.
src: '',
// cache: Boolean
// Whether to load from src only the first time, or every time.
cache: false,
// ioMethod: Function
// Which transport method to use (default: dojo.xhrGet)
ioMethod: dojo.xhrGet,
// loadingHtml: String
// HTML to be displayed before menu contents load.
loadingHtml: '<tr><td class="dijitContentPaneLoading">${loadingState}</td></tr>',
//NOTE: the above string will not work post-1.6 (see [23982]); use:
//loadingHtml: '<tr><td><span class="dijitInline dijitIconLoading"></span>${loadingState}</td></tr>',
_cancelItemsDeferred: function() {
if (this._itemsDeferred) {
this._itemsDeferred.cancel();
delete this._itemsDeferred;
}
},
_completeItemsDeferred: function(html) {
var
cn = this.containerNode,
ln = this._loadingNode;
dojo.place(html, cn);
dojo.parser.parse(cn);
//need to start up children
dojo.forEach(this.getChildren(), function(c) { c.startup(); });
this.startupKeyNavChildren();
this._loaded = true;
ln.parentNode.removeChild(ln);
delete this._itemsDeferred;
},
onOpen: function() {
var self = this;
this.inherited(arguments);
if (!this._loaded || !this.cache) {
//destroy any current menu items if we're (re-)fetching
this.destroyDescendants();
this._loadingNode =
dojo.place(
this._loadingNode || dojo.string.substitute(this.loadingHtml,
dojo.i18n.getLocalization('dijit', 'loading', this.lang)),
this.containerNode);
this._itemsDeferred = this.ioMethod({
url: this.src,
preventCache: !this.cache,
failOk: true, //prevent errors logging on cancel
load: dojo.hitch(this, '_completeItemsDeferred'),
error: function(e) {
if (e.message.indexOf('xhr cancelled') == -1) {
console.error('Error fetching from ' + this.src, e);
}
}
});
}
},
clearCache: function() {
// summary:
// Forces reload of the menu items the next time the menu is opened.
delete this._loaded;
},
onClose: function() {
this.inherited(arguments);
this._cancelItemsDeferred();
},
uninitialize: function() {
this.inherited(arguments);
this._cancelItemsDeferred();
}
});
dojo.declare('kgf.widget.DeferredDeclarativeMenu',
[dijit.Menu, kgf.widget._DeferredDeclarativeMenuMixin], {
// summary:
// Menu which expects to get its items (either initially or always)
// from a server endpoint providing menu items in declarative HTML format.
});
<li dojoType="dijit.MenuItem" onClick="console.log('first item');">item</li>
<li dojoType="dijit.PopupMenuItem"><span>Normal submenu</span>
<ul dojoType="dijit.Menu">
<li dojoType="dijit.MenuItem" onClick="console.log('normal submenu item');">item</li>
</ul>
</li>
<li dojoType="dijit.PopupMenuItem"><span>Deferred submenu to infinity!</span>
<ul dojoType="kgf.widget.DeferredDeclarativeMenu" src="items.html" cache="true">
</ul>
</li>
<!DOCTYPE html>
<!-- NOTE!
This file, and items.html below, belong in a tests/ subfolder. (Gist no likey subfolders)
-->
<html>
<head>
<link rel="stylesheet" type="text/css" href="../../../dijit/themes/claro/claro.css">
</head>
<body class="claro">
<ul dojoType="dijit.MenuBar">
<li dojoType="dijit.MenuBarItem">item</li>
<li dojoType="dijit.PopupMenuBarItem"><span>Normal menu</span>
<ul dojoType="dijit.Menu">
<li dojoType="dijit.PopupMenuItem"><span>Normal submenu</span>
<ul dojoType="dijit.Menu">
<li dojoType="dijit.MenuItem">item</li>
</ul>
</li>
<li dojoType="dijit.PopupMenuItem"><span>Deferred submenu (cached)</span>
<ul dojoType="kgf.widget.DeferredDeclarativeMenu" src="items.html" cache="true" jsId="cachedDDM">
</ul>
</li>
<li dojoType="dijit.MenuItem" onClick="cachedDDM.clearCache();">clear cache of submenu above</li>
</ul>
</li>
<li dojoType="dijit.PopupMenuBarItem"><span>Deferred menu</span>
<ul dojoType="kgf.widget.DeferredDeclarativeMenu" src="items.html">
</ul>
</li>
</ul>
<script type="text/javascript">
var djConfig = {
parseOnLoad: true,
require: [
'dijit.MenuBar',
'dijit.MenuItem',
'dijit.MenuBarItem',
'dijit.PopupMenuItem',
'dijit.PopupMenuBarItem',
'kgf.widget.DeferredDeclarativeMenu'
]
};
</script>
<script type="text/javascript" src="../../../dojo/dojo.js" djConfig="parseOnLoad: true">
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment