Now we will create another interface to wrap this interface and IpropertyPaneCustomFieldProps.
and paste below code.
import { IPropertyPaneCustomFieldProps } from '@microsoft/sp-webpart-base';
import { IPropertyPaneMultiselectDropdownProps } from './IPropertyPaneMultiselectDropdownProps';
export interface IPropertyPaneMultiselectDropdownInternalProps extends IPropertyPaneMultiselectDropdownProps, IPropertyPaneCustomFieldProps {
}
4. Create multiselect drop down property pane control
Create a file named “PropertyPaneMultiselectDropdown” in controls folder and paste the code below
import * as React from 'react';
import * as ReactDom from 'react-dom';
import {
IPropertyPaneField,
PropertyPaneFieldType
} from '@microsoft/sp-webpart-base';
import { IDropdownOption } from 'office-ui-fabric-react/lib/components/Dropdown';
import { IPropertyPaneMultiselectDropdownProps } from './IPropertyPaneMultiselectDropdownProps';
import { IPropertyPaneMultiselectDropdownInternalProps } from './IPropertyPaneMultiselectDropdownInternalProps';
import ListDropdown from './components/ListDropdown';
import { IListDropdownProps } from './components/IListDropdownProps';
import { cloneDeep } from 'lodash';
//multiselect dropdown with custom load deligate and on change handler
export class PropertyPaneMultiselectDropdown implements IPropertyPaneField<IPropertyPaneMultiselectDropdownInternalProps> {
public type: PropertyPaneFieldType = PropertyPaneFieldType.Custom;
public targetProperty: string;
public properties: IPropertyPaneMultiselectDropdownInternalProps;
private elem: HTMLElement;
constructor(targetProperty: string, properties: IPropertyPaneMultiselectDropdownProps) {
this.targetProperty = targetProperty;
this.properties = {
key: properties.label,
label: properties.label,
loadOptions: properties.loadOptions,
onPropertyChange: properties.onPropertyChange,
selectedKeys: properties.selectedKeys,
disabled: properties.disabled,
multiselect:properties.multiselect,
onRender: this.onRender.bind(this)
};
}
public render(): void {
if (!this.elem) {
return;
}
this.onRender(this.elem);
}
private onRender(elem: HTMLElement): void {
if (!this.elem) {
this.elem = elem;
}
const element: React.ReactElement<IListDropdownProps> = React.createElement(ListDropdown, {
label: this.properties.label,
loadOptions: this.properties.loadOptions,
onChanged: this.onChanged.bind(this),
selectedKeys: this.properties.selectedKeys,
disabled: this.properties.disabled,
multiselect:this.properties.multiselect,
// required to allow the component to be re-rendered by calling this.render() externally
stateKey: new Date().toString()
});
ReactDom.render(element, elem);
}
private onChanged(option: IDropdownOption, index?: number): void {
const updateSelectedKeys: any[] = this.properties.selectedKeys ? cloneDeep(this.properties.selectedKeys) : [];
if(this.properties.onPropertyChange)
{ // Check if item got selected
if (option.selected) {
updateSelectedKeys.push(option.key);
} else {
// Remove the item from the selected keys list
const itemIdx =updateSelectedKeys.indexOf(option.key);
if (itemIdx > -1) {
updateSelectedKeys.splice(itemIdx, 1);
}
}
}
this.properties.selectedKeys=updateSelectedKeys;
this.properties.onPropertyChange(this.targetProperty, updateSelectedKeys);
}
}
This is actual dropdown property pane control we have created. save the changes and now its time to use the control that we have created.
5. How to use multiselect dropdown in web part properties
To use in web part first we need to import the package as below.
import {PropertyPaneMultiselectDropdown} from '../controls/PropertyPaneMultiselectDropdown';
Then we need to create a property in webpart properties interface.
multiselectvalue:string[];
Then you need to define on property change load methods.
private loadTestData():Promise<IDropdownOption[]>{
return new Promise<IDropdownOption[]>((resolve)=>{
resolve([
{key:'1',text:'test option 1'},
{key:'2',text:'test option 2'},
{key:'3',text:'test option 3'},
{key:'4',text:'test option 4'},
]);
});
}
private onPropertyChange(propertyPath: string, newValue: any): void {
const oldValue: any = get(this.properties, propertyPath);
// store new value in web part properties
update(this.properties, propertyPath, (): any => { return newValue; });
// refresh web part
this.render();
}
And finally use below code in the property to create property pane control.
new PropertyPaneMultiselectDropdown('multiselectvalue',{
label:'Multiselect dropdown',
loadOptions: this.loadTestData.bind(this),
multiselect:true,
onPropertyChange:this.onPropertyChange.bind(this),
selectedKeys:this.properties.multiselectvalue
})
To view How it looks like and to download whole code and working solution you can go to github
https://github.com/mukeshhope/spfxcomponents