0

I'm following the solution for a modal dialog and the comments from below. Since they are so many I decided to make a new q for the sake of clarity I have the adapted version:

import { Component, ViewChild } from '@angular/core';
import { ModalDirective } from 'ngx-bootstrap';

@Component({
  selector: 'app-modal',
  template: `
  <div #myModal class="modal fade"   tabindex="-1" [ngClass]="{'in': visibleAnimate}"
       [ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}">
    <div class="modal-dialog">
      <div class="modal-content" (click)="$event.stopPropagation();">
        <div class="modal-header">
          <ng-content select=".app-modal-header"></ng-content>
        </div>
        <div class="modal-body">
          <ng-content select=".app-modal-body"></ng-content>
        </div>
        <div class="modal-footer">
          <ng-content select=".app-modal-footer"></ng-content>
        </div>
      </div>
    </div>
  </div>
  `
})
export class ModalComponent {
  @ViewChild('myModal') public myModal: ModalDirective;

  public visible = false;
  private visibleAnimate = false;

  public show(): void {
    this.visible = true;
    setTimeout(() => this.visibleAnimate = true);
    document.body.className += ' modal-open';
  }

  public hide(): void {
    this.visibleAnimate = false;
    document.body.className = document.body.className.replace('modal-open', '');
    setTimeout(() => this.visible = false, 300);
  }

  public onContainerClicked(event: MouseEvent): void {
    if ((<HTMLElement>event.target).classList.contains('modal')) {
      this.hide();
    }
  }
}

The main problem I have now with this approach are:

  1. Keyboard-events are not caught in the modal dialog but rather sent to the backward. How to prevent this?
  2. As asked in the comment section: How to overlay the dialog multiple times? i.e. to have a modal dialog for e.g. editing and than an additional on the top as Error-notification. This appears in the background...

EDIT: After checking several sources I figured out the following:

I need to install ngx-bootstrap, add in the app.module.ts

import { ModalModule } from 'ngx-bootstrap';
...
@NgModule({
  imports: [
    ...
    ModalModule
  ],

and add in the systemjs.config.js

// ngx-bootstrap
        'ngx-bootstrap' : {
            format : 'cjs',
            main : 'bundles/ngx-bootstrap.umd.js',
            defaultExtension : 'js'
        },
        'moment' : {
            main : 'moment.js',
            defaultExtension : 'js'
        },

With the above changes (and the udpated code) I still have problems to get a second modal dialog in front of the first one. Hints?

Community
  • 1
  • 1
LeO
  • 4,238
  • 4
  • 48
  • 88

3 Answers3

1

I'm the original author of that post, sorry for the delay, perhaps its not too late :)

1) Not too sure what you mean here 2) I've since updated that answer to be able to show multiple modals at once.

Stephen Paul
  • 37,253
  • 15
  • 92
  • 74
  • Unfortunately this does not work. A second modal dialog will appear in the background of the first one :-/ – LeO Apr 19 '17 at 07:30
  • Hm, I'm not getting that problem. Maybe you can try and play around with the z-index? In other words each modal has a slightly higher z-index. – Stephen Paul Apr 19 '17 at 07:46
  • If I try to follow your hint with the z-index, i.e. http://stackoverflow.com/questions/19305821/multiple-modals-overlay/24914782#24914782, I'm getting lost about the styles and/or how to calc it dynamically (i.e. if I add a component on the top ==> how/what to increase?) – LeO Apr 19 '17 at 08:02
  • Yeah I was about to look into applying the advice in that post, but I came right anyway. I've since added a plunkr to my original post which you should be able to see. I've noticed that the order of the modals in the template matters. I've tested this on Chrome, Firefox, Edge, and IE11 (Are you perhaps using a different browser? :) – Stephen Paul Apr 19 '17 at 09:00
  • I played little bit around and changed your sample to simplify the usage.... see above... Honestly speaking don't know where to update it more properly - here or in your post ;-) Feel free to update your... – LeO Apr 19 '17 at 09:27
  • You shouldn't need that library you install. I'm morre than happy to help, but I suggest you post the code of the component that displays the modal and create a plunkr which reproduces it. – Stephen Paul Apr 19 '17 at 10:14
0

You did not include the ModalDirective that is the reason your keyboard events are not recognized

@Component({
  selector: 'app-modal',
  template: `/////////////////////
  <div class="modal fade" #myModal tabindex="-1" [ngClass]="{'in': visibleAnimate}"
       [ngStyle]="{'display': visible ? 'block' : 'none', 'opacity': visibleAnimate ? 1 : 0}">
    <div class="modal-dialog">
      <div class="modal-content" (click)="$event.stopPropagation();">
        <div class="modal-header">
          <ng-content select=".app-modal-header"></ng-content>
        </div>
        <div class="modal-body">
          <ng-content select=".app-modal-boddocument.body.className = document.body.className.replace('modal-open', ''); y"></ng-content>
        </div>
        <div class="modal-footer">
          <ng-content select=".app-modal-footer"></ng-content>
        </div>
      </div>
    </div>
  </div>
  `
})
export class ModalComponent {
@ViewChild('myModal') public myModal:ModalDirective; ////
  public visible = false;
  private visibleAnimate = false;

  public show(): void {
    this.visible = true;
    setTimeout(() => this.visibleAnimate = true);
    document.body.className += ' modal-open';
  }

  public hide(): void {
    this.visibleAnimate = false;
    document.body.className = document.body.className.replace('modal-open', ''); 
    setTimeout(() => this.visible = false, 300);
  }
}

For more information on how to reuse the modal component across the application this answer

Community
  • 1
  • 1
Aravind
  • 40,391
  • 16
  • 91
  • 110
  • Sorry for late reply. I test it right now and I'm not really sure how the complete sample should look like. `ModalDirective` would be imported from `ngx-bootstap`. In app.module.ts I import the `ModalDirective` (is `ModalModule` required?) and tried to follow as well your link http://stackoverflow.com/a/42633720/325868. But somehow Chrome has problems to load the `ngx-bootstrap` - namely I get an `Error - unexpected token < ... zone.js:365.... Evaluating http://..../ngx-bootstrap...` - Any ideas? – LeO Apr 19 '17 at 07:57
  • I figured out how to fix my last qs - nevertheless the problem still persists - see above – LeO Apr 19 '17 at 08:33
  • I played around and figured out that the initial approach could be taken. Nevertheless the additional installations were a good practise to learn the dependencies ;-) – LeO Apr 19 '17 at 09:29
0

The following code

import { Component, ViewChild, Input } from '@angular/core';

@Component({
  selector: 'app-modal',
  template: `
  <div class="modal fade"   tabindex="-1" [ngClass]="{'in': visibleAnimate}"
       [ngStyle]="getStyle()">
    <div class="modal-dialog">
      <div class="modal-content" (click)="$event.stopPropagation();">
        <div class="modal-header">
          <ng-content select=".app-modal-header"></ng-content>
        </div>
        <div class="modal-body">
          <ng-content select=".app-modal-body"></ng-content>
        </div>
        <div class="modal-footer">
          <ng-content select=".app-modal-footer"></ng-content>
        </div>
      </div>
    </div>
  </div>
  `
})
export class ModalComponent {

  public visible = false;
  private visibleAnimate = false;
  @Input() public zIndex = 500;

  public show(): void {
    this.visible = true;
    setTimeout(() => this.visibleAnimate = true);
    document.body.className += ' modal-open';
  }

  public hide(): void {
    this.visibleAnimate = false;
    document.body.className = document.body.className.replace('modal-open', '');
    setTimeout(() => this.visible = false, 300);
  }

  public getStyle() {
    return {
      'z-index': this.zIndex,
      'display': this.visible ? 'block' : 'none',
      'opacity': this.visibleAnimate ? 1 : 0
    }
  };

}

allows me to set in the next templates the zIndex like <app-modal [zIndex]=1000> - which fixes the issue very well

LeO
  • 4,238
  • 4
  • 48
  • 88