« Outlook-Fu: How to 'Snooze' Email in Your Inbox | Main | Add a Little Holiday Wonder to SharePoint: Cost $3, Time 10 Minutes »
Tuesday
Jan152013

A Fresh Visualization for SharePoint Calendars with SPServices

This is a set of scripts that can be dropped into a SharePoint 2010 deployment to allow for an alternate view of calendar lists.

There was also a request to color cancelled items that the user had on the calendar so I've left that code in there. The widget display start and end times as well as alter the behavior for those events that span days. I also added CAML support so you can provide your own query to it if you want or just you the built-in default. There is a separate CSS file to do your own styling and a few images that I use. One is optional and controlled by the arguments to the script.

I chose to set this up to live in our farm's common repository and be called relatively easily from any page so you see 2 files here, one being the LoadCalendarWidget function and the other being the code we drop into a page to create the calendar control. Options/args you pass to the function are:

  1. Site's URL, no end '/' character
  2. List name
  3. Title to appear for the webpart
  4. GUID of your calendar list
  5. # of results to show
  6. Optional CAML query to use
  7. Indicator to show icon or use 'Add to Outlook' text instead

If you want to keep it simple and not place file directly on your farm's servers, the zipped package below has all of the files needed and is just about ready-to-use for a dirt-simple deployment.  There is a PDF included that contains instructions on use that are a little more detailed than in the posting that follows.

Download all code and images used here.

This is the code we call to create the control. I house this in a text file in a library and add to the page in a CEWP as the 'Content Link'.

<!-- jQuery -->
<script type="text/javascript" src="https://myfarm/_layouts/1033/jquery.SPServices-0.7.2.min.js"></script>
<script type="text/javascript" src="https://myfarm/_layouts/1033/jquery.dateFormat.js"></script>
<!-- Calendar Widget -->
<script type="text/javascript" src="https://myfarm/_layouts/1033/jquery.SPS.Calendar_Widget-1.0.js"></script>
<link href="/_layouts/1033/styles/Calendar_Widget.css" type="text/css" rel="stylesheet" />
<script language = "javascript">
	$(document).ready(function() {		
		LoadCalendarWidget("https://myfarm/hr/", "Upcoming HR Events Calendar", "Event Calendar", "{B7FE9372-9724-4504-9699-DEDD445B1BA3}", 8, ,true);	
	});	
</script>
<div id="cw_TopContainer" style="margin-bottom:15px;"><div id="cw_HeaderContainer"><table style="width:100%;"><tr><td><span id="cw_HeaderTitle"></span></td><td style="text-align:right;"><a id="cw_HeaderLink" href="#" >Calendar View</a></td></tr></table></div><div id="cw_ItemsContainer" /></div>

And this is the function. I put it in our 14 hive for access across the farm, you put it where you want, just make sure the script source in the code above points to where you dropped this.

// REQUIRES:
// - jquery-1.8.0.js or higher
// - jquery.SPServices-0.7.2.min.js or higher
// - jquery.dateFormat.js

function LoadCalendarWidget(cw_SiteUrl, cw_ListName, cw_ListNameForHeader, cw_EncodedListGuid, cw_ReturnRowCount, cw_CAML , cw_ShowIcon)
{
	// USAGE: --------------
	// cw_SiteUrl = "https://myfarm/hr/"; // Site's URL, no end '/' character
	// cw_ListName = "HR Events Calendar"; // List name
	// cw_ListNameForHeader = "Upcoming HR Events";  // what will appear in webpart
	// cw_EncodedListGuid = "{B7FE9372-9724-4504-9699-DEDD445B1BA3}";  // GUID of your calendar list
	// cw_ReturnRowCount = 15;  // # of results 
	// cw_CAML = Your optional CAML query
	// cw_ShowIcon = true;  // false will use 'Add to Outlook'

	var cw_ListUrlForHeader = cw_SiteUrl + '/lists/' + cw_ListName;
	var cw_IcsEventPath = cw_SiteUrl + "/_vti_bin/owssvr.dll?CS=109&Cmd=Display&List=" + cw_EncodedListGuid + "&CacheControl=1&Using=event.ics&ID=";
	var cw_ListItemDetailPath = cw_SiteUrl + "/Lists/" + cw_ListName + "/DispForm.aspx?ID=";
	var cw_CamlQuery = "";
	if (cw_CAML.length < 2) {
		cw_CamlQuery = "<Query><Where><Geq><FieldRef Name='EventDate' /><Value IncludeTimeValue='TRUE' Type='DateTime'><Today/></Value></Geq></Where></Query>";}
	else { cw_CamlQuery = cw_CAML; }

	// format header info
	$('#cw_HeaderTitle').html(cw_ListNameForHeader);  // title
	$('#cw_HeaderLink').attr('href',cw_ListUrlForHeader); // link
	
   $().SPServices({
		operation: "GetListItems",
		webURL: cw_SiteUrl, 
		listName: cw_ListName,
		async: false,
		CAMLRowLimit: cw_ReturnRowCount,
		CAMLQuery: cw_CamlQuery,	 
	 
		completefunc: function (xData, Status) {							
		   $(xData.responseXML).SPFilterNode("z:row").each(function() {				
				var cw_id = ($(this).attr("ows_ID"));
				var cw_title = ($(this).attr("ows_Title"));
					if(cw_title.length == 0) {cw_title = 'No event title.';}
					
				// By request, if an item is canceled, make that fact stand out.
				cw_title = cw_title.replace("Deleted:","<span class='cw_canceled'>DELETED:</span> ");
				cw_title = cw_title.replace("DELETED:","<span class='cw_canceled'>DELETED:</span> ");
				cw_title = cw_title.replace("Cancelled:","<span class='cw_canceled'>CANCELLED:</span> ");
				cw_title = cw_title.replace("CANCELLED:","<span class='cw_canceled'>CANCELLED:</span> ");
				
				// Clean up date formats				
				var cw_startdateday = 		$.format.date(($(this).attr("ows_EventDate")), "M/d/yyyy");
				var cw_startdatetime = 		$.format.date(($(this).attr("ows_EventDate")), "h:mm a");
				var cw_startdate = 			cw_startdateday + ' - ' + cw_startdatetime;
				var cw_enddateday = 		$.format.date(($(this).attr("ows_EndDate")), "M/d/yyyy");
				var cw_enddatedaytime = 	$.format.date(($(this).attr("ows_EndDate")), "h:mm a");
				var cw_enddate = 			cw_enddateday + ' - ' + cw_enddatedaytime
				
				var cw_CX = '<div class="cw_item">';
				if(cw_startdateday == cw_enddateday)  // single day event
				{
					cw_CX += '<table width="100%" cellpadding="0">';
					cw_CX += '<tr><td colspan="2"><a href="' + cw_ListItemDetailPath + cw_id + '" target="_new" class="cw_title">' + cw_title + '</a></td></tr>';					
					cw_CX += '<tr><td><span class="cw_time">' + cw_startdateday + ' ' + cw_startdatetime + ' to ' + cw_enddatedaytime +'</span></td>';
					cw_CX += '<td align="right" valign="top"><a href="' + cw_IcsEventPath + cw_id + '" target="_new">';					
					if(cw_ShowIcon) {
						cw_CX += '<img src="FARM/Images/add_item.png" class="cw_addIcon" title="Add to Outlook Calendar" /></a></td></tr>'; 
					}
					else { cw_CX += '[Add to Outlook]</a></td></tr>'; }						
					cw_CX += '</table>';
				}
				else // multi day event
				{
					cw_CX += '<table width="100%" cellpadding="0">';
					cw_CX += '<tr><td colspan="2"><a href="' + cw_ListItemDetailPath + cw_id + '" target="_new" class="cw_title">' + cw_title + '</a></td></tr>';					
					cw_CX += '<tr><td><span class="cw_time">Start:' + cw_startdate + '</span></td><td align="right" rowspan="2" valign="top"><a href="' + cw_IcsEventPath + cw_id + '" target="_new">';
					
					if(cw_ShowIcon) {
						cw_CX += '<img src="https://cbhq.cbh.com/_layouts/images/myelite2/cal/add_item.png" class="cw_addIcon" title="Add to Outlook Calendar" /></a></td></tr>';
					}
					else { cw_CX += '[<a href="' + cw_IcsEventPath + cw_id + '" target="_new">Add to Outlook]</a></td></tr>'; }						
					cw_CX += '<tr><td><span class="cw_time">End:' + cw_enddate + '</span></td></tr>';
					cw_CX += '</table>';				
				}				
				cw_CX += '</div>';
				$("#cw_ItemsContainer").append(cw_CX); // insert into DOM						
		   }); // -- $(xData.responseXML).find   
		} // -- completefunc
   }); // -- $().SPServices({
} // -- LoadCalendarWidget()

PrintView Printer Friendly Version

EmailEmail Article to Friend

References (1)

References allow you to track sources for this article, as well as articles that were written in response to this article.

Reader Comments (1)

Realize this is an old post, but in case anyone sees this:

How do I get the calendar to sort by event date? (ascending order)

I tried about a million different things and can't figure out how to get it to work.

September 25, 2014 | Unregistered CommenterCAML Noob

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>