Reputation: 3528
I have been using dojo 1.8 framework to create a widget that includes some other menu widgets. When I create an instance of it it appears, but only shows the basic template elements, and under closer inspection, the menu widgets havent been added. Then when I make a second instance of it, (via button click), it appears correctly, including menus.
This is really confusing me, any ideas?
oh and I'm calling startup() on the widget instance by the way.
here is the code for my template...
<div class="${!baseClass}ConfigPanel">
<div data-dojo-attach-point="heading">Configure data</div>
<div id="menuContainer" data-dojo-attach-point="menu"></div>
</div>
here is the code for my widget...
define(
["dojo/_base/array",
"dijit/Menu",
"dijit/MenuItem",
"dijit/PopupMenuItem",
"dojo/_base/declare",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dojo/text!gdv/chart/configuration/panel/chartConfigTemplate.html",
"dojo/domReady!"],
function (ArrayUtil, Menu, MenuItem, PopupMenu, declare, WidgetBase, TemplatedMixin, template){
var _menuData = [{title:"Region", data:["Region1", "Region2", "Region3"]},
{title: "Variable", data:["variable1", "variable2", "variable3"]},
{title: "Period", data:["period1", "period2"]},
{title: ["latest", "rt1", "rt2"]}];
/**
* Build menu items up with a popup menu style
*/
function buildMenu(nodeId, menuItems){
var mainMenu = new Menu({label: "main menu"}, nodeId);
var subMenuCollection = [];
var subMenu;
ArrayUtil.forEach(menuItems, function(item, index){
subMenu = new Menu({label: item.title});
subMenuCollection.push(subMenu);
//loop through each item in data and create a new menu item from it
ArrayUtil.forEach(item.data, function(subItem, subIndex){
subMenu.addChild(new MenuItem({label: subItem}));
});
//set the sub menu to popup from the main menu
mainMenu.addChild(new PopupMenu({label: item.title, popup: subMenu}));
});
//create the menus
mainMenu.startup();
//start each sub menu
ArrayUtil.forEach(subMenuCollection, function (item, index){
item.startup();
});
}
//return a new widget class
return declare([WidgetBase, TemplatedMixin], {
templateString: template,
baseClass: "plumePlots",
//when dom structure is ready but before page insertion
postCreate: function(){
//run all parent postCreate functions
this.inherited(arguments);
var menuNode = this.menu;
buildMenu(menuNode.id, _menuData);
}
});
}
)
Upvotes: 0
Views: 973
Reputation: 3528
Ok I've found the answer, it was down to the widget lifecyle, this quote straight from the dojo widget tutorial should help explain...
startup()
Probably the second-most important method in the Dijit lifecycle is the startup method. This method is designed to handle processing after any DOM fragments have been actually added to the document; it is not fired until after any potential child widgets have been created and started as well. This is useful for composite widgets as well as layout widgets.
So it turns out I was trying to reference a dom element that had not been added to the document.
To fix my code I simply moved the code creating the menu widgets from the postCreate() method into the startup() method, problem solved, and here is the code snippet showing the change...
//return a new widget class
return declare([WidgetBase, TemplatedMixin], {
templateString: template,
baseClass: "plumePlots",
//when dom structure is ready but before page insertion
postCreate: function(){
//run all parent postCreate functions
this.inherited(arguments);
},
startup: function(){ // added startup function
var menuNode = this.menu; // code moved to here
buildMenu(menuNode.id, _menuData); // and here
}
});
Upvotes: 1