SharePoint Framework (SPFx) : Cascade dropdown in webpart properties


Hi Friends,

In this blog I will be creating a cascade drop down in the webpart properties of a SharePoint Framework - SPFx webpart.



In my previous post I have shown how to create a dynamically populated dropdown in the SharePoint Framework SPFx webpart. This blog will be in continuation to that, where I will be extending the previous example to populating the list in the dropdown.

In this example I will be showing all the "Views" for the selected list. As we usually comes with the scenario where we need the cascade dropdown.

For full code files you can refer here on github.

Step 1: Setting up your SharePoint environment

If you have not yet setup your SharePoint environment , then refer to my previous blog on Setting up your SharePoint environment.

Step 2: Creating a empty SharePoint Framework Project

Create a empty SharePoint Framework project. If you are new than refer to my previous article on Set up your new SPFx project

Step 3: Install supported NPM packages

I very much use the SharePoint Framework helper library, details of which can be found in one of my posts SharePoint Framework (SPFx) Helper. I love this because it has all the methods that I use in most of my coding and it's easy. If you don't want to use it , then you need to write your own code from the scratch.

In order to install the npm package, execute the bellow command

npm install spfxhelper

Step 4: Let's start coding !!

  • Firstly include the spfxhelper class in the solution so that we can get all the available methods from that. I will be using the SPCommonOperations class in this example, as can create custom query using this class.
import  { SPCommonOperations } from   'spfxhelper'
  • Declare the variables to hold the values of the lists and the corresponding views.
private  ddlListOptions :   IPropertyPaneDropdownOption [] =  [];
  private  ddlViewsOptions :   IPropertyPaneDropdownOption [] =  [];
  private  listsLoaded :   boolean   =   false ;
  private   get   oSPComOps () :   SPCommonOperations  {
    return  SPCommonOperations. getInstance ( this .context.spHttpClient as   any , this .context.pageContext.web.absoluteUrl);
 }
  private   get   webUrl () : string {
    return   this .context.pageContext.web.absoluteUrl;
 }

  • Create a method to get all the view for the List
protected   getAllViews ( selectedList :   string ) :   Promise < IPropertyPaneDropdownOption []> {
    let  ddlViewOptions :   IPropertyPaneDropdownOption [] =  [];
    return   this .oSPComOps. queryGETResquest ( ` ${ this .webUrl } /_api/web/lists/getByTitle(' ${ selectedList } ')/Views` ). then ( respViews   =>  {
      if  (respViews.ok) {
       respViews.result.value. forEach ( views   =>  {
         ddlViewOptions. push ({
           key: views.Title,
           text: views.Title
         });
       });
     }
      return   Promise . resolve (ddlViewOptions);
   });
   )

  • Overwrite the method "getPropertyPaneConfiguration" so that we can track the changes made in the "lists" drop-down.
protected   onPropertyPaneFieldChanged ( propertyPath :   string , oldValue :   any , newValue :   any ) :   void  {
    if  (propertyPath ==   `selectedList` ) {
      this . getAllViews (newValue). then ( resView   =>  {
        this .ddlViewsOptions =  resView;
        this .context.propertyPane. refresh ();
     });
   }
 }

  • Initialize the drop-down control in the property pane
PropertyPaneDropdown ( `selectedView` ,{
                 label: `select view` ,
                 options: this .ddlViewsOptions,
                 disabled: this .ddlListOptions.length ==   0
               })


For full sample code, get it from git

Code Sample
import   *   as  React from   'react' ;
import   *   as  ReactDom from   'react-dom' ;
import  { Version } from   '@microsoft/sp-core-library' ;
import  {
 BaseClientSideWebPart,
 IPropertyPaneConfiguration,
 PropertyPaneTextField,
 IPropertyPaneDropdownOption,
 PropertyPaneDropdown
} from   '@microsoft/sp-webpart-base' ;
import   *   as  strings from   'DemoCascadeWebPartStrings' ;
import  DemoCascade from   './components/DemoCascade' ;
import  { IDemoCascadeProps } from   './components/IDemoCascadeProps' ;
import  { SPCommonOperations } from   'spfxhelper' ;
export   interface   IDemoCascadeWebPartProps  {
 description :   string ;
}
export   default   class   DemoCascadeWebPart   extends   BaseClientSideWebPart < IDemoCascadeWebPartProps > {
  private  ddlListOptions :   IPropertyPaneDropdownOption [] =  [];
  private  ddlViewsOptions :   IPropertyPaneDropdownOption [] =  [];
  private  listsLoaded :   boolean   =   false ;
  private   get   oSPComOps () :   SPCommonOperations  {
    return  SPCommonOperations. getInstance ( this .context.spHttpClient as   any , this .context.pageContext.web.absoluteUrl);
 }
  private   get   webUrl () : string {
    return   this .context.pageContext.web.absoluteUrl;
 }
  public   render () :   void  {
    const  element :   React . ReactElement < IDemoCascadeProps > =  React. createElement (
     DemoCascade,
     {
       description: this .properties.description
     }
   );
   ReactDom. render (element, this .domElement);
 }
  protected   get   dataVersion () :   Version  {
    return  Version. parse ( '1.0' );
 }
  protected   get   getAllLists () :   Promise < IPropertyPaneDropdownOption []> {
    let  ddlOptions :   IPropertyPaneDropdownOption [] =  [];
    return   this .oSPComOps. queryGETResquest ( ` ${ this .webUrl } /_api/web/lists` ). then ( resp   =>  {
      if  (resp.ok) {
       resp.result.value. forEach ( lists   =>  {
       
         ddlOptions. push ({
           key: lists.Title,
           text: lists.Title
         });
       });
     }
      return   Promise . resolve (ddlOptions);
   });
 }
  protected   getAllViews ( selectedList :   string ) :   Promise < IPropertyPaneDropdownOption []> {
    let  ddlViewOptions :   IPropertyPaneDropdownOption [] =  [];
    return   this .oSPComOps. queryGETResquest ( ` ${ this .webUrl } /_api/web/lists/getByTitle(' ${ selectedList } ')/Views` ). then ( respViews   =>  {
      if  (respViews.ok) {
       respViews.result.value. forEach ( views   =>  {
         ddlViewOptions. push ({
           key: views.Title,
           text: views.Title
         });
       });
     }
      return   Promise . resolve (ddlViewOptions);
   });
 }
  protected   onPropertyPaneFieldChanged ( propertyPath :   string , oldValue :   any , newValue :   any ) :   void  {
    if  (propertyPath ==   `selectedList` ) {
      this . getAllViews (newValue). then ( resView   =>  {
        this .ddlViewsOptions =  resView;
        this .context.propertyPane. refresh ();
     });
   }
 }
  protected   getPropertyPaneConfiguration () :   IPropertyPaneConfiguration  {
    // Check if the values are recieved
    if  ( ! this .listsLoaded) {
      // Call the method to get all the lists Titles
      this .getAllLists. then ( resp   =>  {
        // Fill the values in the variable assigned
        this .ddlListOptions =  resp;
        // update the flag so it is not called again
        this .listsLoaded =   true ;
        // Refresh the property pane, to reflect the changes
        this .context.propertyPane. refresh ();
     });
   }
    return  {
     pages: [
       {
         header: {
           description: strings.PropertyPaneDescription
         },
         groups: [
           {
             groupName: strings.BasicGroupName,
             groupFields: [
                PropertyPaneTextField ( 'description' , {
                 label: strings.DescriptionFieldLabel
               }),
                PropertyPaneDropdown ( `selectedList` , {
                 label: `select List` ,
                 options: this .ddlListOptions
               }),
                PropertyPaneDropdown ( `selectedView` ,{
                 label: `select view` ,
                 options: this .ddlViewsOptions,
                 disabled: this .ddlListOptions.length ==   0
               })
             ]
           }
         ]
       }
     ]
   };
 }
}



Happy Coding
Sumit Kanchan
#SharePointWidgets #SharePointFramework #SPFx

Comments

  1. Hi. There is no link to your Github. Would be useful to have this link.Thanks

    ReplyDelete
    Replies
    1. Hi Krishant.. You can find my git hub link in the navigation... well here you go.. https://github.com/sumitkanchan4

      Delete

Post a Comment

Popular posts from this blog

Rename Folder using Microsoft Flow / Power Automate in a Document Library in SharePoint Online

Power Automate: How to Add "New Line" to the text in SharePoint multiline text field

How to resolve certificate issue in SharePoint Framework Solution