SharePoint - Document Library Tree View - Asked By Edgar Hernán Rojas M. on 03-Sep-08 12:20 PM

Hi. I want to show the content of a document library in a tree view. I am having trouble finding a solution that works well on WSS. I want to be able to indicate the specific library to display.

It should work as a + or - to expand or close the folders in that document library.

Does samebody knows an existing web part or solution to this?

thanks in advance for your help

Read this - ram kumar replied to Edgar Hernán Rojas M. on 03-Sep-08 12:26 PM


 For each list in site
  If list is a document library
    For each file in root folder
      Add file node to treeview
    For each folder in root folder
      Add folder node to treeview
      Process contents of folder

As you can see, the program is very simple in concept. (Of course, you know it’s the details that keeps us programmers up at night!)

Recursion occurs when the Process contents of folder line is executed, and looks something like this:

For each file in folder
  Add a file node to treeview
For each sub-folder in folder
  Process contents of sub-folder

Iterating Through the Document Libraries, Folders and Files

Using the Sharepoint API you can navigate the list of document libraries, folders, documents and document properties on the current site. I’ll focus first on the steps to iterate through the list of document libraries, access their folders, files, and file properties. After that, I’ll come back to the steps required to format this data as a TreeView.

Step 1 – Getting the Current Site Context

Most SharePoint classes that you will use to create web parts need a context . This essentially tells the class what site it’s operating on. The following code fragment gets the context of the site on which the web part is placed:

Dim site As SPWeb =

Because all other SharePoint objects used will be based on child classes of site, they will inherit its context.

One thing to remember is that all web parts run in the context of the site of the page on which they’re placed. While it’s possible to create a web part that uses a context other than that of the current site, this is the exception rather than the rule. There are other uses for the SharePoint object model (such as to build administrative console applications or web services) where a context cannot be derived from the environment in which the application runs, and so must be provided by the end user or via some other means. The context ultimately resolves to the URL of the site to which the methods and properties refer.

Step 2 – Getting a Collection of All Lists in the Site

The next step is to obtain a collection of lists on the site. This will provide a starting point for navigating through all the document libraries, folders and files needed to display the DLTV.

dlCollection = site.Lists

Step 3 – Extracting the Document Library Lists

Of course, there are many types of lists, and the only ones we’re interested in are the document libraries. We’ll use the following conditional statement to return only the document libraries.

For Each dl In dlCollection
  If IsInDoclibList(dl.Title, [DoclibName]) And dl.BaseType = _
    SPBaseType.DocumentLibrary Then

The SPBaseType enumeration allows you to select just the document libraries. Note the IsInDoclibList() method call, this is a helper function I wrote to determine whether the document library being examined is one of those named in the web part Document library name property .

Step 4 – Displaying the Files in the Root Folder Level for a Doclib

Now that I have a pointer ( dl ) to a document library I want to include in the DLTV, I need a way to iterate through the files and folders of that library. To do so I’ve written a couple of helper functions that are executed recursively. They are ShowSortedFiles() and ShowSortedFolders() . Recursion is used to make it possible to process a tree structure of arbitrary depth without needing to know anything about the structure beforehand. If you’ve ever written code to navigate a file system directory structure, you’ve probably created similar code. I’ll discuss ShowSortedFiles() in this step, and ShowSortedFolders() in the next.

First, let’s dissect the parameter list for the helper function:


The parameters for the ShowSortedFiles() method are:

site.GetFolder(dl.Title.Trim) – returns a folder object, in this case the document library’s root folder

thisNodeId – is a variable whose value uniquely identifies a node in the tree. If you are using a TreeView other than dtree, this may or may not apply.

output – is a reference to the web part’s Sytstem.Web.UI.HtmlTextWriter property. I need a handle to this to write out the client-side JavaScript that will display the tree.

colOutput – is a reference to a collection variable I use to buffer the output if the user has unchecked the Show folders? property. This and the other properties will be covered in the Creating the Web Part Properties section later in this article.

The skeleton of the ShowSortedFiles() method, shown below, is very straightforward.

Private Function ShowSortedFiles(ByVal fldr As SPFolder, _
ByVal thisNodeId As Integer, _
ByVal output As System.Web.UI.HtmlTextWriter, _
ByVal colOutput As Collection)
  Dim arrFlSorted() As String
  Dim i As Integer
  Dim j As Integer
  If _includeFiles Then
    For i = 0 To fldr.Files.Count – 1
      If fldr.Files(i).TimeLastModified >= _
     Now.AddDays(-_daysBack2Include) Then
        ReDim Preserve arrFlSorted(i)
        If Order = EnumSortField.Name Then
          arrFlSorted(i) = fldr.Files(i).Name & CONST_SPLITCHAR & i
        ElseIf Order = EnumSortField.Title Then
          arrFlSorted(i) = fldr.Files(i).Title & CONST_SPLITCHAR & i
        ElseIf Order = EnumSortField.Sequence Then
            arrFlSorted(i) = fldr.Files(i).Item("Sequence") & _
               CONST_SPLITCHAR & i
        End If
    End If
    If _showFolders Then
            For i = 0 To arrFlSorted.Length – 1
                j = arrFlSorted(i).Split(CONST_SPLITCHAR)(1)
                output.Write("d" & _treeViewId.ToString & ".add(" & _
                  IncrNodeId() & "," & thisNodeId & ",’" & _
                  FormatTreeNode(fldr.Files(j).Name, fldr.Files(j).Title, _
                  _maxLinkWidth, _
                  fldr.Files(j).TimeLastModified.ToShortDateString) & "’,’"_
                  & fldr.Files(j).Url & "’,’‘,’_self’,’_layouts/images/" & _
                  fldr.Files(j).IconUrl & "’);")
            ‘If not showing folders, delay writing out until all files
            ‘gathered, then sort all together.
        End If
    End Function

This code iterates through the Files collection of the current folder and writes a list of sort keys and associated indices to an array (delimited by CONST_SPLITCHAR so they may later be broken apart). Once I’ve written data for all the files to the array, I sort it so that the documents in the rendered TreeView will be sorted according to the order selected on the TreeView property sheet. Then I write out the JavaScript to create the TreeView nodes to the output stream. One twist occurs if I am not showing folders, in which case, the sort key and desired output are written to the colOutput collection to be sorted and written to the output stream later.

This same process is repeated (through recursion) for all subfolders of the root as described in the following section.

Step 5 – Displaying all Subfolders in the Root Folder

Any given folder, including the root, may have zero or more sub-folders. I want to display those using a folder icon, and allow the user to drill down to display any files or sub-folders under that folder. The following code shows how the ShowSortedFolders() helper function is called from the root level.

flCollection = site.GetFolder(dl.Title.Trim).SubFolders
ShowSortedFolders(flCollection, 1, thisNodeId, output, colOutput)

The parameters for the ShowSortedFolders() method are:

site.GetFolder(dl.Title.Trim).SubFolders – returns a collection of all sub-folders of the root folder

1 – is the level of the folder in the folder hierarchy, where 1=root

thisNodeId – is simply the node id of the root in our TreeView, in recursive calls to this function, this parameter will be replaced with the TreeView node id of the folder in which the sub-folders reside

output – is a reference to the web part’s Sytstem.Web.UI.HtmlTextWriter property

colOutput – is a reference to a collection variable used to buffer the output

Below is the code for this method with the comments removed:

Private Function ShowSortedFolders(ByVal fldrCol As SPFolderCollection, _
        ByVal lvl As Integer, ByVal thisNodeId As Integer, _
        ByVal output As System.Web.UI.HtmlTextWriter, _
        ByVal colOutput As Collection)
  Dim arrFldrSorted() As String
  Dim i As Integer
  Dim j As Integer
  For i = 0 To fldrCol.Count – 1
    ReDim Preserve arrFldrSorted(i)
    arrFldrSorted(i) = fldrCol(i).Name & CONST_SPLITCHAR & i
  For i = 0 To arrFldrSorted.Length – 1
    j = arrFldrSorted(i).Split(CONST_SPLITCHAR)(1)
    ‘Don’t include forms library
    If fldrCol(j).Name.ToLower <> "forms" Or lvl <> 1 Then
      ShowFolderFiles(fldrCol(j), lvl, output, thisNodeId, colOutput)
    End If
End Function

You will notice that most of the processing is delegated to the ShowFolderFiles() method, which handles all the logic to add the appropriate nodes to the TreeView. This code could have been included in the ShowSortedFolders() method, but was extracted into a separate method for clarity.

One line of code you might be puzzled by is:

If fldrCol(j).Name.ToLower <> "forms" Or lvl <> 1 Then

SharePoint automatically adds a Forms folder when a doclib is created, so this folder needs to be explicitly excluded from the list of folders to process if we are at the root level (i.e. lvl = 1).

Now let’s look at the ShowFolderFiles() method which does the bulk of the work. For now, I want you to note the section that starts with:

If _folderLocation = EnumFolderLocation.Bottom Then

The two lines that follow this logical statement add nodes for the files and folders, respectively, to the TreeView . The call to the ShowSortedFolders() method is the recursive call that walks the hierarchy of folders. The conditional exists because the user may choose to display sub-folders at the top of a folder (as in Windows Explorer) or at the bottom (as does SharePoint).

Private Sub ShowFolderFiles(ByVal fl As SPFolder, ByVal lvl As Integer, _
        ByVal output As System.Web.UI.HtmlTextWriter, _
        ByVal parentNodeId As Integer, ByVal colOutput As Collection)
  Dim sfl As SPFolder
  Dim fi As SPFile
  Dim thisNodeId As Integer = IIf(_showFolders, IncrNodeId(), parentNodeId)
  If _showFolders Then
    output.Write("d" & _treeViewId.ToString & ".add(" & thisNodeId & "," & _
           parentNodeId & ",’" & fl.Name & "’,’" & fl.Url & _
           "’,’‘,’‘,’_layouts/jtree/img/folder.gif’", _           
  End If
  If _folderLocation = EnumFolderLocation.Bottom Then
    ShowSortedFiles(fl, thisNodeId, output, colOutput)
    ShowSortedFolders(fl.SubFolders, lvl + 1, thisNodeId, output, colOutput)
    ShowSortedFolders(fl.SubFolders, lvl + 1, thisNodeId, output, colOutput)
    ShowSortedFiles(fl, thisNodeId, output, colOutput)
  End If
End Sub

That’s really all there is to iterating through the document libraries, folders and files. Now let’s turn to the problem of formatting the output using the dtree TreeView routine.

Formatting the Output to Produce the TreeView

The DLTV is rendered in the user’s browser via JavaScript. The following outlines the basic process:

Include the dtree .js and .css files

Initialize the tree object in JavaScript

Add node objects to the tree object

Write out the tree

Note: Because there is an excellent document ( API.html ) that can be found in the Jtree folder, that describes the dtree API, I won’t cover it in this article.

In any web part, the code to render contents to the web part page, whether HTML or JavaScript, occurs in the RenderWebPart() method which overrides the method of the same name in the base Microsoft.SharePoint.WebPartPages.WebPart class. In effect, the DLTV web part is simply a JavaScript generator that inserts calls to the dtree.js library into the web part page.

Step 1 – Including References to the dTree Library and .css Files

The first step is to make sure the dtree.js library and its associated components are included in the page:

output.Write("<link rel=‘StyleSheet’ href=’_layouts/jtree/dtree.css’
   type=‘text/css’ />")
output.Write("<script type=‘text/javascript’
output.Write("<script type=‘text/javascript’>")

Note: During installation you placed the Jtree folder under [drive]:program filescommon filesMicrosoft sharedweb server extensions60TEMPLATELAYOUTS . Any web application components under this folder will be available as relative URLs within a SharePoint site by prefacing the reference with _layouts/ .

The output.Write statements appear throughout the code and are similar to the Respone.Write() statements used in typical ASP.NET programming. output refers to the System.Web.UI.HtmlTextWriter output stream that is used to write contents to the web part page. Note that in the third output statement I am opening a JavaScript tag. All subsequent output will be JavaScript within this <script> tag and the </script> tag that will be written at the end of the RenderWebPart() method.

Step 2 – Creating an Instance of the TreeView Object

The next line of code instantiates the TreeView object in JavaScript. The _treeViewId returns the value of the TreeView’s ClientId property, which is a unique value automatically generated by .NET for each web page control. Assigning this unique identifier to the TreeView allows multiple instances of the TreeView to coexist on the same web part page.

output.Write("d" & _treeViewId.ToString & " = new dTree(‘d" &
   _treeViewId.ToString & "’);")

A small sample of the generated code looks something like this:

<link rel=‘StyleSheet’ href=’_layouts/jtree/dtree.css’ type=‘text/css’ />
<script type=‘text/javascript’ src=’_layouts/jtree/dtree.js’></script>
<script type=‘text/javascript’>
dLeft_g_213c6909_723c_4456_b02a_f3e58f132ea6 =
   new dTree(‘dLeft_g_213c6909_723c_4456_b02a_f3e58f132ea6’);
dLeft_g_213c6909_723c_4456_b02a_f3e58f132ea6.config.useLines = true;

Step 3 – Inserting Document Library Node if Multiple Libraries Displayed

The next section of code, shown below, checks to see if more than one document library will be displayed, if so it adds a root node for each document library to the tree. If there is only one document library specified in the DoclibName property, we skip over this code:

If _showFolders And IsMultipleDocs([DoclibName]) Then
  thisNodeId = IncrNodeId()
  output.Write("d" & _treeViewId.ToString & ".add(" & thisNodeId & "," & _
               parentNodeId & ",’" & dl.Title.Trim & "’,’" & _
               GetDoclibDefaultViewUrl(dl) & "’,’‘,’_self’,’" & _
               dl.ImageUrl & "’,’" & dl.ImageUrl & "’);")
End If

The IncrNodeId() method simply returns the value of a global integer and increments it at the same time (a la i++ ). This is necessary because each node must have a unique id number.

Also in the above code are references to several properties of a SharePoint List object. These are self-evident, but one of the more interesting ones is ImageUrl , which returns the url of the image for the type of list (in our case a document library) referenced. By using this property, you can let SharePoint figure out what icon to use for this node of the tree.

Because I want the user to be able to click on the document library link to go to the associated default (usually allitems.aspx ) page for this library, I need a way to determine the url to that view. The following code does just that.

Private Function GetDoclibDefaultViewUrl(ByVal dl As SPList) As String
  Dim i As Integer
  Dim vw As SPView
  For Each vw In dl.Views
    If vw.DefaultView Then
      Return vw.Url
    End If
  Return ""
End Function

Step 4 – Inserting Nodes for each File in the Current Folder

As noted above, the ShowSortedFiles() method writes a TreeView nodes for each file in the folder. The following code from that routine does the work:

For i = 0 To arrFlSorted.Length – 1
  j = arrFlSorted(i).Split(CONST_SPLITCHAR)(1)
  output.Write("d" & _treeViewId.ToString & ".add(" & IncrNodeId() & "," & _
                thisNodeId & ",’" & FormatTreeNode(fldr.Files(j).Name, _
                fldr.Files(j).Title, _maxLinkWidth, _
                fldr.Files(j).TimeLastModified.ToShortDateString) & "’,’" &_
                fldr.Files(j).Url & "’,’‘,’_self’,’_layouts/images/" & _
                fldr.Files(j).IconUrl & "’);")

This is very similar to the statement to write a document library node. A few differences include:

FormatTreeNode() – is a helper function to format the node text based on the NodeFormat property

_maxLinkWidth – a parameter based on the MaxLinkWidth property

fldr.Files(j).IconUrl – a property, which returns the appropriate icon .gif url for the current document

Step 5 – Inserting Nodes for each Subfolder of the Current Folder

Finally, in the ShowFolderFiles() method, there is a variant of the above output statement to display a folder.

If _showFolders Then
  output.Write("d" & _treeViewId.ToString & ".add(" & thisNodeId & "," & _
               parentNodeId & ",’" & fl.Name & "’,’" & fl.Url & _
               "’,’‘,’‘,’_layouts/jtree/img/folder.gif’," & _
End If

The only difference being that the folder icons are explicitly referenced as _layouts/jtree/img/folder.gif and _layouts/jtree/img/folderopen.gif .

If the ShowFolders property was set to False , the data for the file nodes was written to a global collection rather than directly to the output stream. This code appears at the bottom of the RenderWebPart() method:

If Not _showFolders Then
  Dim arrSortValue(colOutput.Count – 1) As String
  For i = 1 To colOutput.Count
    arrSortValue(i – 1) = CType(colOutput.Item(i), _
                          String).Split(CONST_SPLITCHAR)(0) & _
                          CONST_SPLITCHAR & CType(colOutput.Item(i), _
  For i = 0 To arrSortValue.Length – 1
    j = arrSortValue(i).Split(CONST_SPLITCHAR)(1)
    output.Write(CType(colOutput.Item(j + 1), _
End If

Finally, I write out the JavaScript to display the TreeView, and close the <script> tag.

output.Write("document. write(d" & _treeViewId.ToString & ");")

Document Library Tree View - Binny ch replied to Edgar Hernán Rojas M. on 03-Sep-08 02:13 PM

System Requirements:

To run the DLTV sample code you will need the following:

  • A server running Windows 2003 and Windows SharePoint Services (if you’ve got SharePoint Portal Server running, you’re covered in this respect)
  • The .NET Framework version 1.1
  • Visual Studio.NET 2003 with VB.NET
  • The dtree TreeView library installed to the C:Program FilesCommon FilesMicrosoft Sharedweb server extensions60TEMPLATELAYOUTSJtree folder (you can find more information on dtree at ). This path will be the same for servers running Windows SharePoint Services alone or with SharePoint Portal Server.

Note: The version of the dtree TreeView library that is included with this source code has been modified to point to the correct IMAGES folder location. If you download a copy from the link noted above you will need to modify the JavaScript file dtree.js to change the paths to point to this location.


The dtree TreeView script is a freeware program that renders a hierarchical tree using JavaScript. It may be used and distributed freely as long as the credit, which appears at the top of the dtree.js file, is retained in the code. I have used this routine to reliably display document libraries containing thousands of documents. You might be aware that Microsoft provides an IE-based TreeView control, and wonder why that wasn’t used. My reasons are that the MSIE control has some display "anomalies" which cause nodes to be displayed incorrectly, and is designed only for IE, whereas the included script should work with any JavaScript compatible browser. You may, however, substitute the MSIE control or another TreeView of preference through minor modifications to the provided source code.

Go through thses article: