Skip to content

Commit

Permalink
Renders file/folder name field. Closes #1683 (#1906)
Browse files Browse the repository at this point in the history
  • Loading branch information
martinlingstuyl authored Nov 27, 2024
1 parent 6abff12 commit f0b33a4
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 26 deletions.
66 changes: 43 additions & 23 deletions src/controls/dynamicForm/DynamicForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const stackTokens: IStackTokens = { childrenGap: 20 };
export class DynamicForm extends React.Component<
IDynamicFormProps,
IDynamicFormState
> {
> {
private _spService: SPservice;
private _formulaEvaluation: FormulaEvaluation;
private _customFormatter: CustomFormattingHelper;
Expand Down Expand Up @@ -594,22 +594,14 @@ export class DynamicForm extends React.Component<
else if (contentTypeId.startsWith("0x0120")) {
// We are adding a folder or a Document Set
try {
const idField = "ID";
const titleField = "Title";
const idField = "ID";
const contentTypeIdField = "ContentTypeId";

const library = await sp.web.lists.getById(listId);
const folderTitle =
objects[titleField] !== undefined && objects[titleField] !== ""
? (objects[titleField] as string).replace(
/["|*|:|<|>|?|/|\\||]/g,
"_"
) // Replace not allowed chars in folder name
: ""; // Empty string will be replaced by SPO with Folder Item ID
const newFolder = await library.rootFolder.addSubFolderUsingPath(
folderTitle
);
const library = await sp.web.lists.getById(listId);
const folderFileName = this.getFolderName(objects);
const newFolder = await library.rootFolder.addSubFolderUsingPath(folderFileName);
const fields = await newFolder.listItemAllFields();

if (fields[idField]) {
// Read the ID of the just created folder or Document Set
const folderId = fields[idField];
Expand Down Expand Up @@ -681,20 +673,20 @@ export class DynamicForm extends React.Component<
? (selectedFile.fileName as string).replace(
/["|*|:|<|>|?|/|\\||]/g,
"_"
) // Replace not allowed chars in folder name
).trim() // Replace not allowed chars in folder name and trim empty spaces at the start or end.
: ""; // Empty string will be replaced by SPO with Folder Item ID

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

if (fields[idField]) {
// Read the ID of the just created folder or Document Set
const folderId = fields[idField];
// Read the ID of the just created file
const fileId = fields[idField];

// Set the content type ID for the target item
objects[contentTypeIdField] = contentTypeId;
// Update the just created folder or Document Set
const iur = await library.items.getById(folderId).update(objects);
// Update the just created file
const iur = await library.items.getById(fileId).update(objects);
if (onSubmitted) {
onSubmitted(
iur.data,
Expand All @@ -705,7 +697,7 @@ export class DynamicForm extends React.Component<
}
} else {
throw new Error(
"Unable to read the ID of the just created folder or Document Set"
"Unable to read the ID of the just created file"
);
}
} catch (error) {
Expand Down Expand Up @@ -990,9 +982,17 @@ export class DynamicForm extends React.Component<
// Load SharePoint list item
const spList = sp.web.lists.getById(listId);
let item = null;
const isEditingItem = listItemId !== undefined && listItemId !== null && listItemId !== 0;
let etag: string | undefined = undefined;
if (listItemId !== undefined && listItemId !== null && listItemId !== 0) {
item = await spList.items.getById(listItemId).get().catch(err => this.updateFormMessages(MessageBarType.error, err.message));

if (isEditingItem) {
const spListItem = spList.items.getById(listItemId);

if (contentTypeId.startsWith("0x0120") || contentTypeId.startsWith("0x0101")) {
spListItem.select("*","FileLeafRef"); // Explainer: FileLeafRef is not loaded by default. Load it to show the file/folder name in the field.
}

item = await spListItem.get().catch(err => this.updateFormMessages(MessageBarType.error, err.message));

if (onListItemLoaded) {
await onListItemLoaded(item);
Expand Down Expand Up @@ -1288,7 +1288,7 @@ export class DynamicForm extends React.Component<
if (defaultValue !== undefined && defaultValue !== null) defaultValue = Boolean(Number(defaultValue));
if (value !== undefined && value !== null) value = Boolean(Number(value));
}

tempFields.push({
value,
newValue: undefined,
Expand Down Expand Up @@ -1476,4 +1476,24 @@ export class DynamicForm extends React.Component<
}
}

/**
* Creates a folder name based on the FileLeafRef field (if rendered) or the Title field (if rendered)
* Replaces not allowed chars in folder name and trims spaces at the start and end of the string
* Empty string will be replaced by SPO with Folder Item ID
* @param objects The object containing the field values
* @returns the folder name
*/
private getFolderName = (objects: {}): string => {
const titleField = "Title";
const fileLeafRefField = "FileLeafRef";
let folderNameValue = "";

if (objects[fileLeafRefField] !== undefined && objects[fileLeafRefField] !== "")
folderNameValue = objects[fileLeafRefField] as string;

if (objects[titleField] !== undefined && objects[titleField] !== "")
folderNameValue = objects[titleField] as string;

return folderNameValue.replace(/["|*|:|<|>|?|/|\\||]/g, "_").trim();
}
}
19 changes: 19 additions & 0 deletions src/controls/dynamicForm/dynamicField/DynamicField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,25 @@ export class DynamicField extends React.Component<IDynamicFieldProps, IDynamicFi
{descriptionEl}
{errorTextEl}
</div>;

case 'File':
return <div className={styles.fieldContainer}>
<div className={styles.titleContainer}>
<Icon className={styles.fieldIcon} iconName={customIcon ?? "Page"} />
{labelEl}
</div>
<TextField
defaultValue={defaultValue}
value={valueToDisplay}
placeholder={placeholder}
className={styles.fieldDisplay}
onChange={(e, newText) => { this.onChange(newText); }}
disabled={disabled}
onBlur={this.onBlur}
errorMessage={errorText}
/>
{descriptionEl}
</div>;
}

return null;
Expand Down
10 changes: 7 additions & 3 deletions src/services/ISPService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ export enum IMEMode {
Active = 2,
Disabled = 3
}
export type ClientFormFieldInfoFieldType = "Attachments" | "Text" | "Number" | "Boolean" | "Choice" | "MultiChoice" | "User" | "UserMulti" | "Note" | "DateTime" | "URL" | "Lookup" | "LookupMulti" | "Hyperlink" | "Thumbnail" | "Currency" | "Location" | "TaxonomyFieldType" | "TaxonomyFieldTypeMulti";
export type ClientFormFieldInfoType = "Attachments" | "Text" | "Number" | "Boolean" | "Choice" | "User" | "Note" | "DateTime" | "URL" | "Lookup" | "URL" | "Thumbnail" | "Currency" | "Location";
export type ClientFormFieldInfoFieldType = "Attachments" | "Text" | "Number" | "Boolean" | "Choice" | "MultiChoice" | "User" | "UserMulti" | "Note" | "DateTime" | "URL" | "Lookup" | "LookupMulti" | "Hyperlink" | "Thumbnail" | "Currency" | "Location" | "TaxonomyFieldType" | "TaxonomyFieldTypeMulti" | "File";
export type ClientFormFieldInfoType = "Attachments" | "Text" | "Number" | "Boolean" | "Choice" | "User" | "Note" | "DateTime" | "URL" | "Lookup" | "URL" | "Thumbnail" | "Currency" | "Location" | "File";
export interface IClientFormBaseInfo {
Id: string;
Title: string;
Expand Down Expand Up @@ -99,6 +99,10 @@ export interface IClientFormBooleanFieldInfo extends IClientFormBaseInfo {
FieldType: "Boolean";
Type: "Boolean";
}
export interface IClientFormFileFieldInfo extends IClientFormBaseInfo {
FieldType: "File";
Type: "File";
}
export interface IClientFormTextFieldInfo extends IClientFormBaseInfo {
FieldType: "Text" | "Note";
Type: "Text" | "Note";
Expand Down Expand Up @@ -213,7 +217,7 @@ export interface IClientFormLookupFieldInfo extends IClientFormBaseLookupFieldIn
LookupListUrl: string;
LookupFieldName: string;
}
export type ClientFormFieldInfo = IClientFormTextFieldInfo | IClientFormNumberFieldInfo | IClientFormChoiceFieldInfo | IClientFormDateFieldInfo | IClientFormLookupFieldInfo | IClientFormUserFieldInfo | IClientFormTaxonomyFieldInfo | IClientFormImageFieldInfo | IClientFormHyperlinkFieldInfo | IClientFormLocationFieldInfo | IClientFormCurrencyFieldInfo | IClientFormBooleanFieldInfo;
export type ClientFormFieldInfo = IClientFormTextFieldInfo | IClientFormNumberFieldInfo | IClientFormChoiceFieldInfo | IClientFormDateFieldInfo | IClientFormLookupFieldInfo | IClientFormUserFieldInfo | IClientFormTaxonomyFieldInfo | IClientFormImageFieldInfo | IClientFormHyperlinkFieldInfo | IClientFormLocationFieldInfo | IClientFormCurrencyFieldInfo | IClientFormBooleanFieldInfo | IClientFormFileFieldInfo;
export interface IClientFormInfoByContentType {
[contentType: string]: ClientFormFieldInfo[];
}
Expand Down

0 comments on commit f0b33a4

Please sign in to comment.