Solution 1 :

Your overlay div should close on top. Try this

<div id="overlay" (click)="closeThis($event)" *ngIf="open" class="overlay"></div>

<div class="bg-modal" id="bg-modal">
  <div class="modal-content" id="openModal">
    <div class="col-12">
      <div class="close" id="close" (click)="closeThis($event)">+</div>
      <p class="title">Modal</p>
      <hr>
    </div>
    <div class="col-12">
      <div class="contents">
        <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequ.</p>
      </div>
    </div>
    <div class="confirm" id="confirm" (click)="confirmModal()">OK</div>
  </div>
</div>



.overlay {
  position: fixed;
  width: 100vw;
  height: 100vh;
  left: 0;
  top: 0;
  background: rgba(0,0,0,0.5);
}

.bg-modal{
  position: fixed;
  z-index: 10
}

Solution 2 :

Have a overlay around your modal like :-

<button (click)="openModalBtn()" id="bt">
  {{buttonName}}
</button>
<div id="overlay" (click)="closeThis($event)" *ngIf="open" class="overlay">
<div class="bg-modal" id="bg-modal">
      <div class="modal-content" id="openModal">
        <div class="col-12">
          <div class="close" id="close" (click)="closeThis($event)">+</div>
          <p class="title">Modal</p>
          <hr>
        </div>
        <div class="col-12">
          <div class="contents">
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequ.</p>
          </div>
        </div>
        <div class="confirm" id="confirm" (click)="confirmModal()">OK</div>
      </div>
    </div>
</div>

And Css :-

.overlay {
  position: fixed;
  width: 100vw;
  height: 100vh;
  left: 0;
  top: 0;
  background: transparent;
}

TS :-

public closeThis(event) {
   if(event.target.id==='close' || event.target.id ==='overlay') {
     this.open= false;
   }
}

Solution 3 :

Listen to window click event and take a Viewchild reference to your modal. On window click check if your modal contains the target element. If it does not contain, close the modal.

@ViewChild("<modal-referece>",{static:false}) modalRef:ElementRef;

@HostListener('window:click', ['$event.target'])
onClick(elem) {
    let element: HTMLElement = elem as HTMLElement;
    if(!(this.modalRef.nativeElement as HTMLElement).contains(element)){
       //close modal
    }
}

Solution 4 :

Try another way to listen to the click event:

import { Component, OnInit, ElementRef, HostListener, AfterViewInit } from '@angular/core';

@Component({
    selector: 'app-modal',
    templateUrl: './modal.component.html',
    styleUrls: ['./modal.component.css']
})
export class ModalComponent implements OnInit, AfterViewInit {

    public open: boolean = false;
    public buttonName: any = 'Open';

    modalElement: any;

    constructor(private elementRef: ElementRef) { }

    @HostListener('document:click', ['$event'])
    clickout(event) {
        if (!this.elementRef.nativeElement.contains(event.target)) {
            this.closeAll();
        }
    }

    ngAfterViewInit() {
        this.modalElement = this.elementRef.nativeElement.querySelector('#bg-modal');
    }

    ngOnInit() {
    }

    openModalBtn() {
        this.open = !this.open;
    }

    public closeThis(): void {
        this.open = false;
    }

    public confirmModal(): void {
        this.open = false;
    }

    public closeAll(): void {
        this.open = false;
    }
}

Problem :

I have made an modal using html, css and typescript in Angular 4.

The modal is working, opening & closing, but I can’t seem to get the click on the background to also close the modal, for now it’s just working on the button X for closing.

The code is:

<button (click)="openModalBtn()" id="bt">
  {{buttonName}}
</button>

<div class="bg-modal" id="bg-modal" *ngIf="open">
      <div class="modal-content" id="openModal">
        <div class="col-12">
          <div class="close" id="close" (click)="closeThis()">+</div>
          <p class="title">Modal</p>
          <hr>
        </div>
        <div class="col-12">
          <div class="contents">
            <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequ.</p>
          </div>
        </div>
        <div class="confirm" id="confirm" (click)="confirmModal()">OK</div>
      </div>
    </div>

&

  public open: boolean = false;
    public buttonName: any = 'Open';


      ngOnInit() {
    }

    openModalBtn() {
        this.open = !this.open;
    }

    public closeThis(): void {
        this.open = false;
    }

     public confirmModal(): void {
        this.open = false;
    }

    public closeAll(): void{
         this.open = false;
    }

I tried putting it all in one more div element and it works for closing by clicking anywhere but that means that clicking anywhere inside the modal closes it also.

Help?

enter image description here

Comments

Comment posted by kaja111

thanks for your reply, I already tried it like this (without the css) and it closes with clicking anywhere outside the modal but the problem is that it closes even if clicking anywhere inside the modal

Comment posted by kaja111

Doesn’t work, with this solution it only closes on the X button :/ I added a picture of the modal so maybe that helps

Comment posted by Aakash Garg

changed css above, try with that. if still doesn’t work try removing overlay div. give overlay id to div with class bg-modal and call closeThis on div with class bg-modal like i called on overlay div.

By