How to close an Angular-ui-bootstrap uibModal on mouseleave using Factory?
Asked Answered
P

4

5

I've recently switched all our modals directives in our app over to Angular-ui-Bootstrap modals. Much better, however running into a new style of modal which closes on mouseleave instead of a cancel click.

this.leaveTag = (tag) => {
    TagHover.off();
};

this.hoverTag = (tag) => {
    TagHover.display();
};

Above is the view logic that calls functions inside of our TagHover Factory.

Below is the Factory, the TagHover.display works fine like with our other modals, but what I'm trying to do with the leaveTag > TagHover.off is call the modal.close. Not working so far.

My question is how do you call the close functionality within the TagHoverController, or close on the $uibModal from my tagsPanel component -> TagsHover Factory? (Without using $scope or $rootScope events)

I'm not trying to call close/cancel from within the TagHover Ctrl scope, but trying to call close from a Parent scope.

const TagHover = angular.module('tickertags-shared')
    .controller('TagHoverController', TagHoverController)
    .factory('TagHover', factory);

TagHoverController.$inject = [
    'TagHover'];

function TagHoverController(
    TagHover) {

    this.$onInit = () => {
        console.log('TagHover onInit')
    };

    this.cancel = () => this.$close();
}

factory.$inject = ['$uibModal'];

function factory($uibModal) {

    const display = () => {
        const modal = $uibModal.open({
            controllerAs: 'tghov',
            bindToController:true,
            templateUrl: 'tags/tag_hover.html',
            windowClass: 'dash-modal',
            resolve: {},
            controller: 'TagHoverController'
        });
    };

    const off = () => {
        $uibModal.close({});
    };

    return {
        display,
        off
    }
}

module.exports = TagHover;

enter image description here

Here are the docs https://angular-ui.github.io/bootstrap/#/modal

The open method returns a modal instance, an object with the following properties:

close(result) (Type: function) - Can be used to close a modal, passing a result.

I also logged out the $uibModal object and I only see an open function, no close :(

enter image description here

Preposterous answered 26/12, 2016 at 17:2 Comment(2)
Use $uibModalInstance.close() instead of $uibModal.close()Blackington
Hmm, I just tried that... I injected $uibModalInstance but got Unknown provider :(Preposterous
S
5

This is wrong approach - you can not "just close modal", cause you dont tell which modal to close. I recommend you to redesign this...

You can have a look at $uibModalStack - it stores opened modals and have methods like dismisAll

Savannasavannah answered 26/12, 2016 at 17:17 Comment(2)
Nice! This is working, I don't see any documentaion on $uibModalStack though, do you have a link?Preposterous
This might be the solution, I found more info here:#25446449Blackington
A
11

In your case, Your are using Factory for dynamic Modal. so you can use $uibModalStack in the below two ways.

  1. $uibModalStack.dismissAll(); // dismiss all opened modal
  2. $uibModalStack.dismiss(openedModal.key); // dismiss modal by key

Example of dismiss Method.

var top = $uibModalStack.getTop();
if (top) {
    $uibModalStack.dismiss(top.key);
}

It's very important to do dismissing the modal during router changes since its dynamic modal.

In general, $uibModal will help to open the modal then each modal is $uibModalInstance, if you want to close modal inside the modal.

Opening Modal on Event

angular.module('myPage')
  .controller('PageController', ['$uibModal',
    function($uibModal) {
      function onModalLink() {
        $uibModal.open({
          templateUrl: 'app/modals/paymentTpl.html',
          controller: 'PaymentModalController as vm',
          windowClass: 'generalModal myModal'
        });
      }
    }
  ]);

To Close from Instance.

angular.module('paymentModal')
  .controller('PaymentModalController', [
    '$uibModalInstance',
    function ChangeRepaymentController($uibModalInstance) {
      function onCancel() {
        $uibModalInstance.close(repaymentPercentage);
      }
    }
  ]);

modalInstance - The modal instance. This is the same $uibModalInstance injectable found when using controller.

WIKI Reference: https://github.com/angular-ui/bootstrap/tree/master/src/modal/docs

Adriaadriaens answered 26/12, 2016 at 17:18 Comment(5)
Thanks, but I'm not trying to close from the Modal, but from the Factory that set it up. I can just call this.cancel if I'm in the Modal's scope.Preposterous
gotcha. you need to use $uibModalStack since its factory with detailed examplesAdriaadriaens
Actually I need to revisit this now... I have to be able to target the specific modal that was opened, not all modals. In your example where is repaymentPercentage coming from?Preposterous
Could you post another code example using my function factory($uibModal) example above? I'm trying to figure out how to set a modal key as well as call something by it's openedModal.keyPreposterous
Added the example for $uibModalStack.dismissAdriaadriaens
S
5

This is wrong approach - you can not "just close modal", cause you dont tell which modal to close. I recommend you to redesign this...

You can have a look at $uibModalStack - it stores opened modals and have methods like dismisAll

Savannasavannah answered 26/12, 2016 at 17:17 Comment(2)
Nice! This is working, I don't see any documentaion on $uibModalStack though, do you have a link?Preposterous
This might be the solution, I found more info here:#25446449Blackington
P
5

I use close() method with $uibModal and open() method for manage in AngularJS $uiModal

Open method

vm.lanzarPopShowTask = lanzarPopShowTask;
function lanzarPopShowTask(index){
    vm.modalInstance = $uibModal.open({
        animation: true,
        ariaLabelledBy: 'modal-title-top',
        ariaDescribedBy: 'modal-body-top',
        templateUrl: '/btask/index/task.html',
        size: 'm',
        controller: function ($scope) {
            vm.task = vm.tasks[index];
            vm.index = index;
        },
        scope: $scope
    });
}

And Close method

vm.modalInstance.close();
Parclose answered 10/3, 2017 at 15:50 Comment(0)
T
3

When doing this I set the modal as a scope variable then use $scope.sweetModal.close() or $scope.sweetModal.dismiss() you just have to remember that if you were to do the following it wouldn't work:

$scope.openModal = function () {
    $scope.sweetModal = $uibModal.open({
        templateUrl: '/modals/sweetModal.html',
        size: 'md',
        scope: $scope,
        backdrop: true
    })
        .result.then($scope.modalCloseFunction, $scope.modalDismissFunction);
};

Where as the following would work because of how the variable is set:

$scope.openModal = function () {
    $scope.sweetModal = $uibModal.open({
        templateUrl: '/modals/sweetModal.html',
        size: 'md',
        scope: $scope,
        backdrop: true
    });

    $scope.sweetModal.result.then($scope.modalCloseFunction, $scope.modalDismissFunction);
};
Time answered 30/5, 2018 at 13:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.