user3711721
user3711721

Reputation: 31

Use SPServices to display contents of a single subfolder from a document library

In SharePoint and using SPServices, I am trying to view folder contents of a specific subfolder of a document library (and not every single file & folder inside the library). The library structure looks like this:

List Name: Shared Documents

Listing out the top-level folders is easy enough with GetListItems but I want to the let the user click on one of the folders and list and list only the direct children of the subfolder.

So, if someone clicks on "Folder #1" then I want to show them only the following:

I have absolutely no idea how to list out the direct children of a specific subfolder.

Can anyone help?

Upvotes: 3

Views: 8250

Answers (3)

Tabares
Tabares

Reputation: 4335

To put the order of all folder, subfolders and files, try with this function:

<script>
$(document).ready(function(){
    var list = "Shared Documents";
    var url = "Shared Documents";    
    createTree(url, 0, list);

 });



function createTree(url, ID, list){
    //get the url to define the level of tree,
    $().SPServices({
    operation: "GetListItems",
    async: false,
    listName: list,
    CAMLViewFields: "<ViewFields><FieldRef Name='Title' /><FieldRef Name='ID' /></ViewFields>",
    CAMLQueryOptions: "<QueryOptions><Folder>" + url + "</Folder></QueryOptions>",
    completefunc: function (xData, Status) {
    $("#"+ID+"").append("<ul id='prime"+ID+"'>");
    $(xData.responseXML).SPFilterNode("z:row").each(function() {
        var id = $(this).attr("ows_ID");
        var title = $(this).attr("ows_Title");      
        var folder =   $(this).attr("ows_FileLeafRef").split(";#")[1]; 
       //var ref =   $(this).attr("ows_FileRef").split(";#")[1]; //this field gets the folder or file url

        $("#prime"+ID+"").append("<li id='"+id+"'>" +
                                    folder +
                                    //', Link: '+ ref +
                                    "  [" +
                                    $(this).attr("ows_FileLeafRef") +
                                    " :: " +
                                    $(this).attr("ows_FSObjType") +
                                    "]" +
                                "</li>");                               

     var thisFSObjType = $(this).attr("ows_FSObjType").split(";#")[1];
     if(thisFSObjType == 1) {
        //auto call the function createTree again, to get subfolders and files, assigning a new url/subfolder and id
        createTree(url+'/'+folder, id, list);         
      }
      });
      $("#"+ID+"").append("</ul>");
    }
 }); 
}

</script>
<body>
  <div><h1>My Tree</h1></div>
  <div id="0">
  </div>
</body>

If you want a accordion functionality try to add this bootstrap behavior to the code.

Best Regards.

Upvotes: 1

Vadim Gremyachev
Vadim Gremyachev

Reputation: 59388

In order to restrict query for a specific folder, CAMLQueryOptions parameter with Folder value could be specified:

<QueryOptions>
     <Folder>/SiteName/Lists/Links/folder/subFolder</Folder>
</QueryOptions>

Example

var listName = "Shared Documents";
var folderName = "/Shared Documents/Folder #1";

$().SPServices({
    operation: "GetListItems",
    async: false,
    listName: listName,
    CAMLViewFields: "<ViewFields><FieldRef Name='Title' /></ViewFields>",
    CAMLQueryOptions: "<QueryOptions><Folder>" + folderName + "</Folder></QueryOptions>",
    completefunc: function (xData, Status) {
      $(xData.responseXML).SPFilterNode("z:row").each(function() {
        var title = $(this).attr("ows_Title");
        console.log(title);
      });
    }
  });

Please follow this thread for a more details.

Upvotes: 3

AymKdn
AymKdn

Reputation: 3927

Instead of SPServices you can use my JavaScript API called SharepointPlus (see at the end if you want to keep SPServices). Two ways to do what you want:

  1. get ALL the structure of your library,
  2. or get just the folder clicked by the user

With the first option you can call the below code only once, and then you'll have to store the structure somewhere:

$SP().list("Shared Documents Library").get({
  fields:"BaseName,FileRef,FSObjType", // "BaseName" is the name of the file/folder; "FileRef" is the full path of the file/folder; "FSObjType" is 0 for a file and 1 for a folder (you need to apply $SP().cleanResult())
  folderOptions:{
    show:"FilesAndFolders_Recursive"
  }
}, function(files) {
  // in "files" you have ALL the files and folders in your library
  for (var i=0; i<files.length; i++) {
    console.log(files[i].getAttribute("FileRef"))
  }
});

For the second option, you'll have to call the below code each time the user clicks on a folder. For example if he clicks on "Folder #1":

$SP().list("Shared Documents Library").get({
  fields:"BaseName,FileRef,FSObjType", // "BaseName" is the name of the file/folder; "FileRef" is the full path of the file/folder; "FSObjType" is 0 for a file and 1 for a folder (you need to apply $SP().cleanResult())
  folderOptions:{
    show:"FilesAndFolders_InFolder", /* this option changed from 1) */
    path:"Folder #1" /* here is the name of the folder */
  }
}, function(files) {
  // it will get the files and folders into the "Folder #3"
  for (var i=0; i<files.length; i++) {
    console.log(files[i].getAttribute("FileRef"))
  }
});

If you don't want to use SharepointPlus, with SPServices, you'll have to define the queryOptions for your query. If you use option 1 (above) then your queryOptions will look like that:

<QueryOptions>
  <ViewAttributes Scope="RecursiveAll"></ViewAttributes>
  <Folder>http://your.siteweb.com/path/to/site/collection/path/to/Folder #1</Folder>
</QueryOptions>

To know which ViewAttributes Scope to use you can check my code.

Upvotes: 1

Related Questions