Step 5 - gunjandatta/spfx-forms GitHub Wiki

Create Forms WebPart

Andrew Connel recently published a blog post going over SPFx custom list forms. Credit to him for explaining how to apply/remove the custom list forms from a modern list. I won't go over the low level details, but essentially it's similar to the class way of customizing the New/Edit/Display form. For modern lists, we will set a new property on the content type and set the component id that is generated with you extension. To make life easier, the SPFx List Form WebPart component is designed to help you out.

Create WebPart

From the console, run the yo @microsoft/sharepoint method to add a webpart to the same project. Set the following options:

  • Type of Solution: WebPart
  • WebPart Name: ListFormManager
  • Form Customizer Name: CustomForm
  • Template to Use: No Framework

Import Components

We will include the Environment component from the core library, and the WebParts component from the SharePoint REST Framework.

import { Environment, Log } from "@microsoft/sp-core-library";
import { WebParts } from "gd-sprest-bs";

Code Updates

Complete the following:

  • Clear the associated scss file contents
  • Update the properties
  • Clear the render method
  • Remove the getPropertyPaneConfiguration method
  • Remove unused import statements
  • Set the render method

WebPart Properties

Set the webpart properties. The framework will store its configuration as a JSON string in this property.

export interface IListFormManagerWebPartProps {
  configuration: string;
}

Render Method

Reference the src/extensions/customForm/CustomFormFormCustomizer.manifest.json file and copy the id property of the custom list form extension. We will set the componentId property of the webpart, which will default the component id property of the helper webpart. Optionally, the componentProps property can be set for any custom properties required for your form.

public render(): void {
    // Render the list form webpart
    WebParts.SPFxListFormWebPart({
        // This is from the manifest file of the custom form extension
        componentId: "7ed045f6-8c5e-4f01-8f66-ccf6f2e5c8cd",
        envType: Environment.type,
        spfx: this as any
    });
}

src/extensions/customForm/CustomFormFormCustomizer.ts

The code should look similar to this. Additional cleanup will be needed, but I want to show the minimal amount of code required to get this demo working.

import { Environment, Version } from '@microsoft/sp-core-library';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import { IReadonlyTheme } from '@microsoft/sp-component-base';

import styles from './ListFormManagerWebPart.module.scss';
import * as strings from 'ListFormManagerWebPartStrings';

import { WebParts } from "gd-sprest-bs";

export interface IListFormManagerWebPartProps {
  configuration: string;
}

export default class ListFormManagerWebPart extends BaseClientSideWebPart<IListFormManagerWebPartProps> {

  private _isDarkTheme: boolean = false;
  private _environmentMessage: string = '';

  public render(): void {
    // Render the list form webpart
    WebParts.SPFxListFormWebPart({
      // This is from the manifest file of the custom form extension
      componentId: "7ed045f6-8c5e-4f01-8f66-ccf6f2e5c8cd",
      envType: Environment.type,
      spfx: this as any
    });
  }

  protected onInit(): Promise<void> {
    this._environmentMessage = this._getEnvironmentMessage();

    return super.onInit();
  }



  private _getEnvironmentMessage(): string {
    if (!!this.context.sdks.microsoftTeams) { // running in Teams
      return this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentTeams : strings.AppTeamsTabEnvironment;
    }

    return this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentSharePoint : strings.AppSharePointEnvironment;
  }

  protected onThemeChanged(currentTheme: IReadonlyTheme | undefined): void {
    if (!currentTheme) {
      return;
    }

    this._isDarkTheme = !!currentTheme.isInverted;
    const {
      semanticColors
    } = currentTheme;

    if (semanticColors) {
      this.domElement.style.setProperty('--bodyText', semanticColors.bodyText || null);
      this.domElement.style.setProperty('--link', semanticColors.link || null);
      this.domElement.style.setProperty('--linkHovered', semanticColors.linkHovered || null);
    }

  }

  protected get dataVersion(): Version {
    return Version.parse('1.0');
  }
}
⚠️ **GitHub.com Fallback** ⚠️