Search code examples
angularfrontendangular5popoverngx-bootstrap

Ngx Bootstrap Popover to display only one popover at a time


I'm using angular to make a popover only appear once at a time this is the plunker I'm using angular5 with Ngx-Bootstrap.

Because I have multiple popover that I need in my project however the popover should only close if we press the (x) at the top right.

The toggle currently works with 2 popover provided if you press the toggle button first and then the press "Pop over with title and a x button!" My objective is to disable the other popover, if a popover is currently open.

Example there is 4 popover, popover 1-4. if popover 1 is open no other popover can be open.

The other popover can be open provided we close popover 1.

<div>
  <ng-template #popoverContent3>
    <div style="font-size:18px; font-family:'Times New Roman'; font-weight:bold;">
      <p>this is a title...
      <button type="button" (click)='pop2.hide()' class="close" aria-label="Close">
      <span aria-hidden="true">&times;</span>
      </button>
      </p>
    </div>
    <div>
     <p>The best looking pop over, with a TITLE!</p>  
    </div>
  </ng-template>
  <br><br><br><br><br><br><br>
  <a  [popover]="popoverContent3" #pop2="bs-popover" (click)="isOpen = !isOpen" [outsideClick]="false"  placement="right">
   Pop over with title and a x button!
    </a>
</div>
<p>
  <span popover="Hello there! I was triggered by input"
        triggers=""  [isOpen]="isOpen">
  This text has attached popover
  </span>
</p>
<button type="button" class="btn btn-primary"
        (click)="isOpen = !isOpen">
  Toggle
</button>


Solution

  • If you want to see only one opened popover at a time, it can be achieved via ViewChildren and onShown.

    The algorithm is something like this:

    1) Listen to all onShown events

    2) Close all other popovers

    @ViewChildren(PopoverDirective) popovers: QueryList<PopoverDirective>;
    
    ngAfterViewInit() {
      this.popovers.forEach((popover: PopoverDirective) => {
        popover.onShown.subscribe(() => {
          this.popovers
          .filter(p => p !== popover)
          .forEach(p => p.hide());
        });
      });
    }
    

    Example - https://stackblitz.com/edit/angular-zkw9mz?file=app%2Ffour-directions.ts