Entries in JQuery (8)

Thursday
May102012

Using SPServices, jQuery and an $8 Tab Plugin to Create a Stunning SharePoint List Visualization

AKA: Making SharePoint look like a million bucks on a shoestring budget - Part I

I'd been wanting to spend some time getting familiar with the brilliant open source jQuery library for SharePoint's web services, SPServices, and had the opportunity this past week.  We had a SharePoint site under construction that needed to have a list of links and a little explanation to accompany them  and initially just hosted a standard grouping mechanism on the list view which looks terrible.  I thought that this might be a chance to offer a better way to visualize list data using an inexpensive tabbing control in my library.  The result is shown below, with each 'tab' here linking to 3 fields from a custom list, the title, the sub-title and the content.  This stays in our needed model of users interacting with the standard SP forms that they understand and is leaps and bounds a better user experience.  If this takes you more than a lunch break to implement you might need longer lunch breaks, this is an easy setup and looks great, even responding to mouse-wheel scrolling through the tabs.

 

To do this I used a stunning jQuery plugin called 'Sliding Tabs' that I bought from CodeCanyon.net for a dirt cheap 8 bucks (authored by 360north).  You can see/buy it here and it is one of the many ridiculous bargains on that site that I'll be extending in future posts.  That 8 dollars is all this costs and it looks like $1,000,008 when done.  You'll also need to grab the jQuery file and the SPServices file, we have these hosted on our farm and embedded in the master page for ease of use as seen in the includes in the code.  All includes that are needed but the core jQuery and SPServices files come with the Sliding Tabs package.

With the code in hand from them I created a new list with the aforementioned title, subtitle and content (being a rich content type) list and hooked it up.  Full code follows below.

Notice in the code that you have to specify your site and list names (lines 13 and 15) and if you name your columns something other than I did, you'll need to change the mappings to the 'ows_XXX' moniker that matches your fields (lines 26, 28 and 30).  If you are unsure of what your field's names are you can uncomment line 20 and see for yourself.

You can change the size, shape, orientation and other options with the tab control with the options section starting at line 58.  It does not handle overflow well (um, not at all really, it just gets clipped) but for what we needed it was perfect.

 

<script type="text/javascript" src="_layouts/1033/jquery.min.js"></script>
<script type="text/javascript" src="_layouts/1033/jquery.SPServices.min.js"></script>
<script type="text/javascript" src="_layouts/1033/jquery.mousewheel.js"></script>
<script type="text/javascript" src="_layouts/1033/jquery.slidingtabs.pack.js"></script>
<script type="text/javascript" src="_layouts/1033/jquery.easing.js"></script>

<link href="_layouts/1033/styles/slidingtabs-vertical.css" rel="stylesheet" type="text/css" media="screen"/>

<script language = "javascript">
$(document).ready(function() {
	$().SPServices({
		operation: "GetListItems",
		webURL: "https://MY_SHAREPOINT_ROOT/SOME_SITE",    
		async: false,
		listName: "SIMPLE DEMO LIST",
		completefunc: function (xData, Status) {

			//alert("Status of XML message reaching Sharepoint webservice: " + Status); // handy for debug
			//alert("Response from server: " + xData.responseText); // also handy for debug
			var output = "";
			$("#WSOutput").html(output);
			var TabCounter = 0; // to keep track of tabs/containers

			$(xData.responseXML).find("[nodeName='z:row']").each(function() {

				var title = ($(this).attr("ows_Title"));
					if(title.length == 0) {title = ' ';}
				var subtitle = ($(this).attr("ows_Subtitle"));
					if(subtitle.length == 0) {subtitle = ' ';}
				var content = ($(this).attr("ows_Content"));
					if(content.length == 0) {content = ' ';}
				 
				var TabClass = 'st_tab';
				var ContainerClass = 'st_tab_view';
						
				if(TabCounter==0) // our first items get special 'active' class styling
				{				
					TabClass = 'st_tab st_tab_active';
					ContainerClass = 'st_tab_view st_first_tab_view';
				}
				// Create new tab element as <li>
				var TabHeader = '<li><a href="#stv_content_' + TabCounter + '" rel="v_tab_' + TabCounter + '" class="' + TabClass + '">'
					TabHeader += title + '<span>' + subtitle + '</span></a></li>';
				$("#tablisting").append(TabHeader); // insert into DOM

				// Create new lined content container as <div>
				var stv_content = '<div id="stv_content_' + TabCounter + '" class="' + ContainerClass + '" style="overflow:auto;">';
					stv_content +='<h2 class="sc_title">' + title + '</h2><div class="text"><p>' + content + '</p></div></div>';			
				$("#st_tabs_container").append(stv_content); // insert into DOM

				TabCounter++;  // increment counter
			});
		}
	});
	   
	// Instantiate Vertical Sliding Tabs
	$('div#st_vertical').slideTabs({  			
		// Options
		contentAnim: 'slideH',
		contentAnimTime: 600,
		contentEasing: 'easeInOutExpo',
		orientation: 'vertical',
		tabsAnimTime: 300,
		totalWidth: '660',		
		tabScroll: true				
	});
});	
</script>
       
<!-- Start HTML - Vertical tabs -->
<div id="st_vertical" class="st_vertical">
	<div class="st_tabs_container">   
		<a href="#prev" class="st_prev"></a>
		<a href="#next" class="st_next"></a>                                                                    
		<div class="st_slide_container">            
			<ul class="st_tabs" id="tablisting"></ul><!-- tabs inserted here -->               
		</div> <!-- /.st_slide_container -->
	</div> <!-- /.st_tabs_container -->                               
	<div class="st_view_container">        	            
		<div class="st_view" id="st_tabs_container"></div> <!-- content blocks inserted here -->                        
	</div> <!-- /.st_view_container -->
</div> <!-- /#st_vertical -->
<!-- End HTML - Vertical tabs -->
More jQuery visual enhancements to come...
Wednesday
Apr252012

SharePoint and jQuery - Get the Authenticated User's Name and Modify Content Client-Side

Getting the user's name from a SharePoint page and handing off to some client-side code proved messier than I had hoped for.  Part of the problem is that our farm runs on SSL and IE likes to throw the error message when some resources are secure and others are not and the common solution to this (using jquery.SPServices) was falling prone to that error.  Instead I worked around it so we could serve up a custom control on the intranet for someone's 50th birthday and manage it without audiencing controls.

It requires jQuery and the control that contains the username was not always assigned the same ID though it has the same AccessKey attribute so we made do with what we had.

Since this elegant method did not work:
$(document).ready(function() {
	alert($().SPServices.SPGetCurrentUser());
});

we instead went with the following (note that this includes the resulting action). If you are not in an HTTPS environment go with the SPServices option...

<script type="text/javascript">
	$(document).ready(function() {
		var str = '';
		var strContainer = '';
		
		// find the container that contains the user's name (not always the same...)
		if($('#zz14_Menu').attr("accesskey") == 'W') {strContainer = 'zz14_Menu';}
		if($('#zz15_Menu').attr("accesskey") == 'W') {strContainer = 'zz15_Menu';}
		if($('#zz16_Menu').attr("accesskey") == 'W') {strContainer = 'zz16_Menu';}
		if($('#zz17_Menu').attr("accesskey") == 'W') {strContainer = 'zz17_Menu';}
		
		var str = $('#' + strContainer).find("span").text();

		// date driven
		var d = new Date();
		var n = d.getDate();
		if(n==26) // only show on the 26th...
		{
			if(str == 'Jane User')
			{
				$('#mycontrol').attr('src', 'https://server/Rotator/alternative.htm');
			}
		}
	});
</script>
Thursday
Nov032011

SharePoint Popup Contextual Images

Also known as the 'hover over for screenshot' functionality.  This is a nice jquery driven code snippet that will take any link on your SharePoint page that has an image as its url and allow the user to simply hover over the link to see the image.

This has come in handy for providing contextual help in the form of screenshots right in with content.  A dead simple implementation might look like the following with a hyperlink column in your list and that being the only element in the view.

Yielding this type of thing when you hover over a link on your page:

Otherwise this just requires a reference to your local jquery file (or maybe not local, do what you want cowboy).


<script type="text/javascript" src="jquery.min.js"></script></span></div>
<script type="text/javascript"></span></div>
<br /></span></div>
function imagePreview(){</span></div>
arrOfImageTypes = ['jpg','jpeg','gif','png'];</span></div>
 $("table.ms-listviewtable td.ms-vb2 a").hover(function(e){</span></div>
 var href = this.href;</span></div>
 var img = href.substring(href.lastIndexOf('.')+1).toLowerCase();</span></div>
 if(href.indexOf('http')==0 && $.inArray(img,arrOfImageTypes)>-1){</span></div>
    $("body").append("<img id='preview' src='"+ this.href +"' alt='Image preview' />");</span></div>
 }</span></div>
 var obj = $("#preview");</span></div>
 var offset = $(this).offset();</span></div>
 var winHeight = $(window).height();</span></div>
 var winWidth = $(window).width();</span></div>
 var scrollLeft = $(window).scrollLeft();</span></div>
 var scrollTop = $(window).scrollTop();</span></div>
 var objHeight = obj.outerHeight();</span></div>
 var objWidth = obj.width()+15;</span></div>
 if(((winWidth+scrollLeft)-offset.left)<objWidth){</span></div>
 offset.left=((winWidth+scrollLeft)-objWidth);</span></div>
 }</span></div>
 var maxHeight = (winHeight+scrollTop)-offset.top;</span></div>
 if(objHeight>maxHeight){</span></div>
 if(offset.top-scrollTop>objHeight){</span></div>
 offset.top=offset.top-objHeight-20;</span></div>
 }</span></div>
 height = (objHeight<winHeight)?objHeight:winHeight;</span></div>
 }</span></div>
 obj.css({"position":"absolute","top":(offset.top+20)+"px","left":(offset.left+20),"border":"1px solid black"})</span></div>
 .fadeIn("fast");</span></div>
 },</span></div>
 function(){</span></div>
 $("#preview").remove();</span></div>
 });</span></div>
};</span></div>
<br /></span></div>
// Call the script on page load</span></div>
$(document).ready(function(){</span></div>
 imagePreview();</span></div>
});</span></div>
</script></span></div>
Page 1 2