web-dev-qa-db-fra.com

Masquer l'infobulle de l'interface angulaire sur l'événement personnalisé

J'ai regardé autour de moi et essayé différentes choses, mais je n'arrive pas à comprendre. Est-il possible de cacher une info-bulle angular-ui avec un certain événement?

Ce que je veux faire, c'est afficher une info-bulle lorsque quelqu'un survole une div et la fermer lorsqu'un utilisateur clique dessus car je vais afficher une autre fenêtre contextuelle. Je l'ai essayé avec des événements déclencheurs personnalisés, mais je n'arrive pas à le faire fonctionner. J'ai fabriqué ça:

<div ng-app="someApp" ng-controller="MainCtrl" class="likes" tooltip="show favorites"     tooltip-trigger="{{{true: 'mouseenter', false: 'hideonclick'}[showTooltip]}}" ng-click="doSomething()">{{likes}}</div>

var app = angular.module('someApp', ['ui.bootstrap']);

app.config(['$tooltipProvider', function($tooltipProvider){
 $tooltipProvider.setTriggers({
  'mouseenter': 'mouseleave',
  'click': 'click',
  'focus': 'blur',
  'hideonclick': 'click'
 });
}]);

app.controller('MainCtrl', function ($scope) {
 $scope.showTooltip = true;
 $scope.likes = 999;

 $scope.doSomething = function(){
    //hide the tooltip
    $scope.showTooltip = false;                                   
 };

})

http://jsfiddle.net/3ywMd/

L'info-bulle doit se fermer au premier clic et non au 2e. Avez-vous une idée de la façon de fermer l'info-bulle si l'utilisateur clique sur div?

11

J'ai essayé la suggestion de @ shidhin-cr de définir $scope.tt_isOpen = false, mais le problème assez important est que, même si l'info-bulle disparaît, elle est toujours présente dans le DOM (et gère les événements de pointeur!). Ainsi, même s'ils ne peuvent pas le voir, l'info-bulle peut empêcher les utilisateurs d'interagir avec du contenu précédemment affiché derrière l'info-bulle.

Un meilleur moyen que j'ai trouvé consistait simplement à déclencher l'événement utilisé en tant que déclencheur d'info-bulle sur la cible de l'info-bulle. Ainsi, par exemple, si vous avez un bouton qui est une cible d'info-bulle et qui déclenche un clic ...

<button id="myButton"
        tooltip="hi"
        tooltip-trigger="click">
</button>

Ensuite, dans votre code JavaScript, vous pouvez à tout moment déclencher l'événement 'clic' pour ignorer votre info-bulle. Assurez-vous que l'info-bulle est réellement ouverte avant de déclencher l'événement.

// ... meanwhile, in JavaScript land, in your custom event handler...
if (angular.element('#myButton').scope().tt_isOpen) {
    angular.element('#myButton').trigger('click');
}

Comme cela déclenche les éléments internes de la directive Tooltip de AngularUI, vous n'avez pas les effets secondaires désagréables de la solution précédente.

6
Michael Cook

En gros, vous ne pouvez pas jouer avec le tooltip-trigger pour que cela fonctionne. Après avoir fouillé dans le code de la directive ToolTip, j’ai constaté que l’attribut ToolTip expose un attribut de portée appelé tt_isOpen .

Ainsi, dans votre fonction ng-click, si vous définissez cet attribut sur false, l’info-bulle sera masquée.

Voir la démo mise à jour ici

http://jsfiddle.net/3ywMd/10/

Comme ça

app.controller('MainCtrl', function ($scope) {
 $scope.likes = 999;
 $scope.doSomething = function(){
    //hide the tooltip
    $scope.tt_isOpen = false;
 };                                    
})
4
Shidhin Cr

La solution de Michael m'a fourni 90% du chemin mais lorsque j'ai exécuté le code, angular a répondu avec "$ digest déjà en cours". J'ai simplement enveloppé la gâchette dans un délai d'attente. Probablement pas la meilleure solution, mais nécessitait un code minimal

// ... meanwhile, in JavaScript land, in your custom event handler...
if (angular.element('#myButton').scope().tt_isOpen) {
    $timeout( function(){
        angular.element('#myButton').trigger('click');
    }, 100);
}
4
liteflier

Pour référence future, la réponse acceptée angular.element('.yourTooltip').scope().tt_isOpen ne fonctionnera pas dans les nouvelles versions car les info-bulles ont été rendus non observables. Par conséquent, l'intégralité de la tootlip est supprimée de DOM. La solution simple consiste simplement à vérifier si une info-bulle est présente dans le DOM ou non.

Empruntant à la réponse de @ liteflier,

// ... meanwhile, in JavaScript land, in your custom event handler...
if (angular.element('.yourTooltip').length) { //if element is present in DOM
    setTimeout( function(){
        //Trigger click on tooltip container
        angular.element('.yourTooltipParent').trigger('click');
    }, 100);
}
1
RijulB