Category Archives: Utilities

CommentBox for SharePoint

13.08.2011 v1.2 released with these changes to the argObj:

  • paging: Use this in conjunction with the next parameter to set the number of top level comments to display initially.
  • topLevelCommentsLimit: The number of top level comments to display initially.
  • showMoreCommentsText: If there are more comments, this text is used for the link to show the rest of the comments.
  • sortAscending: true or false. Used to control the order of the comments.
  • commentFormVisible: true or false. Used to have the comment box expanded or collapsed initially.

There are changes to these files:

  • CommentBox.js
  • CommentBox.css

And the CEWP-code. See the CEWP-code section below for details.


17.07.2011 v1.1 released with these changes:

  • Anonymous users can read comments, but must sign in to post.
  • Added new parameter “loadLiveProfile” to the CEWP argObj. This defines whether or not to load the profile image and email from the user profile, or to use the values stored in the comment. This will automatically be set to false for anonymous users. To accompany this change i have added some new fields to the configuration list (these will be automatically created when submitting the first comment), and changed the parameters “newCommentText” and “replyText” from string to array.

There are changes to these files:

  • CommentBox.js
  • spjs-webservices.js

And to the CEWP-code.


I got this request from Brett:

Hi Alexander,

Got an awesome request for your mad skills.
Are you able to provide a Javascript/JQuery code for a Comments Box Web Part? So it can be added to any page, list or library?

I’m thinking you could set it like the Poll web part, where the Admin can specify the ID Name for each Comments Web Part instance, which will allow the user comments be allocated to the correct web part.

So it would function exactly like the Comments Web Part in a Blog Site, using the authenticated user credentials and/or anonymous comments if you desire.

There are a few Posts mentioning DVWP’s and SP Designer but I’m hoping to use a Javascript based solution.

I’ve looked everywhere for this function and closest I found was this Post.
http://devgrow.com/simple-threaded-comments-with-jcollapsible/

Many thanks for your time and efforts,

Brett


I thought this would be a useful solution for many users – myself included. It’s not very complicated as all comments are stored in a single list – identified by the pages relative URL.

Of course – as i started building – i incorporated this and that, an all of a sudden i had myself a full featured, multi level comment solution.

Sample thread:

IMG

New comment – plain text:

IMG

New comment – Rich text:

IMG

List of features

  • Supports both SharePoint 2007 and SharePoint 2010
  • Tested in IE7, IE9, Safari 5.0.5 for Windows, Firefox 5.0 and Google Chrome 12.0.742.112
  • Multi level comments
  • You can collapse top level threads
  • Rich text or plain text comments
  • Option to allow the authors to edit their comments
  • Option to let specific users act as “moderators”
  • Can be used in multiple locations within the site as each instance is identified by the relative URL of the page
  • Simple “drop in CEWP-setup”
  • On list holds all comments for all instances within the site
  • This list that holds the comments is automatically created
  • Layout customizable trough separate css-file
  • And more…

How to use

This solution is designed to be put in a CEWP where you want to use it. You will have to download all the files from the download section to a local folder/library where all users have read access, and change the <script src=”… in the CEWP code to reflect your local path.

CEWP code example

<div id="myCommentBox"></div>
<link rel="stylesheet" href="/test/EMSKJS/CommentBox/CommentBox.css">
<script type="text/javascript" src="/test/EMSKJS/CommentBox/jquery-1.6.2.min.js"></script>
<script type="text/javascript" src="/test/EMSKJS/CommentBox/CommentBox.js"></script>
<script type="text/javascript" src="/test/EMSKJS/CommentBox/spjs-webservices.js"></script>
<script type="text/javascript" src="/test/EMSKJS/CommentBox/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript">

var pageID = location.pathname+"?ID="+GetUrlKeyValue('ID');
var argObj = {pageID:pageID,
			 containerID:'myCommentBox',
			 containerWidth:600,
			 replyLevels:2,
			 threadInitiallyCollapsed:false,
			 commentIndent:40,			 
			 commentBoxHeight:100,
			 showProfileImage:true,
			 createdByPrefix:'Posted by ',
			 createdPrefix:' on ',
			 modifiedPrefix:'- Modified: ',
			 modifiedByPrefix:' by ',
			 showUserEmail:true,
			 authorCanEdit:true,
			 editText:'Edit',			 
			 commentBoxRTE:false,
			 expandThread:"<span title='Expand thread'><img style='vertical-align:text-bottom' src='/_layouts/images/tpmax2.gif'  border='0'> Expand</span>",
			 collapseThread:"<span title='Collapse thread'><img style='vertical-align:text-bottom' src='/_layouts/images/tpmin2.gif' border='0'> Collapse</span>",
			 newCommentText:['Leave comment','You must sign in to comment'],
			 replyText:['Reply','<span title="You must be signed in to leave replies">Sign in</span>'],			 
			 submitText:'Submit comment',
			 canceImgHover:"Cancel",
			 deleteThreadText:'Delete comment',
			 moderateText:'Moderate',
			 moderatorID:['15','27'],
			 loadLiveProfile:true,
		 	 paging:false,
			 topLevelCommentsLimit:25,
			 showMoreCommentsText:"More comments",
			 sortAscending:true,
			 commentFormVisible:true
			 };

init_getComments(argObj);
</script>

Note to SharePoint 2010 users:
Add this code to a text file and put it in a document library, then use the content link option on the CEWP to link to this code. This is necessary to overcome a “bug” in the CEWP handling when editing a SP2010 page. If you put a script that generates HTML directly into a CEWP, the HTML is accumulated when editing the page.

This tip is also recommended for SharePoint 2007 users, but is not absolutely necessary.

Argument object parameters

  • pageID: The identifier for the unique instance – see separate description below.
  • containerID: The container where the comments are inserted – see separate description below.
  • containerWidth: Width in pixels.
  • replyLevels: The number of nested levels.
  • threadInitiallyCollapsed: true or false to indicate whether the threads are initially collapsed.
  • commentIndent: The number of pixels to indent each nested level of comments.
  • commentBoxHeight: The textbox (for new comments or reply) height in pixels.
  • showProfileImage: true or false to indicate whether or not to display the profile image from the SharePoint user profile.
  • createdByPrefix: The text before the user name of the author.
  • createdPrefix: The text between the author name and the date/time for when the comment is created.
  • modifiedPrefix: The text before the date/time for when the comment is modified.
  • modifiedByPrefix: The text before the name of the editor.
  • showUserEmail: true or false to indicate whether to show the email for the author.
  • authorCanEdit: true or false to indicate whether the author can edit his or hers own comments.
  • editText: The text on the “Edit item link”.
  • commentBoxRTE: true or false to indicate whether to use the TinyMCE rich text editor – see separate description below.
  • expandThread: The text/image of the “Expand thread” link.
  • collapseThread: The text/image of the “Collapse thread” link.
  • newCommentText: Array with the text on the “Leave comment” link for both authenticated and unauthenticated users.
  • replyText: Array with the text on the “Reply” link for both authenticated and unauthenticated users.
  • submitText: The text on the “Submit comment button”.
  • canceImgHover: The mouseover text on the “Cancel comment image”
  • deleteThreadText: The text on the “Delete comment” link.
  • moderateText: The text on the “Moderate item link”.
  • moderatorID: An array of the user ID’s (as string) for the moderators.
  • loadLiveProfile: true or false to indicate whether to load the profile image and email from the user profile, or to use the values stored in the comment.

New in v1.2

  • paging: Use this in conjunction with the next parameter to set the number of top level comments to display initially.
  • topLevelCommentsLimit: The number of top level comments to display initially.
  • showMoreCommentsText: If there are more comments, this text is used for the link to show the rest of the comments.
  • sortAscending: true or false. Used to control the order of the comments.
  • commentFormVisible: true or false. Used to have the comment box expanded or collapsed initially.

Details on “pageID”
For ordinary aspx-pages, use

location.pathname

When using in DispForm/EditForm, use

location.pathname+"?ID="+GetUrlKeyValue('ID')

Details on “containerID”

You can supply a placeholder in the page with the ID corresponding with the parameter “containerID” from the function call. You will want to do this to control the placement of the container, or to supply some custom settings (style or class). If you do not supply a container, it will be created automatically by the script.

Details on “commentBoxRTE”

TinyMCE – Javascript WYSIWYG Editor is a platform independent web based Javascript HTML WYSIWYG editor control released as Open Source under LGPL by Moxiecode Systems AB.

You can change the buttons and plugins for the TinyMCE by modifying the function “init_MCE” at the bottom of the file “CommentBox.js”. Refer the official site for details.

SharePoint 2010 users:
The TinyMCE solution has to be modified to change all “htm” files (and the references in the scripts) to “aspx” as the built in security feature in SharePoint 2010 does not let you open htm-files unless you change the “Browser file handling” from “Strict” to “Permissive”.

I have modified the files used in the default setup for the CommentBox solution. If you change the setup to include more plugins you must change the appropriate files. The modified package can be found in the download section.

Download

You find the files here

Copyright and disclaimer


Please let me know if you find any bugs.
Alexander

If you use this solution, please consider donating a few dollars to keep me motivated.

Pull on-call information from calendar

10.06.2011 Update: I forgot to separate out the FieldInternalNames for the start and end date. See updated code.


This solution is an answer to a request from Colin Blake:

Hey Alexander,

I’ve been browsing through your blog (amazing!) and have not been able
to come up with anything yet using your posted solutions so I was
hoping you could help me or get me pointed in the right direction. I
have a calender that holds our “On-Call” information. I have added a
custom column to the calender that holds a text value(the name of the
on call person). What I would like to do is is on another Web Part
Page is have the text value from the custom “on-call” column for the
current week displayed in a CEWP Web Part. Is this something that
could be easily done?

Thanks,
Colin Blake

This solution is designed to be put directly into a CEWP and will insert the name of the person “on call” in a placeholder <div>.

Note to SharePoint 2010 users:
Add this code to a text file and put it in a document library, then use the content link option on the CEWP to link to this code. This is necessary to overcome a “bug” in the CEWP handling when editing a SP2010 page. If you put a script that generates HTML directly into a CEWP, the HTML is accumulated when editing the page.

CEWP code:

&lt;div id=&quot;insertOnCallNameHere&quot;&gt;&lt;/div&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;

// Define list name or GUID
var calendarName = &quot;OnCallCalendar&quot;;
// Define the FieldInternalName to pull in the value from
var fieldToReturn = 'OnCallPerson';
// Define the start and end date fields
var startDateFIN = 'EventDate';
var endDateFIN = 'EndDate';
// Call the cunction
var onCallArr = getOnCallInfo(calendarName,fieldToReturn,startDateFIN,endDateFIN);

// Handle the result
var buffer = [];
$.each(onCallArr,function(i,obj){
	// obj.url = hyperlink to profile page
	// obj.name = name
	// obj.userId = user id
	// url and userid is available only when &quot;fieldToReturn&quot; is a people picker.
	buffer.push(&quot;&lt;div&gt;&quot;+obj.url+&quot;&lt;/div&gt;&quot;);
});
$(&quot;#insertOnCallNameHere&quot;).html(buffer.join(''));

// ****************************************************************
//	Do not edit below this line
// ****************************************************************

function getOnCallInfo(listName,fieldNameToReturn,startDateFIN,endDateFIN){
	var result = [];
	var queryBuffer = [];
		queryBuffer.push(&quot;&lt;Where&gt;&quot;);
		queryBuffer.push(&quot;&lt;And&gt;&quot;);
		queryBuffer.push(&quot;&lt;Leq&gt;&lt;FieldRef Name='&quot;+startDateFIN+&quot;' /&gt;&lt;Value Type='DateTime'&gt;&lt;Today /&gt;&lt;/Value&gt;&lt;/Leq&gt;&quot;);
		queryBuffer.push(&quot;&lt;Geq&gt;&lt;FieldRef Name='&quot;+endDateFIN+&quot;' /&gt;&lt;Value Type='DateTime'&gt;&lt;Today /&gt;&lt;/Value&gt;&lt;/Geq&gt;&quot;);
		queryBuffer.push(&quot;&lt;/And&gt;&quot;);
		queryBuffer.push(&quot;&lt;/Where&gt;&quot;);
	var res = spjs_QueryItems({listName:listName,query:queryBuffer.join(''),viewFields:['ID',fieldNameToReturn]});
	$.each(res.items,function(i,item){
		if(item[fieldNameToReturn]!==null){
			var split = item[fieldNameToReturn].split(';#');
			var name = split[1];
			var userId = split[0];
			if(split.length===2&amp;&amp;!isNaN(parseInt(split[0],10))){
			result.push({url:&quot;&lt;a href='&quot;+L_Menu_BaseUrl+&quot;/_layouts/userdisp.aspx?Force=True&amp;ID=&quot;+userId+&quot;' target='_blank'&gt;&quot;+name+&quot;&lt;/a&gt;&quot;,
						 name:name,
						 userId:userId});
			}else{
				if(split.length===2){
					name = split[1];
				}
				result.push({url:'URL: This value is available using a people picker only.',
							 name:name,
							 userId:'userId: This value is available using a people picker only.'});
			}	
		}	
	});
	return result;		
}

function spjs_QueryItems(argObj){
	if(argObj.listBaseUrl==undefined)argObj.listBaseUrl=L_Menu_BaseUrl;
	if(argObj.listName==undefined || (argObj.query==undefined &amp;&amp; argObj.viewName==undefined)){
		alert(&quot;Missing parameters!nnYou must provide a minimum of &quot;listName&quot;, &quot;query&quot; or &quot;viewName&quot; and &quot;viewFields&quot;.&quot;);
		return;
	}
	var content = spjs_wrapQueryContent({'listName':argObj.listName,'query':argObj.query,'viewName':argObj.viewName,'viewFields':argObj.viewFields,'rowLimit':argObj.rowLimit,'pagingInfo':argObj.pagingInfo});
	var result = {'count':-1,'nextPagingInfo':'',items:[]};	
	spjs_wrapSoapRequest(argObj.listBaseUrl + '/_vti_bin/lists.asmx', 'http://schemas.microsoft.com/sharepoint/soap/GetListItems', content, function(data){
		result.count = $(data).find(&quot;[nodeName='rs:data']&quot;).attr('ItemCount');
		result.nextPagingInfo = $(data).find(&quot;[nodeName='rs:data']&quot;).attr('ListItemCollectionPositionNext');
		$(data).find(&quot;[nodeName='z:row']&quot;).each(function(idx, itemData){
			var fieldValObj = {}
			$.each(argObj.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 spjs_wrapQueryContent(paramObj){
	var result = [];
	result.push('&lt;GetListItems xmlns=&quot;http://schemas.microsoft.com/sharepoint/soap/&quot;&gt;');
	result.push('&lt;listName&gt;' + paramObj.listName + '&lt;/listName&gt;');
	if(paramObj.viewName!=undefined &amp;&amp; paramObj.viewName!=''){
		result.push('&lt;viewName&gt;' + paramObj.viewName + '&lt;/viewName&gt;');
	}
	if(paramObj.query != null &amp;&amp; paramObj.query != ''){
		result.push('&lt;query&gt;&lt;Query xmlns=&quot;&quot;&gt;');
		result.push(paramObj.query);
		result.push('&lt;/Query&gt;&lt;/query&gt;');
	}
	if(paramObj.viewFields!=undefined &amp;&amp; paramObj.viewFields!='' &amp;&amp; paramObj.viewFields.length &gt; 0){
		result.push('&lt;viewFields&gt;&lt;ViewFields xmlns=&quot;&quot;&gt;');
		$.each(paramObj.viewFields, function(idx, field){
			result.push('&lt;FieldRef Name=&quot;' + field + '&quot;/&gt;');
		});
		result.push('&lt;/ViewFields&gt;&lt;/viewFields&gt;');
	}
	// A view overrides the itemlimit
	if(paramObj.viewName==undefined){
		if(paramObj.rowLimit != undefined &amp;&amp; paramObj.rowLimit &gt; 0){
			result.push('&lt;rowLimit&gt;' + paramObj.rowLimit + '&lt;/rowLimit&gt;');
		}else{
		    result.push('&lt;rowLimit&gt;100000&lt;/rowLimit&gt;');
		}
	}
	result.push('&lt;queryOptions&gt;&lt;QueryOptions xmlns=&quot;&quot;&gt;&lt;IncludeMandatoryColumns&gt;FALSE&lt;/IncludeMandatoryColumns&gt;');
	if(paramObj.pagingInfo != undefined &amp;&amp; paramObj.pagingInfo != null &amp;&amp; paramObj.pagingInfo != '')
		result.push('&lt;Paging ListItemCollectionPositionNext=&quot;' + paramObj.pagingInfo.replace(/&amp;/g, '&amp;amp;') + '&quot; /&gt;');
	result.push('&lt;/QueryOptions&gt;&lt;/queryOptions&gt;');
	result.push('&lt;/GetListItems&gt;');
	return result.join('');
}

function spjs_wrapSoapRequest(webserviceUrl,requestHeader,soapBody,successFunc){
	var xmlWrap = [];
		xmlWrap.push(&quot;&lt;?xml version='1.0' encoding='utf-8'?&gt;&quot;);
		xmlWrap.push(&quot;&lt;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/'&gt;&quot;);
		xmlWrap.push(&quot;&lt;soap:Body&gt;&quot;);
		xmlWrap.push(soapBody);
		xmlWrap.push(&quot;&lt;/soap:Body&gt;&quot;);
		xmlWrap.push(&quot;&lt;/soap:Envelope&gt;&quot;);
		xmlWrap = xmlWrap.join('');
	$.ajax({
		async:false,
		type:&quot;POST&quot;,
		url:webserviceUrl,
		contentType:&quot;text/xml; charset=utf-8&quot;,
		processData:false,
		data:xmlWrap,
		dataType:&quot;xml&quot;,
		beforeSend:function(xhr){
			xhr.setRequestHeader('SOAPAction',requestHeader);
		},
		success:successFunc,
		error:function(xhr){
			alert(xhr.status+&quot;n&quot;+xhr.responseText);
		}
	});
}
&lt;/script&gt; 

The parameters

calendarName: The list name or list GUID of the list/calendar.
fieldToReturn: The FieldInternalName of the field to return the value from.
startDateFIN: The FieldInternalName of the start date field.
endDateFIN: The FieldInternalName of the end date field.

The returnvalue

The returnvalue from call to the function “getOnCallInfo” is an array of objects. The object has three properties:
url = a link to the SharePoint user info for the user.
userId = the userId from SharePoints user profile.
name = the name stored in the field.

The property “url” and “userId” is for use with people pickers only.

Hope someone can make use of this.
Alexander

Interactive Charts using Google Visualization API: Examples

This post describes the use of the tool posted here. The latest changes are found here.


This post will be updated with examples on how to utilize this tool to build various charts. I will add examples upon request. If you have a smashing chart or a special trick, please send it to me and i will post the images here.


Combo chart

The chart:
IMG

The list:
IMG

The configuration:
IMG

The reason for using “chartArea.left:50” is to align the chart left so that the legend is not truncated.

NOTE: The “Column index” used when setting up the series is one notch down from the index shown to the left of the columns. This has to do with the series only applying to the numeric columns.


How to put multiple charts in one page

Here is a few screenshots showing how to put multiple charts in one page.
IMG

IMG

IMG

You must ensure that the CEWP holding the code is placed below all containers.


Motion chart

The chart:
IMG

The list:
IMG

The configuration:
IMG


URL filter

This filter is applied in the “Custom CAML” section like this:
The configuration:
IMG
Use the FieldInternalName of your field – my field is named “Status”.

The URL:
IMG

The chart:
IMG

Manual filter setup filter

This is used to filter on “Single line of text” columns. This filter is applied in the “Custom CAML” section like this:
The configuration:
IMG
To get the CAML, select the checkbox “Create a filter field above the chart using”, select “manual filter setup” and then click “Build CAML from selected filters”. You need to know the FieldInternalName of the field and insert it in the placeholder in the CAML.

The list:
IMG

The chart:
IMG

Grouped by choice column value

I got a request from Michael:

Hello,
Im trying to chart a Calendar, i created a Column called “Category” (its a drop-down box with the categories)
Now i want to create a chart that:
– is a bar chart
– the h axis is “created by”
– the v axis is a the sum of a column that calculate the hours between end and starttime of events (allready solved this with a formular)
– the Bars are grouped by the Creator
– the chart is stacked (allready done)
– the stacked bars show the name of the category
– for each category a specified colour

Here are some screenshots of the list fields

The “Time” field calculates the difference between start and end:
IMG

The Category field is a plain choice field:
IMG

The series in the chart are made up by one calculated column per choice in the “Category” field:
IMG
Make one for each category.

The configuration:
IMG

The chart:
IMG


Please make requests, and i will post examples to the best of my knowledge.

Alexander

Charting for SharePoint using Google Visualization API: Update 05.06.2011


I have posted a new version of the “Charting for SharePoint using Google Visualization API” – v2.9.0. The changes are described here, but the background story and the code is found in original article. This post describes the new features in v2.9.0.

You should read the original post found here, the update for v2.8 posted here and the update for v2.8.5 posted here.


Changes from v2.8.5:

  1. Changed the behavior of “Average” to divide the grand total on the number of columns actually containing a value. This means any columns being blank or “null” will not be considered into the “total column count”. Thanks to Ayodele Ayodeji for pointing this out to me.
  2. Changed the “Chart option parser” to use eval on the Chart Options. YES i know it’s not the smartest thing to do, but as the Google Visualization API changes, my crude “option parser” failed to swallow some of the object literation formatted options.
  3. Added new chart types: Combo Chart and Candlestick Chart
  4. Added support for PatternFormat
  5. Pulled the variables: “showFilterInfo”, “showItemCount”, “itemCountPrefix”, “itemCountSuffix”, “labelIfEmpty”, introduced in v.2.8.5 in from the CEWP code and into the Chart configuration. This update should override the CEWP settings and these obsolete settings should not interfere.
  6. Added a few minor GUI tweaks like auto open the configuration for a newly added chart – no more “Table has no columns” error. Changed some of the error message. And a few other small fixes.
  7. Changed the solution to check for any missing columns in the configuration list and add them as needed. No more need to manually add columns to the configuration list when updating from a previous version!
  8. I have changed the code for the “save configuration function” as jQuery v1.6 introduced a new approach on DOM attributes and properties which affected the value returned by .attr(“checked”). This made saving “checked” checkboxes impossible when using jQuery v1.6.x.

NOTE: I have done one change in the way the formatters are targeted to a column. I originally went for a numbering of the columns starting with 1, but changed this to use 0 for the first column. This has to do with the columns being 0-indexed in the DataTable “behind the scenes” and this making things easier. To those of you using formatters now, you might end up with an error message, but it is just a matter of notching the “index” down by one.

If you use this solution, please consider donating a few dollars.

Hit counter and star rating for SharePoint

Change log
June 06. 2013
I have updated the code to v2.3 to fix some problems with “countOneHitPerUser”, “countOneHitPerUserPerDay” and “oneRatingPerUser” setting not working. Thanks to Jeroen for pointing this out.

April 23. 2013
I have updated the code to use spjs-utility.js and to support newer versions of jQuery. I have tested with v1.91. v2.0 has not been tested.

04.09.2011
I have changed code to allow turning off the star-rating function. The version number is 2.1.

The file “HitCounterAndStarRatingForSharePoint.js” and the CEWP code has changed.

I have redone the Hit counter for SharePoint and changed from a simple “Like” to a star-rating.

I have done a total rebuild of the code and this new release will perform better in lists with a large number of hits.

Note: If your pages will have more than a few thousand hits, you most likely would want to hide the “hitcount” from the users. This has to do with the fact that rendering the number of hits in the browser requires the data to be pulled down to the client for counting.

As an example, 8000 “hits” will be a 2-3MB download to the client just to display the itemcount.

If you hide the counter from the user, you can still display the itemcount by looking at the “HitCounter-list” directly.

I would love to have a webservice that could return the itemcount from a given CAML query without having to pull down the entire XML-blob to the client. If someone has the knowledge to make such a webservice i would be more than happy to make it available here.

Here how it could look like in a blog:
IMG

How to setup the solution:


Step 1:
Create a list to hold the ratings. This list could be shared by all sites in a site collection if you point to it in the CEWP configuration option “counterListBaseUrl” and ensure all site users have write permission. The list should have these fields:
IMG


Step 2:
Download the code for the file “HitCounterAndStarRatingForSharePoint.js” and the images star_off.gifstar_on.gifstar_selected.gif from here, and spjs-utility.js from here

Put them in a document library where all users have read permission. If you are using SharePoint Designer you could put the files in a folder on the site collection root for safe storage.


Step 3:
Insert a CEWP with this code where you want the hitcounter/rating to appear:

Updated with reference to spjs-utility.js

<span id="hitAndLike"></span>
<script type="text/javascript" src="/test/English/Scripts/HitAndStar/jquery-1.9.1.min.js"></script>
<script type="text/javascript" src="/test/English/Scripts/HitAndStar/spjs-utility.js"></script>
<script type="text/javascript" src="/test/English/Scripts/HitAndStar/HitCounterAndStarRatingForSharePoint.js"></script>
<script type="text/javascript">
	var argObj = {counterListName:'HitCounter',
				  counterListBaseUrl:'/test/English/Blog/',
				  countHits:true,
				  hitCounterVisible:true,				  
				  countOneHitPerUser:false,
				  countOneHitPerUserPerDay:false,
				  hitSuffix:['Hit','Hits'],				  	  
				  isDispForm:true,
				  activateRating:true,
				  starImageSrc:['/test/English/blog/Scripts/HitCounter/star_off.gif',
				  				'/test/English/blog/Scripts/HitCounter/star_on.gif',
				  				'/test/English/blog/Scripts/HitCounter/star_selected.gif'],
				  starCount:5,
				  starMouseoverArr:['Very poor','Poor','Good','Very good','Fantastic'],
				  oneRatingPerUser:false,
				  ratingCountSuffix:['Vote','Votes'],
				  alreadyRatedMouseover:"You have already given this item {starCount} stars!",				  
				  debug:false};
	hitCounter(argObj);
</script>

NOTE:
Change the script src to reflect the location of your local file.

Note for SharePoint 2010 users:
You cannot put this code in the CEWP directly because of a “bug” in how the CEWP content is handled when editing the page. It basically incorporates the HTML generated by the script and thus corrupts the CEWP code.

To overcome this you must put the CEWP code in a text-file alongside the file “HitCounterAndStarRatingForSharePoint.js” and linking to it using the “Content link” option in the CEWP.

Configuration option:

  • counterListName: The GUID or the “DisplayName” of the hit counter list.
  • counterListBaseUrl: The baseUrl of the “HitCounter” list.
  • countHits: true or false. If false, no hits are recorded. Use this setting if you want star rating only.
  • hitCounterVisible: true or false. If false, the item count is not displayed to the end user. This setting is recommended if you expect a lot of hits and/or your users are on a low bandwidth connection. See note in the top of the article.
  • countOneHitPerUser: true or false. If true, only one hit will ever be recorder for an unique user. If false (and the next parameter also is false) all refreshes of the page will record a new hit in the “HitCounter” list.
  • countOneHitPerUserPerDay: If true, only one hit per day will be recorded for any unique user.
  • hitSuffix: An array with the hit suffix in singular and plural form.
  • isDispForm: true or false. If true, the item ID will be used to distinguish between records in the “HitCounter” list.
  • activateRating New in v2.1: true or false. Turns the star-rating part on or off.
  • starImageSrc: An array containing the relative URL to the 3 images representing the statuses “off”, “on” and “selected”.
  • starCount: The number of stars in you “rating control”. You can have as many as you like.
  • starMouseoverArr: An array of strings describing the rating steps. The text is displayed on mouse over on the star.
  • oneRatingPerUser: true or false. If true, one user can rate an item once.
  • ratingCountSuffix: An array with the rating suffix in singular and plural form.
  • alreadyRatedMouseover: The mouseover if a user has already rated an item. The text “{starcount}” will be replaced with the users rating.
  • debug: true or false. If true, a debug section will be displayed in the top of the screen providing all the configuration options and all variable used by the solution.

Learn how to find the list GUID or the ListBaseUrl

This solution is tested in SP2007 and in SP2010 with IE9.0, Firefox 4.0.1 and Chrome 11.0.696.68.

Copyright and disclaimer

I hope you all enjoy this code and please report any bugs in the comment section below.

Regards
Alexander

PS!

If you like this solution, please consider donating a few dollars to fund some flowers to my wife who must endure my continuous blogging…


Charting for SharePoint using Google Visualization API: Update 05.05.2011


I have posted a new version of the “Charting for SharePoint using Google Visualization API” – v2.8.5. The changes are described here, but the background story and the code is found in original article. This post describes the new features and changes from v2.8.

You should read the original post found here, and the update for v2.8 posted here.


Changes from v2.8:

  1. Removed option to “listen to” specific list filter columns using “{list:FieldInternalName}”
  2. Added option to “consume” a list view web part filter (read from the URL). You can now have the chart “connected” to a list view. Further details below. This new feature requires existing users to manually add one column to the configuration list: “ConsumeFilterFromListView”.
  3. Fixed a bug regarding the use of “&” in a custom filter field which broke the CAML
  4. Added a “counter” to display the total number of items below the chart
  5. Added a few “options” to be set in the CEWP code: “showFilterInfo”, “showItemCount”, “itemCountPrefix”, “itemCountSuffix”, “labelIfEmpty”. All these have a default value and are optional.
  6. Added option to pull the CAML from an existing list view to use as “Custom CAML”

Details on item number 2:

In v2.8 i introduced an option to “hook into” the list view veb part filter for specific columns. In this release this is removed and replaced with an option to “connect to” a list view web part and consume all filters applied to any column.

This has a few limitations:
It reads the filter values from the URL and therefore only one list view webpart can coexist with the chart. If more than one list view web part is placed alongside a chart, it would not know which list the filter came from.

To use this option, check this box:
IMG

This requires existing users to add one column to the configuration list: “ConsumeFilterFromListView”. For new users this field will be added automatically when creating the configuration list. The chart configuration list should look like this:
IMG

Details on item number 4:

I have added a “counter” to display the total number of items below the chart:
IMG
This counter can be switched off – see next item.

Details on item number 5:

These variables can be added to the CEWP code:

  • showFilterInfo: true [default] or false. Controls the visibility of the “filter label” below the chart when using a filter.
  • showItemCount: true [default] or false. Controls the visibility of the item count below the chart.
  • itemCountPrefix: A string to put in front of the item count. Default empty string.
  • itemCountSuffix: A string to add after the item count. Default ” items”.
  • labelIfEmpty: A string representing the default label for empty values. Default is “(empty)”.

Example CEWP code:

&lt;div id=&quot;MyChart1&quot;&gt;&lt;/div&gt;
&lt;div id=&quot;MyChart2&quot;&gt;&lt;/div&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
/*****************************************************
		Address all containers
*****************************************************/
// All charts must be represented by a container with a unique id. This container  must be present in the page
arrOfChartContainers = [&quot;MyChart1&quot;,&quot;MyChart2&quot;];

var showFilterInfo = true;
var showItemCount = true;
var itemCountPrefix = &quot;A total of &quot;;
var itemCountSuffix = &quot; items&quot;;
var labelIfEmpty = &quot;(no value)&quot;;

&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://www.google.com/jsapi&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Charts/Javascript/v2.8.5/ChartUsingGoogleVisualizationAPI.js&quot;&gt;&lt;/script&gt;

Details on item number 6:

Use this link to pull the CAML from the list view:
IMG
Select a view in the “View selector” and click this link to pull it into the textarea.


Please post a comment if you have questions.

Alexander

Charting for SharePoint using Google Visualization API: Update 27.03.2011

05.05.2011 I have released version 2.8.5. Read about it here


I have posted a new version of the “Charting for SharePoint using Google Visualization API” – v2.8. The changes are described here, but the background story and the code is found in original article. This post describes the new features.


1. Filter the chart using a choice column from the list

IMG
The dropdown is created from the choice options supplied in the list settings for that column. You set the filter in the GUI like this:
IMG
You must use “custom CAML” and select “Create a filter field above the chart using”. In the dropdown you will find all the single-choice columns in your list. Click on the text “Build CAML from selected filters” to create the appropriate CAML query.


2. Manually build the dropdown filter

If you want to make a dropdown filter for your chart, filtering by a text in a single line choice column you can create it like this. Click “Create a filter field above the chart using”, and select “manual filter setup”. You can then build the filter manually. See the description below the “filter options” textarea for formatting options for the dropdown.

When using a manual filter setup and using “Build CAML from selected filters”, you must change the “FieldInternalNameToMatch” with the proper FieldInternalName of your target field in the CAML. In this example, switch the text “FieldInternalNameToMatch” with “Region”.
IMG
IMG


3. Filter the chart using a value from the URL query string

Use {url:ParameterName} as placeholder in the CAML.
IMG
Before the list is filtered, the chart looks like this:
IMG
Pass the filter in the URL like this:
IMG
IMG


4. Filter the chart by filtering the “attached” view

This only applies if the chart is in a page with a single list view. It reads the filter provided by the list filter action and filters the chart accordingly. There are no real connection between the list and the chart – it merely reads the URL and looks for a filter value matching the placeholder in the CAML.

Use {list:FieldInternalName} as placeholder in the CAML.
IMG
Before the list is filtered, the chart looks like this:
IMG
Filter the list by the appropriate column to render the chart.
IMG
IMG


Important

Users upgrading from v2.7 must add three columns to the configuration list:

  • UseCustomQueryFilter: Yes/No column (boolean)
  • CustomQueryFilterField: Single line text
  • CustomQueryFilterChoices: Multi line plain text

For new users, this list is automatically created, but for users upgrading from older versions these fields must be added manually. In that case, compare your configuration list with this image:
IMG


Bugfixes:
If a column name had “&” or “/” in it, the chart “broke”. Thanks to Eric Guy for finding the bug.

I might very well have forgotten something in this walktrough so please post any comment or question below.

Alexander

Slideshow for SharePoint

This is a repost of one of my articles article originally posted over at NothingButSharePoint.com


This solution lets you setup a smooth scrolling slideshow with data from your SharePoint list or your picture library. This solution displays all items in the specified view.

You can customize the appearance of the slideshow web part by changing the size of the slide, the scroll direction (both in and out), border style, background color and image, slide time and display time etc. See bottom of article for full configuration details.

You can have multiple slideshow web parts in one page and have them scroll independently (it would be messy to look at, but you can do it…).

Tested in IE8, Firefox 3.6.13, Safari 5.0.3 and Chrome 9.0.597.98 in both SharePoint 2007 and 2010.

Screenshots from the slideshow

IMG

IMG

Move the mouse over the slide to pause

IMG
The dummy text is snagged from here and the images from Google’s picture search on color-in line drawings

The tool pane:
The button on the left brings you to “NewForm” for that specific list (not available if you are pulling images from an image library).

The middle ones are “Previous slide”, “Resume slideshow” and “Next slide”. The button on the right takes you to “DispForm” for that specific item.

The configuration options:

  • listGuid: The GUID of the list you will pull information from – see below for instructions getting this GUID
  • listBaseUrl: The base URL (site URL, not list URL) of the site containing the list to pull from
  • listViewGuid: The GUID of the view you will pull information from – see below for instructions getting this GUID
  • viewFields: An array of all the fields you want to include – using FieldInternalName
  • viewFieldsStyle: An array that corresponds with the above array. Used to set an individual CSS style of the value
  • imageMax: Object literal with the parameters “height” and “width”. This represents the max-height OR the max-width of images that are either pulled from a picture library, or from a hyperlink field configured as “Image”. This does NOT apply to images embedded in a rich text field. Use only one parameter at the time to keep the image aspect ratio. The one not specified should have the value null
  • containerID: A unique ID (unique in the current page) for the slideshow container.
  • containerHeight: Height in pixles
  • containerWidth: Width in pixles
  • containerBorderStyle: CSS style for the border of the container
  • containerBgColor: Background color of the container
  • containerBgImg: Background image to use for the container
  • inDir: The direction to scroll in the content (n,nv,ne,s,sv,se,v,e)
  • outDir: The direction to scroll out the content (n,nv,ne,s,sv,se,v,e or fade)
  • displayTime: How long to display each slide – in milliseconds
  • slideTime: The slide time – in milliseconds
  • readMoreLink: true or false
  • readMoreText: If the above parameter is true – the text or image to click to go to DispForm for the specific item
  • addNewLink: true or false
  • addNewText: If the above parameter is true – the text or image to click to add a new item to the list
  • emptyCaution: If the list view contains no items – this is the text displayed in the first (and only) slide

How to find the listGuid, viewGuid and FieldInternalName:
Go to the list view that will provide the input for your scrolling web part. Right click somewhere in the list view webpart and select “view source”. Search for “ctx.listname”, and you will find something like this:
ctx.listName = “{A4B4E15A-C5B0-47BC-A08B-739CD48FE58A}”;
ctx.view = “{B83E87C1-D25A-47DE-8196-A0A12DB89106}”;

The value for “ctx.listName” is used as “listGuid”, and the value for “ctx.view” is used as “listViewGuid” in the configuration.

To find the FieldInternalName of your field, go to DispForm on any element in the list, right click and select “view source”. You find the FieldInternalNames by searching for the “FieldName” (the display name) of your field. The FieldInternalName is found like this:

<!-- FieldName="My new field"
    FieldInternalName="My_x0020_new_x0020_field"
    FieldType="SPFieldText"
-->

The code

Download the code for the file “SlideshowForSharePoint.js” here

Store the file in a document library or a dedicated script repository in your site collection. Ensure all users have read access to this repository.

Place the CEWP where you want the slideshow to appear and add this code:

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.0/jquery.min.js"></script>
<script type="text/javascript" src="/test/English/Javascript/SlideshowForSharePoint/SlideshowForSharePoint.js"></script>
<script type="text/javascript">

var myScrSettings = {'listGuid':'A4B4E15A-C5B0-47BC-A08B-739CD48FE58A',
	'listBaseUrl':'/test/English',
	'listViewGuid':'5BD378F4-25D5-4880-9C5B-1667FE43978D',
	'viewFields':['Title','MultiLine','Image'],	
	'viewFieldsStyle':['padding:5px;font-size:16px','padding:5px;font-style:italic','text-align:center'],
	'imageMax':{height:150,width:null},
	'containerID':'myScrollableDiv',
	'containerHeight':270,
	'containerWidth':500,
	'containerBorderStyle':'border:6px silver double',
	'containerBgColor':'#CAE1FF',
	'containerBgImg':'/test/English/Javascript/SlideShowForSharePoint/bgImg6.png',
	'inDir':'e',
	'outDir':'v',
	'displayTime':3000,
	'slideTime':1500,
	'readMoreLink':true,
	'readMoreText':"<img title='Go to item' src='/_layouts/images/magnify.gif' border='0'>",
	'addNewLink':true,
	'addNewText':"<img title='Add new item' src='/_layouts/images/newitem.gif' border='0'>",
	'emptyCaution':"<div style='height:100%;width:100%;padding-top:140px;text-align:center'>There are no items to show here..."};
	
init_fillScrollableDiv(myScrSettings);
</script>
Change at least the listGuid, listViewGuid, viewFields and the “script src” to the file “SlideshowForSharePoint.js”

Regarding picture libraries:

You do not have to provide any entries in the array for the “viewFields” – leave it empty like this []. If you like to put additional fields above the image, add them to the array as shown above.

Ask if something is unclear
Alexander