Introduction
In SPFx property pane configuration, many times we are required to filter records based on another property pane controls. In this article, we will learn how to cascade a dropdown in the property pane without creating any custom control.
Scenario
For example, there are multiple lists on a Sharepoint site, and based on the selection of list we want to get fields of the selected list. So in this type of scenario, we require cascading dropdowns.
In this example, we will use PropertyFieldListPicker to select the list and will use PropertyFieldMultiSelect to select the list's fields. And here we will use PnP js to get fields of the selected list and then filter it based on list selection, as shown below:

Let's see the step-by-step implementation.
Implementation
- Open a command prompt
- Move to the path where you want to create a project
- Create a project directory using:
- md directory-name
Move to the above-created directory using:
- cd directory-name
Now execute the below command to create an SPFx solution:
- yo @microsoft/sharepoint
It will ask some questions, as shown below:

After a successful installation, we can open a project in any source code tool. Here, I am using VS code, so I will execute a command:
- code .
Now we will install pnpjs and pnp-spfx-property-controls as shown below:
- npm install @pnp/sp --save
- npm install @pnp/spfx-property-controls --save --save-exact
Here, we will declare the properties for a list, the fields and context to get SharePoint context are shown below:
- import { WebPartContext } from "@microsoft/sp-webpart-base";
- export interface IPnpCascadingProps {
- description: string;
- context: WebPartContext;
- list: string,
- fields: string[]
- }
Now create a folder called service inside a webpart folder, and then create a file called service.ts in this folder. In this file, we will create a SPService to get fields for the selected list.
- import { WebPartContext } from "@microsoft/sp-webpart-base";
- import { sp } from "@pnp/sp/presets/all";
- export class SPService {
- constructor(private context: WebPartContext) {
- sp.setup({
- spfxContext: this.context
- });
- }
- public async getFields(selectedList: string): Promise<any> {
- try {
- const allFields: any[] = await sp.web.lists
- .getById(selectedList).
- fields.
- filter("Hidden eq false and ReadOnlyField eq false").get();;
- return allFields;
- }
- catch (err) {
- Promise.reject(err);
- }
- }
- }
Now go to the {webpartName}webpart.ts file. here we will create the property pane controls so will call the method to get fields and bind it with a multi-select dropdown field.
Import all the dependencies, as shown below:
- import * as React from 'react';
- import * as ReactDom from 'react-dom';
- import { Version } from '@microsoft/sp-core-library';
- import {
- IPropertyPaneConfiguration,
- PropertyPaneTextField,
- IPropertyPaneDropdownOption
- } from '@microsoft/sp-property-pane';
- import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
- import * as strings from 'PnpCascadingWebPartStrings';
- import PnpCascading from './components/PnpCascading';
- import { IPnpCascadingProps } from './components/IPnpCascadingProps';
- import { PropertyFieldListPicker, PropertyFieldListPickerOrderBy } from '@pnp/spfx-property-controls/lib/PropertyFieldListPicker';
- import { PropertyFieldMultiSelect } from '@pnp/spfx-property-controls/lib/PropertyFieldMultiSelect';
- import { sp } from '@pnp/sp';
- import { SPService } from '../service/Service';
Declare the list and field inside props interface as shown below:
- export interface IPnpCascadingWebPartProps {
- description: string;
- lists: string;
- fields: string[];
- }
- private _services: SPService = null;
- private _listFields: IPropertyPaneDropdownOption[] = [];
Create a function to get all fields. Here we will call a service as shown below:
- public async getListFields() {
- if (this.properties.lists) {
- let allFields = await this._services.getFields(this.properties.lists);
- (this._listFields as []).length = 0;
- this._listFields.push(...allFields.map(field => ({ key: field.InternalName, text: field.Title })));
- }
- }
Create an OnInit() method to get sharepoint context and bind service and methods:
- public onInit(): Promise<void> {
- return super.onInit().then(_ => {
- sp.setup({
- spfxContext: this.context
- });
- this._services = new SPService(this.context);
- this.getListFields = this.getListFields.bind(this);
- });
- }
- private listConfigurationChanged(propertyPath: string, oldValue: any, newValue: any) {
- console.log("LIST FIELDS:", this._listFields);
- if (propertyPath === 'lists' && newValue) {
- this.properties.fields = [];
- this.onPropertyPaneFieldChanged(propertyPath, oldValue, newValue);
- this.context.propertyPane.refresh();
- }
- else {
- super.onPropertyPaneFieldChanged(propertyPath, oldValue, newValue);
- }
- }
Create a property pane controls and map the values as shown below:
- protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
- this.getListFields();
- return {
- pages: [
- {
- header: {
- description: strings.PropertyPaneDescription
- },
- groups: [
- {
- groupName: strings.BasicGroupName,
- groupFields: [
- PropertyPaneTextField('description', {
- label: strings.DescriptionFieldLabel
- }),
- PropertyFieldListPicker('lists', {
- label: 'Select a list',
- selectedList: this.properties.lists,
- includeHidden: false,
- orderBy: PropertyFieldListPickerOrderBy.Title,
- disabled: false,
- baseTemplate: 100,
- onPropertyChange: this.listConfigurationChanged.bind(this),
- properties: this.properties,
- context: this.context,
- onGetErrorMessage: null,
- key: 'listPickerFieldId',
- }),
- PropertyFieldMultiSelect('fields', {
- key: 'multiSelect',
- label: "Multi select list fields",
- options: this._listFields,
- selectedKeys: this.properties.fields
- })
- ]
- }
- ]
- }
- ]
- };
- }
- import * as React from 'react';
- import styles from './PnpCascading.module.scss';
- import { IPnpCascadingProps } from './IPnpCascadingProps';
- import { escape } from '@microsoft/sp-lodash-subset';
- export default class PnpCascading extends React.Component<IPnpCascadingProps, {}> {
- public render(): React.ReactElement<IPnpCascadingProps> {
- return (
- <div className={styles.pnpCascading}>
- <p>Selected List: {this.props.list}</p>
- <p>Selected Fields: {this.props.fields}</p>
- </div>
- );
- }
- }
Output

Find the complete source code here.
Summary
In this article, we have seen how to implement cascading dropdown in property pane configuration using pnp js and reusable property pane controls.
I hope this helps.
Sharing is caring!!

Hitesh HariramaniPosted May 18, 2021, 6:54 PM
Hi, is there any other way of doing this, I mean instead of using SP service is there anything else we can use ?
Rajat SahaniPosted Jan 5, 2021, 9:32 AM
Great article
Anas KhanPosted Nov 24, 2020, 7:08 AM
Thanks for sharing this one! I have a requirement to display data of selected list and selected columns in accordion, appreciate your help on this.
Madhan ThuraiPosted Oct 24, 2020, 1:36 PM
Good article :)