Angular Reusable Loading Component Using Directive

Sometimes, we need reusable components which you develop once and use anywhere without any additional change.
 
Let's start. We will create a common directive first with @Input property to receive true or false conditionally to add and remove the CSS class accordingly, as we use the directive to extend the HTML functionality.
 
Step 1
 
Create a Directive with Angular CLI (ng g d dir_name),
  1. import { Directive, ElementRef, Input, OnChanges, Renderer2 } from '@angular/core';  
  2. import { LoaderSyncService } from './loader-sync.service';  
  3.   
  4. @Directive({  
  5.   // tslint:disable-next-line:directive-selector  
  6.   selector: '[drloader]'  
  7. })  
  8. export class LoaderDirective implements OnChanges {  
  9.     @Input('drloader') drloader: boolean;  
  10.     constructor(private el: ElementRef, private loader: LoaderSyncService, private renderer: Renderer2) { }  
  11.   
  12.         ngOnChanges() {  
  13.                if (this.drloader) {  
  14.                 const parent = this.renderer.parentNode(this.el.nativeElement);  
  15.                 const div = this.renderer.createElement('div');  
  16.                 this.renderer.addClass(div, 'divshow');  
  17.                 // tslint:disable-next-line:label-position  
  18.                 const ispan: Element = this.renderer.createElement('i');  
  19.                 this.renderer.addClass(ispan, 'fa');  
  20.                 this.renderer.addClass(ispan, 'fa-spinner');  
  21.                 this.renderer.addClass(ispan, 'fa-spin');  
  22.                 this.renderer.addClass(ispan, 'center');  
  23.                 this.renderer.addClass(ispan, 'loder-icon');  
  24.                 this.el.nativeElement.parentElement.classList.add('positionReletive');  
  25.                 const finalhtml = this.renderer.appendChild(div, ispan);  
  26.                 this.renderer.appendChild(this.el.nativeElement, div);  
  27.             } else {  
  28.                    Array.from(this.el.nativeElement.children).forEach(child => {  
  29.                     if (child['className'] === 'divshow') {  
  30.                                     this.renderer.removeChild(this.el.nativeElement, child);  
  31.                     }  
  32.                 });  
  33.             }  
  34.         }  
  35. }  
Step 2
 
Add CSS class definition which will help us to use it in any size HTML element,
  1. .center {  
  2.     marginauto;  
  3.     margin-left:  680px;  
  4. }  
  5.   
  6. .loder-icon {  
  7.     positionabsolute;  
  8.     font-size54px;  
  9.     colorred;  
  10.     left: 50%;  
  11.     top:50%;  
  12.     margin-top-20px;  
  13.     margin-left-20px;  
  14. }  
  15.   
  16. .positionReletive {  
  17.       width:100%;position:relative;  
  18. }  
  19.   
  20. .divshow {  
  21.     displayblock;  
  22. }  
  23.   
  24. .divhide {  
  25.     displaynone;  
  26. }  

Step 3

Use the custom directive in to HTML with isLoader=true and false below,
  1. <div style="width:100%;" class="bd">  
  2.            <h3 [drloader]="isLoader">My content with width:100% :     
  3.                {{tempData | json}}  
  4.           </h3>  
  5. </div>  
  6.   
  7. <div style="width:50%;" class="bd">  
  8.            <h3 [drloader]="isLoader">My content with width:50% :     
  9.                {{tempData | json}}  
  10.           </h3>  
  11. </div>  
  12.   
  13. <div style="width:25%;" class="bd">  
  14.            <h3 [drloader]="isLoader">My content :     
  15.                {{tempData | json}}  
  16.            </h3>  
  17. </div>  
Step 4
 
Let's check the output with 100% and 50% width div's. No matter what the div size is the loader icon will display at the center of div content.
 
Angular Reusable Loading Component Using Directive