88 articles and 335 comments as of Friday, February 10th, 2012

Monday, July 19, 2010

SharePoint 2007 style view selector for SharePoint 2010

Guest Author: Alexander Bautz
SharePoint JavaScripts

I have just started to look at SharePoint 2010, but one of the first things I noticed, was how cumbersome it was to change view in a list or library. In the default “Browse” layout, you must use at least 4 clicks to change view.

I therefore made this solution to add a SharePoint 2007 style view selector to the top link bar:



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 named “Javascript” and added “jquery-1.4.2.min.js” and “spjs_customViewMenu.js”:



Add this code to a CEWP in the list view where you want the menu to appear:

<script type="text/javascript" src="../../Javascript/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="../../Javascript/spjs_customViewMenu.js"></script>
<script type="text/javascript">
$(document).ready(function(){
	createCustomViewMenu();
});
</script>

The code for the file “spjs_customViewMenu.js”:

/* SharePoint 2007 style view selector for SharePoint 2010
 * Adds a view selector to the Top link bar
 * ---------------------------------------------
 * Created by Alexander Bautz
 * [email protected]
 * Copyright (c) 2009-2010 Alexander Bautz (Licensed under the MIT X11 License)
 * v1.0
 * LastMod: 11.07.2010
 * ---------------------------------------------
 * Include reference to:
 *  jQuery - http://jquery.com
 *	spjs_customViewMenu.js (this file)
 * ---------------------------------------------
*/

function createCustomViewMenu(){
	// Get the view collection for the list
	var viewColl = customGetViewCollection(_spPageContextInfo.pageListId);
	var activeViewName = '';
	var htmlBuffer = [];
	// Build the view selector
	$.each(viewColl.views,function(){
		var viewIcon = 'itgen.png'
		var viewType = $(this).attr('Type');
		var viewUrl = $(this).attr('Url');
		var viewDispName = $(this).attr('DisplayName');
		if(viewType=='CALENDAR')viewIcon = 'itevent.png'
		var thisViewGuid = $(this).attr('Name');
		if(location.href.match(escape(viewUrl))!=null){
			activeViewName = $(this).attr('DisplayName');
			_spPageContextInfo.activeViewGuid = thisViewGuid;
		}
		htmlBuffer.push("<div class='ms-cui-ctl' style='display:block;padding:2px 0px 0px 2px;cursor:pointer' viewUrl='"+viewUrl+"' ");
		htmlBuffer.push("onclick='javascript:selectView(this)'>");
		htmlBuffer.push("<img style='vertical-align:middle;padding-left:2px;' src='"+L_Menu_BaseUrl+"/_layouts/images/"+viewIcon+"'>&nbsp;"+viewDispName+"</div>");
	});
	// Edit view and create view
	htmlBuffer.push("<div style='border-bottom:1px silver solid;height:4px'>&nbsp;</div>");
	htmlBuffer.push("<div class='ms-cui-ctl' style='padding:2px 0px 0px 2px;cursor:pointer;display:block' ");
	htmlBuffer.push("viewUrl='modify' onclick='javascript:selectView(this)'>");
	htmlBuffer.push("<img style='vertical-align:middle;padding-left:2px;' src='"+L_Menu_BaseUrl+"/_layouts/images/modifyview.gif'>&nbsp;Modify view</div>");
	htmlBuffer.push("<div class='ms-cui-ctl' style='padding:2px;cursor:pointer;display:block' ");
	htmlBuffer.push("viewUrl='create' onclick='javascript:selectView(this)'>");
	htmlBuffer.push("<img style='vertical-align:middle;padding-left:2px;' src='"+L_Menu_BaseUrl+"/_layouts/images/createview.gif'>&nbsp;Create view</div>");
	// Wrap the selector
	var htmlWrap = [];
	htmlWrap.push("<div id='customViewMenuWrapper' style='cursor:pointer' class='menu-item' onclick='javascript:customShowMenu()' onmouseout='customMouseOutHideMenu(event)'>");
	htmlWrap.push(activeViewName);
	htmlWrap.push("<img id='customViewMenuWrapperImg' onmouseout='customMouseOutHideMenu(event)' style='vertical-align:middle;padding-left:4px' src='/_layouts/images/ecbarw.png' alt='Open Menu'></div>");
	htmlWrap.push("<div id='customViewMenuDiv' style='padding:1px;background-color:white;border:1px silver solid;display:none;position:absolute;z-index:1001;width:150' ");
	htmlWrap.push("onmouseover='customHideMenu(false)' onmouseout='customMouseOutHideMenu(event)'>");
	htmlWrap.push(htmlBuffer.join('')+"</div>");
	// Append the new menu to the toplink bar
	$("div.s4-toplinks ul").append("<li class='static'>"+htmlWrap.join('')+"</li>");
}

// Overcome the missing onmouseleave event in Firefox
function customMouseOutHideMenu(e){
if(!e) var e = window.event;
	var target = e.srcElement || e.target;
	var relTarg = e.relatedTarget || e.toElement;
	var relTargID = $(relTarg).attr('id')
	isInWrapper = ($(target).attr('id')=='customViewMenuWrapper' || $(target).parents("div[id='customViewMenuWrapper']").length>0);
	if(!isInWrapper || relTargID.match('customViewMenu')==null){
		customHideMenu(true);
	}
}

// Hide menu if user moves mouse outside the container
function customHideMenu(hide){
	if(hide){
		hideMenu = setTimeout(function(){
			$("#customViewMenuDiv").hide();
		},500);
	}else{
		if(typeof(hideMenu)!='undefined'){
			clearTimeout(hideMenu);
		}
	}
}

function customShowMenu(){
	$("#customViewMenuDiv").show();
	// Fix div width in IE 7
	var menuWidth = 150;
	$("#customViewMenuDiv").find('div.ms-cui-ctl').each(function(){
		thisWidth = $(this).width();
		if(thisWidth>menuWidth)menuWidth=thisWidth+10
	});
	$("#customViewMenuDiv").css('width',menuWidth);
}

function selectView(obj){
	var Url = $(obj).attr('viewUrl');
	var activeViewGuid = _spPageContextInfo.activeViewGuid;
	var activeList = _spPageContextInfo.pageListId;
	if(Url=='modify'){
		Url = L_Menu_BaseUrl + "/_layouts/ViewEdit.aspx?List="+activeList+"&View="+activeViewGuid;
	}else if(Url=='create'){
		Url = L_Menu_BaseUrl + "/_layouts/ViewType.aspx?List="+activeList+"&View="+activeViewGuid;
	}
	location.href=Url;
}

/*****************************************************
				Get view collection
*****************************************************/
function customGetViewCollection(listGuid){
	xmlStr = "<GetViewCollection xmlns='http://schemas.microsoft.com/sharepoint/soap/'><listName>"+listGuid+"</listName></GetViewCollection>";
	var result = {success:false, errorCode:'', errorText:'internal error', views:[]};
	wrapSoapRequest(L_Menu_BaseUrl + '/_vti_bin/views.asmx', 'http://schemas.microsoft.com/sharepoint/soap/GetViewCollection', xmlStr, function(data){
		if($('ErrorText', data).length>0) {
			result.success = false;
		}else{
			result.success = true;
			$('View', data).each(function(i){
				if($(this).attr('Hidden')!='TRUE'){
					result.views.push($(this));
				}
			});
		}
	});
	return result;
}

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

Save as “spjs_customViewMenu.js” – mind the file extension – and upload to the scriptlibrary as shown above.

Ask if something is unclear!
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.

Bookmark and Share
 

Please Join the Discussion

8 Responses to “SharePoint 2007 style view selector for SharePoint 2010”
  1. Greg says:

    Alex,
    You have such a resource for SP2007, I am SO glad to see you dig into SP2010!
    One general suggestion would be to include snapshots of before and after…

    Also, for the webservices call, why wouln’t you give SPServices by Marc Anderson a try?
    http://spservices.codeplex.com/documentation
    I think it could help at various levels:
    * provide endusers with more ‘reusable’ code
    * provide additional real life examples of more ‘complex’ solutions for this library
    * contribute to making the SPServices library SP2010 compatible

    Greg

  2. Greg says:

    Alex,

    Scratch the snapshots remark…your solution is so well integrated I didn’t see it as not being OOTB.

    It seems to me that it will be so useful that:
    * I am thinking of integrating as part of the Master page but you would really want to only run it for pages with ‘List Views’ (wouldn’t make senseotherwise, right?)
    * maybe integrating it as a deployable feature would be worth it?

    Again, thanks for digging into SP2010 – going to be an exciting run!
    Greg

  3. Alexander:

    I think you and I have exchanged emails somewhere along the way, and i’ve definitely seen your stuff. Good work. If you ever want to pitch something like this into SPServices, let me know!

    M.

  4. Matt B. says:

    This is a win… I’m happy to see other people wrangle the JavaScript beast. I’m a humble beginner, so thanks very much for your awesome code!

  5. Dave says:

    Alex,
    Am I missing something?
    This functionality, in my experience comes out of the Box in SP 2010 without any need for code.
    It’s actually can be provided in 2 methods – in the site breadcrumb and on a full toolbar in any view?
    If I could post an image I could show you. I can email you.
    Regards
    David

  6. Hi,
    Originally this functionality was missing from SharePoint 2010 (i think – or maybe i just didn’t see it?).

    One flaw in Microsoft’s implementation is the fact that the view selector disappears if you add another web part to the page.

    Alexander

    • Leigh Webber says:

      Er — how do I “Add this code to a CEWP in the list view where you want the menu to appear”? WHen I am modifying a view, I don’t see any way to add a web part. Web parts get added to *pages*, right? Not views. Or do I need to create a page, drop in a web part to show the list, then drop in a Content Editor Web Part on the *page* that contains the list web part?

      • In a list each view has it’s own page. Go to your view/page, edit the page and put in a CEWP. – move the CEWP below the list view webpart.and insert the code.

        Alexander

Subscribe without commenting

Speak and you will be heard.

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