How to create a custom styled file upload in angular 9
29.04.2021The basic HTML file upload

<h1>Basic HTML File Upload</h1> <input type="file">
How change the style of this element?
npm i ng2-file-upload@latest --save
import { FileUploadModule } from 'ng2-file-upload';
imports: [
FileUploadModule, ...
], imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
FormsModule,
ReactiveFormsModule,
MatToolbarModule,
MatButtonModule,
FileUploadModule
],
Implement the client part
<div id="direct_upload" ng2FileDrop [uploader]="uploader" (fileOver)="fileOverBase($event)" [ngClass]="{ 'nv-file-over': hasBaseDropZoneOver }">
<h1>Upload File</h1>
<p>
Please select an image. You can also drag and drop an image file into the
dashed area.
</p>
<form [formGroup]="imageForm">
<div>
<button type="button" mat-raised-button (click)="fileInput.click()">
Choose File
</button>
<input hidden [uploader]="uploader" (change)="fileInput.value = ''" ng2FileSelect #fileInput type="file" id="file" multiple />
</div>
</form>
</div>import { Component, OnInit, Input } from "@angular/core";
import { FormGroup, FormBuilder } from "@angular/forms";
import { FileUploader } from "ng2-file-upload";
@Component({
selector: "app-file-upload",
templateUrl: "./file-upload.component.html",
styleUrls: ["./file-upload.component.scss"]
})
export class FileUploadComponent implements OnInit {
responses: any[];
hasBaseDropZoneOver = false;
uploader: FileUploader;
imageForm: FormGroup;
constructor(private formBuilder: FormBuilder) {
this.imageForm = this.formBuilder.group({});
}
ngOnInit(): void {}
fileOverBase(e: any): void {
this.hasBaseDropZoneOver = e;
}
}
#direct_upload {
padding: 20px;
box-sizing: content-box;
border-top: 1px solid #ccc;
border-bottom: 1px solid #ccc;
border: 4px dashed #ccc;
} Handling file upload
ngOnInit(): void {
this.initializeUploader();
}
initializeUploader(): void {
//Create the file uploader, wire it to upload to your account
const uploaderOptions: FileUploaderOptions = {
url: 'http://localhost:59976/files',
// Upload files automatically upon addition to upload queue
autoUpload: true,
// Use xhrTransport in favor of iframeTransport
isHTML5: true,
// Calculate progress independently for each uploaded file
removeAfterUpload: true,
// XHR request headers
headers: [
{
name: "X-Requested-With",
value: "XMLHttpRequest"
},
{
name: "Access-Control-Allow-Origin",
value: "http://localhost:4200"
}
]
};
this.uploader = new FileUploader(uploaderOptions);
this.uploader.onBuildItemForm = (fileItem: any, form: FormData): any => {
return { fileItem, form };
};
}[Route("[controller]")]
[ApiController]
public class FilesController : ControllerBase
{
[HttpPost()]
public async Task<IActionResult> OnPostUploadAsync()
{
var files = Request.Form.Files;
long size = files.Sum(f => f.Length);
foreach (var formFile in files)
{
if (formFile.Length > 0)
{
var filePath = Path.GetTempFileName();
}
}
return Ok(new { count = files.Count, size });
}
}public void ConfigureServices(IServiceCollection services)
{
services.AddCors(c =>
c.AddPolicy("DemoAPIPolicy", policy => policy.AllowAnyHeader().WithMethods("POST", "OPTIONS").WithOrigins("http://localhost:4200").AllowCredentials()));
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors("DemoAPIPolicy");
...
}Handle upload status
<h2>Upload Status</h2>
<div class="file" *ngFor="let response of responses; let i = index">
<h3>{{ response.file.name }}</h3>
<div class="status" *ngIf="response.progress < 100">
Uploading... {{ response.progress }}%
<div *ngIf="!response.status">In progress</div>
<div class="status-code" *ngIf="response.status">
Upload completed with status code {{ response.status }}
</div>
</div>
<div class="progress-container">
<div class="progress-bar">
<div
class="progress"
role="progressbar"
[style.width.%]="response.progress"
></div>
</div>
</div>
<div class="info">
<div *ngIf="response.progress && response.progress < 100">
Still working...
</div>
<div *ngIf="(response.progress && response.progress == 100)">
Upload was successful
</div>
<div *ngIf="response.status && response.status !== 200">
Ooops something went wrong
</div>
</div>
</div>this.uploader.onProgressItem = (fileItem: any, progress: any) =>
this.upsertResponse({
file: fileItem.file,
progress,
data: {},
});
}
upsertResponse = (fileItem: any) => {
const existingId: any = this.responses.reduce(
(prev: any, current: any, index: number) => {
if (
current.file.name === fileItem.file.name &&
!current.status
) {
return index;
}
return prev;
},
-1
);
if (existingId > -1) {
this.responses[existingId] = Object.assign(
this.responses[existingId],
fileItem
);
} else {
this.responses.push(fileItem);
}
};constructor(private formBuilder: FormBuilder) {
this.imageForm = this.formBuilder.group({});
this.responses = [];
}.progress-container {
width: 100vw;
height: 12px;
position: relative;
.progress-bar {
width: 100px;
height: 12px;
position: absolute;
top: 50%;
right: 50%;
transform: translate(50%, -50%);
.progress {
height: 12px;
background-color: #b5d3e7;
width: 0;
}
}
}
