Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ng-bootstrap modal animation

The fade class doesn't appear to work on the ngb-modal.

I've looked at trying to apply my own animation to the modal but the modal template is obviously injected into modal dialogue by ng-bootstrap e.g. I don't have access to the modal dialogue. I only have access to the template:

<template #content let-c="close" let-d="dismiss">
  <div class="modal-header card-header" style="border-radius: 10px;">
    <h4 class="modal-title">Contact Form</h4>
 </div>
    <div class="modal-body"> </div>
...etc
</template>

I need to apply my animation to the top level dialogue otherwise just bits of the modal animate. If I apply it to the template it blows up.

Any idea how I would animate the whole modal??

like image 271
72GM Avatar asked Mar 05 '17 16:03

72GM


3 Answers

Here is simple solution. Just put it in style.css

/* modal animation */
.modal-content{
  animation-name: example;
  animation-duration: 0.3s;
}

@keyframes example {
  0%   {transform: scale(0.5)}
  75%  {transform: scale(1.1)}
  100% {transform: scale(1)}
}
like image 126
Saptarshee Das Avatar answered Nov 11 '22 14:11

Saptarshee Das


You need to add animation css class to global styles and add NgbModalOptions.

styles.css: // or whatever is your global css

.modal-holder{
  animation-name: example;
  animation-duration: 0.3s;
}

@keyframes example {
  0%   {transform: scale(0.5)}
  100% {transform: scale(1)}
}

modal.component.ts

const modalRef = this.modalService.open(NgbdModalContent, {windowClass: 'modal-holder', centered: true});

Enough talk, you can see example on:

StackBlitz

like image 25
Amel Avatar answered Nov 11 '22 16:11

Amel


Here is the exact replica of FADE IN - OUT animation with SLIDE DOWN as of bootstrap 4.x

SOLUTION 1: Initialize animation in constructor

app.component.ts:-

import { NgbModal, NgbModalRef } from "@ng-bootstrap/ng-bootstrap";
  constructor(private modalService: NgbModal) {
    NgbModalRef.prototype["c"] = NgbModalRef.prototype.close;
    NgbModalRef.prototype.close = function(reason: string) {
      document.querySelector(".modal-backdrop").classList.remove("show");
      document.querySelector(".modal").classList.remove("show");
      setTimeout(() => {
        this["c"](reason);
      }, 500);
    };
    NgbModalRef.prototype["d"] = NgbModalRef.prototype.dismiss;
    NgbModalRef.prototype.dismiss = function(reason: string) {
      document.querySelector(".modal-backdrop").classList.remove("show");
      document.querySelector(".modal").classList.remove("show");
      setTimeout(() => {
        this["d"](reason);
      }, 500);
    };
  }
  open(basic) {
    this.modalService.open(basic);
  }

app.component.html :-

<div class="card">
    <div class="card-header">
        <h4 class="card-title">Basic Modal</h4>
    </div>
    <div class="card-content">
        <div class="card-body">
            <div class="row">
                <div class="col-sm-12">
                    <p>Toggle a modal via TypeScript by clicking the button above.</p>
                    <!-- Button trigger modal -->
                    <button type="button" (click)="open(basic)" class="btn btn-outline-primary block btn-lg">
                  Launch Modal
                </button>

                    <!-- Modal -->
                    <ng-template #basic let-modal>
                        <div class="modal-header">
                            <h4 class="modal-title" id="myModalLabel1">Basic Modal</h4>
                            <button type="button" class="close" (click)="modal.dismiss('Cross click')" aria-label="Close">
                      <span aria-hidden="true">&times;</span>
                    </button>
                        </div>
                        <div class="modal-body" tabindex="0" ngbAutofocus>
                            <h5>Check First Paragraph</h5>
                            <p>Oat cake ice cream candy chocolate cake chocolate cake cotton candy dragée apple pie.
                                Brownie carrot cake candy canes bonbon fruitcake topping halvah. Cake sweet roll cake
                                cheesecake cookie chocolate cake liquorice.</p>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-primary" (click)="modal.close('Accept click')">Accept</button>
                        </div>
                    </ng-template>
                    <!-- / Modal -->

                </div>
            </div>
        </div>
    </div>
</div>

styles.scss :-

// modal animation
@keyframes modal-fade {
  from {
    top: -50px;
    opacity: 0;
  }

  to {
    top: 0;
    opacity: 1;
  }
}

.modal {
  top: -100px;
  animation: ease-in-out .3s modal-fade;

  &.show {
    top: 0;
  }
    .modal-body {
    &:focus {
      outline: none;
    }
  }
}

stackblitz link here

SOLUTION 2: initalize animation in individual modal call

app.component.ts :-

import { NgbModal } from "@ng-bootstrap/ng-bootstrap";
  constructor(private ngbModal: NgbModal) {}

  open(content: any, config?: any) {
    let modal = this.ngbModal.open(content, config);
    let instance = (modal as any)._windowCmptRef.instance;
    setImmediate(() => {
      instance.windowClass = "custom-show";
    });

    let fx = (modal as any)._removeModalElements.bind(modal);
    (modal as any)._removeModalElements = () => {
      instance.windowClass = "";
      setTimeout(fx, 250);
    };

    return modal;
  }

app.component.html :-

<div class="card">
    <div class="card-header">
        <h4 class="card-title">Basic Modal</h4>
    </div>
    <div class="card-content">
        <div class="card-body">
            <div class="row">
                <div class="col-sm-12">
                    <p>Toggle a modal via TypeScript by clicking the button above.</p>
                    <!-- Button trigger modal -->
                    <button type="button" (click)="open(basic)" class="btn btn-outline-primary block btn-lg">
                  Launch Modal
                </button>

                    <!-- Modal -->
                    <ng-template #basic let-modal>
                        <div class="modal-header">
                            <h4 class="modal-title" id="myModalLabel1">Basic Modal</h4>
                            <button type="button" class="close" (click)="modal.dismiss('Cross click')" aria-label="Close">
                      <span aria-hidden="true">&times;</span>
                    </button>
                        </div>
                        <div class="modal-body" tabindex="0" ngbAutofocus>
                            <h5>Check First Paragraph</h5>
                            <p>Oat cake ice cream candy chocolate cake chocolate cake cotton candy dragée apple pie.
                                Brownie carrot cake candy canes bonbon fruitcake topping halvah. Cake sweet roll cake
                                cheesecake cookie chocolate cake liquorice.</p>
                        </div>
                        <div class="modal-footer">
                            <button type="button" class="btn btn-primary" (click)="modal.close('Accept click')">Accept</button>
                        </div>
                    </ng-template>
                    <!-- / Modal -->

                </div>
            </div>
        </div>
    </div>
</div>

styles.scss :-

// animation style 
// --------------------------
.modal {
    &.show .modal-dialog {
        transition: 0.25s all;
        // opacity: 0;
        transform: translate(0, -5vh);
    }

    &.custom-show .modal-dialog {
        opacity: 1;
        transform: translate(0, 0);
    }
  .modal-body {
    &:focus {
      outline: none;
    }
  }
}

stackblitz link here

like image 3
Parth Developer Avatar answered Nov 11 '22 16:11

Parth Developer