dojo.provide("dojox.widget.MenuGenerator"); dojo.require("dijit._Widget"); dojo.require("dijit.Menu"); dojo.declare("dojox.widget.MenuGenerator", [dijit._Widget],{ // summary // A context menu generator constructor: function(){ this._entries = []; this._toHide = []; this.menuEntries = []; this.targetNodeIds = []; }, //menuEntries: Array // Json for creating menu. menuEntries: null, //targetNodeIds: Array // Array of dom node ids of nodes to attach to. // Fill this with nodeIds upon widget creation and it becomes context menu for those nodes. targetNodeIds: null, //leftClickToOpen: Boolean // If true, menu will open on left click instead of right click, similiar to a file menu. leftClickToOpen: false, //contextMenuForWindow: Boolean // if true, right clicking anywhere on the window will cause this context menu to open; // if false, must specify targetNodeIds contextMenuForWindow: false, //popupDelay: Integer // number of milliseconds before hovering (without clicking) causes the popup to automatically open popupDelay: 500, //String // class used for creating menu*/ menuClass: "dijit.Menu", menuItemClass: "dijit.MenuItem", subMenuItemClass: "dijit.PopupMenuItem", menuSeparatorClass: "dijit.MenuSeparator", checkedMenuItemClass: "dijit.CheckedMenuItem", //_menu:Object // popup menu. _menu: null, //_entries: Array // associative array for id/widget reference. _entries: null, //_toHide: Array // Elements to hide just before creation _toHide: null, startup: function(){ this.inherited("startup",arguments); this._menu = this._generateMenu(this.menuEntries,this.id + "_Menu"); this.connect(this._menu,"onOpen","onOpen"); this.connect(this._menu,"onExecute","onExecute"); this.connect(this._menu,"onCancel","onCancel"); this.connect(this._menu,"onClose","onClose"); dojo.forEach(this.targetNodeIds, this._menu.bindDomNode, this._menu); this.setHidden(this._toHide, true); }, destroy: function(){ this._menu.uninitialize(); for(var i in this._entries){ var entry = this._entries[i]; this._entries[i].destroyRecursive(); } this._menu.destroyRecursive(); delete this._menu; this.inherited("destroy",arguments); }, bindDomNode: function(/*see dijit.Menu.bindDomNode*/){ // summary: attach menu to given node return this._menu.bindDomNode.apply(this._menu,arguments); }, unBindDomNode: function(/*see dijit.Menu.unBindDomNode*/){ // summary: detach menu from given node return this._menu.unBindDomNode.apply(this._menu,arguments); }, getMenu: function(){ // summary: return the real menu widget return this._menu; }, _generateMenu: function(/*Array*/menuEntries, /*String|Object*/popUpMenu, /*Int, Optional*/insertIndex){ // summary: Generate the context menu with the data provided by the user // Warn : This method is recursive. // //menuEntries: An array representing the data to generate //popUpMenu: The menu id (or the menu object) //insertIndex: Position to insert items //menuEntries exemple : /* [ {id:"i1", onClick:dojo.hitch(this,"foo"), label : "foo"}, {id:"i2", label : "-"}, {id:"i3", label : "bar",subMenuId:"i3_Sub", subMenu : [ {id:"i3_Sub1", onClick:dojo.hitch(this,"foobar"), label : "foo bar", disabled:true}, {id:"i3_Sub2", onClick:dojo.hitch(this,"foobaz"), label : "foo baz", hidden:true} {id:"i3_Sub3", onClick:dojo.hitch(this,"foobarbaz"), label : "foo bar baz"} ] }, {id:"i4", onChange:dojo.hitch(this,"foo"), label : "bar", checked:true}, ] */ var menuProto = dojo.getObject(this.menuClass, false); var menuItemProto = dojo.getObject(this.menuItemClass, false); var subMenuItemProto = dojo.getObject(this.subMenuItemClass, false); var menuSeparatorProto = dojo.getObject(this.menuSeparatorClass, false); var checkedMenuItemProto = dojo.getObject(this.checkedMenuItemClass, false); if(typeof popUpMenu == "string"){ var popUpMenuId = popUpMenu; popUpMenu = dijit.byId(popUpMenu); if(typeof popUpMenu == "undefined" || popUpMenu == null){ popUpMenu = new menuProto({ id : popUpMenuId, leftClickToOpen : this.leftClickToOpen, contextMenuForWindow : this.contextMenuForWindow, popupDelay : this.popupDelay }); } } var menuItem = null; for(var i in menuEntries){ if(typeof menuEntries[i]["subMenu"] !== "undefined" && menuEntries[i].subMenu.length > 0){ var id = (typeof menuEntries[i].subMenuId == "string") ? menuEntries[i].subMenuId : menuEntries[i].id + "_Sub"; menuEntries[i].popup = this._generateMenu(menuEntries[i].subMenu, id); menuItem = new subMenuItemProto(menuEntries[i]); }else if(menuEntries[i].label == "-"){ menuItem = new menuSeparatorProto(menuEntries[i]); }else if(menuEntries[i].checked === true || menuEntries[i].checked === false){ menuItem = new checkedMenuItemProto(menuEntries[i]); }else{ menuItem = new menuItemProto(menuEntries[i]); } menuItem.startup(); this._entries[menuItem.id] = menuItem; if(typeof menuEntries[i].disabled != "undefined" && menuEntries[i].disabled != null && menuEntries[i].disabled == true){ menuItem.attr('disabled', true); } if(typeof menuEntries[i].hidden != "undefined" && menuEntries[i].hidden != null && menuEntries[i].hidden == true){ this._toHide.push(menuItem); } if(insertIndex == null || typeof insertIndex == "undefined"){ popUpMenu.addChild(menuItem); }else{ popUpMenu.addChild(menuItem,insertIndex); } menuItem = null; } try{ return popUpMenu; }finally{ popUpMenu = null; menuItem = null; } }, addItems: function(/*Array*/menuEntries, /*String|Object*/popUpMenu, /*Int, Optional*/insertIndex){ // summary: add some item into specified menu (and at specified position) this._generateMenu(menuEntries,popUpMenu,insertIndex); }, setItems: function(/*Array*/menuEntries){ // summary: replace all menu items this.removeItems(this.menuEntries); this._entries = []; this.menuEntries = menuEntries; this.addItems(this.menuEntries, this._menu); }, _transformEntriesParam: function(/*Object|Array|String*/value){ // summary: transform all kind of params in array return (typeof value == "string" || typeof value.declaredClass != "undefined") ? [value] : value; }, removeItems: function(/*Object|Array|String*/menuEntries){ // summary: remove some items. // menuEntries: Array , string, widget to determine item(s) to remove. menuEntries = this._transformEntriesParam(menuEntries); for(var i = 0; i < menuEntries.length; i++){ if(typeof menuEntries[i].declaredClass != "undefined"){ //widget? menuEntries[i].destroyRecursive(); }else{ //id ? var key = menuEntries[i]; if(typeof menuEntries[i] == "object"){ key = menuEntries[i].id; } this._entries[key].destroyRecursive(); } } }, setDisabled: function(/*Object|Array|String*/menuEntries, /*Bool*/ state){ // summary: enable or disable some items. // menuEntries: Array, string, widget to determine item(s) to disable. // state : true for disable, false for enable menuEntries = this._transformEntriesParam(menuEntries); for(var i = 0; i < menuEntries.length; i++){ if(typeof menuEntries[i].declaredClass != "undefined"){ //widget? menuEntries[i].attr('disabled', state); }else{ //id ? var key = menuEntries[i]; if(typeof menuEntries[i] == "object"){ key = menuEntries[i].id; } this._entries[key].attr('disabled', state); } } }, setHidden: function(/*Object|Array|String*/menuEntries, /*Bool*/ state){ // summary: display or hide some items. // menuEntries: Array, string, widget to determine item(s) to disable. // state : true for hide, false for show menuEntries = this._transformEntriesParam(menuEntries); for(var i = 0; i < menuEntries.length; i++){ if(typeof menuEntries[i].declaredClass != "undefined"){ //widget? dojo.style(menuEntries[i].domNode,'display',(state ? "none" : "")); }else{ //id ? var key = menuEntries[i]; if(typeof menuEntries[i] == "object"){ key = menuEntries[i].id; } dojo.style(this._entries[key].domNode,'display',(state ? "none" : "")); } } }, setLabel: function(/*Object|Array|String*/menuEntries, /*String*/ label){ // summary: Change label of some items // menuEntries: Array, string, widget to determine item(s) to change. // label : the new label to show menuEntries = this._transformEntriesParam(menuEntries); for(var i = 0; i < menuEntries.length; i++){ if(typeof menuEntries[i].declaredClass != "undefined"){ //widget? menuEntries[i].setLabel(label); }else{ //id ? var key = menuEntries[i]; if(typeof menuEntries[i] == "object"){ key = menuEntries[i].id; } this._entries[key].setLabel(label); } } }, onOpen: function(){ // summary: attach point for notification about when a menu item has been opened }, onExecute: function(){ // summary: attach point for notification about when a menu item has been executed }, onCancel: function(){ // summary: attach point for notification about when a menu item has been canceled }, onClose: function(){ // summary: attach point for notification about when a menu item has been closed } });