1,691 articles and 12,616 comments as of Friday, September 10th, 2010

Friday, April 30, 2010

SharePoint: Filter a Calendar View Based on User Profile Property

Guest Author: Alexander Bautz
SharePoint JavaScripts

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:

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

// Set variables
listGuid = 'FilterCalendarView'; // Use list Name or List Guid
listBaseUrl = L_Menu_BaseUrl;
userListGuid = "{570D772F-0EAB-45A8-8C54-9CCD4EC6A0AF}"; // The "People and Groups" 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
$(".ms-cal-gempty").hide();

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

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

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

function filterCalendarView(arrOfIDs){
	$(".ms-cal-gempty a[href*='DispForm.aspx?ID=']").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>1){
				for(i=1;i<colspan;i++){
					thisParentTd.after("<td class='ms-cal-workitem'>&nbsp;</td>");
				}
				thisParentTd.replaceWith("<td class='ms-cal-workitem'>&nbsp;</td>");
			}else{
				thisParentTd.html('&nbsp;');
			}
		}
	});
// Show calendar view after it has been filtered
$(".ms-cal-gempty").show();
}

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

if(typeof(UserId)=="undefined" || 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<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<arrOfFields.length;i++){
    		uiObj[arrOfFields[i]] = "User with id " + UserId + " not found.";
    	}
		return uiObj;
	}
}
</script>

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

Guest Author: Alexander Bautz
SharePoint JavaScripts

Alexander Bautz is a SharePoint consultant/developer (mainly JavaScript/jQuery solution) living in Norway. Alexander spends a lot of his spare time blogging on the same topics. His focus area is "end user customizations" with no (or as little as possible) server side code.

 

Please Join the Discussion

3 Responses to “SharePoint: Filter a Calendar View Based on User Profile Property”
  1. Arijana says:

    I have a request to filter the shared calendar either based on who the manager is (to enable managers to see items from all of their people) or for employees to see items only from their work group (defined in user profile within moss site). I couldn’t get this code to work. I have a calendar (named Time Management Calendar) with added fields “Group” and “Manager” which are automatically added from user profile when item is added to the calendar. What I’m trying to do is filter either by Manager or Group field but based on Manager or Group values of the current user. When I try to use your code the calendar comes back empty. From what I can see getMyItemsID function returns nothing and I cannot figure why. Everything seems to work fine but the calendar view returns no records. Can you check the code or give me some pointers on where to look for errors?

    I appreciate your help.

    Arijana

    • Arijana says:

      Forgot to add that I did find one error in the code but I still get empty calendar. I still wanted to share it with you. I replaced

      $.each(findInArr,function(i,fin){
              query += ""+find+"";
              if(i&gt;0)query = "" + query + "";
          });
      

      with

      $.each(findInArr,function(i,find){
      35	        query += ""+find+"";
      36	        if(i&gt;0)query = "" + query + "";
      37	    });
      

Trackbacks

Check out what others are saying about this post...
  1. [...] SharePoint: Filter a Calendar View Based on User Profile Property [...]




Notify me of comments to this article:


Speak and you will be heard.

We check comments hourly.
If you want a pic to show with your comment, go get a gravatar!