Skip to content

Commit ff369dc

Browse files
committed
Added customIcons property on DynamicForm.
1 parent d58bb93 commit ff369dc

File tree

6 files changed

+89
-67
lines changed

6 files changed

+89
-67
lines changed

docs/documentation/docs/controls/DynamicForm.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ The `DynamicForm` can be configured with the following properties:
6262
| fieldOverrides | {[columnInternalName: string] : {(fieldProperties: IDynamicFieldProps): React.ReactElement\<IDynamicFieldProps\>}} | no | Key value pair for fields you want to override. Key is the internal field name, value is the function to be called for the custom element to render. |
6363
| respectEtag | boolean | no | Specifies if the form should respect the ETag of the item. Default - `true` |
6464
| validationErrorDialogProps | IValidationErrorDialogProps | no | Specifies validation error dialog properties |
65+
| customIcons | { [ columnInternalName: string ]: string } | no | Specifies custom icons for the form. The key of this dictionary is the column internal name, the value is the Fluent UI icon name. |
6566

6667
## Validation Error Dialog Properties `IValidationErrorDialogProps`
6768
| Property | Type | Required | Description |

src/controls/dynamicForm/DynamicForm.tsx

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ export class DynamicForm extends React.Component<
148148
*/
149149
public render(): JSX.Element {
150150
const { customFormatting, fieldCollection, hiddenByFormula, infoErrorMessages, isSaving } = this.state;
151-
151+
152152
const customFormattingDisabled = this.props.useCustomFormatting === false;
153153

154154
// Custom Formatting - Header
@@ -177,7 +177,7 @@ export class DynamicForm extends React.Component<
177177
footerContent = this._customFormatter.renderCustomFormatContent(customFormatting.footer, this.getFormValuesForValidation(), true) as JSX.Element;
178178
}
179179

180-
// Content Type
180+
// Content Type
181181
let contentTypeId = this.props.contentTypeId;
182182
if (this.state.contentTypeId !== undefined) contentTypeId = this.state.contentTypeId;
183183

@@ -301,7 +301,7 @@ export class DynamicForm extends React.Component<
301301
);
302302
}
303303

304-
private updateFormMessages(type: MessageBarType, message: string): void {
304+
private updateFormMessages(type: MessageBarType, message: string): void {
305305
const { infoErrorMessages } = this.state;
306306
const newMessages = infoErrorMessages.slice();
307307
newMessages.push({ type, message });
@@ -320,7 +320,7 @@ export class DynamicForm extends React.Component<
320320
validationErrorDialogProps,
321321
returnListItemInstanceOnSubmit
322322
} = this.props;
323-
323+
324324
let contentTypeId = this.props.contentTypeId;
325325
if (this.state.contentTypeId !== undefined) contentTypeId = this.state.contentTypeId;
326326

@@ -491,7 +491,7 @@ export class DynamicForm extends React.Component<
491491
} else {
492492
objects[columnInternalName] = null;
493493
}
494-
}
494+
}
495495
}
496496
}
497497

@@ -615,7 +615,7 @@ export class DynamicForm extends React.Component<
615615
}
616616
console.log("Error", error);
617617
}
618-
}
618+
}
619619

620620
this.setState({
621621
isSaving: false,
@@ -646,7 +646,7 @@ export class DynamicForm extends React.Component<
646646
returnListItemInstanceOnSubmit
647647
} = this.props;
648648

649-
649+
650650
if (selectedFile !== undefined) {
651651
try {
652652
const idField = "ID";
@@ -660,14 +660,14 @@ export class DynamicForm extends React.Component<
660660
"_"
661661
) // Replace not allowed chars in folder name
662662
: ""; // Empty string will be replaced by SPO with Folder Item ID
663-
663+
664664
const fileCreatedResult = await library.rootFolder.files.addChunked(encodeURI(itemTitle), await selectedFile.downloadFileContent());
665665
const fields = await fileCreatedResult.file.listItemAllFields();
666-
666+
667667
if (fields[idField]) {
668668
// Read the ID of the just created folder or Document Set
669669
const folderId = fields[idField];
670-
670+
671671
// Set the content type ID for the target item
672672
objects[contentTypeIdField] = contentTypeId;
673673
// Update the just created folder or Document Set
@@ -784,7 +784,7 @@ export class DynamicForm extends React.Component<
784784
fieldCollection: fieldCol,
785785
validationErrors
786786
}, () => {
787-
if (validate) this.performValidation();
787+
if (validate) this.performValidation();
788788
});
789789
};
790790

@@ -821,7 +821,7 @@ export class DynamicForm extends React.Component<
821821
* @param formulas A Record / dictionary-like object, where key is internal column name and value is an object with ValidationFormula and ValidationMessage properties
822822
* @param returnMessages Determines whether a Record of error messages is returned or an array of column names that have failed validation
823823
* @param requireValue Set to true if the formula should only be evaluated when the field has a value
824-
* @returns
824+
* @returns
825825
*/
826826
private evaluateFormulas = (
827827
formulas: Record<string, Pick<ISPField, "ValidationFormula" | "ValidationMessage">>,
@@ -853,12 +853,12 @@ export class DynamicForm extends React.Component<
853853
}
854854

855855
/**
856-
* Used for validation. Returns a Record of field values, where key is internal column name and value is the field value.
856+
* Used for validation. Returns a Record of field values, where key is internal column name and value is the field value.
857857
* Expands certain properties and stores many of them as primitives (strings, numbers or bools) so the expression evaluator
858858
* can process them. For example: a User column named Person will have values stored as Person, Person.email, Person.title etc.
859-
* This is so the expression evaluator can process expressions like '=[$Person.title] == "Contoso Employee 1138"'
859+
* This is so the expression evaluator can process expressions like '=[$Person.title] == "Contoso Employee 1138"'
860860
* @param fieldCollection Optional. Could be used to compare field values in state with previous state.
861-
* @returns
861+
* @returns
862862
*/
863863
private getFormValuesForValidation = (fieldCollection?: IDynamicFieldProps[]): Context => {
864864
const { fieldCollection: fieldColFromState } = this.state;
@@ -909,10 +909,11 @@ export class DynamicForm extends React.Component<
909909
listItemId,
910910
disabledFields,
911911
respectETag,
912+
customIcons,
912913
onListItemLoaded,
913914
} = this.props;
914915
let contentTypeId = this.props.contentTypeId;
915-
916+
916917
try {
917918

918919
// Fetch form rendering information from SharePoint
@@ -987,13 +988,14 @@ export class DynamicForm extends React.Component<
987988
numberFields,
988989
listId,
989990
listItemId,
990-
disabledFields
991+
disabledFields,
992+
customIcons
991993
);
992994

993995
// Get installed languages for Currency fields
994996
let installedLanguages: IInstalledLanguageInfo[];
995997
if (tempFields.filter(f => f.fieldType === "Currency").length > 0) {
996-
installedLanguages = await sp.web.regionalSettings.getInstalledLanguages();
998+
installedLanguages = await sp.web.regionalSettings.getInstalledLanguages();
997999
}
9981000

9991001
this.setState({
@@ -1026,10 +1028,10 @@ export class DynamicForm extends React.Component<
10261028
* @param listId SharePoint List ID
10271029
* @param listItemId SharePoint List Item ID
10281030
* @param disabledFields Fields that should be disabled due to configuration
1029-
* @returns
1031+
* @returns
10301032
*/
10311033
// eslint-disable-next-line @typescript-eslint/no-explicit-any
1032-
private async buildFieldCollection(listInfo: IRenderListDataAsStreamClientFormResult, contentTypeName: string, item: any, numberFields: ISPField[], listId: string, listItemId: number, disabledFields: string[]): Promise<IDynamicFieldProps[]> {
1034+
private async buildFieldCollection(listInfo: IRenderListDataAsStreamClientFormResult, contentTypeName: string, item: any, numberFields: ISPField[], listId: string, listItemId: number, disabledFields: string[], customIcons: {[key: string]: string}): Promise<IDynamicFieldProps[]> {
10331035
const tempFields: IDynamicFieldProps[] = [];
10341036
let order: number = 0;
10351037
const hiddenFields = this.props.hiddenFields !== undefined ? this.props.hiddenFields : [];
@@ -1286,6 +1288,7 @@ export class DynamicForm extends React.Component<
12861288
minimumValue: minValue,
12871289
maximumValue: maxValue,
12881290
showAsPercentage: showAsPercentage,
1291+
customIcon: customIcons ? customIcons[field.InternalName] : undefined
12891292
});
12901293

12911294
// This may not be necessary now using RenderListDataAsStream

src/controls/dynamicForm/IDynamicFormProps.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@ export interface IDynamicFormProps {
5151
/**
5252
* Key value pair for fields you want to override. Key is the internal field name, value is the function to be called for the custom element to render
5353
*/
54-
fieldOverrides?: {[columnInternalName: string] : {(fieldProperties: IDynamicFieldProps): React.ReactElement<IDynamicFieldProps>}};
54+
fieldOverrides?: {
55+
[columnInternalName: string]: {
56+
(
57+
fieldProperties: IDynamicFieldProps
58+
): React.ReactElement<IDynamicFieldProps>;
59+
};
60+
};
5561

5662
/**
5763
* Specifies if onSubmitted event should pass PnPJS list item (IItem) as a second parameter. Default - true
@@ -110,4 +116,10 @@ export interface IDynamicFormProps {
110116
* Only used when enableFileSelection is true
111117
*/
112118
supportedFileExtensions?: string[];
119+
120+
/**
121+
* Specify a set of custom icons to be used.
122+
* The key is the field internal name and the value is the Fluent UI icon name.
123+
*/
124+
customIcons?: { [columnInternalName: string]: string };
113125
}

0 commit comments

Comments
 (0)