Skip to content

Commit f0b33a4

Browse files
Renders file/folder name field. Closes #1683 (#1906)
1 parent 6abff12 commit f0b33a4

File tree

3 files changed

+69
-26
lines changed

3 files changed

+69
-26
lines changed

src/controls/dynamicForm/DynamicForm.tsx

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ const stackTokens: IStackTokens = { childrenGap: 20 };
5454
export class DynamicForm extends React.Component<
5555
IDynamicFormProps,
5656
IDynamicFormState
57-
> {
57+
> {
5858
private _spService: SPservice;
5959
private _formulaEvaluation: FormulaEvaluation;
6060
private _customFormatter: CustomFormattingHelper;
@@ -594,22 +594,14 @@ export class DynamicForm extends React.Component<
594594
else if (contentTypeId.startsWith("0x0120")) {
595595
// We are adding a folder or a Document Set
596596
try {
597-
const idField = "ID";
598-
const titleField = "Title";
597+
const idField = "ID";
599598
const contentTypeIdField = "ContentTypeId";
600599

601-
const library = await sp.web.lists.getById(listId);
602-
const folderTitle =
603-
objects[titleField] !== undefined && objects[titleField] !== ""
604-
? (objects[titleField] as string).replace(
605-
/["|*|:|<|>|?|/|\\||]/g,
606-
"_"
607-
) // Replace not allowed chars in folder name
608-
: ""; // Empty string will be replaced by SPO with Folder Item ID
609-
const newFolder = await library.rootFolder.addSubFolderUsingPath(
610-
folderTitle
611-
);
600+
const library = await sp.web.lists.getById(listId);
601+
const folderFileName = this.getFolderName(objects);
602+
const newFolder = await library.rootFolder.addSubFolderUsingPath(folderFileName);
612603
const fields = await newFolder.listItemAllFields();
604+
613605
if (fields[idField]) {
614606
// Read the ID of the just created folder or Document Set
615607
const folderId = fields[idField];
@@ -681,20 +673,20 @@ export class DynamicForm extends React.Component<
681673
? (selectedFile.fileName as string).replace(
682674
/["|*|:|<|>|?|/|\\||]/g,
683675
"_"
684-
) // Replace not allowed chars in folder name
676+
).trim() // Replace not allowed chars in folder name and trim empty spaces at the start or end.
685677
: ""; // Empty string will be replaced by SPO with Folder Item ID
686678

687679
const fileCreatedResult = await library.rootFolder.files.addChunked(encodeURI(itemTitle), await selectedFile.downloadFileContent());
688680
const fields = await fileCreatedResult.file.listItemAllFields();
689681

690682
if (fields[idField]) {
691-
// Read the ID of the just created folder or Document Set
692-
const folderId = fields[idField];
683+
// Read the ID of the just created file
684+
const fileId = fields[idField];
693685

694686
// Set the content type ID for the target item
695687
objects[contentTypeIdField] = contentTypeId;
696-
// Update the just created folder or Document Set
697-
const iur = await library.items.getById(folderId).update(objects);
688+
// Update the just created file
689+
const iur = await library.items.getById(fileId).update(objects);
698690
if (onSubmitted) {
699691
onSubmitted(
700692
iur.data,
@@ -705,7 +697,7 @@ export class DynamicForm extends React.Component<
705697
}
706698
} else {
707699
throw new Error(
708-
"Unable to read the ID of the just created folder or Document Set"
700+
"Unable to read the ID of the just created file"
709701
);
710702
}
711703
} catch (error) {
@@ -990,9 +982,17 @@ export class DynamicForm extends React.Component<
990982
// Load SharePoint list item
991983
const spList = sp.web.lists.getById(listId);
992984
let item = null;
985+
const isEditingItem = listItemId !== undefined && listItemId !== null && listItemId !== 0;
993986
let etag: string | undefined = undefined;
994-
if (listItemId !== undefined && listItemId !== null && listItemId !== 0) {
995-
item = await spList.items.getById(listItemId).get().catch(err => this.updateFormMessages(MessageBarType.error, err.message));
987+
988+
if (isEditingItem) {
989+
const spListItem = spList.items.getById(listItemId);
990+
991+
if (contentTypeId.startsWith("0x0120") || contentTypeId.startsWith("0x0101")) {
992+
spListItem.select("*","FileLeafRef"); // Explainer: FileLeafRef is not loaded by default. Load it to show the file/folder name in the field.
993+
}
994+
995+
item = await spListItem.get().catch(err => this.updateFormMessages(MessageBarType.error, err.message));
996996

997997
if (onListItemLoaded) {
998998
await onListItemLoaded(item);
@@ -1288,7 +1288,7 @@ export class DynamicForm extends React.Component<
12881288
if (defaultValue !== undefined && defaultValue !== null) defaultValue = Boolean(Number(defaultValue));
12891289
if (value !== undefined && value !== null) value = Boolean(Number(value));
12901290
}
1291-
1291+
12921292
tempFields.push({
12931293
value,
12941294
newValue: undefined,
@@ -1476,4 +1476,24 @@ export class DynamicForm extends React.Component<
14761476
}
14771477
}
14781478

1479+
/**
1480+
* Creates a folder name based on the FileLeafRef field (if rendered) or the Title field (if rendered)
1481+
* Replaces not allowed chars in folder name and trims spaces at the start and end of the string
1482+
* Empty string will be replaced by SPO with Folder Item ID
1483+
* @param objects The object containing the field values
1484+
* @returns the folder name
1485+
*/
1486+
private getFolderName = (objects: {}): string => {
1487+
const titleField = "Title";
1488+
const fileLeafRefField = "FileLeafRef";
1489+
let folderNameValue = "";
1490+
1491+
if (objects[fileLeafRefField] !== undefined && objects[fileLeafRefField] !== "")
1492+
folderNameValue = objects[fileLeafRefField] as string;
1493+
1494+
if (objects[titleField] !== undefined && objects[titleField] !== "")
1495+
folderNameValue = objects[titleField] as string;
1496+
1497+
return folderNameValue.replace(/["|*|:|<|>|?|/|\\||]/g, "_").trim();
1498+
}
14791499
}

src/controls/dynamicForm/dynamicField/DynamicField.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,6 +548,25 @@ export class DynamicField extends React.Component<IDynamicFieldProps, IDynamicFi
548548
{descriptionEl}
549549
{errorTextEl}
550550
</div>;
551+
552+
case 'File':
553+
return <div className={styles.fieldContainer}>
554+
<div className={styles.titleContainer}>
555+
<Icon className={styles.fieldIcon} iconName={customIcon ?? "Page"} />
556+
{labelEl}
557+
</div>
558+
<TextField
559+
defaultValue={defaultValue}
560+
value={valueToDisplay}
561+
placeholder={placeholder}
562+
className={styles.fieldDisplay}
563+
onChange={(e, newText) => { this.onChange(newText); }}
564+
disabled={disabled}
565+
onBlur={this.onBlur}
566+
errorMessage={errorText}
567+
/>
568+
{descriptionEl}
569+
</div>;
551570
}
552571

553572
return null;

src/services/ISPService.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ export enum IMEMode {
5959
Active = 2,
6060
Disabled = 3
6161
}
62-
export type ClientFormFieldInfoFieldType = "Attachments" | "Text" | "Number" | "Boolean" | "Choice" | "MultiChoice" | "User" | "UserMulti" | "Note" | "DateTime" | "URL" | "Lookup" | "LookupMulti" | "Hyperlink" | "Thumbnail" | "Currency" | "Location" | "TaxonomyFieldType" | "TaxonomyFieldTypeMulti";
63-
export type ClientFormFieldInfoType = "Attachments" | "Text" | "Number" | "Boolean" | "Choice" | "User" | "Note" | "DateTime" | "URL" | "Lookup" | "URL" | "Thumbnail" | "Currency" | "Location";
62+
export type ClientFormFieldInfoFieldType = "Attachments" | "Text" | "Number" | "Boolean" | "Choice" | "MultiChoice" | "User" | "UserMulti" | "Note" | "DateTime" | "URL" | "Lookup" | "LookupMulti" | "Hyperlink" | "Thumbnail" | "Currency" | "Location" | "TaxonomyFieldType" | "TaxonomyFieldTypeMulti" | "File";
63+
export type ClientFormFieldInfoType = "Attachments" | "Text" | "Number" | "Boolean" | "Choice" | "User" | "Note" | "DateTime" | "URL" | "Lookup" | "URL" | "Thumbnail" | "Currency" | "Location" | "File";
6464
export interface IClientFormBaseInfo {
6565
Id: string;
6666
Title: string;
@@ -99,6 +99,10 @@ export interface IClientFormBooleanFieldInfo extends IClientFormBaseInfo {
9999
FieldType: "Boolean";
100100
Type: "Boolean";
101101
}
102+
export interface IClientFormFileFieldInfo extends IClientFormBaseInfo {
103+
FieldType: "File";
104+
Type: "File";
105+
}
102106
export interface IClientFormTextFieldInfo extends IClientFormBaseInfo {
103107
FieldType: "Text" | "Note";
104108
Type: "Text" | "Note";
@@ -213,7 +217,7 @@ export interface IClientFormLookupFieldInfo extends IClientFormBaseLookupFieldIn
213217
LookupListUrl: string;
214218
LookupFieldName: string;
215219
}
216-
export type ClientFormFieldInfo = IClientFormTextFieldInfo | IClientFormNumberFieldInfo | IClientFormChoiceFieldInfo | IClientFormDateFieldInfo | IClientFormLookupFieldInfo | IClientFormUserFieldInfo | IClientFormTaxonomyFieldInfo | IClientFormImageFieldInfo | IClientFormHyperlinkFieldInfo | IClientFormLocationFieldInfo | IClientFormCurrencyFieldInfo | IClientFormBooleanFieldInfo;
220+
export type ClientFormFieldInfo = IClientFormTextFieldInfo | IClientFormNumberFieldInfo | IClientFormChoiceFieldInfo | IClientFormDateFieldInfo | IClientFormLookupFieldInfo | IClientFormUserFieldInfo | IClientFormTaxonomyFieldInfo | IClientFormImageFieldInfo | IClientFormHyperlinkFieldInfo | IClientFormLocationFieldInfo | IClientFormCurrencyFieldInfo | IClientFormBooleanFieldInfo | IClientFormFileFieldInfo;
217221
export interface IClientFormInfoByContentType {
218222
[contentType: string]: ClientFormFieldInfo[];
219223
}

0 commit comments

Comments
 (0)