0

The HTML of my Angular application has a modal box which pops on application start up.

<div >
  <div class="css-grid-container" *ngIf="!loading">
    <app-nav-component></app-nav-component>
    <app-content-component></app-content-component>

    <app-footer-component></app-footer-component>
  </div>
  <app-progress-bar></app-progress-bar>

  <app-dialog-box #dialogBox [dialogMessage]="" [dialogID]="'appDialog'" [dialogContext]=""></app-dialog-box>
</div>

app-dialog-box is an Angular component and it shows/hides Bootstrap's modal using JavaScript API modal('show') and modal('hide').

<div #modal class="modal fade" tabindex="-1" role="dialog" id={{dialogID}}>
  <div class="modal-dialog modal-dialog-centered" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">CodingJedi</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close" (click)="dialogHide()">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body">
        <p>{{dialogMessage}}</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal" (click)="dialogHide()">Close</button>
      </div>
    </div>
  </div>
</div>

Code to show and hide the modal

 $(this.dialogRef.nativeElement).modal('show');

and

$(this.dialogRef.nativeElement).modal('hide');

My issue is that Bootstrap seem to add <div class="modal-backdrop fade"></div> in the html which takes up the entire page and makes other components unclickable. See the pic below. You'll notice that the div takes the entire space even when the modal is not visible because after clicking close on the modal, it is hidden using $(this.dialogRef.nativeElement).modal('hide');

enter image description here

It is interesting to notice that the modal div is within the app-dialog element but the modal background div is not at the same level! (see pic 2) What could I do to solve my issue?

enter image description here

UPDATE

Still not able to find the answer but the issue certainly seems to be with z-index value. The modal box is created within the app-dialog-box within app-root

<app-root>
<div>
  <!-- the below div is a grid container - parent. All elements one element below this are its children.
  Elements under children are not grid children -->
  <div class="css-grid-container" *ngIf="!loading">
    <app-nav-component></app-nav-component><!-- grid child -->
    <!--this component has router-outlet to put new componnents in it -->
    <!-- the components which target this router-outlet could be containers-->
    <app-content-component></app-content-component><!-- grid child -->

    <app-footer-component></app-footer-component><!-- grid child -->

  <app-progress-bar></app-progress-bar><!-- not a grid child -->  <!--this is positioned using absolute positioning and thus will not affect positions of others -->
  <app-dialog-box #dialogBox [dialogMessage]="" [dialogID]="'appDialog'" [dialogContext]=""></app-dialog-box>
  </div>
</div>
<app-root>

But Bootstrap adds the <div class="modal-backdrop fade show"></div> at the same level as app-root and not inside app-root. As app-root's z-index is lower than that of <div class="modal-backdrop fade show"></div>, the backdrop is always on top. As explained in Bootstrap Modal sitting behind backdrop

" Although the z-index of the .modal is higher than that of the .modal-backdrop, if .modal is in a parent div, z-index will not take priority and .modal-backdrop will have higher z-index`. This is because if the parent has lower z-index than the .modal-backdrop, everything in it will be behind the modal, irrespective of any z-index given to the children."

Manu Chadha
  • 15,555
  • 19
  • 91
  • 184
  • set z-index to 10000 or above and check if the problem is still there – Satya Sep 13 '18 at 04:09
  • thanks but it doesn't :( – Manu Chadha Sep 13 '18 at 04:19
  • https://stackoverflow.com/questions/11519660/twitter-bootstrap-modal-backdrop-doesnt-disappear – SubSul Sep 13 '18 at 04:46
  • Thanks @SunSul. The link has several suggestions but it isn't clear which one is genuine and which is a hack! I would rather prefer an explanation why the problem exists as this seem to be very basic functionality of modals. – Manu Chadha Sep 13 '18 at 16:32
  • @SubSul - it seems the solution described in the link you provided is my best option for the moment! I'll research a bit more though – Manu Chadha Sep 14 '18 at 07:39
  • 1
    @Satya - my temporary solution is based on your suggestion as well. On close of the dialog box, the component emits an event and when I handle that event, I set the following properties in the top most div (id = top-div) `$('#top-div').css('z-index',10000); $('#top-div').css('width','100%'); $('#top-div').css('position','absolute');` – Manu Chadha Sep 14 '18 at 07:42

1 Answers1

0

The issue was something entirely different! I had added the logic to show the modal in ngAfterViewChecked. This function gets called repeatedly by Angular (see Lifecycle hook in Angular). It seems that due to repeated execution of this function, Bootstrap was adding multiple `` but was removing only one leaving another one to cover the page. I moved the logic to ngAfterViewInit which is called once and it solved my issue.

ngAfterViewChecked(){}

  {

    setTimeout(()=>this.isSignupProcess()); //moved this to ngViewInit

  }

See Getting different behaviour of bootstrap for almost identical html. I created another problem, it has a video which explains the behaviour.

The way I debugged it was interesting. I added few console.log in bootstrap.js and observed that the messages I had added were being printed repeatedly.

Manu Chadha
  • 15,555
  • 19
  • 91
  • 184