Vertical Scrolling WebPart


15.07.2010 Updated the code for the file “VerticalScrollingWebPart.js” to try to fix the overflow issue in IE6.

24.06.2010 The code for the file “VerticalScrollingWebPart.js” is updated. I actually forgot to update it as i made some adjustments in the CEWP code… I hope the overflow issue is fixed with this update.

I got this request from Charlie:

…a solution that I can use as a dashboard web part to vertically scroll the most recent “top 10” items from a 2nd list?

Example: I need to be able to grab the most recently items marked as “Completed” or “Sold” from a list and be able to show 2-3 fields in the scroller.

Click here for a crude example – the scrolling is not so choppy – this is only a animated gif to give you a hint of how the solution works.

The scrolling action pauses when hovered with the mouse.

As always we start like this:
Create a document library to hold your scripts (or a folder on the root created in SharePoint Designer). In this example i have made a document library with a relative URL of “/test/English/Javascript” (a sub site named “test” with a sub site named “English” with a document library named “Javascript”):
IMG

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.4.2.min. Update the script “src” if you use another version.

The sourcecode for the file “VerticalScrollingWebPart.js” is provided below.

Add this code to a CEWP where you want the scrollable contents to appear:

<script type="text/javascript" src="/test/English/Javascript/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="/test/English/Javascript/VerticalScrollingWebPart.js"></script>
<script type="text/javascript">
init_fillScrollableDiv({'listGuid':'A4B4E15A-C5B0-47BC-A08B-739CD48FE58A',
	'listBaseUrl':'/test/English',
	'listViewGuid':'5BD378F4-25D5-4880-9C5B-1667FE43978D',											
	'viewFields':['Title','MultiLine'],
	'viewFieldsStyle':['font-weight:bold','padding:0 0 0 5'],	
	'divID':'myScrollableDiv',
	'divHeight':'250px',
	'divWidth':'500px',	
	'speed':4,
	'linkBack':true});
</script>

Read here how to find the FieldInternalNames for your fields and the “listGuid” or “listViewGuid” for your list.

Parameters explained:

  • listGuid: GUID of the source-list
  • listBaseUrl: Relative URL to site/subsite. If root site use only two quotes representing a blank string – like this: “”.
  • listViewGuid: GUID of the view to use from the source-list – if left empty it uses the default view.
  • viewFields: Array of FieldInternalNames to use in the scrolling webpart.
  • viewFieldsStyle: Array of styles to match the array of FieldInternalNames above.
  • divID: The ID of the scrollable DIV. Can be anything as long as it is unique on the page.
  • divHeight: The hight of the scrollable area.
  • divWidth: The width of the scrollable area.
  • speed: A number representing the scroll speed.
  • linkBack: If set to true it adds a link to open the item clicked on.

The sourcecode for the file “VerticalScrollingWebPart.js”:
/* Pulls items from a list view and presents them as a Vertical Scrolling Web Part
 * ---------------------------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * http://sharepointjavascript.wordpress.com
 * Copyright (c) 2009-2010 Alexander Bautz (Licensed under the MIT X11 License)
 * v1.2
 * LastMod: 14.07.2010
 	- LastChange: Attempted to fix the overflow issue in IE6
 * ---------------------------------------------
 * Include reference to:
 *  jquery - http://jquery.com
 *	VerticalScrollingWebPart.js (this file)
 * ---------------------------------------------
*/

function init_fillScrollableDiv(obj){
	// Build the div
	var myDivBuffer = [];
	myDivBuffer.push("<div style='vertical-align:top;position:relative;overflow:hidden;cursor:default;height:"+obj.divHeight+";width:"+obj.divWidth+"'>");
	myDivBuffer.push("<div id='"+obj.divID+"' style='position:relative'></div>");
	myDivBuffer.push("</div>");
	myDivContainer=myDivBuffer.join('');	
	document.write(myDivContainer);
	$(document).ready(function(){
		fillScrollableDiv(obj)
	});
}

function fillScrollableDiv(info){
	wsBaseUrl = info.listBaseUrl + '/_vti_bin/';
	info.animBegin = 0;
	info.animPart = 0;
	// Query the list for items	
	var res = queryItemsByViewName(info.listGuid,info.listViewGuid,info.viewFields.concat('ID','FileDirRef'));
	if(res.count==-1)alert("An error occured - check the parameters \"listGuid\", \"listBaseUrl\" and \"listViewGuid\".");
	var finalBuffer = [];
	var path = '';
	$.each(res.items,function(i,item){
		var partBuffer = [];
		if(path==''){
			var pathRaw = item['FileDirRef'];
			path = "/"+pathRaw.substring(pathRaw.indexOf(';#')+2);
		}	
		$.each(info.viewFields,function(idx,fin){
			var style = '';
			var thisVal = (item[fin]==null)?'':item[fin];
			if(thisVal.indexOf(';#')>-1){
				thisVal = thisVal.substring(thisVal.indexOf(';#')+2);
			}			
			if(info.viewFieldsStyle[idx]!=undefined){
				style = " style='"+info.viewFieldsStyle[idx]+"'";
			}
			partBuffer.push("<tr><td"+style+">"+thisVal+"</td></tr>");	
		});		
		finalBuffer.push("<hr style='height:1px;color:black' />");
		if(info.linkBack){
			finalBuffer.push("<table title='Go to item' style='cursor:pointer' ");
			finalBuffer.push("onclick='javascript:location.href=\""+path+"/DispForm.aspx?ID="+item['ID']+"&Source="+location.href+"\"' ");
			finalBuffer.push("cellspacing='0' cellpadding='0'>"+partBuffer.join('')+"</table>");
		}else{
			finalBuffer.push("<table cellspacing='0' cellpadding='0'>"+partBuffer.join('')+"</table>");
		}	
	});
	var myContents = finalBuffer.join('');
	// Update the content in the scrollable div
	$("#"+info.divID).html(myContents)
		.mouseenter(function(){			
			var now = new Date();
			info.animPart += (now-info.animBegin);		
			$(this).stop();
		})
		.mouseleave(function(){		
			$(this).stop();
			var partScr = parseInt($(this).css('top'));
			scrollMyDiv(partScr,info);
		});
	// Call scroll function
	scrollMyDiv('',info);
}

function scrollMyDiv(scroll,info){
	info.animBegin = new Date();
	var myDiv = $("#"+info.divID);
	var ch = myDiv.height();
	var chpHeight = myDiv.parent().height();	
	if(scroll==''){
		var scroll=chpHeight;
	}
	var duration = (ch*(info.speed*10))-info.animPart;
	myDiv.css({'top':scroll}).animate({"top":-ch},duration,'linear',function(){
		info.animPart = 0;
		scrollMyDiv('',info);
	});
}

// Function to pull items from view
function queryItemsByViewName(listName, viewName, viewFields, pagingInfo){
	var content = buildQueryContentByViewName(listName, viewName, viewFields, pagingInfo);
	var result = {count:-1, nextPagingInfo:'', items:[]};
	wrapSoapRequest(wsBaseUrl + 'lists.asmx', 'http://schemas.microsoft.com/sharepoint/soap/GetListItems', content, function(data){
		result.count = $('rs\\:data', data).attr('ItemCount');
		result.nextPagingInfo = $('rs\\:data', data).attr('ListItemCollectionPositionNext');
		$('z\\:row', data).each(function(idx, itemData){
			var fieldValObj = {}
			$.each(viewFields,function(i,field){
				var value = $(itemData).attr('ows_' + field);
				if(value == undefined) value = null;
				fieldValObj[field]=value;
			});	
			result.items.push(fieldValObj);		
		});
	});
	return result;
}

function buildQueryContentByViewName(listName, viewName, viewFields, pagingInfo){
	var result = [];
	result.push('<GetListItems xmlns="http://schemas.microsoft.com/sharepoint/soap/">');
	result.push('<listName>' + listName + '</listName>');
	result.push('<viewName>' + viewName + '</viewName>');
	if(viewFields != null && viewFields.length > 0){
		result.push('<viewFields><ViewFields xmlns="">');
		$.each(viewFields, function(idx, field){
			result.push('<FieldRef Name="' + field + '"/>');
		});
		result.push('</ViewFields></viewFields>');
	}
	result.push('<queryOptions><QueryOptions xmlns=""><IncludeMandatoryColumns>FALSE</IncludeMandatoryColumns>');
	if(pagingInfo != undefined && pagingInfo != null && pagingInfo != '')
		result.push('<Paging ListItemCollectionPositionNext="' + pagingInfo.replace(/&/g, '&amp;') + '" />');
	result.push('</QueryOptions></queryOptions>');
	result.push('</GetListItems>');
	return result.join('');
}

function wrapSoapRequest(webserviceUrl,requestHeader,soapBody,successFunc){
	var xmlWrap = [];
		xmlWrap.push("<?xml version='1.0' encoding='utf-8'?>");
		xmlWrap.push("<soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'>");
		xmlWrap.push("<soap:Body>");
		xmlWrap.push(soapBody);
		xmlWrap.push("</soap:Body>");
		xmlWrap.push("</soap:Envelope>");
		xmlWrap = xmlWrap.join('');
	$.ajax({
		async:false,
		type:"POST",
		url:webserviceUrl,
		contentType:"text/xml; charset=utf-8",
		processData:false,
		data:xmlWrap,
		dataType:"xml",
		beforeSend:function(xhr){
			xhr.setRequestHeader('SOAPAction',requestHeader);
		},
		success:successFunc
	});
}

Click the “view source” button, highlight the code in the new window and copy it from there to notepad. Save as “VerticalScrollingWebPart.js” – mind the file extension – and upload to the scriplibrary as shown above.

Ask if anything is unclear!
Alexander

104 Responses to “Vertical Scrolling WebPart”

  1. Dave Says:

    Hi,

    It did not work Alex.

    However, I managed to get it working by…..

    1.) Going to my list and creating a column called “Link” (normal text field, NOT a hyperlink field).

    2.) Populate the list, make sure your “Link” column contans hyperlinks that start with HTTP://www. and not just www.

    3.) Replace line 59 (In verticalscrollingwebpart.js) with:

    finalBuffer.push(“onclick=’javascript:location.href=\”"+item['Link']+”\”‘ “);

  2. Walter Says:

    The VerticalScrollingWebpart is behaving differently in 2010 for me… I still get the scrolling but the majority of the list is displayed staticly under the web part. Any suggestions?

  3. Roger Says:

    Alexander,

    How do I get this to auto-update upon change to the list i.e. The list view pointed to by the scrolling webpart shows only open items. When the Item changes to closed it is no longer in the view that the scrolling webpart points to, but the webpart does not update. A manual page refresh is necessary to get the item out of the scroll.

    Thanks

    • Alexander Bautz Says:

      Try wrapping the function call like this:

      setInterval(function(){
      init_fillScrollableDiv({'listGuid':'A4B4E15A-C5B0-47BC-A08B-739CD48FE58A',
      	'listBaseUrl':'/test/English',
      	'listViewGuid':'5BD378F4-25D5-4880-9C5B-1667FE43978D',
      	'viewFields':['Title','MultiLine'],
      	'viewFieldsStyle':['font-weight:bold','padding:0 0 0 5'],
      	'divID':'myScrollableDiv',
      	'divHeight':'250px',
      	'divWidth':'500px',
      	'speed':4,
      	'linkBack':true});
      },10000);
      

      This will reload the dataset every 10000 milliseconds (10 sec). I have not tested it, but I guess it should work.

      Alexander

  4. Anna Says:

    Thanks, works beautifully. I was wondering whether there’s any code I can add to have the scroll pause for a few seconds on each list item automatically, so the scroll speed could be faster, but each item display for a little also.
    Also I seem to be getting a large chunk of white space between the last and first item of the list each time. Can I reduce this?
    Otherwise, works beautifully, thanks!

  5. bijesh Says:

    I am new to this…can u pleasee explain wherer to put this and how this works…i was trying to get this runnig for a long time now.

  6. Nick D Says:

    Hi Alex,
    I’m having an overflow issue on IE8. I know there were issues with this in your earlier solution on IE6. Is there a more recent fix?

  7. Rashmi Says:

    The links take the default theme color. Is there a way to over-ride and provide custom colors without changing theme?

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 )

Connecting to %s


Follow

Get every new post delivered to your Inbox.

Join 435 other followers