Witold Tkaczyk
Witold Tkaczyk

Reputation: 713

Modal event before hide

I have a problem. I need to show toastr informing that changes are not saved when someone wants to hide modal. I need to trigger toastr before modal hide, and when the user tries again to dismiss modal allow this. I tried something like this:

declare let jQuery: any;
declare let $: any;
declare let toastr: any;

@Component({
  selector: 'app-trigger',
  templateUrl: './trigger.component.html',
  styleUrls: ['./trigger.component.scss']
})
export class TriggerComponent implements OnInit {

  name: string

  private canHideModal = true;

  constructor() {
  }


ngOnInit(){
      const self = this;
      $('#triggerModal').on('hide.bs.modal', () => {
        if (self.canHideModal) {
          //hide modal here  <---------
        } else {
          toastr['warning']('You have unsaved changes');

          self.canHideModal = true;
           return false
        }
       });
    }

 fireModal(changes : {action:string, name:string}){
   changes.action  = 'show';
   changes.name = 'test';
   this.name = changes.name
   $('#triggerModal').modal(changes.action);
 }

}

and it works fine for first time, after this hide event seems to be overwriten and function $('#triggerModal').on('hide.bs.modal', () => { doesn't trigger anymore.

HTML:

<div class="modal fade" id="triggerModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" style="display: none;" aria-hidden="true">
    <div class="modal-dialog modal-lg px-4" role="document">

        <!--Content-->
        <div class="modal-content">

            <!--Header-->
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                        <span aria-hidden="true">×</span>
                    </button>
            </div>

            <!--Body-->
            <div class="modal-body mb-0">

                <!--Grid row-->
                <div class="row d-flex justify-content-center mb-4">

                    <!--Grid column-->
                    <div class="col-md-6">

                        <!--Name-->
                        <div class="md-form">
                            <input type="text" id="triggerStartName" (input)="canHideModal = false" class="form-control" #triggerName [value]="name">
                            <label for="triggerStartName" [ngClass]="{ 'active': name }">Trigger name</label>
                        </div>

                    </div>
                    <!--Grid column-->

                </div>
                <!--Grid row-->

            </div>

            <!--Footer-->
            <div class="modal-footer justify-content-center">
                <button type="button" class="btn btn-primary waves-effect waves-light" data-dismiss="modal">Close</button>
            </div>

        </div>
        <!--/.Content-->

    </div>
</div>

Upvotes: 6

Views: 1767

Answers (1)

Martin Parenteau
Martin Parenteau

Reputation: 73721

You can do it with the ng-bootstrap Modal component, by assigning a method to its beforeDismiss option, as illustrated in this plunker:

import {Component} from '@angular/core';

import {NgbModal, ModalDismissReasons} from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'ngbd-modal-basic',
  templateUrl: 'src/modal-basic.html'
})
export class NgbdModalBasic {
  closeResult: string;
  private canHideModal = false;

  constructor(private modalService: NgbModal) {}

  open(content) {
    this.canHideModal = false;
    const options : NgbModalOptions = {
      beforeDismiss: () => {
        if (this.canHideModal) {
          return true;
        } else {
          alert('You have unsaved changes');
          this.canHideModal = true;
          return false;
        }
      }
    };    
    this.modalService.open(content, options).result.then((result) => {
      this.closeResult = `Closed with: ${result}`;
    }, (reason) => {
      this.closeResult = `Dismissed ${this.getDismissReason(reason)}`;
    });
  }
  ...
}

Upvotes: 4

Related Questions