The SharePoint 2010 Ribbon is highly customizable. This paper will demonstrate how to add a button to the View Item form that will create a copy of the current item in the list. This example will use the Tasks list, but the steps are generally applicable for any list type. The general steps are as follows:
1. Create a new Visual Studio SharePoint 2010 project of the type Empty SharePoint Project
2. Enter the web site for testing and choose Deploy as a sandboxed solution. (Note: If deploying along with workflows or other customizations that required GAC-installed DLLs or files on the file system you will want to use a Farm Solution)
3. In Solution Explorer, right click the project name and click Add -> New Item.
4. Choose Empty Element from the item types and give it a name, such as CustomActions
5. At this point you will have an empty elements file
![1_thumb[1]_thumb[3][3] 1_thumb[1]_thumb[3][3]](http://www.joshmeyer.net/blog/image.axd?picture=1_thumb%5B1%5D_thumb%5B3%5D%5B3%5D.jpg)
Add the following XML between the Elements tags:
<CustomAction Id="Contoso.CustomActions.CopyTaskAction"
Location="CommandUI.Ribbon"
RegistrationId="107"
RegistrationType="List"
Sequence="1">
<CommandUIExtension>
<CommandUIDefinitions>
<CommandUIDefinition Location="Ribbon.ListForm.Display.Manage.Controls._children">
<Button Id="Contoso.Ribbon.CopyTask"
Command="Contoso.Ribbon.CopyTask"
Sequence="5"
Image16by16="/_layouts/images/NoteBoard_16x16.png"
Image32by32="/_layouts/images/NoteBoard_32x32.png"
Description="Uses the notification area to display a message."
LabelText="Copy Task"
TemplateAlias="o1"/>
</CommandUIDefinition>
</CommandUIDefinitions>
</CommandUIExtension>
</CustomAction>
<CustomAction>
(http://msdn.microsoft.com/en-us/library/ms465980.aspx)
The CustomAction tag is used for deploying custom actions to the SharePoint UI. This includes many types of customizations, such as the Site Actions menu and the item context menus, as well as the ribbon.
The Location attribute specifies where the custom action will be created. For the Ribbon, the location should be CommandUI.Ribbon.
The RegistrationId and RegistrationType attributes specify what type of objects to attach the customization to as well as the specific IDs of the specified type. In this case, we want the customization to be attached to a list of type 107 (107 is the list template ID for the Tasks list).
Sequence is used throughout SharePoint declarative programming and refers to the order in which an element appears in the UI. Lower sequences appear first. SharePoint typically uses multiples of 10, but you will probably have to check the definitions yourself if you’re trying to place a customization in a very specific location, like between two other SharePoint elements.
<CommandUIDefinition>
(http://msdn.microsoft.com/en-us/library/ff458373.aspx)
This is used for adding specific elements to the SharePoint UI.
The Location attribute of the CommandUIDefinition specifies exactly where in the Ribbon the customization should be located. In this case we want the button to appear in the Manage group of the list item Display form. Specifying Controls._children tells SharePoint to add the customization to the controls collection of the specified group.
<Button>
(http://msdn.microsoft.com/en-us/library/ff458366.aspx)
As might be expected, the Button tag represents a button in the Ribbon.
The Command attribute specifies the command to be executed when the button is clicked. This will be used in the CommandUIHandler to execute some JavaScript code.
The Image16by16 and Image32by32 attributes allow specify the large and small icons to be used with the button. The 16 and 32 represent pixel sizes for the respective images.
The LabelText attribute is the text that will be displayed on the button in the Ribbon.
The TemplateAlias attribute specifies a display template for the button. These are defined by SharePoint and can be found in the SharePoint root directory at TEMPLATE\GLOBAL\XML\CMDUI.XML. In this case, setting the attribute to “o1” will display a large icon similar to the “Edit Item” button, and “o2” will display a small icon similar to the “Delete Item” button.
6. Deploy the solution from Visual Studio. At this point you will see the button in the View form but it will be disabled because there are no handlers defined for it yet.
![2_thumb_thumb_thumb[3] 2_thumb_thumb_thumb[3]](http://www.joshmeyer.net/blog/image.axd?picture=2_thumb_thumb_thumb%5B3%5D.jpg)
Now copy the following XML between the closing CommandUIDefinitions and the closing CommandUIExtension tags:
<CommandUIHandlers>
<CommandUIHandler
Command="Contoso.Ribbon.CopyTask"
CommandAction="javascript:
if(confirm('Copy Task, are you sure?')){
var ctx;
var taskList;
var web;
var taskItem;
//Get client context
ctx = new SP.ClientContext.get_current();
//Get reference to current web
web = ctx.get_web();
//Load web into context
ctx.load(web);
//Get reference to current list
taskList = web.get_lists().getById('{ListId}');
//Load list into context
ctx.load(taskList);
//Get reference to current list item
taskItem = taskList.getItemById('{ItemId}');
//Load listitem into context, including specified columns.
ctx.load(taskItem);
//Perform batched queries on server
ctx.executeQueryAsync(onQuerySucceeded, onQueryFailed);
}
function onQuerySucceeded(sender, args) {
//Create ListItemCreationInformation for use when creating new task item
var taskItemInfo = new SP.ListItemCreationInformation();
//Create new request item
newTask = taskList.addItem(taskItemInfo);
//Set properties on new request from current request
newTask.set_item('Title','COPY OF TASK {ItemId}');
newTask.set_item('Body',taskItem.get_item('Body'));
newTask.set_item('AssignedTo',taskItem.get_item('AssignedTo'));
newTask.set_item('DueDate',taskItem.get_item('DueDate'));
newTask.set_item('Priority',taskItem.get_item('Priority'));
newTask.set_item('StartDate',taskItem.get_item('StartDate'));
newTask.set_item('TaskGroup',taskItem.get_item('TaskGroup'));
//Update database with changes
newTask.update();
//Load new request into context
ctx.load(newTask);
//Perform batched operations on server
ctx.executeQueryAsync(requestAddSucceeded, requestAddFailed);
}
function requestAddSucceeded(sender, args) {
//Notify user that copy succeeded
SP.UI.Notify.addNotification('Task copied successfully');
}
function requestAddFailed(sender, args)
{
//Notify user that copy failed
SP.UI.Notify.addNotification('Task failed to copy!');
}
function onQueryFailed(sender, args)
{
//Notify user that an error occurred
SP.UI.Notify.addNotification('Error copying task!');
}
"
/>
</CommandUIHandlers>
<CommandUIHandler>
(http://msdn.microsoft.com/en-us/library/ff458385.aspx)
This tag defines a handler for a custom action command. In this case we want to define a handler for the Contoso.Ribbon.CopyTask command, which we specify in the Command attribute.
The CommandAction attribute is where we define the handler for the command. Here we add the javascript to actually perform the copy using the SharePoint ECMAscript Client Object Model. I won’t go into detail here about programming against the Client OM, but there are many good articles, blog posts, etc. out there. Some good ones I’ve found are *here*…
In a nutshell, the javascript code gets a reference to the task using the {ListId} and {ItemId} tokens, which are replaced at runtime with the IDs of the list and item from the current context (e.g. the item being displayed in the View form). Then a new task is created in the same list and the properties are populated from the current task. As far as I can tell, this is the best way to perform a copy on a list item. There is no CopyTo method or anything like that, at least that I could find.
7. With the CommandUIHandlers code added, redeploy the solution. You will now be able to click the Copy Task button.
and when you click the button you will be prompted to confirm your desire to copy the task…
and when you click OK you will be notified, using the new notification framework, that the task copied successfully.
![5_thumb_thumb_thumb[3] 5_thumb_thumb_thumb[3]](http://www.joshmeyer.net/blog/image.axd?picture=5_thumb_thumb_thumb%5B3%5D.jpg)
8. Refreshing the list view, you will see the original task and the new copy.
![6_thumb_thumb_thumb[3] 6_thumb_thumb_thumb[3]](http://www.joshmeyer.net/blog/image.axd?picture=6_thumb_thumb_thumb%5B3%5D.jpg)
Here’s a few helpful blog posts related to Ribbon Customizations and the ECMAscript Client OM:
- Chris O’Brien’s series on Ribbon Customizations
- Channel 9 Developer Training videos on the Client OM