Customizing SharePoint Framework Web Part Properties - Part Five

Introduction

In this article, you will learn how to add the dropdown field, bind the values dynamically to SharePoint Framework Web part properties pane, and load the Web part based on the dropdown value selected. In my previous articles, I have introduced the custom properties, explained check box field properties samples and managing multiple pages on the properties pane of SharePoint Framework (SPFx) Web part.

In my SPFx article series, you can learn about SPFx introduction, prerequisites, steps for setting up the environment, and developing and testing the Web parts, using the local environments.

In my previous article, you will have seen how to add a dropdown field to the Web part property pane.

In this article, you will see how to bind the values dynamically to the dropdown field of the Web part properties and load the Web part when a dropdown is selected with the code samples. 


Drop down Property Declaration/Definition

The values appended to the dropdown field are of type IPropertyPaneDropdownOption. The variable "dropDownOptions" of the same type is declared inside the class.

  1. private dropDownOptions: IPropertyPaneDropdownOption[] =[];  

The properties are defined, using propertyPaneSettings method. The snippet given below shows the defined properties. As you can see, the values are not appended directly to the options, rather variable "dropDownOptions" of type IPropertyPaneDropdownOption is assigned.

  1. protected get propertyPaneSettings(): IPropertyPaneSettings {  

  2. return {      

  3. pages: [        {          

  4. header: {            

  5. description: strings.PropertyPaneDescription,          

  6. },          

  7. groups: [            {              

  8. groupName:"Lists",              

  9. groupFields:[                

  10. PropertyPaneDropdown('DropDownProp',{                  

  11. label: "Select List To Display on the page",                  

  12. options:this.dropDownOptions,                  

  13. isDisabled: false               

  14. })             

  15.  ]           

  16.  }         

  17.  ]        

  18. }      

  19. ]    

  20. };  

  21. }  


Load/Add Values To Drop Down Property

Now, we need to load the list names on to the drop down field dynamically. Basically it means, the variable this.dropDownOptions should be loaded with necessary values (list names as values). To load the values, either onInit() or onPropertyPaneConfigurationStart() methods can be used.onInit() method is executed whenever the page loads.onPropertyPaneConfigurationStart() loads only when the web part property pane is opened.


In this sample, onPropertyPaneConfigurationStart() method will be used.  The snippet given below shows the method. The custom function is written to load SharePoint list names into the dropdown property. Here, this.dropDownOptions property is loaded with the list names.

  1. protected onPropertyPaneConfigurationStart(): void 

  2. {  

  3. // Stops execution, if the list values already exists

  4. if(this.dropDownOptions.length>0) 

  5. return;  

  6. // Calls function to append the list names to dropdown

  7. this.GetLists();  

  8. }  

  9. private GetLists():void{  

  10. // REST API to pull the list names   

  11. let listresturl: string = this.context.pageContext.web.absoluteUrl + "/_api/web/lists?

  12. $select=Id,Title";  

  13. this.LoadLists(listresturl).then((response)=>{  

  14. // Render the data in the web part

  15. this.LoadDropDownValues(response.value);    

  16. });  

  17. }  

  18. private LoadLists(listresturl:string): Promise<spLists>{  

  19. return this.context.httpClient.get(listresturl).then((response: Response)=>{  

  20. return response.json();    

  21. });  

  22. }  

  23. private LoadDropDownValues(lists: spList[]): void{    

  24. lists.forEach((list:spList)=>{  

  25. // Loads the drop down values

  26. this.dropDownOptions.push({key:list.Title,text:list.Title});    

  27. });  

  28. }  


Display data on the Web part

The data displayed on the Web part is rendered, using render() method. The corresponding custom functions are written and called to display the data on the Web part, which is based on the dropdown value selected. I have explained the same in my previous article (The code can be found the below section). The render() method is called, whenever dropdown property (this.properties.DropDownProp) is changed.  


Entire Code

The entire code snippets given below shows the changes made to the various files in the basic Web part project. 


IListItemsFormWebPartProps.ts File

  1. export interface IListItemsFormWebPartProps 

  2. {    

  3. DropDownProp: string;  

  4. }  

ListItemsFormWebPart.ts File

  1. import {    

  2. BaseClientSideWebPart,    

  3. IPropertyPaneSettings,    

  4. IWebPartContext,    

  5. PropertyPaneDropdown,    

  6. IPropertyPaneDropdownOption  

  7. from '@microsoft/sp-client-preview';  

  8. import styles from './ListItemsForm.module.scss';  

  9. import * as strings from 'listItemsFormStrings';  

  10. import { IListItemsFormWebPartProps } from './IListItemsFormWebPartProps';  

  11. export interface spListItems{   

  12.  value: spListItem[];  

  13. }  

  14. export interface spListItem{    

  15. Title: string;    

  16. id: string;    

  17. Created: string;   

  18.  Author: {      

  19. Title: string;    

  20. };  

  21. }  

  22. export interface spList{  Title:string;  id: string;  }  

  23. export interface spLists{    

  24. value: spList[];  

  25. }  

  26. export default class ListItemsFormWebPart 

  27. extends BaseClientSideWebPart<IListItemsFormWebPartProps> {  

  28. private dropDownOptions: IPropertyPaneDropdownOption[] =[];  

  29. public constructor(context: IWebPartContext) {  

  30. super(context);    

  31. }  

  32. public render(): void {  

  33. // Render the items in tabular format

  34. this.domElement.innerHTML = <div class="${styles.listItemsForm}">          

  35. <div class="${styles.Table}">            

  36. <div class="${styles.Heading}">              

  37. <div class="${styles.Cell}">Title</div>              

  38. <div class="${styles.Cell}">Created</div>              

  39. <div class="${styles.Cell}">Author</div>            

  40. </div>          

  41. </div>        

  42. </div>`;        

  43. console.log("Render");  

  44. this.LoadData();    

  45. }  

  46. private LoadData(): void{  

  47. if(this.properties.DropDownProp != undefined)

  48. {        

  49. let url: string = this.context.pageContext.web.absoluteUrl + "/_api/web/lists/getbytitle('"+this.properties.DropDownProp+"')/items?$select=Title,Created,Author/Title&$expand=Author";  

  50. this.GetListData(url).then((response)=>{  

  51. // Render the data in the web part

  52. this.RenderListData(response.value);      

  53. });      

  54. }     

  55. }  

  56. private GetListData(url: string): Promise<spListItems>{  

  57. // Retrieves data from SP list

  58. return this.context.httpClient.get(url).then((response: Response)=>{  

  59. return response.json();      

  60. });    

  61. }  

  62. private RenderListData(listItems: spListItem[]): void{      

  63. let itemsHtml: string = "";  

  64. // Displays the values in table rows    

  65.  listItems.forEach((listItem: spListItem)=>

  66. {        

  67. itemsHtml += `<div class="${styles.Row}">`;        

  68. itemsHtml += `<div class="${styles.Cell}">

  69. <p>${listItem.Title}</p></div>`;         

  70.  itemsHtml += `<div class="${styles.Cell}">

  71. <p>${listItem.Created}</p></div>`;         

  72.  itemsHtml += `<div class="${styles.Cell}">

  73. <p>${listItem.Author.Title}</p></div>`;         

  74. itemsHtml += `</div>`;      

  75. });  

  76. this.domElement.querySelector("."+styles.Table).innerHTML +=itemsHtml;    

  77. }  

  78. protected onPropertyPaneConfigurationStart(): void {  

  79. // Stops execution, if the list values already exists

  80. if(this.dropDownOptions.length>0) return;  

  81. // Calls function to append the list names to dropdown

  82. this.GetLists();     }  

  83. private GetLists():void{  

  84. // REST API to pull the list names     

  85. let listresturl: string = this.context.pageContext.web.absoluteUrl + "/_api/web/lists?

  86. $select=Id,Title";  

  87. this.LoadLists(listresturl).then((response)=>{  

  88. // Render the data in the web part

  89. this.LoadDropDownValues(response.value);      

  90. });    

  91. }  

  92. private LoadLists(listresturl:string): Promise<spLists>{  

  93. return this.context.httpClient.get(listresturl).then((response: Response)=>{  

  94. return response.json();      

  95. });    

  96. }  

  97. private LoadDropDownValues(lists: spList[]): void{     

  98.  lists.forEach((list:spList)=>{  

  99. // Loads the drop down values

  100. this.dropDownOptions.push({key:list.Title,text:list.Title});      });    }  

  101. protected get propertyPaneSettings(): IPropertyPaneSettings {  

  102. return {        

  103. pages: [          {            

  104. header: {              

  105. description: strings.PropertyPaneDescription,           

  106.  },            

  107. groups: [              {                

  108. groupName:"Lists",                

  109. groupFields:

  110. [                  

  111. PropertyPaneDropdown('DropDownProp',

  112. {                    

  113. label: "Select List To Display on the page",                   

  114.  options:this.dropDownOptions,                    

  115. isDisabled: false                 

  116. })                

  117. ]              

  118. }            

  119. ]          

  120. }        

  121. ]      

  122. };   

  123.  }  

  124. }  


ListItemsForm.module.scss File

  1. .listItemsForm {    

  2. .container {      

  3. max-width: 700px;      

  4. margin: 0px auto;      

  5. box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);    

  6. }     

  7. .row {     

  8.  padding: 20px;    

  9. }     

  10. .listItem {      

  11. max-width: 715px;      

  12. margin: 5px auto 5px auto;      

  13. box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1);    }     

  14. .button {      

  15. text-decoration: none;    

  16. }    

  17. .listItemTitle{      

  18. font-size: large;      

  19. color: darkblue;    

  20. }    

  21. .listItemProps{      

  22. font-size: small;    

  23. }     

  24. .Table      

  25. {          

  26. display: table;      

  27. }      

  28. .Title      

  29. {          

  30. display: table-caption;          

  31. text-align: center;          

  32. font-weight: bold;          

  33. font-size: larger;      

  34. }     

  35.  .Heading      

  36. {          

  37. display: table-row;          

  38. font-weight: bold;          

  39. text-align: center;      

  40. }      

  41. .Row      

  42. {          

  43. display: table-row;      

  44. }      

  45. .Cell      

  46. {          

  47. display: table-cell;          

  48. border: solid;          

  49. border-width: thin;          

  50. padding-left: 5px;          

  51. padding-right: 5px;      

  52. }  

  53. }  


mystrings.d.ts File

  1. declare interface IListItemsFormStrings {    

  2. PropertyPaneDescription: string;    

  3. BasicGroupName: string;    

  4. DescriptionFieldLabel: string;    

  5. TitleFieldLabel: string;    

  6. BasicInfo: string;  

  7. }  

  8. declare module 'listItemsFormStrings' 

  9. {  

  10. const strings: IListItemsFormStrings;  

  11. export = strings;  

  12. }  


en-us.js File

  1. define([], function() {  

  2. return {  

  3. "PropertyPaneDescription": "Config Web Part",   "BasicGroupName": "Group Name",   "DescriptionFieldLabel": "Description Field",   "BasicInfo": "Basic Information"   

  4. }  

  5. });  


Summary

Thus, you have learned how to add dropdown field to the Web part property pane, bind dropdown values dynamically and load the Web part, which is based on the selected dropdown property.

Recent Posts

See All