Category Archives: User information

Showing or hiding form fields based on membership in a SharePoint group

This solution will let you control the visibility of individual fields in NewForm, DispForm and EditForm based on membership in a specific SharePoint group.

This is an updated version of this post.

I have updated it to support newer versions of jQuery, and to use spjs-utility.js.

Note:
If you plan to hide empty fields in NewForm or EditForm, these fields cannot be required to contains information as the user would not be able to save the form – and as the field is invisible, the user will not see the empty field validation message.
How to set up this solution:
  • Download the latest version of spjs-utility.js, and save it locally. You can put it in a folder created using SharePoint designer, or in a shared document library where all users have read permission.
  • If you prefer to use a local version of jQuery, get it here and save it alongside the file above.
  • Add the below code to a CEWP or a HTML form web part, and update the script src to reflect your local copy of spjs-utility.js and jQuery.
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript" src="https://files.spjsworks.com/files/spjs-utility/07.03.2012/spjs-utility.js"></script>
<script type="text/javascript">

var fields = init_fields_v2();
// The group ID
var groupId = 146; // This number must be changed to match your local group ID
// Show this array for members in the above group
var arrToShowForMembersInTheGroup = ['Title','ForOwnersOnly'];
// And this array for everybody else
var arrToShowForEverybodyElse = ['Title'];

var isInGroup = isCurrentUserInGroup(groupId,false);
if(isInGroup){
	hideAllButThese(arrToShowForMembersInTheGroup);
}else{
	hideAllButThese(arrToShowForEverybodyElse);
}

/************************************
     Do not edit below this line
************************************/
function isCurrentUserInGroup(groupId,returnGroupName){
	var ui, userLoginName, ug, result;
	ui = getUserInfo_v2(_spUserId); 
	userLoginName = ui['Name'];
	ug = getGroupCollectionFromUser(userLoginName);
	result = false;	
	$.each(ug,function(i,obj){
		if(obj.groupId===groupId){
			if(returnGroupName){
				result = obj.groupName;
			}else{
				result = true;
			}
			return false;			
		}
	});
	return result;
}

function getGroupCollectionFromUser(userLoginName,userListBaseUrl){
	if(userListBaseUrl===undefined){
		userListBaseUrl = L_Menu_BaseUrl;
	}
	var result = [];
	spjs_wrapSoapRequest(userListBaseUrl + '/_vti_bin/usergroup.asmx', 
		'http://schemas.microsoft.com/sharepoint/soap/directory/GetGroupCollectionFromUser',
		'<GetGroupCollectionFromUser xmlns="http://schemas.microsoft.com/sharepoint/soap/directory/"><userLoginName>' + userLoginName + '</userLoginName></GetGroupCollectionFromUser>',
		function(data){		
			$('Group', data).each(function(idx, itemData){
				result.push({"groupId":parseInt($(itemData).attr('ID'),10),"groupName":$(itemData).attr('Name')});
			});
		});
	return result;
}

function hideAllButThese(arrToShow){
	$.each(fields,function(fin){
		if($.inArray(fin,arrToShow)===-1){
			$(fields[fin]).hide();
		}else{
			$(fields[fin]).show();
		}
	});	
}
</script>
How to configure the solution

Find the group ID of the group you want to use by going to Site Settings > People and Groups, select your group and look at the URL:
http://www.contoso.com/_layouts/people.aspx?MembershipGroupId=6

Change the FieldInternalNames in the array “arrToShowForMembersInTheGroup” and “arrToShowForEverybodyElse” to match your setup.

Look here to learn how to manually retrieve FieldInternalNames, or here to find a solution that shows you all in one go.

If you have trouble, post a comment below.

Alexander

Pull user list property from people picker and write to separate textfield

I have previously posted a solution for pulling the email address from a people picker. This is an updated version that lets you pull any user list property (this is the built in user list in SharePoint and NOT the SharePoint Server Shared Service Provider profile) from the people picker and write it to a separate text field.

Unlike the previous solution, this one is designed for multi select people pickers.

How does it work

This solution binds to the blur event on the picker input field, and on the click event on the Check Names and Browse button. It checks to see that the picker selections resolve, and then pulls the login name form the selections. It then uses the function “getUserInfo_v2” from the file “spjs-utility.js” to get the user list information for the current selection.

The function “getUserInfo_v2” may not return all fields from the user list. If you miss some fields, you can add them to the array “arrOfFields”. Go here to learn how to find the FieldInternalName of the fields

How to set it up

Go here and download the latest version of “spjs-utility.js”

Add a CEWP below the list form in NewForm or EditForm. Read here how to add a CEWP in SharePoint 2007. In SharePoint 2010 you can add the CEWP by selectiong “Form Web Parts” from the list ribbon menu.

Insert this code in it. In line 05: replace “from” and “to” with your FieldInternalNames, and the “propertyName” with the one you want to retrieve. The “multiValueSeparator” is the separator between multiple values (if the picker is a multi select).

<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="/test/Scripts/spjs-utility.js"></script>
<script type="text/javascript">

pullEmailFromPickerOnChange({from:'MyPeoplePicker',to:'Title',propertyName:'Title',multiValueSeparator:'; '});

/******************************************************
		Do not change anything below this line
*******************************************************/
fields = init_fields_v2();
function pullEmailFromPickerOnChange(obj){
	var toFind, arr, data, val;
	$(document).ready(function(){
		toFind = "div.ms-inputuserfield";
		if(!browseris.ie5up && typeof(_fV4UI)==='undefined'){
			toFind = "textarea";
		}
		$(fields[obj.from]).find(toFind).bind('blur',function(){
			$(fields[obj.to]).find('input').val('');
			arr = pullUserInfoFromPicker(obj.from,obj.to,obj.propertyName);
			$.each(arr,function(i,data){
				if(data[obj.propertyName]!==undefined){
					val = $(fields[obj.to]).find('input').val();
					if(val!==''){
						val += obj.multiValueSeparator;
					}
					$(fields[obj.to]).find('input').val(val+data[obj.propertyName]);
				}
			});
		});
		$(fields[obj.from]).find('img').bind('click',function(){
			setTimeout(function(){
				$(fields[obj.to]).find('input').val('');
				arr = pullUserInfoFromPicker(obj.from,obj.to,obj.propertyName);
				$.each(arr,function(i,data){
					if(data[obj.propertyName]!==undefined){			
						val = $(fields[obj.to]).find('input').val();
						if(val!==''){
							val += obj.multiValueSeparator;
						}
						$(fields[obj.to]).find('input').val(val+data[obj.propertyName]);
					}
				});
			},500);
		});
	});
}

function pullUserInfoFromPicker(finFrom,finTo){
	var result,	isResolved;	
	result = [];
	$(fields[finFrom]).find('.ms-formbody').find("div[id='divEntityData']").each(function(){
		isResolved = ($(this).attr('isresolved').toLowerCase()=='true')?true:false;		
		if(isResolved){	
			result.push(getUserInfo_v2($(this).attr('description')));				
		}			
	});
	return result;
}
</script>

Change the script src to match your location of “spjs-utility.js”. If you prefer to use a local copy of jQuery, go here to download v1.6.4. I have not had the time to make it work with jQuery 1.7x so you must use v1.6.4 for now.

Alexander

Accessing user profile information in SharePoint with javascript – updated version

I have previously posted a solution for pulling user information from the built-in user information list in SharePoint (found in WSS 3.0, MOSS 2007 and SharePoint 2010 both foundation and server). This is NOT the user profile found in MOSS 2007 and in SharePoint 2010 server. You find the solution here

This solution is an updated version of the script – and should hopefully work better with sites on a managed path.

Insert this code in a CEWP
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<script type="text/javascript" src="/test/EMSKJS/spjs-utility.js"></script>
<script type="text/javascript">

var userInfoObj = getUserInfo_v2(_spUserId);
var name = userInfoObj.Title;
var email = userInfoObj.EMail;
</script>

I have incorporated the new “getUserInfo_v2” in the file “spjs-utility.js”.

The parameter “_spUserId” is provided by SharePoint and represents the current user’s userID.

The function takes one argument which can be a userID or a login name (domainlogin or appname:user). If you use domainuser as a string like this:

var userInfoObj = getUserInfo_v2("contoso\alexander");

Please note the extra “” as it must be escaped in javascript.

The variables “name” and “email” are examples, the full range of “out of the box fields” are:
ID, Name, Title, EMail, Department, JobTitle, Notes, Picture, IsSiteAdmin, Created, Author, Modified, Editor, SipAddress

Download

You can download the file “spjs-utility.js” here. Ensure you pick the version dated 18.09.2011, or newer.

Pull e-mail from people picker and write to a separate textfield – updated version

08.01.2012 I have published an updated version of this script here


I have previously posted a solution for pulling the e-mail address from a people picker and writing it to a separate field when saving the form. You find it here.

This one does the same, but i have updated the scripts and added an “onchange event” that triggers when you enter the name in the input field (and move focus away from the field), or uses the address book to pick a user.

This solution is designed for single selection people picker fields.

For Internet Explorer in SharePoint 2007, and for most browsers in SharePoint 2010, the email is pulled from the picker itself. For all other browsers than IE in SharePoint 2007, the email is retrieved by using a call to the built in “user list” in SharePoint using the function “getUserInfo_v2”. This function is part of “spjs-utility.js” and can be found below.

How to use

Insert a ContentEditorWebPart (CEWP) under the form in NewForm.aspx / EditForm.aspx by switching the page to edit mode. Read here on how to do it in SharePoint 2007. In SharePoint 2010 you can add the CEWP on the list ribbon menu “Form Web Parts”.

CEWP code for both SharePoint 2007 and 2010:

&lt;script type=&quot;text/javascript&quot; src=&quot;https://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/EMSKJS/PeoplePickerEmail/spjs-utility.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;

fields = init_fields_v2();
pullEmailFromPickerOnChange({from:'MyPeoplePicker',to:'Title'});

/******************************************************
		Do not change anything below this line
*******************************************************/
function pullEmailFromPickerOnChange(obj){
	var toFind, data;
	$(document).ready(function(){
		toFind = &quot;div.ms-inputuserfield&quot;;
		if(!browseris.ie5up &amp;&amp; typeof(_fV4UI)==='undefined'){
			toFind = &quot;textarea&quot;;
		}
		$(fields[obj.from]).find(toFind).bind('blur',function(){
			data = pullEmailFromPicker(obj.from,obj.to);
			if(data.EMail!==undefined){
				$(fields[obj.to]).find('input').val(data.EMail);
			}
		});
		$(fields[obj.from]).find('img:last').bind('click',function(){
			setTimeout(function(){
				data = pullEmailFromPicker(obj.from,obj.to);
				if(data.EMail!==undefined){			
					$(fields[obj.to]).find('input').val(data.EMail);
				}
			},500);
		});
	});
}

function pullEmailFromPicker(finFrom,finTo){
	var result,	isResolved, data, matchArrRaw, matchArr;
	result = {};
	$(fields[finFrom]).find('.ms-formbody').find(&quot;div[id='divEntityData']&quot;).each(function(){
		isResolved = ($(this).attr('isresolved').toLowerCase()=='true')?true:false;
		if(isResolved){	
			data = $(this).find('div:first').attr('data');
			matchArr = [];
			matchArrRaw = data.split(/&lt;[^&gt;]*&gt;/);
			$.each(matchArrRaw,function(i,val){
				if(val!==''){
					matchArr.push(val);
				}
			});
			if(matchArr.length&gt;1){
				$.each(matchArr,function(i,val){
					if(i%2===0){
						switch(val){
							case'SPUserID':
								val = 'ID';
							break;
							case 'Email':
								val = 'EMail';
							break;
							case 'DisplayName':
								val = 'Title';
							break;
						}
						result[val] = matchArr[i+1];
					}
				});
			}else{ // Non IE in SP2007
				result = getUserInfo_v2($(this).attr('description'));				
			}
		}	
	});
	return result;
}
&lt;/script&gt;

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 possible “bug” in the CEWP handling when editing a SP2010 page where the HTML is accumulated when editing the page.

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

Parameters

You call this function using an object literation like this
pullEmailFromPickerOnChange({from:’MyPeoplePicker’,to:’Title’});

The attribute “from” is the FieldInternalName of the people picker and “to” is the FieldInternalName of the field to write the email to.
Read here on how to find the FieldInternalName

Download

You find the file “spjs-utility.js” here, ensure you grab the version dated 18.09.2010 or newer.


Post any question below.

Alexander

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.

Filter a calendar view based on user profile property

I got this request from Carel Schotborgh:

Using WSS 3.0

Not have been able to find it anywhere so, since it is possible to filter a list items (in all event/task/etc view) based on membership in SharePoint group (By Alexander). I would like to request the possibility to filter an Agenda View on a single line text, based on a field of the current user information field (for instance department). I import data into SharePoint list what contains names of people. So users do not create the list items and there are multiple columns with names like Judge1 Judge2 Lawyer etc. As you all know you can’t use [ME] value in a single line text. This can only be used with columns: Created by, Modified by, Assigned to and People picking data. Problem with agenda view is also that it only displays 1 field (in general description of appointment for instance).

What do I want?
Filter (a) specific column(s) on the basis of the current user that is logged on (department field for example) in an agenda view.

The agenda should only show items that match the same text as entered in the department field of the user information field of the user that is currently logged on.

In my case IF Judge1 = Mr. J. Jenkins display it OR IF Judge2 = Mr. J. Jenkins display it. The OR statement is very important since SharePoint also filters with AND statement. So I would like to filter multiple columns with department field (any other also ok, as long I can fill in a value that is connected to the current user).

I already managed to create something that filters all event/tasks/etc list view, searching all the columns based upon the current user department field with or statement idea, but not specific columns. Also in agenda view my code and Alexanders code will not work.

If it is not possible to do this on each specific column it is also ok to search all of the columns since the names in my list are unique for each column. Other columns do not contain their names in such a way anyway. I’m already using my script for the not agenda view and works perfectly except user with slow internet will see the entire list my filter starts working.

Excuse me for long text, but it is complex. Much appreciated any help, suggestion or solution.


Here is one suggestion on how this can be done. It pulls the “Department” from the user profile and searches for a match in one of the fields specified in the script (in the variable “arrOfFieldInternalNames”).

This solution does:

  • Filters a calendar view based on a text retrieved from the current users profile (from People and Groups)
  • Filters with an “OR” statement looking for a match in multiple text fields
  • Handles “single day items” and items spanning over multiple days.
  • Hide the calendar view until it has been filtered

This solution doesn’t:

  • If multiple elements are located in one day, the standard calendar view will display a “x more items” link to expand all items that day. My filter solution will filter the items, but may display a link saying there are “3 more items”, but when clicking the link there may no items to display.

The solution
To keep a nice even background when removing items spanning over multiple days, i had to change the background for the “not in this month items” to white.

Add this code to a CEWP below the calendar view:

&lt;style type=&quot;text/css&quot;&gt;
.ms-cal-nodataMid,.ms-cal-nodataBtm2{
	background-color:#FFFFFF;
}
&lt;/style&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.3.2.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/interaction.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/stringBuffer.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;

// Set variables
listGuid = 'FilterCalendarView'; // Use list Name or List Guid
listBaseUrl = L_Menu_BaseUrl;
userListGuid = &quot;{570D772F-0EAB-45A8-8C54-9CCD4EC6A0AF}&quot;; // The &quot;People and Groups&quot; list
userListBaseUrl = ''; // Modify if on a managed path
// The FieldInternalNames to search for information matching the selected user property
arrOfFieldInternalNames = ['Judge1','Judge2'];

// Hide calendar view until it is filtered
$(&quot;.ms-cal-gempty&quot;).hide();

// Get the UserInfo
var userInfoObj = getUserInfo();
var dep = userInfoObj.Department; // User profile property &quot;Department&quot;

// Find all &quot;relevant&quot; items
var myItems = getMyItemsID(dep,arrOfFieldInternalNames);
// Filter view
filterCalendarView(myItems);

function getMyItemsID(find,findInArr){
	wsBaseUrl = listBaseUrl + '/_vti_bin/';
	var query = &quot;&quot;;
	$.each(findInArr,function(i,fin){
		query += &quot;&lt;Eq&gt;&lt;FieldRef Name='&quot;+fin+&quot;' /&gt;&lt;Value Type='Text'&gt;&quot;+find+&quot;&lt;/Value&gt;&lt;/Eq&gt;&quot;;
		if(i&gt;0)query = &quot;&lt;Or&gt;&quot; + query + &quot;&lt;/Or&gt;&quot;;
	});
	query = &quot;&lt;Where&gt;&quot; + query + &quot;&lt;/Where&gt;&quot;;
	var arrToReturn = [];
	res = queryItems(listGuid,query,['ID']);
	$.each(res.items,function(i,item){
		arrToReturn.push(item.ID);
	});
	return arrToReturn;
}

function filterCalendarView(arrOfIDs){
	$(&quot;.ms-cal-gempty a[href*='DispForm.aspx?ID=']&quot;).each(function(){
		var currID = $(this).attr('href').match(/ID=(d+)/);
		if($.inArray(currID[1],arrOfIDs)==-1){
			// remove
			var thisParentTd = $(this).parents('table:first').parents('td:first');
			var colspan = thisParentTd.attr('colspan');
			if(colspan&gt;1){		
				for(i=1;i&lt;colspan;i++){				
					thisParentTd.after(&quot;&lt;td class='ms-cal-workitem'&gt;&amp;nbsp;&lt;/td&gt;&quot;);
				}
				thisParentTd.replaceWith(&quot;&lt;td class='ms-cal-workitem'&gt;&amp;nbsp;&lt;/td&gt;&quot;);
			}else{
				thisParentTd.html('&amp;nbsp;');			
			}		
		}
	});
// Show calendar view after it has been filtered
$(&quot;.ms-cal-gempty&quot;).show();
}

function getUserInfo(UserId){
wsBaseUrl = userListBaseUrl + '/_vti_bin/';
var uiObj = {};

if(typeof(UserId)==&quot;undefined&quot; || UserId=='')UserId = _spUserId;

var arrOfFields = ['ID', 'Name', 'Title', 'EMail', 'Department', 'JobTitle', 'Notes', 'Picture',
'IsSiteAdmin', 'Created', 'Author', 'Modified', 'Editor', 'SipAddress', 'Deleted'];

var item = getItemById(userListGuid,UserId,arrOfFields);
    if(item != null){
	    for(i=0;i&lt;arrOfFields.length;i++){
	    	if(item[arrOfFields[i]]!=null){
	    		uiObj[arrOfFields[i]] = item[arrOfFields[i]];
	    	}else{
	    		uiObj[arrOfFields[i]] = '';
	    	}
	    }
       	return uiObj;
    }else{
        for(i=0;i&lt;arrOfFields.length;i++){
    		uiObj[arrOfFields[i]] = &quot;User with id &quot; + UserId + &quot; not found.&quot;;
    	}
		return uiObj;
	}
}	
&lt;/script&gt;

Modify the parameters:

  • listGuid: The list name or list Guid of the list to filter.
  • listBaseUrl: The base URL of the list to filter.
  • userListGuid: The list Guid of the user list (People and Groups).
  • userListBaseUrl: The user list base URL – Most likely an empty string “”. If the site resides on a manage path this must be reflected.
  • arrOfFieldInternalNames: Array of the FieldInternalNames to search for a match on the search string-

The jQuery-library is found here. The sourcecode refers to jquery-1.3.2.min.js. If you use another version, please update the reference in the code.

The scripts “interaction.js” and “stringBuffer.js” is created by Erucy and published on CodePlex.

Read here how to add a CEWP to NewForm or EditForm, and how to get the guid for a list.

I do not think this is a “production environment solution” at this stage, but please test it and post back any comments or suggestions and i will try to adapt the script.

Regards
Alexander

Pull e-mail from people picker and write to a separate textfield

18.09.2011 I have posted a new solution to this “problem”. I recommend you use the new one. You find it here


I got this request from Indra:

Hi Alex,

This is really great blog!! awesome work and i am big fan of this site, i check everyday and look at the things and learn , but i need something that i cannot find any where. Let me explain what i need..

I have a list with a people picker and a field called email address, i want to get the email address populated automatically depending the person on people picker ( single user). I know that i need to get user information from profile, but i am not a programmer and there i need your help.

I know you are really busy but please spotlight when you have time.

Thanks in Advance.

This code fills the e-mail address when the item is saved. It pulls the email address from a “resolved” user in a people picker, and writes it to a separate text field.

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.min. If you use another version, please update the reference in the code.

The scripts “interaction.js” and “stringBuffer.js” is created by Erucy and published on CodePlex.

Read here how to add a CEWP to NewForm or EditForm, and how to get the guid for a list.

Add this code to a CEWP below the NewForm or EditForm:

&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.4.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/interaction.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/stringBuffer.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
fields = init_fields();

userListGuid = '570D772F-0EAB-45A8-8C54-9CCD4EC6A0AF';
userListBaseUrl = '';
myPeoplePickerFin = 'MyPeoplePicker';
myTextFieldFin = 'MyTextField';

function PreSaveAction(){
	var myPeoplePicker = $(fields[myPeoplePickerFin]).find('.ms-formbody').find(&quot;div[id='divEntityData']&quot;);
	if(myPeoplePicker.length&gt;0){
		var isResolved = (myPeoplePicker.attr('isresolved').toLowerCase()=='true')?true:false;
		if(isResolved){	
			var login = myPeoplePicker.attr('description');	
			var uiObj = getUserInfoFromLogin(login);
			$(fields[myTextFieldFin]).find('input').val(uiObj.EMail);	
		}
	}
	return true;
}

function getUserInfoFromLogin(UserLogin){ //
wsBaseUrl = userListBaseUrl + '/_vti_bin/'; 
var retObj = {};
var arrOfFields = ['ID','Name','Title','EMail','Department','JobTitle','Notes','Picture','IsSiteAdmin',
				   'Created','Author','Modified','Editor','SipAddress','Deleted'];
				   
var query = &quot;&lt;Where&gt;&lt;Eq&gt;&lt;FieldRef Name='Name' /&gt;&lt;Value Type='Text'&gt;&quot; + UserLogin + &quot;&lt;/Value&gt;&lt;/Eq&gt;&lt;/Where&gt;&quot;;
var res = queryItems(userListGuid,query,arrOfFields,1); 
    if(res.count&gt;0){ 
	    for(i=0;i&lt;arrOfFields.length;i++){
	    	retObj[arrOfFields[i]] = res.items[0][arrOfFields[i]];    
	    }
       	return retObj; 	
    }else{
        for(i=0;i&lt;arrOfFields.length;i++){
    		retObj[arrOfFields[i]] = &quot;User with id &quot; + UserLogin + &quot; not found.&quot;;    
    	}
		return retObj; 
	}
}

function init_fields(){
var res = {};
$(&quot;td.ms-formbody&quot;).each(function(){
if($(this).html().indexOf('FieldInternalName=&quot;')&lt;0) return;
var start = $(this).html().indexOf('FieldInternalName=&quot;')+19;
var stopp = $(this).html().indexOf('FieldType=&quot;')-7;
var nm = $(this).html().substring(start,stopp);
res[nm] = this.parentNode;
});
return res;
}
&lt;/script&gt;

You must change these four parameters in the script:

  • userListGuid: The listGuid of the user list
  • userListBaseUrl: The base URL for the userList. Most likely an empty string “”, but If the site resides on a managed path, this must be reflected.
  • myPeoplePickerFin: FieldInternalName for the people picker
  • myTextFieldFin: FieldInternalName for the single line text field to hold the email address

Ask if anything is unclear.

Regards
Alexander

Autocomplete for SharePoint people picker

26.03.2010 Updated code to be able to clear the selection It’s only the code for the file “AutocompleteForPeoplePicker.js” that has changed. Thanks to Steve for pointing out the bug.

This solution adds auto complete functionality to a standard SharePoint people picker.

This solution is built with the autocomplete widget from jQuery UI. The values are pulled from the user list based on a query. All users with an email address are available.

Limitations:

  • Single choice only
  • No filter against user group, all users are displayed

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

In addition to the above scripts, i have the jQuery UI 1.8 in a separate folder. See the CEWP code and point the links to your jQuery UI location.

The jQuery UI-library is found here. The pictures and the sourcecode refers to jquery-ui-1.8. The autocomplete widget is not found in previous releases.

The jQuery-library is found here. The pictures and the sourcecode refers to jquery-1.4.min. The autocomplete widget is not supported in previous releases.

The scripts “interaction.js” and “stringBuffer.js” is created by Erucy and published on CodePlex.

The sourcecode for the file “AutocompleteForPeoplePicker.js” is found below.

Read here how to add a CEWP to the NewForm or EditForm, how to find the list Guid of your list, and how to find the FieldInternalName of your columns.

Add a CEWP below the list form in NewForm or EditForm, and insert this code:

&lt;style type=&quot;text/css&quot;&gt;
.ui-menu .ui-menu-item {
	font-size:xx-small;
}
&lt;/style&gt;
&lt;link type=&quot;text/css&quot; href=&quot;/test/English/jQueryUI18/smoothness/jquery-ui-1.8.custom.css&quot; rel=&quot;stylesheet&quot; /&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/jquery-1.4.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/interaction.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/stringBuffer.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/jQueryUI18/jquery-ui-1.8.custom.min.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;/test/English/Javascript/AutocompleteForPeoplePicker.js&quot;&gt;&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
fields = init_fields();

// Find all users from userlist. Parameters &quot;userListBaseUrl&quot; and &quot;userListGuid&quot;
var allUsers = getUsers('','570D772F-0EAB-45A8-8C54-9CCD4EC6A0AF');

// Call with FieldInternalName of your people picker field(s)
$(document).ready(function(){
	peoplePickerAutoclomplete('MyPeoplePicker');
	peoplePickerAutoclomplete('AnotherPeoplePicker');	
});
&lt;/script&gt;

Parameters explained:

  • userListBaseUrl: The base URL of the site the user list resides. If your site is in a managed path, it must reflect this managed path. If not, this parameter is most likely an empty string (“”)
  • userListGuid: The list Guid of the user list.

The sourcecode for the file “AutocompleteForPeoplePicker.js” looks like this:

/* Add autocomplete functionality to a SharePoint people picker
 * -----------------------------
 * Created by Alexander Bautz
 * alexander.bautz@gmail.com
 * https://spjsblog.com
 * v1.0
 * LastMod: 24.03.2010
 * -----------------------------
 * Must include reference to jQuery 1.4, jQuery UI 1.8 and to the folloving scripts:
 * ----------------------------------------------------
 * interaction.js - http://spjslib.codeplex.com/
 * stringBuffer.js - http://spjslib.codeplex.com/
 * ----------------------------------------------------
*/

function peoplePickerAutoclomplete(FieldInternalName){
if(typeof(fields)=='undefined')fields = init_fields();

var myPicker = $(fields[FieldInternalName]);
if(myPicker.find('div.ms-inputuserfield:visible').length&gt;0){
	var ie=true; // Internet Explorer
	var toFind = 'div.ms-inputuserfield';
	var inputStyle = &quot;margin:-1 0 -1 0;height:18px;font-family:Verdana,sans-serif;font-size:8pt;width:100%;display:none&quot;;

}else{
	var ie=false; // Firefox
	var toFind = 'textarea:first';
	myPicker.find('textarea:first').css({'height':'18px'});
	var inputStyle = &quot;margin:1 0 1 0;height:18px;font-family:Verdana,sans-serif;font-size:8pt;width:100%;display:none&quot;;
}
	myPicker.find(toFind)
		.before(&quot;&lt;input hiddenval='' style='&quot;+inputStyle+&quot;' id='&quot;+FieldInternalName+&quot;'/&gt;&quot;)
		.focus(function(){
			$(this).hide().prev().show().focus();
		});

	// Add autocomplete
	$(&quot;#&quot;+FieldInternalName).autocomplete({
			source: allUsers,
			select: function(event, ui) {
				fillPicker(ie,myPicker,FieldInternalName,ui.item.writeBackValue,ui.item.value);				
				return false;
			}		
		}).blur(function(){
			var currVal = $(this).val();
			var prevVal = $(this).attr('hiddenval')
			if(currVal!=''&amp;&amp;currVal!=prevVal){
				$(this).val($(this).attr('hiddenval'))
			}else if(currVal==''){
				fillPicker(ie,myPicker,FieldInternalName,'','');	
			}
			$(this).hide().next().show();
	});	
}

function fillPicker(ie,field,fin,loginName,dispName){
	if(ie){
		// IE
		field.find('.ms-inputuserfield').html(loginName);
		$(&quot;#&quot;+fin).val(dispName).attr('hiddenval',dispName);
		field.find('img:first').click();
	}else{
		// FF
		field.find(&quot;textarea:first&quot;).val(loginName);
		$(&quot;#&quot;+fin).val(dispName).attr('hiddenval',dispName);
	}
}

function getUsers(userListBaseUrl,userListGuid){
	var query = &quot;&lt;Where&gt;&lt;And&gt;&lt;IsNotNull&gt;&lt;FieldRef Name='EMail' /&gt;&lt;/IsNotNull&gt;&quot; +
				&quot;&lt;Eq&gt;&lt;FieldRef Name='ContentType' /&gt;&lt;Value Type='Text'&gt;Person&lt;/Value&gt;&lt;/Eq&gt;&lt;/And&gt;&lt;/Where&gt;&quot; +
				&quot;&lt;OrderBy&gt;&lt;FieldRef Name='Title' Ascending='TRUE'/&gt;&lt;/OrderBy&gt;&quot;;
	wsBaseUrl = userListBaseUrl + '/_vti_bin/';	
	var res = queryItems(userListGuid,query,['ID','Title','Name','EMail','ContentType']); 
    var ret = [];
    $.each(res.items,function(idx,item){ 	
    	ret.push({label:item['Title']+&quot;&lt;br&gt;&quot;+item['EMail']+&quot;&lt;br&gt;&quot;+item['Name'],value:item['Title'],writeBackValue:item['Name'],desc:'Test'});	
    });
    return ret;    
}

function init_fields(){
var res = {};
$(&quot;td.ms-formbody&quot;).each(function(){
if($(this).html().indexOf('FieldInternalName=&quot;')&lt;0) return;
var start = $(this).html().indexOf('FieldInternalName=&quot;')+19;
var stopp = $(this).html().indexOf('FieldType=&quot;')-7;
var nm = $(this).html().substring(start,stopp);
res[nm] = this.parentNode;
});
return res;
}

Save as “AutocompleteForPeoplePicker.js”, mind the file extension, and upload to the script library as shown above.

I will update the article on Edit date, single line text, number or boolean columns directly in list view based on this script to allow setting a people picker field directly in a list view.

Ask is anything is unclear.

Regards
Alexander