Step 5 - gunjandatta/spfx-forms GitHub Wiki
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.
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
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";
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
Set the webpart properties. The framework will store its configuration as a JSON string in this property.
export interface IListFormManagerWebPartProps {
configuration: string;
}
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
});
}
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');
}
}