Skip to content

Repository files navigation

The AttachmentControl component is a PowerApps Component Framework (PCF) control designed for handling file uploads. It supports multiple file uploads, drag-and-drop functionality, file previews, and base64 encoding for easy data handling.

Features Supports multiple file uploads

Drag-and-drop functionality

File type and size validation

Base64 conversion for uploaded files

Preview support for images, PDFs, and text files

File removal functionality

Code Breakdown Importing Dependencies import { IInputs, IOutputs } from "./generated/ManifestTypes"; The component imports IInputs and IOutputs from the generated manifest file to define the control's input and output types.

Component Definition export class AttachmentControl implements ComponentFramework.StandardControl<IInputs, IOutputs> { Defines the AttachmentControl class, implementing the StandardControl interface from PCF.

Class Variables private container: HTMLDivElement; private fileInput: HTMLInputElement; private previewContainer: HTMLDivElement; private notifyOutputChanged: () => void; private fileBase64List: { name: string; data: string }[] = []; // List of uploaded files (name + base64)

private readonly maxFileSizeMB: number = 5; private readonly acceptedFileTypes: string[] = ["image/", "application/pdf", "text/"]; container: Holds the UI elements.

fileInput: Hidden file input for selecting files manually.

previewContainer: Displays uploaded file previews.

notifyOutputChanged: Callback function to notify PowerApps about data updates.

fileBase64List: Stores uploaded files with their names and base64-encoded content.

maxFileSizeMB: Defines the maximum allowed file size (5MB).

acceptedFileTypes: Specifies allowed file types (images, PDFs, and text files).

init Method public init( context: ComponentFramework.Context, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container: HTMLDivElement ): void { this.container = container; this.notifyOutputChanged = notifyOutputChanged; this.createUI(); } Initializes the component.

Stores the container and notifyOutputChanged reference.

Calls createUI to render UI elements.

UI Creation File Input (Hidden) this.fileInput = document.createElement("input"); this.fileInput.type = "file"; this.fileInput.accept = this.acceptedFileTypes.join(","); this.fileInput.style.display = "none"; this.fileInput.multiple = true; this.fileInput.onchange = this.handleFileUpload.bind(this); Creates a hidden element for file selection.

Supports multiple files.

Triggers handleFileUpload when files are selected.

Upload Icon const uploadIcon = this.createUploadIcon(); uploadIcon.onclick = () => this.fileInput.click(); Creates an upload button that triggers the file input on click.

Drag-and-Drop Area const dragDropArea = this.createDragDropArea(); Initializes the drag-and-drop file upload area.

Preview Container this.previewContainer = document.createElement("div"); this.previewContainer.style.border = "1px solid #ddd"; this.previewContainer.style.padding = "10px"; this.previewContainer.style.marginTop = "10px"; this.previewContainer.textContent = "No files uploaded."; Creates a container to display uploaded files.

Handling File Uploads handleFileUpload private handleFileUpload(event: Event): void { const files = (event.target as HTMLInputElement).files; if (files) { Array.from(files).forEach((file) => this.processFile(file)); } } Retrieves selected files and processes each one.

processFile private processFile(file: File): void { if (!this.validateFile(file)) { return; }

const reader = new FileReader();
reader.onload = () => {
    const fileData = reader.result as string;
    this.fileBase64List.push({ name: file.name, data: fileData });
    this.notifyOutputChanged();
    this.displayPreviews();
};
reader.readAsDataURL(file);

} Validates file type and size.

Reads the file and converts it to base64.

Adds file to fileBase64List.

Updates the UI.

File Validation private validateFile(file: File): boolean { const maxSizeBytes = this.maxFileSizeMB * 1024 * 1024; if (file.size > maxSizeBytes) { alert(File "${file.name}" exceeds the ${this.maxFileSizeMB} MB size limit.); return false; }

if (!this.acceptedFileTypes.some((type) => file.type.startsWith(type))) {
    alert(`Unsupported file type for "${file.name}".`);
    return false;
}
return true;

} Ensures the file does not exceed the size limit.

Checks that the file type is supported.

Displaying Previews private displayPreviews(): void { this.previewContainer.innerHTML = "";

if (this.fileBase64List.length === 0) {
    this.previewContainer.textContent = "No files uploaded.";
    return;
}

this.fileBase64List.forEach((file, index) => {
    const fileContainer = document.createElement("div");
    fileContainer.style.marginBottom = "10px";

    const fileLabel = document.createElement("p");
    fileLabel.textContent = `File ${index + 1}: ${file.name}`;
    fileContainer.appendChild(fileLabel);

    if (file.data.startsWith("data:image/")) {
        const img = document.createElement("img");
        img.src = file.data;
        img.style.maxWidth = "100%";
        fileContainer.appendChild(img);
    }
    this.previewContainer.appendChild(fileContainer);
});

} Clears previous previews.

Displays uploaded files with appropriate previews (images, text, PDF previews).

Removing Files private removeFile(index: number): void { this.fileBase64List.splice(index, 1); this.notifyOutputChanged(); this.displayPreviews(); } Removes a file from the list.

Updates the UI.

Output Handling public getOutputs(): IOutputs { return { uploadedFile: JSON.stringify(this.fileBase64List) }; } Returns the list of uploaded files as a JSON string.

Cleanup public destroy(): void { // Cleanup if necessary } Placeholder for cleanup logic.

Conclusion This AttachmentControl PCF component provides a robust file upload solution with UI enhancements, validation, and base64 conversion. It is well-suited for PowerApps applications requiring file handling capabilities.

About

No description, website, or topics provided.

Resources

Stars

3 stars

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages