December 18, 2013

Expand SPTreeView Node Automatically When Selected


Before:
After:


The standard behavior of SharePoint tree view control (SPTreeView) is that when you select a folder node it will not expand its children nodes. You must click the expand icon [+] in order to show the sub folders. Also, that is not exclusive, so when you click the expand [+] icons of another node folder, the tree will show it's children without collapsing the previous node folder.


The objective:

I wanted to customize the tree view navigation to combine the functionality of clicking the node title and clicking the expand icon so that user can expand nodes with less hassle. The user should only click a node folder title and the tree will automatically expand to show child nodes while other nodes will collapse.


How:

I'll use JQuery. The idea is when a node title is clicked then a post back occurs and there will be a RootFolder parameter in page Url indicating selected folder node, so we will call the javascript function associated with its exapnd [+] icon.

This is the markup for the SPTreeView in the page:

<SharePoint:SPHierarchyDataSourceControl id="doclibDataSource" runat="server" RootListId="a65a6e37-de92-496a-b896-5b976dff7b61"
RootWebId="277d98b7-be33-451f-9ed8-6691a5a72736" ShowFolderChildren="true" EnableViewState="false">

</SharePoint:SPHierarchyDataSourceControl>
<SharePoint:SPRememberScroll runat="server" id="TreeViewRememberScrollV4" onscroll="javascript:_spRecordScrollPositions(this);" style="overflow: auto">
<SharePoint:SPTreeView ID="doclibtreeview" runat="server" DataSourceID="doclibDataSource" EnableViewState="false" ExpandDepth="1" SelectedNodeStyle-CssClass="SelectedItemStyle">
</SharePoint:SPTreeView>
</SharePoint:SPRememberScroll>


Inject the following script in the master page or in CEWP. I added the SelectedItemStyle CSS style to make selected nodes more visible.


<style>
.SelectedItemStyle {
BORDER-TOP: 1px dotted; BORDER-RIGHT: 1px dotted; BORDER-BOTTOM: 1px dotted; BORDER-LEFT: 1px dotted; BACKGROUND-COLOR: #dddddd
}</style>

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>

<script>

_spBodyOnLoadFunctionNames.push("customIBRTreeNav");

function customIBRTreeNav(){
var SelectedFolder = unescape(getUrlParameter('RootFolder'));
var ItemTitle = SelectedFolder.substring(SelectedFolder.lastIndexOf("/") + 1);
var LinkItem = jQuery('a[title="' + ItemTitle + '"]:not(:has(img))');
var IconItem = LinkItem.closest('td').prev('td').prev('td').find('a');// [+] & [-] icon
var IconItemHref = IconItem.attr("href");
var CustomTreeViewPopulate = new Function(IconItemHref); // create the function from string
CustomTreeViewPopulate.call(this);
}

function getUrlParameter(name)
{
  name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
  var regexS = "[\\?&]"+name+"=([^&#]*)";
  var regex = new RegExp( regexS );
  var results = regex.exec( window.location.href );
  if( results == null )
    return "";
  else
    return results[1];
}</script>


Note: remember to set the ExpandDepth parameter to value of '1' in the SPTreeView control. 
This is necessary to get the intended functionality. I didn't have time to implement the logic when ExpandDepth is 2 or more.. maybe later!


No comments:

Post a Comment