Friday, February 18, 2011

Add SPNavigation Heading without link functionality to QuickLaunch

Adding items to the Quicklaunch or TopNavigation is easy. However adding a heading to the Quicklaunch without the link functionality is not possible by using the basic SharePoint 2010 API. In this post I’ll show you how to create a navigation item, transform it into a heading without link functionality, and add it to the Quicklaunch.

The options:

  1. Create a SPNavigationNode
    add it to navigation using spWeb.Navigation.AddToQuickLaunch(SPNavigationNode node, SPQuickLaunchHeading heading), where heading is an enum of some default SP2010 headings.
  2. Create a SPNavigationNode
    Get SPNavigationNodeCollection from spWeb.Navigation.QuickLaunch
    Add SPNavigationNode to the SPNavigationNodeCollection using methods like AddAsFirst, or AddAsLast

As option 1 can only to add items to default SP2010 headings. So we need to go for option 2.


The problem
Option 2 can only add a heading navigation node to the quicklaunch that has a link. When you use the following code it will create a heading, however it will link to the ‘base url’ of the current SPWeb.

// Create the node.
SPNavigationNodeCollection quicklaunchNav = web.Navigation.QuickLaunch;

// Create heading
SPNavigationNode headerNode = new SPNavigationNode(headerTitle, string.Empty, true);
headerNode = quicklaunchNav.AddAsLast(headerNode);

// Add subnode to heading.
SPNavigationNode node = new SPNavigationNode("title", "url", true);
headerNode.Children.AddAsLast(node);
 

 The Solution
The difference between a navigation item and a heading navigation item are some value in the NavigationNode.Properties HashTable.

To create a heading use the following code.

public static class SPNavigationNodeExtensions
{
public static void MakeHeaderNode(this SPNavigationNode node)
{
node.Properties["BlankUrl"] = "True";
node.Properties["LastModifiedDate"] = DateTime.Now;
node.Properties["Target"] = "";
node.Properties["vti_navsequencechild"] = "true";
node.Properties["UrlQueryString"] = "";
node.Properties["CreatedDate"] = DateTime.Now;
node.Properties["Description"] = "";
node.Properties["UrlFragment"] = "";
node.Properties["NodeType"] = "Heading";
node.Properties["Audience"] = "";
node.Update();
}
}

As you can see, the “BlankUrl'” = True, and NodeType = “Heading”. Using the Update method it saves changes of the properties.
It’s now possible to transform the heading node using this extension method.
//Transform Node into Header.
headerNode.MakeHeaderNode();

The final code is:

// Create the node.
SPNavigationNodeCollection quicklaunchNav = web.Navigation.QuickLaunch;

// Create heading
SPNavigationNode headerNode = new SPNavigationNode("HeadingTitle", string.Empty, true);
headerNode = quicklaunchNav.AddAsLast(headerNode);

//Transform Node into Header.
headerNode.MakeHeaderNode();

// Add subnode to heading.
SPNavigationNode node = new SPNavigationNode("title", "url", true);
headerNode.Children.AddAsLast(node);

At this point you’ll have a heading with '”HeadingTitle” that doesn’t link. It has a sub navigation item “title”, that links to “url”. Also thanks to Matthijs Woolderink (@MWoolderink) for some background information.

14 comments:

  1. Did you know you can add more hierarchy levels in the Quicklaunch navigation programmatically? MOSS2007 doesn't even allow that via the web interface, and I don't know about SP2010.

    However, it seems that this header node trick can only be used on the top level - when I tried to create a header node on the second level the node itself was properly changed, but all its child nodes were invisible.

    ReplyDelete
  2. I just enter # for my QL headings. Seems a lot easier.

    ReplyDelete
    Replies
    1. YOU ARE FANTASTIC... if anyone tells you anything different.. send them to me.

      Delete
    2. OK sorry i take my words back. It doesn't work for TopNav :(

      Delete
    3. QL stands for QuickLaunch, which isn't Global Nav..

      Delete
  3. Well, very good post with informative information. I really appreciate the fact that you approach these topics from a stand point of knowledge and information.

    ReplyDelete
  4. I have tried this code but its is getting add 2 time means 2 same link in Navigation bar

    ReplyDelete
  5. Hi, I am interested to know where in Sharepoint would I add the code for this solution?

    ReplyDelete
  6. Great post! It worked like a charm. Thanks for sharing!

    ReplyDelete
  7. Has the behaviour of SharePoint 2010 changed since this was posted? What I have tested is:

    1) Create a new sitecollection based on the blank site template.
    2) Notice that the built in headers that are added for libraries/lists/discussions are all clickable links by default.
    3) Activate feature to add new headers as non-clickable links.
    4) Notice that newly added headers are also still clickable links in the UI, just like the default headers.

    ... I wrote a feature solution to test the code in this article. On activation it runs through the code as written here. Everything runs without error/exceptions, the properties are successfully set as viewed in the debugger, etc. However, the headings are still clickable links in the UI. The change of properties does absolutely nothing to the behaviour of the SPNavigationNode. Has anybody had this work? Is it only functional in a specific site template? What am I missing?

    Thanks,
    ~NiceNix

    ReplyDelete
  8. Why not just use 'javascript:location.reload();' as the Quick Launch Header url?

    ReplyDelete
    Replies
    1. Because we don't want to reload the page unnecessarily?

      Delete
  9. This is what i was looking for. Thanks a lot for sharing this.

    ReplyDelete
  10. This looks as if it will solve my problem, but as a beginner SP developer I dont know how to implement this. Would it be possible for you to provide more details as to how this code is used?

    ReplyDelete