web-dev-qa-db-fra.com

Angularjs bootstrap appel de fermeture modal lors d'un clic à l'extérieur / esc

J'utilise le modal Angular-ui/bootstrap dans mon projet.

Voici mon modal:

$scope.toggleModal = function () {
    $scope.theModal = $modal.open({
        animation: true,
        templateUrl: 'pages/templates/modal.html',
        size: "sm",
        scope: $scope
    });
}

On peut fermer le modal en cliquant sur le bouton [~ # ~] esc [~ # ~] ou en cliquant en dehors de la zone modale. Existe-t-il un moyen d'exécuter une fonction lorsque cela se produit? Je ne sais pas trop comment saisir le genre de fermeture.

Je sais que je peux supprimer manuellement un modal en ayant une ng-click="closeModal()" comme ceci:

$scope.closeModal = function () {
    $scope.theModal.dismiss('cancel');
};

Si quelqu'un pouvait aider, ce serait grandement apprécié.

20
bryan

Oui, vous pouvez. Il provoque un événement de licenciement et la promesse est rejetée dans ce cas. Notez également que la méthode $modal.open() renvoie un objet qui a une propriété result qui est une promesse.

Avec la promesse que vous pouvez ...

//This will run when modal dismisses itself when clicked outside or
//when you explicitly dismiss the modal using .dismiss function.
$scope.theModal.result.catch(function(){
    //Do stuff with respect to dismissal
});

//Runs when modal is closed without being dismissed, i.e when you close it
//via $scope.theModal.close(...);
$scope.theModal.result.then(function(datapassedinwhileclosing){
    //Do stuff with respect to closure
});

comme raccourci, vous pouvez écrire:

 $scope.theModal.result.then(doClosureFn, doDismissFn);

Voir réf

La méthode open renvoie une instance modale, un objet avec les propriétés suivantes:

  • close (result) - une méthode qui peut être utilisée pour fermer un modal, en passant un résultat
  • rejeter (raison) - une méthode qui peut être utilisée pour rejeter un modal, en passant une raison
  • résultat - une promesse qui est résolue lorsqu'un modal est fermé et rejetée lorsqu'un modal est rejeté
  • ouvert - une promesse qui est résolue lorsqu'un modal est ouvert après le téléchargement du modèle de contenu et la résolution de toutes les variables `` rendues '' - une promesse qui est résolue lorsqu'un modal est rendu.
26
PSL

Ancienne question, mais si vous souhaitez ajouter des boîtes de dialogue de confirmation sur diverses actions de fermeture, ajoutez ceci à votre contrôleur d'instance modale:

$scope.$on('modal.closing', function(event, reason, closed) {
    console.log('modal.closing: ' + (closed ? 'close' : 'dismiss') + '(' + reason + ')');
    var message = "You are about to leave the edit view. Uncaught reason. Are you sure?";
    switch (reason){
        // clicked outside
        case "backdrop click":
            message = "Any changes will be lost, are you sure?";
            break;

        // cancel button
        case "cancel":
            message = "Any changes will be lost, are you sure?";
            break;

        // escape key
        case "escape key press":
            message = "Any changes will be lost, are you sure?";
            break;
    }
    if (!confirm(message)) {
        event.preventDefault();
    }
});

J'ai un bouton de fermeture en haut à droite du mien, qui déclenche l'action "annuler". En cliquant sur le fond (si activé), déclenche l'action d'annulation. Vous pouvez l'utiliser pour utiliser différents messages pour divers événements de clôture. Pensais que je partagerais au cas où cela serait utile pour les autres.

19
Tiago

Vous pouvez utiliser la promesse "result" renvoyée par la méthode $ modal.open (). Comme ci-dessous:

 $scope.toggleModal = function () {
      $scope.theModal = $modal.open({
          animation: true,
          templateUrl: 'pages/templates/modal.html',
          size: "sm",
          scope: $scope
      });

      $scope.theModal.result.then(function(){
          console.log("Modal Closed!!!");
      }, function(){
          console.log("Modal Dismissed!!!");
      });
 }

Vous pouvez également utiliser le rappel "finalement" de la promesse "résultat" comme ci-dessous:

     $scope.theModal.result.finally(function(){
          console.log("Modal Closed!!!");
      });
11
Yashika Garg

Dans mon cas, en cliquant sur le modal, nous voulions afficher une invite avertissant l'utilisateur que cela supprimerait toutes les données non enregistrées dans le formulaire modal. Pour ce faire, définissez les options suivantes sur le modal:

var myModal = $uibModal.open({
          controller: 'MyModalController',
          controllerAs: 'modal',
          templateUrl: 'views/myModal.html',
          backdrop: 'static',
          keyboard: false,
          scope: modalScope,
          bindToController: true,
        });

Cela empêche le modal de se fermer lorsque vous cliquez dessus:

backdrop: 'static'

Et cela empêche le modal de se fermer en appuyant sur 'esc':

keyboard: false

Ensuite, dans le contrôleur modal, ajoutez une fonction "Annuler" personnalisée - dans mon cas, une alerte douce apparaît pour demander si l'utilisateur souhaite fermer le modal:

  modal.cancel = function () {
    $timeout(function () {
      swal({
        title: 'Attention',
        text: 'Do you wish to discard this data?',
        type: 'warning',
        confirmButtonText: 'Yes',
        cancelButtonText: 'No',
        showCancelButton: true,
      }).then(function (confirm) {
        if (confirm) {
          $uibModalInstance.dismiss('cancel');
        }
      });
    })
  };

Enfin, à l'intérieur du contrôleur modal, ajoutez les écouteurs d'événement suivants:

  var myModal = document.getElementsByClassName('modal');
  var myModalDialog = document.getElementsByClassName('modal-dialog');

  $timeout(function () {
    myModal[0].addEventListener("click", function () {
      console.log('clicked')
      modal.cancel();
    })

    myModalDialog[0].addEventListener("click", function (e) {
      console.log('dialog clicked')
      e.stopPropagation();
    })
  }, 100);

"myModal" est l'élément sur lequel vous souhaitez appeler la fonction de rappel modal.cancel (). "myModalDialog" est la fenêtre de contenu modal - nous arrêtons la propagation des événements pour cet élément afin qu'il ne bouillonne pas jusqu'à "myModal".

Cela ne fonctionne que pour cliquer sur le modal (en d'autres termes, cliquer sur le fond). Appuyer sur 'esc' ne déclenchera pas ce rappel.

1
Maegan Womble

Au lieu de ng-click="closeModal()" vous pouvez essayer ng-click="$dismiss()"

<button ng-click="$dismiss()">Close</button>
0
Felipe Anselmo