We support #BlackLivesMatters !
If you support us then follow us by clicking here and following us!

How to create modal pop up in Angular without bootstrap or any npm modal dependency?

Get support on Angular & Typescript related technology.
Post Reply
admin
Site Admin
Posts: 44

How to create modal pop up in Angular without bootstrap or any npm modal dependency?

Post by admin » Sun Sep 08, 2019 6:54 pm

Image


Image

Firstly create a modal component:

src/app/_component/modal.component.html

Code: Select all

<div class="modal-popup">
    <div class="modal-popup-body">
        <ng-content></ng-content>
    </div>
</div>
<div class="modal-popup-background"></div>
src/app/_component/modal.component.ts

Code: Select all

import { Component, ElementRef, Input, OnInit, OnDestroy } from '@angular/core';

import { ModalService } from '../_services/modal.service';

@Component({
    selector: 'modal-popup',
    templateUrl: './modal.component.html'
})
export class ModalComponent implements OnInit, OnDestroy {
    @Input() id: string;
    private element: any;

    constructor(private modalService: ModalService, private el: ElementRef) {
        this.element = el.nativeElement;
    }

    ngOnInit(): void {
        let modal = this;

        // ensure id attribute exists
        if (!this.id) {
            console.error('modal must have an id');
            return;
        }

        // move element to bottom of page (just before </body>) so it can be displayed above everything else
        document.body.appendChild(this.element);

        // close modal on background click
        this.element.addEventListener('click', function (e: any) {
            if (e.target.className === 'modal-popup') {
                modal.close();
            }
        });

        // add self (this modal instance) to the modal service so it's accessible from controllers
        this.modalService.add(this);
    }

    // remove self from modal service when directive is destroyed
    ngOnDestroy(): void {
        this.modalService.remove(this.id);
        this.element.remove();
    }

    // open modal
    open(): void {
        this.element.style.display = 'block';
        document.body.classList.add('modal-popup-open');
        console.log('modal open called');
    }

    // close modal
    close(): void {
        this.element.style.display = 'none';
        document.body.classList.remove('modal-popup-open');
        console.log('modal close called');
    }
}    
As you can see in above code we are calling modal service, so let's create the modal service:
src/app/_services/modal.service.ts

Code: Select all

import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class ModalService {
    private modals: any[] = [];

    add(modal: any) {
        // add modal to array of active modals
        this.modals.push(modal);
    }

    remove(id: string) {
        // remove modal from array of active modals
        this.modals = this.modals.filter(x => x.id !== id);
    }

    open(id: string) {
        // open modal specified by id
        let modal: any = this.modals.filter(x => x.id === id)[0];
        modal.open();
    }

    close(id: string) {
        // close modal specified by id
        let modal: any = this.modals.filter(x => x.id === id)[0];
        modal.close();
    }
}
Note : I've used _component folder for component, _services folder for services, you can choose as per your choice for the path or folder name but make sure to configure the imports as per your choice of folder or path

Now let's create about page, for example I want to have a button on about page and when that button will be clicked modal pop up should be open, let's create about component:

src/app/about/about.component.html

Code: Select all

<p>about works!</p>
<div>
    <button (click)="openModal('modal1')">Open Modal 1</button>
</div>

<modal-popup id="modal1">
    <h1>A Custom Modal!</h1>
    <p>This is dummy text</p>
    <button (click)="closeModal('modal1');">Close</button>
</modal-popup>
Here you can create as many as modal pop up and buttons to open it. You need to make sure the function has parameter this should be mapped to decide which pop up should be open. Here you can see modal1 button will be clicked and modal1 modal will be open.Similarly, you can create more buttons and more modals by any name or like modal2, modal3.

src/app/about/about.component.ts

Code: Select all

import { Component, OnInit } from '@angular/core';
import { ModalService } from '../_services/modal.service';

@Component({
  selector: 'app-about',
  templateUrl: './about.component.html',
  styleUrls: ['./about.component.scss']
})
export class AboutComponent implements OnInit {

  constructor(private modalService: ModalService) {
  } 

  ngOnInit() {
      
  }

  openModal(id: string) {
      this.modalService.open(id);
  }

  closeModal(id: string) {
      this.modalService.close(id);
  }

}

Now modal component and styles are ready with calling it inside about page. But we also need to style modal pop up so that by default it would be hidden and on button click it will be open. Also we will do some basic styles but you can enhance as per your requirements, my basic target is to explain how to create modal pop up in angular, not about how to style modal pop up :lol:

open you style.scss and paste below code:

Code: Select all

/* You can add global styles to this file, and also import other style files */
/* MODAL STYLES
-------------------------------*/
modal-popup {
    /* modals are hidden by default */
    display: none;

    .modal-popup {
        /* modal container fixed across whole screen */
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        max-width:400px;
        min-width:300px;
        width:50%;
        margin:auto;
        min-height:300px;

        /* z-index must be higher than .modal-popup-background */
        z-index: 1000;
        
        /* enables scrolling for tall modals */
        overflow: auto;

        .modal-popup-body {
            padding: 20px;
            background: #fff;

            /* margin exposes part of the modal background */
            margin: 40px;
        }
    }

    .modal-popup-background {
        /* modal background fixed across whole screen */
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;

        /* semi-transparent black  */
        background-color: #000;
        opacity: 0.75;
        z-index: 900;
    }
}

body.modal-popup-open {
    /* body overflow is hidden to hide main scrollbar when modal window is open */
    overflow: hidden;
}

Now you modal pop needs to be configured in app.module.ts like:

Code: Select all

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';

import { ModalComponent } from './_components/modal.component';

@NgModule({
  declarations: [
    AppComponent,
    AboutComponent,
    ModalComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    FormsModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Extra Tip:
app.routing.module.ts
As you noticed I have created about page and using routing, you can configure routing as mentioned below:

Code: Select all


import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AppComponent } from './app.component';
import { AboutComponent } from './about/about.component';


const routes: Routes = [
  {path:'', component:AppComponent},
  {path:'about', component:AboutComponent}
  
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Demo - download this zip file and run -

Code: Select all

npm install
then

Code: Select all

ng serve
Source Code :
modal-pop-angular.zip
You do not have the required permissions to view the files attached to this post.

anono4
Posts: 0

Post by anono4 » Sun Sep 08, 2019 8:16 pm

Nice

admin
Site Admin
Posts: 44

Post by admin » Sun Sep 08, 2019 8:18 pm

anono4 wrote:
Sun Sep 08, 2019 8:16 pm
Nice
Thanks

Post Reply