This past week I needed a solution to do customized server-side work from the EditControlBlock menu in a list. I had to lace together a few solutions that I found when googling the net.
1) Creating a CustomAction as a feature to install on the SharePoint server.
2) Creating a custom WebControl for the CustomAction.
3) Utilize jQuery and a Generic Handler to perform server side code.
For the CustomAction it was pretty easy. You need to place the following XML in the elements.xml file for your feature.
elements.xml
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<CustomAction
Id="Unique Id Here"
Title="Action Name in Menu"
Description="Description of Action"
RegistrationType="List"
RegistrationId="101"
Location="EditControlBlock"
Sequence="1000"
ControlAssembly="[Fully Qualified Assembly Name]"
ControlClass="ImportXML.Import">
<UrlAction Url="javascript:ExecuteAJAXCall();"/>
</CustomAction>
</Elements>
This will create a CustomAction for the Edit Control Block menu. The Edit Control Block menu is the pop down menu that appears for List Items. RegistrationId can change based on the type of list you want to attach this CustomAction to.
The second part is creating a generic handler to handle the server side functionality.
HandlerRequest.ashx
<%@ Assembly Name="[Fully Qualified Assembly Name]" %><%@ WebHandler Language="C#" CodeBehind="HandlerRequest.ashx.cs" Class="HttpHandler.HandlerRequest" %>
HandlerRequest.ashx.cs
namespace HttpHandler
{
public class HandlerRequest : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string webUrl = context.Request.Form["thisWebUrl"];
string listName = context.Request.Form["thisListName"];
string stringListId = context.Request.Form["thisListItemId"];
int itemId = Convert.ToInt32(stringListId);
List<string> response = new List<string>();
try
{
using (SPSite site = new SPSite(webUrl))
{
using (SPWeb web = site.OpenWeb())
{
SPList list = web.Lists[listName];
SPListItem item = list.Items[itemId];
response.Add("1");
response.Add(item.ID.ToString());
response.Add(item.Title);
}
}
}
catch(Exception ex)
{
response.Add("0");
response.Add("Operations failed.");
response.Add(ex.Message);
response.Add(ex.StackTrace);
}
JavaScriptSerializer JSSerializer = new JavaScriptSerializer();
context.Response.ContentType = "text/plain";
context.Response.Write(JSSerializer.Serialize(response));
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
Finally I am using javascript in the default.master to compose the ExecuteAJAXCall() method. I utilized SharePoint Designer to access default.master.
Javascript
<script type='text/javascript' src='jquery.js' ></script>
<script>
function ExecuteAJAXCall() {
var userResponse = confirm("Are you sure you want to import this data?");
if (userResponse) {
$.post("/_layouts/ImportXML/ImportRequest.ashx",
{thisWebUrl:ctx.HttpRoot,thisListName:ctx.ListTitle,thisListItemId:currentItemID},
function(data, status, request){
Callback_AJAXCall(data, status, request);
},
'json'
);
}
};
function Callback_AJAXCall(data, status, request) {
if (data[0] == "1") {
alert(data[1]);
} else {
alert(data[1] + "\r\n\r\nError Message:" + data[2] + "\r\n\r\nStack Trace:" + data[3]);
}
};
</script>
After the creation of all these files you are ready to start putting it all together for the server.
1) The generic handler needs to be placed in the "12\TEMPLATE\LAYOUTS" folder.
2) The .dll file from the handler code needs to be placed in "InetPub\wwwroot\wss\VirtualDirectories\80\bin"
3) Last step is to install the feature through stsadm.exe command line utility and you are set!
Hope that helps out someone.