Customizing SharePoint Framework Web Part Properties - Part Three

Introduction 
 
In this article, you will learn how to manage multiple pages on the SharePoint Framework web part "Properties" pane. You will also see different fields or properties getting appended to the Properties pane.
 
In my previous articles, I have introduced the custom properties and explained check box field properties sample on 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 the previous article sample, you will have seen descriptions and check box fields added to the properties pane on a single page. Here you can see them separated on multiple pages. I will be using the samples from the previous article.
 
In this sample, the web part property pane contains two pages. 
  • The first page contains the text and label fields.
  • The second page contains the check box fields. 
Components
 
propertyPaneSettings method holds the basic pane structure where it defines the basic definition for the web part properties. Basically, in the property definition file, pane page contains the following components.
  • Header 
    Contains the description property about the page.

  • Groups
    Multiple groups with each group having multiple properties.

  • Group
    Contains the group name and the properties. The properties can be anything like label, description, check box, drop down, etc. 
Pages 
 
In the first page of property pane, let us show two groups. 
  • The first group contains a set of text field properties.
  • The second group contains the label property, which shows the static text. 
In the second page of property pane, let us define one group.
  • The group contains the check box fields.
The below structure shows the first page of the properties pane which has a header and groups attached with multiple properties. At the bottom of the screen, you can see the pagination option.
 
 
Implementation 
 
Let us look at the implementation. The property pane method which needs to be included in the web part file is shown below. It shows two pages with necessary headers and groups. The group contains the properties.
  1. protected get propertyPaneSettings(): IPropertyPaneSettings {  
  2.   return {  
  3.     pages: [  
  4.       {  
  5.         header: {  
  6.           description: strings.PropertyPaneDescription,  
  7.         },  
  8.         groups: [  
  9.           {  
  10.             groupName: strings.BasicInfo,  
  11.             groupFields: [  
  12.               PropertyPaneTextField('title', {  
  13.                 label: strings.TitleFieldLabel  
  14.               }),  
  15.               PropertyPaneTextField('description', {  
  16.                 label: strings.DescriptionFieldLabel  
  17.               })  
  18.             ]  
  19.           },  
  20.           {  
  21.             groupName: "Static Info",  
  22.             groupFields:  
  23.             [  
  24.               PropertyPaneLabel('About', {  
  25.                   text:'Users can edit this web part and provide necessary inputs using the properties pane'  
  26.               })  
  27.             ]  
  28.           }  
  29.   
  30.         ]  
  31.       },  
  32.       {  
  33.         header: {  
  34.           description: strings.PropertyPaneDescription  
  35.         },  
  36.         groups: [  
  37.           {  
  38.             groupName: "Optional Fields",  
  39.             groupFields: [  
  40.               PropertyPaneCheckbox('checkboxProperty1',{  
  41.                 isChecked:false,  
  42.                 isEnabled:true,  
  43.                 text: this.checkboxProperty1  
  44.               }),  
  45.               PropertyPaneCheckbox('checkboxProperty2',{  
  46.                 isChecked:false,  
  47.                 isEnabled:true,  
  48.                 text: this.checkboxProperty2  
  49.               })  
  50.             ]  
  51.           }  
  52.         ]  
  53.       }  
  54.     ]  
  55.   };  
  56. }  
The custom implementation or logic is included in the custom methods of web part file.
 
IListItemsFormWebPartProps.ts file
 
The properties are defined using IListItemsFormWebPartProps.ts file.
  1. export interface IListItemsFormWebPartProps {  
  2.   description: string;  
  3.   checkboxProperty1: string;  
  4.   checkboxProperty2: string;  
  5. }  
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.   
  9. declare module 'listItemsFormStrings' {  
  10.   const strings: IListItemsFormStrings;  
  11.   export = strings;  
  12. }  
en-us.js File
  1. define([], function() {  
  2.   return {  
  3.     "PropertyPaneDescription""Config Web Part",  
  4.     "BasicGroupName""Group Name",  
  5.     "DescriptionFieldLabel""Description Field",  
  6.     "BasicInfo""Basic Information"  
  7.   }  
  8. });  
ListItemsForm.module.scss File
 
The necessary style content is present inside ListItemsForm.module.scss file. Refer to my previous article.
 
ListItemsFormWebPart.ts File
 
The ListItemsFormWebPart.ts file contains the implementation part. 
  1. import {  
  2.   BaseClientSideWebPart,  
  3.   IPropertyPaneSettings,  
  4.   IWebPartContext,  
  5.   PropertyPaneTextField,  
  6.   PropertyPaneCheckbox,  
  7.   PropertyPaneLabel  
  8. } from '@microsoft/sp-client-preview';  
  9.   
  10. import styles from './ListItemsForm.module.scss';  
  11. import * as strings from 'listItemsFormStrings';  
  12. import { IListItemsFormWebPartProps } from './IListItemsFormWebPartProps';  
  13.   
  14. export interface spListItems{  
  15.   value: spListItem[]  
  16. }  
  17. export interface spListItem{  
  18.   Title: string;  
  19.   id: string;  
  20.   Created: string;  
  21.   Author: {  
  22.     Title: string;  
  23.   };  
  24. }  
  25.   
  26.   
  27. export default class ListItemsFormWebPart extends BaseClientSideWebPart<IListItemsFormWebPartProps> {  
  28.   private listName: string = "";  
  29.   private checkboxProperty1: string = "Created";  
  30.   private checkboxProperty2: string = "Author";  
  31.   
  32.   public constructor(context: IWebPartContext) {  
  33.     super(context);  
  34.   }  
  35.   
  36.   public render(): void {  
  37.     // Render the items in tabular format  
  38.     this.domElement.innerHTML = `  
  39.       <div class="${styles.listItemsForm}">  
  40.         <div class="${styles.Table}">  
  41.           <div class="${styles.Heading}">  
  42.             <div class="${styles.Cell}">Title</div>  
  43.           </div>  
  44.         </div>  
  45.       </div>`;  
  46.   
  47.       this.listName = "TestList";  
  48.       this.LoadData();  
  49.   }  
  50.   
  51.   private LoadData(): void{  
  52.   
  53.     let url: string = this.context.pageContext.web.absoluteUrl + "/_api/web/lists/getbytitle('"+this.listName+"')/items?$select=Title";  
  54.     // If Created Time check box option is selected  
  55.     if(this.properties.checkboxProperty1){  
  56.       url += ",Created";  
  57.       // Column header for Created Time field  
  58.        this.domElement.querySelector("."+styles.Heading).innerHTML +=`<div class="${styles.Cell}">Created</div>`;  
  59.     }  
  60.     // If Author check box option is selected  
  61.     if(this.properties.checkboxProperty2){  
  62.       url += ",Author/Title&$expand=Author";  
  63.       // Column header for Author field  
  64.       this.domElement.querySelector("."+styles.Heading).innerHTML +=`<div class="${styles.Cell}">Author</div>`;  
  65.     }  
  66.   
  67.     this.GetListData(url).then((response)=>{  
  68.       // Render the data in the web part  
  69.       this.RenderListData(response.value);  
  70.     });  
  71.   }  
  72.   
  73.   private GetListData(url: string): Promise<spListItems>{  
  74.     // Retrieves data from SP list  
  75.     return this.context.httpClient.get(url).then((response: Response)=>{  
  76.        return response.json();  
  77.     });  
  78.   }  
  79.   private RenderListData(listItems: spListItem[]): void{  
  80.     let itemsHtml: string = "";  
  81.     // Displays the values in table rows  
  82.     listItems.forEach((listItem: spListItem)=>{  
  83.       let itemTimeStr: string = listItem.Created;  
  84.       let itemTime: Date = new Date(itemTimeStr);  
  85.       itemsHtml += `<div class="${styles.Row}">`;  
  86.       itemsHtml += `<div class="${styles.Cell}"><p>${listItem.Title}</p></div>`;  
  87.       if(this.properties.checkboxProperty1){  
  88.         itemsHtml += `<div class="${styles.Cell}"><p>${listItem.Created}</p></div>`;  
  89.       }  
  90.       if(this.properties.checkboxProperty2){  
  91.         itemsHtml += `<div class="${styles.Cell}"><p>${listItem.Author.Title}</p></div>`;  
  92.       }  
  93.   
  94.       itemsHtml += `</div>`;  
  95.     });  
  96.     this.domElement.querySelector("."+styles.Table).innerHTML +=itemsHtml;  
  97.   }  
  98.   protected get propertyPaneSettings(): IPropertyPaneSettings {  
  99.     return {  
  100.       pages: [  
  101.         {  
  102.           header: {  
  103.             description: strings.PropertyPaneDescription,  
  104.           },  
  105.           groups: [  
  106.             {  
  107.               groupName: strings.BasicInfo,  
  108.               groupFields: [  
  109.                 PropertyPaneTextField('title', {  
  110.                   label: strings.TitleFieldLabel  
  111.                 }),  
  112.                 PropertyPaneTextField('description', {  
  113.                   label: strings.DescriptionFieldLabel  
  114.                 })  
  115.               ]  
  116.             },  
  117.             {  
  118.               groupName: "Static Info",  
  119.               groupFields:  
  120.               [  
  121.                 PropertyPaneLabel('About', {  
  122.                     text:'Users can edit this web part and provide necessary inputs using the properties pane'  
  123.                 })  
  124.               ]  
  125.             }  
  126.   
  127.           ]  
  128.         },  
  129.         {  
  130.           header: {  
  131.             description: strings.PropertyPaneDescription  
  132.           },  
  133.           groups: [  
  134.             {  
  135.               groupName: "Optional Fields",  
  136.               groupFields: [  
  137.                 PropertyPaneCheckbox('checkboxProperty1',{  
  138.                   isChecked:false,  
  139.                   isEnabled:true,  
  140.                   text: this.checkboxProperty1  
  141.                 }),  
  142.                 PropertyPaneCheckbox('checkboxProperty2',{  
  143.                   isChecked:false,  
  144.                   isEnabled:true,  
  145.                   text: this.checkboxProperty2  
  146.                 })  
  147.               ]  
  148.             }  
  149.           ]  
  150.         }  
  151.       ]  
  152.     };  
  153.   }  
  154. }  
Note
 
The web part needs to be deployed to the site and added to the page. In my previous article, you can see the steps for deployment.
 
Screenshots 
 
The following screenshot shows the web part page with first page of the web part property pane.
 
The following screenshot shows the web part page with second page of the web part property pane. 

 
Summary
 
Thus, you have learned how to manage multiple pages on the SharePoint Framework web part Properties pane with different fields or properties.
 
What Next?
 
In the next article, you will learn about working with adding other custom properties that are available to the properties pane.