Monday, April 27, 2009

For very big projects in SharePoint or any other platform it's very difficult to organize the navigation to keep all the data on page. For example, you have plenty of data around 15 to 20 subsites and 50 pages, then it's impossible to display all the links at one place. So, it's big challenge that even you have more data on site but if user failed to find what he want on the site then it's just waste. So by thinking that for a long time, I came up with a good solution and here I am presenting for you with code.

What is my goal?
I want to show all the sites and pages in a SharePoint site in navigation area [lefft navigation] using asp tree view control in SharePoint.

Below is the complete code of the treeview functionality
In my case, we have 3 levels of data. So used tree view that has 3 levels.

ASPX Code:
Treeview control declaration and it's tree nodes 3 levels. We are writing some server side code to get and render the data as we want using different conditions. So for this purpose I am using prerender event of the tree view control.

<asp:TreeView ID="treeviewLeftNav" runat="server"
Width="191px" HoverNodeStyle-CssClass="leftNavHover"
DataSourceID="SiteMapDS" SelectedNodeStyle-CssClass="leftNavSelected"
OnPreRender="ControlTreeView_OnPreRender"
<LevelStyles>
<asp:TreeNodeStyle CssClass="leftNav1"></asp:TreeNodeStyle>
<asp:TreeNodeStyle CssClass="leftNav2"></asp:TreeNodeStyle>
<asp:TreeNodeStyle CssClass="leftNav3"></asp:TreeNodeStyle>
</LevelStyles>
</asp:TreeView>

We are using publishing site with all features enabled. So we are using PublishingNavigation control with PortalSiteMapDataSource to pull all pages and sites from SharePoint site.

<PublishingNavigation:PortalSiteMapDataSource ID="SiteMapDS" Runat="server"
SiteMapProvider="CurrentNavSiteMapProvider" EnableViewState="true"
StartingNodeOffset="0" ShowStartingNode="False"
TrimNonCurrentTypes="Heading"/>

In c#, I wrote below code for exact functionality of Expand/collapse TreeView.
C# code:
void ControlTreeView_OnPreRender(object sender, EventArgs e)
{
foreach(TreeNode n in treeviewLeftNav.Nodes)
{
if(n.NavigateUrl == Request.Url.AbsolutePath)
n.Expand();
else
{
if(treeviewLeftNav.SelectedNode!=null)
{
if(n!=treeviewLeftNav.SelectedNode.Parent)
{
if(n.ChildNodes.Count>0)
n.Collapse();
}
}
else
{
treeviewLeftNav.CollapseAll();
break;
}
}
RenderTreeNodes(n);
}

if(treeviewLeftNav.SelectedNode!=null)
treeviewLeftNav.SelectedNode.Expand();
}

void RenderTreeNodes(TreeNode node)
{
if(node!=null)
{
if(node.ChildNodes.Count>0)
{
foreach(TreeNode n in node.ChildNodes)
{
if(n.NavigateUrl == Request.Url.AbsolutePath)
{
n.Expand();
}
else
{
if(n!=treeviewLeftNav.SelectedNode.Parent)
n.Collapse();
else
n.Parent.Expand();
}
}
}
}
}
Note: please change your web.config of the site to allow server side code in pages where you are writing server side code.

4 comments:

  1. Thanks it did the trick. You saved so much time to me.

    ReplyDelete
  2. another option

    http://www.getsharepoint.com/blog/Lists/Posts/Post.aspx?ID=26

    also modifying the web.config for code is not a great idea

    ReplyDelete
  3. In web.config, we are not actually modifying anything. If you need customization then you need to use the features of SharePoint. All needed is in the web.config, allow the server side code in SharePoint pages by using <PageParsersPath>

    thanks
    -Praveen.

    ReplyDelete