Dev Notes

Notes on Development with Microsoft Technologies

Add To Favorites in SharePoint

2 Comments

In a recent project, a co-worker described a scenario where users navigate to a site and review a handful of up to 30 or 40 reports/documents stored in the site. Each user visits the site on a periodic basis to review these various reports. My co-worker proposed allowing users to place links to the reports they need to review each period in a links library and then filter the default view to show links created by the current user. The client wanted to make it as easy as possible to add the report by including it as an option on the edit control block. In most cases, this would call for a farm solution that deploys a new ECB custom action. However, farm solutions are off limits — and this is a SharePoint 2007 environment so SPD custom actions are not available either.

My co-worked had already discovered a way to edit the ECB using JavaScript (http://ermeha.blogspot.com/2011/09/customizing-sharepoint-ecb-with.html) and then he called upon my expertise to create a script that would handle the work.

I started by simply creating a function that would render the new action on the ECB.

// Called by core.js to insert a new item into the ECB
var onGetMetaDataListName = null;

function Custom_AddDocLibMenuItems(m, ctx) {
	onGetMetaDataListName = ctx.listName; // Sets the name of the list for the ECB target
	CAMOpt(m, "Add favorite", "addDocumentToFavorites();", "/sites/community/assets/images/bookmark.png"); // Adds the menu option to the ECB
	CAMSep(m); // Adds a seperator to the ECB
}

This function is called by core.js and will insert the command into the ECB. A global variable is used to store the name of the list obtained when the new ECB action is created. When the user clicks on the ECB, the function addDocumentToFavorites() will be called. This is where the work begins.

But first, a few more global variables are defined to hold key information.

var serverRootUrl = "https://sharepointserver/"; // The root url for the server including the trailing slash
var rootSiteUrl = serverRootUrl + "sites/community/"; // The root absolute URL to the site including the trailing slash
var linkListName = "Links"; // The name of the list to write the link into
var urlFormat = "[[LINKURL]], [[LINKTITLE]]"; // The format of the url, must include the placeholders [[LINKURL]] and [[LINKTITLE]]

The addDocumentToFavorites() function is simply a way to call another function that expects callback functions.

// Called to actually kick off the addition of the item to the links list
function addDocumentToFavorites(){
	getMetaData(onGetMetaData_Success, onGetMetaData_Failed); //Calls the function to obtain metadata and to set the necessary callbacks for asynch operations
}

The first thing necessary is to get some additional metadata about the item that has been clicked to add as a favorite. Using SPServices, the list is queried for the necessary information which is passed into the success callback defined on the function. The variable currentItemID is defined in core.js and is used by the ECB to store the index of the selected item. This is used by SPServices to get the necessary information from the document. You could easily add more fields to be retrieved if your business rules called for it.

// Calls into the current document/report library to get metadata for the current item.
function getMetaData(callbackSuccess, callbackFailed) {
	// Make sure there is a current item selected
	if(currentItemID !== null){
		// Get metadata by querying the ECB list
		$().SPServices({
			operation: "GetListItems",
			listName: onGetMetaDataListName,
			CAMLViewFields: "<ViewFields><FieldRef Name=\"ReportLinkFilename\"/><FieldRef Name=\"Name\"/><FieldRef Name=\"FileRef\"/></ViewFields>",
			CAMLQuery: "<Query><Where><Eq><FieldRef Name=\"ID\"/><Value Type=\"Counter\">" + currentItemID + "</Value></Eq></Where></Query>",
			CAMLRowLimit: 1,
			async: true,
			completefunc: function (xData, Status) {
				// Check the status of the AJAX call to lists.asmx
				if(Status === "success") {
					// Successful, attempt to write to the list
					$(xData.responseXML).SPFilterNode("z:row").each(function () {
						var title = $(this).attr("ows_ReportLinkFilename");
						var linkUrl = $(this).attr("ows_FileRef").split(";#")[1];
						callbackSuccess(title, linkUrl);
					});
				} else {
					// Unsuccessful, indicate an error occured
					callbackFailed("Unable to retrieve information about the document.");
				}
			}
		});
	} else {
		// No item was set in the currentItemID
		callbackFailed("Unable to determine the correct item identifier.");
	}
}

Once the metadata has been queried, this information is passed into the success delegate and used to update the links list. Additionally, if any errors are encountered the failure delegate just simply shows an alert on the page.

// Callback to handle succcessful query for data
function onGetMetaData_Success(title, linkUrl) {
	// Format the URL
	var formatedUrl = urlFormat.replace("[[LINKURL]]",encodeURI(serverRootUrl + linkUrl)).replace("[[LINKTITLE]]",title);
	// Create the value pairs used for the update
	var valuePairs = [["Title",title],["URL",formatedUrl]];
	
	// Call SPServices
	$().SPServices({
		operation: "UpdateListItems",
		listName: linkListName,
		batchCmd: "New",
		async: true, 
		valuepairs: valuePairs,
		completefunc: function(xData, Status) {
			if(Status === "success") {
				// Check to make sure the individual call did not experience an error
				$(xData.responseXML).find("Result").each(function () {
					var error = $(this).find("ErrorCode").text();
					if(error === "0x00000000"){
						alert("Link added");
					} else {
						onGetMetaData_Failed("Unable to add the link to the list. There was an error processing the update.");
					}
				});
			} else {
				onGetMetaData_Failed("Unable to add the link to the list. The list could not be found or was not specified.");
			}
		}
	});
}

// Callback to handle any errors experienced during ajax operations
function onGetMetaData_Failed(message) {
	alert(message);
}

Next, an HTML fragment is created that links to jQuery, SPServices and my javascript file.

<script type="text/javascript" src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.3.min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery.SPServices/0.7.2/jquery.SPServices-0.7.2.min.js"></script>
<script type="text/javascript" src="/sites/community/SiteAssets/Script/addToLinks.js"></script>

All of the reports are stored in a document library. To add the functionality, it is necessary to edit the view for the library and include a content editor web part
and link the content to the HTML fragment. Once in place, the ECB will contain the new command and allow users to quickly add links to the links list. This makes it easy for users to quickly
add a new link to their favorites on the site. Since the links are stored in a links list, the user can also easily edit or remove links in the future.

Advertisements

Author: Chris Quick

I have been a developer of web based solutions since early 2001 delivering solutions to a wide array of organizations using ASP, ASP.NET and SharePoint. I was introduced to SharePoint in 2003 when the consulting firm I worked for at the time introduced it into the workplace. I began working with MOSS 2007 as soon as Microsoft released the RTM version in November 2006. The platform was implemented at the organization I worked for in 2007 and went live in March of that year. I was tasked with the administration and ongoing development of the platform. I currently work as a SharePoint Architect with Artis Consulting, developing solutions for a wide variety of business problems. The goal of this blog is to share my discoveries developing solutions with SharePoint. I welcome your comments and feedback to any post -- and I welcome suggestions for future topics.

2 thoughts on “Add To Favorites in SharePoint

  1. Hi Chris,
    are you sure this code is still valid for SharePoint 2010? I’m trying it, but my currentitemID is ALWAYS null, when I check the value of that variable inside the first function “AddDocumentToFavorites” I receive the correct ID, but as soon as I enter the callback function it’s null…

    any thoughts?

    • And never mind 🙂 I added an Alert to display the currentItemID, but as soon as this alert appeared the currentItemID was set to null… so yes, it still works! Thanks!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s