In this post we are going to see how we can get selected
list / document items from our customized ribbon control.
We may have a requirement to process multiple selected items
and then take user to another page for further processing or process the items
on another page and then show some messages to the user based on the processing
statuses.
If you have not gone through the series of customizing
Ribbon from SharePoint Kings, I would recommend you reading the entire series
first and then continue reading from here on.
We are going to take an example of document library.
First open up the project and add the empty element file to
the project.
Pay proper attention to what we are doing in this element file.
<?xml version="1.0" encoding="utf-8"?> <Elements > <CustomAction Id="NewItemCustomization" Location="CommandUI.Ribbon" RegistrationId="101" RegistrationType="List" Title="New Item Customization"> <CommandUIExtension> <CommandUIDefinitions> <CommandUIDefinition Location="Ribbon.Documents.Manage.Controls._children"> <Button Id="ListItemButton" Image16by16="/_layouts/images/CustomImages/Select16.png" Image32by32="/_layouts/images/CustomImages/Select32.png" Command="ListItemCommand" Description="Process Selected List Items" LabelText="Process List Items" TemplateAlias="o2" Sequence="81"/> </CommandUIDefinition> </CommandUIDefinitions> <CommandUIHandlers> <CommandUIHandler Command="ListItemCommand" CommandAction="[removed]avascript: function dialogCallback(dialogResult, returnValue){ SP.UI.Notify.addNotification(returnValue); SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK); } var selectedItems = SP.ListOperation.Selection.getSelectedItems(); var selectedItemIds = ''; var selectedItemIndex; for (selectedItemIndex in selectedItems){ selectedItemIds += '|' + selectedItems[selectedItemIndex].id; } var dialogOptions = { url: '/sites/SharePointSite/_layouts/MetadataSiteColumn/ProcessSelectedDocuments.aspx?selectedItems=' +selectedItemIds +'&ListId=' +SP.ListOperation.Selection.getSelectedList(), title: 'Set Document Prefix', allowMaximize: false, showClose: false, width:500, height:400, dialogReturnValueCallback: dialogCallback }; SP.UI.ModalDialog.showModalDialog(dialogOptions);" /> </CommandUIHandlers> </CommandUIExtension> </CustomAction> </Elements>
First we are targeting our customization to the manage group
in the document selection under documents tab. Hence we have taken up
Ribbon.Documents.Manage.Controls._children as location.
Next we have defined the button with 16 by 16 image and the
image is placed under the layouts folder. We have chosen the default alias for
template and a sequence number.
This will give us a result like this.
The important action here is what happens when the button is
clicked.
We have define the entire JavaScript inside the element file
itself.
In that first we have defined one function.
function dialogCallback(dialogResult, returnValue){
SP.UI.Notify.addNotification(returnValue);
SP.UI.ModalDialog.RefreshPage(SP.UI.DialogResult.OK);
}
This will make sure that when we get a result back from the
application page which we will built shortly we display a message as a part of
notification as well as we refresh the parent page.
then we take the selected documents. The procedure is same
also for the list items. We need to use SP.ListOperations.Selection and then
call getSelectedItems() to get all the selected items.
Once we get the items we need to separate them by some
separator. So in this example, we have
taken pipeline character. We will then process this items and split them in
application page code.
var selectedItems = SP.ListOperation.Selection.getSelectedItems();
var
selectedItemIds = '';
var
selectedItemIndex;
for
(selectedItemIndex in selectedItems){
selectedItemIds += '|' + selectedItems[selectedItemIndex].id;
}
Then we are actually opening up an application page and pass
on the selecteditems string that we built in prior function. we are also
registering the dialogue call back function which is the first function in our
code which will refresh the parent page and shows a message as a part of
notification.
another point to observe we also get the list name from
another method called getSelectedList.
var dialogOptions =
{
url:
'/sites/SharePointSite/_layouts/MetadataSiteColumn/ProcessSelectedDocuments.aspx?selectedItems='
+selectedItemIds +'&ListId='
+SP.ListOperation.Selection.getSelectedList(),
title: 'Set
Document Prefix',
allowMaximize: false,
showClose:
false,
width:500,
height:400,
dialogReturnValueCallback:
dialogCallback
};
So far so good. Time to create one application page. Right
click your project and then add application page as new item.
So in application page code behind, we will first take a
List object of type list items and then we will add to this object our list
items that we get from query string. We will bind them to a classic datalist
control of asp.net. But we will make sure that we do it in inputformsection.
In another Input form section we then have one textbox on
the application page. What we are planning to do is we will ask user to enter
document prefix and then we will process our documents and add a prefix to
them.
We will have button section and a button which will does
this processing of adding prefix to the documents.
Finally we will have a method which will do a magic trick of
adding a method called ExecuteOrDelayUntilScriptLoaded to the additional page
head of master page and register the method which will close the application page
with commonModalDialogClose method.
Here is the class code
public partial class ProcessSelectedDocuments : LayoutsPageBase { List<SPListItem> _selectedListItems = new List<SPListItem>(); protected override void OnLoad(EventArgs e) { // Get all the selected documents. string ListGUID = Request.QueryString["ListId"]; SPList selectedDocumentLibrary = SPContext.Current.Web.Lists[new Guid( ListGUID )]; string[] selectedItems = Request.QueryString["selectedItems"].ToString().Split('|'); for (int index = 1; index < selectedItems.Length; index++) { _selectedListItems.Add( selectedDocumentLibrary.GetItemById( int.Parse(selectedItems[index])) ); } // Bind to the repeater. SelectedDocumentsDataList.DataSource = _selectedListItems; SelectedDocumentsDataList.DataBind(); } protected void OnClickSetPrefixButton(object sender, EventArgs e) { foreach (SPListItem listItem in _selectedListItems) { listItem["Name"] = DocumentPrefixTextBox.Text + " " + listItem.File.Name; listItem.Update(); } CloseDialogOnSuccess(); } private void CloseDialogOnSuccess() { ContentPlaceHolder pageHead = this.Master.FindControl("PlaceHolderAdditionalPageHead") as ContentPlaceHolder; if (pageHead != null) pageHead.Controls.Add( new LiteralControl("[removed]ExecuteOrDelayUntilScriptLoaded(closeDialog,'sp.js');function closeDialog(){ SP.UI.ModalDialog.commonModalDialogClose(SP.UI.DialogResult.OK, 'Prefix assigned to selected documents.');}[removed]")); } }
and here is the application page aspx
<%@ Assembly Name="$SharePoint.Project.AssemblyFullName$" %> <%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="asp" Namespace="System.Web.UI" Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Assembly Name="Microsoft.Web.CommandUI, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="ProcessSelectedDocuments.aspx.cs" Inherits="MetadataSiteColumn.Layouts.MetadataSiteColumn.ProcessSelectedDocuments" DynamicMasterPageFile="~masterurl/default.master" %> <%@ Register TagPrefix="wssuc" TagName="InputFormSection" Src="~/_controltemplates/InputFormSection.ascx" %> <%@ Register TagPrefix="wssuc" TagName="InputFormControl" src="~/_controltemplates/InputFormControl.ascx" %> <%@ Register TagPrefix="wssuc" TagName="ButtonSection" Src="~/_controltemplates/ButtonSection.ascx" %> <asp:Content ID="PageHead" ContentPlaceHolderID="PlaceHolderAdditionalPageHead" runat="server"> </asp:Content> <asp:Content ID="Main" ContentPlaceHolderID="PlaceHolderMain" runat="server"> <table border="0" cellspacing="0" cellpadding="0" width="100%"> <tr> <td> <wssuc:InputFormSection runat="server" Title="Selected Documents" Description="The following documents have been selected to have the specified prefix added to their titles."> <Template_InputFormControls> <tr> <td> <asp:DataList ID="SelectedDocumentsDataList" runat="server" RepeatColumns="2" CellPadding="2" CellSpacing="5"> <ItemTemplate><li><%# DataBinder.Eval(Container.DataItem, "File.Name").ToString()%></li></ItemTemplate> </asp:DataList> </td> </tr> </Template_InputFormControls> </wssuc:InputFormSection> <wssuc:InputFormSection runat="server" Title="Document Prefix" Description="Prefix to add to the selected document titles."> <Template_InputFormControls> <wssuc:InputFormControl LabelText="Prefix to add to the selected documents:" runat="server"> <Template_control> <asp:TextBox ID="DocumentPrefixTextBox" runat="server" /> </Template_control> </wssuc:InputFormControl> </Template_InputFormControls> </wssuc:InputFormSection> <wssuc:ButtonSection runat="server" ShowStandardCancelButton="FALSE" TopButtons="TRUE"> <Template_Buttons> <asp:Button ID="SetPrefixButton" class="ms-ButtonHeightWidth" runat="server" Text="Set Prefix"> <asp:Button ID="CancelButton" class="ms-ButtonHeightWidth" runat="server" Text="Cancel"> </Template_Buttons> </wssuc:ButtonSection> </td> </tr> </table> </asp:Content> <asp:Content ID="PageTitle" ContentPlaceHolderID="PlaceHolderPageTitle" runat="server"> Application Page </asp:Content> <asp:Content ID="PageTitleInTitleArea" ContentPlaceHolderID="PlaceHolderPageTitleInTitleArea" runat="server" > My Application Page </asp:Content>
Time to deploy the application and test it.
Once the solution is deployed, open up a document library.
Select couple of documents as shown in image below.
Click on process list items button.
It will show up the selected documents name and a textbox to
enter the text that will be appended as a prefix.
I entered test and click on ok on model dialog application
page. The model application page closes and a notification is shown on parent
page and finally prefix gets applied.
I hope this helps.