Friday, December 16, 2005 12:57 PM
matthias
Custom drop down menu like SharePoint does
In Windows Sharepoint Service sites a special drop down menu is used
for context menus of document library items. You can reuse the
javascript code for your own drop down menus. One example for such a
drop down menu is a custom 'create new document' combobox which lets
you choose a template for the new document from a list of registered
document templates. (In SharePoint you can select only one template per
document library which is not very useful in practice)
Here is what you have to do for it.
- Create a webpart that renders a hidden table with all elements
for your new 'magicmagic' combobox. The webpart registers the
javascript for displaying the combobox a la SharePoint
public MyWebPart()
{
this.PreRender += new EventHandler(PreRenderScript);
}
private void PreRenderScript(object sender , System.EventArgs e)
{
if(!Page.IsClientScriptBlockRegistered("MYSPDDScript"))
{
Page.RegisterClientScriptBlock("MYSPDDScript", "<script
language=""javascript""
src=""/_layouts/1031/t-myspdd.js""></script>");
}
}
protected override void RenderWebPart(HtmlTextWriter output)
{
output.RenderBeginTag(HtmlTextWriterTag.Table);
output.RenderBeginTag(HtmlTextWriterTag.Tr);
output.RenderBeginTag(HtmlTextWriterTag.Td);
foreach(Item contextMenuItem in Items)
// add your data for the context menu item instead of ... !
output.Write("<a name=\"MyData\" ... />\n");
output.RenderEndTag();
output.RenderEndTag();
output.RenderEndTag();
}
- Add a combobox to the xml file of a site and register mouse
events wich call the onMyItem-Method of your registered Javascript code
(step 1). The xml will look something like this.
<!-- MyButton -->
<td class="ms-toolbar" id="]]></HTML><GetVar Name="WPQ"/><HTML><![CDATA[buttonMy">
<table cellpadding=1 cellspacing=0 border=0>
<tr>
<td class="ms-toolbar" nowrap>
<img
src="/_layouts/images/newdoc.gif" ID="tbbutton1N"
alt=]]></HTML><HTML>"MyDropdown"</HTML><HTML><![CDATA[
border=0 width=16 height=16>
</td>
<td nowrap>
<table
class="ms-unselectedtitle" onmouseover="OnMyItem(this,
']]></HTML><GetVar
Name="MyParameter"/><HTML><![CDATA[')" CTXName="ctx1"
ItemId="1" >
<tr>
<td class="ms-vb" nowrap>MySomething</td>
<td><img src="/_layouts/images/blank.gif" width=13
style="visibility: hidden" alt=""></td>
</tr>
</table>
</td>
</tr>
</table>
</td>
- Write your own javascript with the help of the sharepoint
javascript for displaying the drop down menu. The code reads the table
items (created by the webpart in step 1) and fills the object
structures for the Sharepoint methods with it.
// triggered by onmouseover
// creates the contexmenu similar to OnItem in ows.js
function OnMyItem(elm, libUrl)
{
if(IsMenuOn())
{
StartDeferItem(elm);
return false;
}
if (itemTable != null)
OutItem();
itemTable = elm;
currentItemID = itemTable.ItemId;
var createCtx = new Function("setupMyMenuContext(" + itemTable.CTXName + ");");
createCtx();
var ctx = currentCtx;
itemTable.className="ms-selectedtitle";
itemTable.onclick = CreateMyMenu;
itemTable.oncontextmenu = CreateMyMenu;
itemTable.onmouseout = OutItem;
itemTable.libUrl = libUrl;
titleRow = itemTable.children[0].children[0];
i = 0;
while (titleRow.children[i] != null)
imageCell = titleRow.children[i++];
downArrowText = "MyCombo";
imageCell.children[0].src = ctx.imagesPath + "downarrw.gif";
imageCell.children[0].alt = downArrowText;
imageCell.children[0].style.visibility = "visible";
imageCell.style.visibility="visible";
imageCell.className="ms-menuimagecell";
return true;
}
function setupMyMenuContext(ctx)
{
currentCtx = ctx;
}
// creates the contextmenu-object similar to CreateMenu in ows.js
function CreateMyMenu()
{
if (! IsContextSet())
return;
var ctx = currentCtx;
if (itemTable == null || imageCell == null ||
(onKeyPress == false &&
(event.srcElement.tagName=="A" ||
event.srcElement.parentNode.tagName == "A")))
return;
IsMenuShown = true;
window.document.body.onclick="";
m = CMenu(currentItemID + "_menu");
currenMenu = m;
AddMyMenuItems(m, itemTable.libUrl, ctx);
OMenu(m, itemTable, null, null, -1);
document.body.onclick=HideSelectedRow;
return false;
}
// adds the menu entries for every a-element rendered in RenderWebPart
function AddMyMenuItems(m, libUrl, ctx)
{
setupMenuContext(ctx);
if(document.getElementsByName("MyDat") != null)
{
for(i = 0; i < document.getElementsByName("MyDat").length; i++)
{
var myData = document.getElementsByName("MyData")[i];
var optionEntry = document.createElement("option");
strTitle = ""; // add your menu item text here
(i.e. myData.Title)
strAction = ""; // add your menu item selection
action here
// i.e. call createNewDocumentWithProgID to launch an office app with a
new document
strImagePath = ""; // add the path to the menu item icon here
// CAMSep(m); // adds a separator in the menu item list
// add the next item to the drop down menu
mi = CAMOpt(m, strTitle, strAction, strImagePath);
}
}
}
The code is a little bit
cumbersome but works in the current versions of Sharepoint Portal
Server and Windows Sharepoint Services. As the previous code relies
heavily on the internal script structure of SharePoint it can not be
guaranteed, that this method will work in the next versions.