Customizing the SharePoint ECB with Javascript, Part 2
Other articles in this series:
- Customizing the SharePoint ECB with Javascript, Part 1
- Customizing the SharePoint ECB with Javascript, Part 3
In the previous article in this series I explained how to add menu items in the Edit Control Block of Lists and Document Libraries. The menu items added so far are all displayed at the same level; directly in the ECB. It is possible however to build hierarchical menus (menu items with sub menu items) using this technique as well. A good example of a hierarchical menu in the ECB is the default Send To menu:
Actually this is very easy to accomplish, instead of the CAMOpt Javascript function discussed in the previous post, the function CASubM can be used to create fly-out menu items (the ‘parent’ menu items). The following code snippet makes use of this technique:
function Custom_AddListMenuItems(m, ctx) {
var menuItem = CASubM(m,"Menu Item", "/_layouts/images/LWV16.GIF")
CAMOpt(menuItem, "Sub Menu Item 1", "alert('Hello World!');");
CAMOpt(menuItem, "Sub Menu Item 2", "alert('Hello World!');");
var subMenuItem = CASubM(menuItem,"Sub Menu Item 3")
CAMOpt(subMenuItem, "Sub Menu Item 4", "alert('Hello World!');");
CAMOpt(subMenuItem, "Sub Menu Item 5", "alert('Hello World!');");
CAMSep(m); // separator
return false; // render the default menu items too
}
When this code is dropped in a Content Editor web part on a List page for example (see the previous article for the steps to follow), the rendered ECB will have the Menu Item at the first level. This item contains three child menu items; the third child on itself contains two additional child menu items.
As already mentioned the key to this technique is the CASubM Javascript function. The return value is a reference to the menu item that is created; it is this instance that is used as a parameter of the CAMOpt function to specify on which level the menu item should be created. The CASubM function can have 6 parameters (the first two are required):
- a reference to the parent menu (just like the CAMOpt function)
- the text to display
- the URL of an icon for the menu item
- the HTML alt attribute value of the icon
- the HTML sequence attribute value of the menu item
- the HTML description attribute value of the icon
The code discussed above is a basic sample that does nothing more than displaying a Hello World message box when one of the list items is clicked. In real life you probably want to do something interesting when the user clicks on an ECB menu item; let’s try to create the following ECB:
The code to render the Open in New Window menu item, including the sub menu items, goes as follows:
function Custom_AddListMenuItems(m, ctx) {
var openMenu = CASubM(m,"Open in New Window");
CAMOpt(openMenu, "View Item", "alert('Todo');");
CAMOpt(openMenu, "Edit Item",
"alert('Todo');", "/_layouts/images/edititem.gif");
return false; // render the default menu items too
}
So far nothing new or exciting, the challenge however is to come up with the Javascript functions which will be called when the View Item or Edit Item sub menu items are clicked (now they just display a dialog box). The issue (or challenge) is that the Javascript function needs to now for which item in the List or Document Library the ECB is rendered. Once again the core.js is helping us out; it contains code that populates some context information about these items. There is for example a variable in the core.js called currentItemID which contains the ID of the List item or Document for which the ECB is being rendered. Some other interesting variables at the same location are: currentItemIcon, currentItemFileUrl, currentItemCheckedOutUserId and currentItemModerationStatus. For a full list, just open the core.js file in the \12 hive and you’ll see all of them at the top. Besides those variables there is also an object called ctx with even more information about the List or Document Library itself. The ctx object is defined in the init.js, and has properties like listName, view, displayFormUrl etc. So if we adopt the code to build some URL’s which will be opened in a new window, the work is done.
function Custom_AddListMenuItems(m, ctx) {
var viewURL = window.location.protocol + "//" + window.location.host +
ctx.displayFormUrl + "?ID=" + currentItemID;
var editURL = window.location.protocol + "//" + window.location.host +
ctx.editFormUrl + "?ID=" + currentItemID;
var openMenu = CASubM(m,"Open in New Window");
CAMOpt(openMenu, "View Item", "window.open('" + viewURL + "');");
CAMOpt(openMenu, "Edit Item",
"window.open('" + editURL + "');", "/_layouts/images/edititem.gif");
return false; // render the default menu items too
}
Using the variables found in the core.js and init.js files, you have access to the most basic set of metadata. But quite often it’s necessary to have access to even more metadata like non default fields etc. In the next article in this series, I’ll show you how this can be accomplished.