Search This Blog

Thursday, September 25, 2014

How to add ribbon button in SharePoint list and library

The premise behind the ribbon is that it provides a more results-driven interface. Users focus on what they are doing, and commands are presented only for those things they can do at a specific time.

Those who think that ribbon concept is completely new in SharePoint 2010 are wrong. It was also in SharePoint 2007 to add button in that menu bar etc. Actually in SharePoint 2007, users face difficult to find actions button. So in SharePoint 2010, Microsoft added the Server ribbon to SharePoint to address this problem and added additional things to make it more powerful. Let me get in to more detail in ribbon button show that we can create our custom ribbon button.

Adding custom ribbon button in SharePoint list and library to provide various actions can make user life very easy. Let me take an out box ribbon button example to make you realize importance of ribbon button.  If you are familiar with SharePoint 2010, you must aware about "Delete" ribbon button. Refer Mentioned below screenshot; user has options to delete multiple items at a time using delete ribbon button. But in SharePoint 2007 user will have to delete itemsone by one. So one of the best use of ribbon button to provide bulk operation in the SharePoint and you can use this architecture to provide various functionalities in the ribbon button to make good user experience.

Out-Of-Box-Ribbon-Button

Now we know the importance of ribbon button, so it is right time to get our hand dirty with custom ribbon button(Download sample code). 

Steps to add ribbon button:
1.  Create a "Empty SharePoint Project" > Add New Item > Click Empty Element
SharePoint-Empty-Element


2.  Copy following XML file into Empty Element file
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  <CustomAction
  Id="ShowHelloWorldButton"
  RegistrationType="List"
  RegistrationId="100"
  Location="CommandUI.Ribbon.ListView"
  Rights="EditListItems">
    <CommandUIExtension>
      <CommandUIDefinitions>
        <CommandUIDefinition
         Location="Ribbon.ListItem.Actions.Controls._children">
          <Button
           Id="Ribbon.ListItem.Actions.Controls.ShowHelloWorldButton"
           Alt="Show HelloWorld Alert"
           Sequence="1"
           Image32by32="/_layouts/DemoSharePointRibbon/HelloWorld.jpg"
           Command="ShowHelloWorldCommand"
           LabelText="Hello World"
           TemplateAlias="o1"
           CommandType="General"/>
        </CommandUIDefinition>
      </CommandUIDefinitions>
      <CommandUIHandlers>
        <CommandUIHandler
         Command="ShowHelloWorldCommand"
         CommandAction="javascript:alert('Hello World');" />
      </CommandUIHandlers>
    </CommandUIExtension>
  </CustomAction>
</Elements>

3.  Deploy this solution, a hello world button will appear in all the custom list

Custom-Ribbon-Button

Our first "Hello World" ribbon button is ready. Now I will walk you through important configurable properties of "Element .xml" file.
Property
Description
RegistrationType
None, List,  ContentType,  ProgId  or  FileType
E.g. To show ribbon button on SharePoint list set List
RegistrationId
It is identifier of the list or item content type that this action is associated with. E.g. 100 RegistrationId is used to attach action with the custom list.
Location
Location of this custom action. Few important locations are mentioned below:
·         Microsoft.SharePoint.SiteSettings
·         If the custom action is a menu item or toolbar button, the possible options include EditControlBlock, NewFormToolbar, DisplayFormToolbar, and EditFormToolbar.
·         If the CustomAction element contains a CommandUIExtension child element, the Location must start with "CommandUI.Ribbon". E.g. In the "Hello World" sample we used CommandUI.Ribbon.ListView.

Rights
·         If it is not specified, the action always appears in the list of actions.
·         Specifies a set of rights, so that it will visible only if user has all specified rights (logical AND will be applied if we assign multiple permission comma separated).
Few important values for "Rights" property are mentioned below:
ViewListItems, AddListItems, EditListItems, OpenItems, ViewVersions, ManagePersonalViews, ViewFormPages, Open, ViewPages, CreateSSCSite, BrowseDirectories, BrowseUserInfo, AddDelPrivateWebParts, UpdatePersonalWebParts, UseRemoteAPIs, CreateAlerts, EditMyUserInfo
E.g. Specified "EditListItems" right to visible this button to the user who has edit item permission.
Sequence
Specifies the ordering priority for actions

Button properties:
Property
Description
Sequence
Order of placement if there are multiple ribbon buttons
Command
The name of the command to execute when the control is clicked.
Note:  Command attribute of the control should be the same as the value of the Command attribute of a corresponding CommandUIHandler element.
E.g. "ShowHelloWorldCommand" is used in our sample.
CommandType
General | OptionSelect | IgnoredByMenu

Above mentioned information is enough to create ribbon button, but I wanted to highlight few challenges you are going to face when you actually started using it to solve real time requirement in your application:

1. Show ribbon button in the specific group:  In our "Hello World" ribbon button appear in the "Actions" group. What if, we want appear in the other group like Manage, "Share & Track", "Workflows" etc.  If you see element file of our sample carefully, we have specified location (Ribbon.ListItem.Actions.Controls._children) in the "CommandUIDefinition". So using this attribute we can change the group of ribbon button.

2. Button should be visible to user having specific permission:  We have already discussed about the "Rights"attribute of button element, by specifying "Rights" attribute we can handle this scenario.

3. External JavaScript file:  In our "Hello World" sample we need write just online line of JavaScript code. But to solve real world problem we need to write a lots of JavaScript code. So it is not a good idea to write JavaScript code in element file. In this case, we need an external JavaScript file to maintain code. There are two ways to achieve the same. Either create a JavaScript file and put reference in your mater page or follow the mentioned below steps to associate external JavaScript file:
a. Add this mentioned below custom action in your element file and put your JavaScript in the JavaScript file (e.g. HelloWorld.js).
<CustomAction
    Id="ShowHelloWorldCommand.Script"
    Location="ScriptLink"
    ScriptSrc ="/_layouts/DemoSharePointRibbon/js/HelloWorld.js"/>

b.  Call JavaScript method from "CommandAction" instead of writing inline JavaScript.

4. How to get selected items when user clicks on ribbon button: Put mentioned below code to get selecteditems:
//Using JavaScript client object model, we can get the selected items id
function GetSelectedItemsId() {
    var ctx = SP.ClientContext.get_current();
    var items = SP.ListOperation.Selection.getSelectedItems(ctx);
    var selectedItems = '';
    for (index in items) {
        selectedItems = selectedItems + ',' + items[index].id;
    }
    return selectedItems;
}

5. Button should be disable if no item selected in the list view:  Just check the behavior of out of box "Delete" ribbon button, If there is no item select, this button will be disable. Follow mentioned below steps to achieve this functionality:

a. Add following attribute in the element file under "CommandUIHandler" section:

<CommandUIHandlers>
        <CommandUIHandler
         Command="ExternalFileShowHelloWorldCommand"
         EnabledScript="javascript:EnableButton();"
         CommandAction="javascript:ShowAlert();" />
</CommandUIHandlers>

b. Add following JavaScript code in the external file:
function EnableButton() {
    var ctx = SP.ClientContext.get_current();
    var items = SP.ListOperation.Selection.getSelectedItems(ctx);
    return items.length > 0;
}

6. How to perform server site operation using ribbon button:
There are three ways to do server site operation. They are mentioned below:

a.  Put following code for postback and server side using the request id we can identify the button, and then perform action accordingly:
<CommandUIHandlers>
        <CommandUIHandler
         Command="ExternalFileShowHelloWorldCommand"
         EnabledScript="javascript:EnableButton();"
         CommandAction="__doPostBack('ShowHelloWorldPostback','');" />
</CommandUIHandlers>
//On page load check for request id 
if (this.Page.Request["__EVENTTARGET"] == "ShowHelloWorldPostback")
{
    //Call your method
}


 Note:  Selected items collection will be available in the server side. If you want selected items server side, before calling _doPostBack method save selected items id in the hidden variable.

b.  Use JavaScript client side object model to perform action like add, edit, delete.
For example, suppose we have to provide functionality to change status of selected items to approve. So we can use following client side code to achieve the same:
function ApproveSelectedItems() {
    var ctx = SP.ClientContext.get_current();
    var items = SP.ListOperation.Selection.getSelectedItems(ctx);
    var web = ctx.get_web();
    var crList = web.get_lists().getById (SP.ListOperation.Selection.getSelectedList(ctx));
    var index;
    for (index in items) {
        var selectedItem = crList.getItemById(items[index].id);
        selectedItem.set_item(columnName, columnValue);
        if ('' != currentList && changeRequestListName == currentList) {
            selectedItem.set_item('Status''Approve');
        }
        selectedItem.update();
    }
    ctx.executeQueryAsync(Function.createDelegate(thisthis.onsccess),
Function.createDelegate(thisthis.onFail));
}
function onsccess (sender, args) {
    if (this.SuccessMsg != undefined || this.SuccessMsg != null) {
        alert(this.SuccessMsg);
    }
}
function onfailure (sender, args) {
    alert(MsgOperationFailed);
}


Note:  But in this approach we are not providing any option to enter the status. But ideally we should ask from you to select option or enter status of the item. Because user might approve or reject the selected items.

c.  Using layout page we can provide user to input information before updating or performing any action on any item. Follow mention below steps to achieve the same:
i.  Create a layout page say approve.aspx
ii.   Write your server side code in the code behind of layout page
iii.  When user click on ribbon button, open layout page in the popup using SharePoint modal dialog API
iv.  Pass selected items id as a query string parameter to the layout page
v.  Read query string parameter
vi.  Perform whatever action you want to do it on selected items  




No comments:

Post a Comment