Then we need to add the ReactiveFormsModule into our App Module.
Like this;
import { NgModule } from '@angular/core';
import { ReactiveFormsModule } from '@angular/forms';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
declarations: [
AddUserComponent,
],
imports: [
CommonModule,
ReactiveFormsModule,
]
})
export class AdminConfigModule { }
Now we create the Html form with input fields with angular forms.
We bind to the FormGroup in the appComponent.html file using [formGroup] directive.
appComponent.html
<div class="container">
<form [formGroup]="Userform">
<div class="container-group">
<div class="text-center">
<div class="text-center">
<img id="image" class="profile-image" src="" />
</div>
<label (click)="fileInput.click()" for="fileInput" type="button" class="brows-button cursor-pointer bg-white font-medium">
<i class="fa-light fa-camera"></i>
Browse Photo
</label>
<div class="brows-label text-center mt-1">Click to add profile picture</div>
<input formControlName="userPhoto" name="photo" id="imageUploadProfile" #fileInput accept="image/*" (change)="uploadFile($event)" class="hidden" type="file" >
</div>
</div>
</form>
</div>
Now, open app/app.component.ts, we’re import necessary library first, because the app component Form Validation will be built with the @angular/forms and @angular/core
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup } from '@angular/forms';
....
constructor(private formBuilder: FormBuilder) {}
Here, We use Angular FormBuilder to create a FormGroup and create a getter formCheck() function to access form controls (form.controls) from the template.
ngOnInit(): void {
this.Userform = this.formBuilder.group({
userPhoto: [''],
});
}
// ****** getter formCheck() function ******
get formCheck(): { [key: string]: AbstractControl } {
return this.Userform.controls;
}
Now, set default user avatar image
aadd-user.component.ts
imageUrl: any = '../assets/images/user.jpg';
add-user.component.html
<img id="image" class="profile-image" src="{{imageUrl}}" />
Now we will set the functionality of the upload and preview image, For that we have to import two things : 1) ChangeDetectorRef and 2) ElementRef
And, ChangeDetectorRef put it use to inject dependencies into the component class
import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { AbstractControl, FormBuilder, FormGroup } from '@angular/forms';
........
constructor(private formBuilder: FormBuilder, private cdr: ChangeDetectorRef) {}
Before writing any code, let's see what ElementRef and ChangeDetectorRef is and why it's used in Angular.
ElementRef is a backed by a render-specific element. In the browser, this is usually a DOM element. By providing the nativeElement object which exposes all the methods and properties of the native elements.
According to the official docs
ChangeDetectorRef is Base class that provides change detection functionality. Use the methods to add and remove views from the tree, initiate change-detection functionality work.
More details official docs
// ***** UPLOAD AND PREVIEW IMAGE *****
@ViewChild('fileInput') el: ElementRef | undefined;
editFile: boolean = true;
removeUpload: boolean = false;
uploadFile(event:any) {
let reader = new FileReader(); // HTML5 FileReader API
let file = event.target.files[0];
if (event.target.files && event.target.files[0]) {
reader.readAsDataURL(file);
// When file uploads set it to file formcontrol
reader.onload = () => {
this.imageUrl = reader.result;
this.Userform.patchValue({
file: reader.result
});
this.editFile = false;
this.removeUpload = true;
}
// ChangeDetectorRef since file is loading outside the zone
this.cdr.markForCheck();
}
}
We need to add some CSS to make the HTML more creative.
img {
display: block;
vertical-align: middle;
}
.container-group {
max-width: 500px;
margin: auto;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
.hidden {
display: none;
}
.profile-image {
width: 8rem;
object-fit: cover;
height: 8rem;
border-radius: 9999px;
display: block;
vertical-align: middle;
border: 2px solid #fff;
margin: auto;
margin-bottom: 20px;
}
.brows-label {
color: rgba(160,174,192, 1);
font-size: 12px;
width: 12rem;
margin: auto;
}
.brows-button {
justify-content: space-between;
cursor: pointer;
align-items: center;
border-width: 1px;
padding-top: 0.5rem;
padding-bottom: 0.5rem;
padding-left: 1rem;
padding-right: 1rem;
border-radius: 0.5rem;
text-align: left;
color: #718096;
color: rgba(113,128,150,1);
font-weight: 500;
}
.profile-icon {
display: inline-flex;
flex-shrink: 0;
width: 1.5rem;
height: 1.5rem;
margin-top: -0.25rem;
margin-right: 0.25rem;
}
Now see the final result,
0 Comments