5

I have created a SPFX Listview command and I need to get the current URL of the folder that I am in.

Does anyone know if this is possible? I can't find any documentation regarding this on sp-pnp-js github or other sources.

Any help is much appreciated :)

4 Answers 4

5
+100

SPFx has some utility classes to help you get the folder url. Its not available in pageContextInfo or any other page property. However, you can split it from the query string's Id parameter.

Add the below import statement:

import { Log, UrlQueryParameterCollection } from '@microsoft/sp-core-library';

And in your execution logic, use it as:

@override
  public onExecute(event: IListViewCommandSetExecuteEventParameters): void {         

      var queryParameters = new UrlQueryParameterCollection(window.location.href);
      var current_folder_path= url_query_param.getValue("Id") || url_query_param.getValue("RootFolder");

      if (queryParameters.getValue("Id")) {
          var folderUrl = decodeURIComponent(current_folder_path);
          Dialog.alert(`${folderUrl}`);
      }        
  }

End result - in the Shared Document library, have created a folder named Test:

enter image description here

3
  • 1
    Just FYI, the URLQueryParameterCollection is obsolete in favor of the URLSearchParams (native in all modern browsers). You would pass everything after the "?" in the window.location.href to use this. That is why I just parsed it out in the variable (the other params are not needed). The URLSearchParams is much cleaner looking.
    – Ken Hansen
    Commented Mar 1, 2018 at 17:28
  • This method doesn't work if library is hosted in custom page, e.g: Home. In this case windows.location.href doesn't contain Id or RootFolder parameters.
    – 23W
    Commented Nov 7, 2019 at 16:15
  • where does "url_query_param" variable coming from please?
    – Pedro
    Commented May 19, 2020 at 9:48
5

It is pretty easy. Because you know which item is selected, you know url of the file. event.selectedRows[0] holds a lot of information about the selected item. Or you can use query string.

@override
public onExecute(event: IListViewCommandSetExecuteEventParameters): void {
  switch (event.itemId) {
    case 'COMMAND_1':
      {
        var folderUrl: string;

        // Get file url of first selected item
        if (event.selectedRows.length > 0) {
          const fileUrl: string = event.selectedRows[0].getValueByName("FileRef");

          // Trim the file name and you have server relative folder url
          folderUrl = fileUrl.substring(0, fileUrl.lastIndexOf('/'));
        } else {
          // Get url form query string
          folderUrl = this.getFolderUrlFromQueryString();
        }

        Dialog.alert(folderUrl);
        break;
      }
    default:
      throw new Error('Unknown command');
  }
}

private getFolderUrlFromQueryString(): string {
  const id = this.getQueryStringParameter("Id");
  const rootFolder = this.getQueryStringParameter("RootFolder");

  var url = id != null ? id : rootFolder;
  if (url === undefined) {
    // in case of root folder
    url = this.context.pageContext.list.serverRelativeUrl;
  }

  return decodeURIComponent(url);
}

private getQueryStringParameter(paramToRetrieve: string) {
  if (document.URL.indexOf("?") == -1)
    return null;

  var params = document.URL.split("?")[1].split("&");
  var strParams = "";
  for (var i = 0; i < params.length; i = i + 1) {
    var singleParam = params[i].split("=");
    if (singleParam[0].toLowerCase() == paramToRetrieve.toLowerCase())
      return singleParam[1];
  }
}
4
  • 1
    Thanks for the suggestion, but I forgot to mention that I don´t select any items. The functionality opens a dialogue window without anything being selected first.
    – Frank H
    Commented Feb 26, 2018 at 16:52
  • @FrankH see modified answer Commented Feb 27, 2018 at 15:54
  • Due to bugs in SPO it doesn't work. I've added question in SPFx github repo. github.com/SharePoint/sp-dev-docs/issues/4885
    – 23W
    Commented Nov 12, 2019 at 9:19
  • I assume that you are talking about github.com/SharePoint/sp-dev-docs/issues/4769 This code works, just event could point to wrong selectedRows[0] which is not problem of this code, but SPFX. Commented Nov 12, 2019 at 9:26
1

As you mentioned that you want the folder URL without selecting any items or folders then you can write your code under the "onListViewUpdated" function. If the returned URL is empty then your outside of the folder.

  @override
  public onListViewUpdated(event: IListViewCommandSetListViewUpdatedParameters): void {
    Dialog.alert(this.getParameterByName('id'));    
  }

  private getParameterByName(name) {
    var url = window.location.href;
    name = name.replace(/[\[\]]/g, "\\$&");
    var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
      results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
  }
0

I assume you mean a folder once inside a list or library. Here's how I'd approach it...


var folderUrl = decodeURIComponent(window.location.href.split("?")[1].split("RootFolder=")[1].split("&FolderCTID")[0]);

var folderServerRelativeUrl = this.context.pageContext.web.absoluteUrl + folderUrl;

folderUrl gets the entire query parameter, then gets everything after "RootFolder=" but before "&FolderCTID", then decodes the %2F characters into "/".

Then using the page context concatenate the webs' absoluteUrl and the folderUrl.

1
  • Basically use the url to get the folder specific info and add it to the info available in the page context
    – Ken Hansen
    Commented Feb 26, 2018 at 22:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.