web-dev-qa-db-fra.com

Créer un popover Hoverable en utilisant angular-ui-bootstrap

J'ai le code suivant pour créer un popover dans mon fichier de modèle:

<span class="icon-globe visibility" 
      id="visibilityFor{{post.metaData.assetId}}" 
      popover="{{post.visibilityListStr}}" 
      popover-placement="right" 
      popover-trigger="mouseenter" 
      popover-popup-delay="50" 
      visibility>
</span>

J'ai quelques liens cliquables sur le popover. Mais le problème est que je ne peux pas survoler la popover créée. J'ai fait référence au lien http://jsfiddle.net/xZxkq/ Et j'ai essayé de créer une directive, à savoir. «visibilité» à cet effet.

Voici le code:

myAppModule.directive("visibility", function ($timeout,$rootScope) {
  return {

    controller: function ($scope, $element) {
        $scope.attachEvents = function (element) {
            $('.popover').on('mouseenter', function () {
                $rootScope.insidePopover = true;
            });
            $('.popover').on('mouseleave', function () {
                $rootScope.insidePopover = false;
                $(element).popover('hide');
            });
        }
    },
    link: function (scope, element, attrs) {
        $rootScope.insidePopover = false;

        element.bind('mouseenter', function (e) {
            $timeout(function () {
                if (!$rootScope.insidePopover) {
                    element.popover('show');
                    attachEvents(element);
                }
            }, 200);
        });

        element.bind('mouseout', function (e) {
            $timeout(function () {
                if (!$rootScope.insidePopover) {
                    element.popover('show');
                    attachEvents(element);
                }
            }, 200);
        });

    }
  }
});

Mais je reçois une exception pour 'element.popover' car il n'est pas défini. Veuillez indiquer ce que je ne fais pas bien et comment puis-je afficher/masquer le popover angulaire de la directive. J'utilise le fichier JS bootstrap UI angulaire.

9
Adarsh Konchady

Je ne sais plus si cela concerne davantage le PO, mais j'ai le même problème et heureusement, j'ai réussi à le résoudre.

Erreur non définie

Tout d’abord, l’erreur non définie que vous obtenez peut être (du moins dans mon cas) parce que vous utilisez la version de développement de ui-bootstrap. Dans mon cas, j'ai eu cette erreur en essayant de lier element.popover. Après avoir ajouté la version simplifiée de la bibliothèque, l'erreur a disparu.

Laissez la fenêtre popover ouverte lorsque vous la survolez

Pour ce faire, j'ai créé une directive personnalisée qui utilise la variable popover de la bibliothèque ui-bootstrap.

Directive

app.directive('hoverPopover', function ($compile, $templateCache, $timeout, $rootScope) {
var getTemplate = function (contentType) {
    return $templateCache.get('popoverTemplate.html');
};
return {
    restrict: 'A',
    link: function (scope, element, attrs) {
        var content = getTemplate();
        $rootScope.insidePopover = false;
        $(element).popover({
            content: content,
            placement: 'top',
            html: true
        });
        $(element).bind('mouseenter', function (e) {
            $timeout(function () {
                if (!$rootScope.insidePopover) {
                    $(element).popover('show');
                    scope.attachEvents(element);
                }
            }, 200);
        });
        $(element).bind('mouseleave', function (e) {
            $timeout(function () {
                if (!$rootScope.insidePopover)
                    $(element).popover('hide');
            }, 400);
        });
    },
    controller: function ($scope, $element) {
        $scope.attachEvents = function (element) {
            $('.popover').on('mouseenter', function () {
                $rootScope.insidePopover = true;
            });
            $('.popover').on('mouseleave', function () {
                $rootScope.insidePopover = false;
                $(element).popover('hide');
            });
        }
    }
};
});

Cette directive accepte également un modèle personnalisé pour le popover, vous n'êtes donc pas limité à un titre et à du texte. Vous pouvez créer votre propre modèle HTML et l’alimenter au contrôle.

Utilisation

<a href="#" hover-popover>Click here</a>

J'espère que cela aidera quelqu'un d'autre à l'avenir :)

Modifier

Comme demandé, voici un Fiddle link . Cela manque de style, mais cela devrait montrer comment cela fonctionne.

8
Cosmin Ionascu

Je l'ai résolu de manière très propre et j'ai pensé le partager:

.popover n'est pas créé en tant qu'enfant du uib-popover . L'idée est donc d'envelopper uib-popover avec un parent et contrôler l'affichage et le masquage lors du survol du parent.

.popover et uib-popover sont les enfants de ce parent donc il ne reste plus qu'à définir popover-trigger = none et vous avez ce que vous êtes souhaitant.

J'ai créé un exemple plunk :

<span ng-init="popoverOpened=false" ng-mouseover="popoverOpened=true" ng-mouseleave="popoverOpened=false">
    <button class="btn btn-default" uib-popover-html="htmlPopover" 
            popover-trigger="none" popover-placement="bottom-left" popover-is-open="popoverOpened" >
       <span>hover me</span>
    </button>
</span>

prendre plaisir.

7
oded

Je pense que Cosmin a le popover hoverable correct, mais il semble utiliser la méthode Twitter Bootstrap popover. L'idée est de faire en sorte que ce popover survolable ne soit implémenté qu'avec AngularJS et l'un des wrappers Bootstrap pour AngularJS, qui sont UI Bootstrap ou AngularStrap .

J'ai donc mis en place une implémentation qui utilise uniquement AngularStrap:

myApp.directive('hoverablePopover', function ($rootScope, $timeout, $popover) {
    return {
        restrict: "A",
        link: function (scope, element, attrs) {

            element.bind('mouseenter', function (e) {
                $timeout(function () {
                    if (!scope.insidePopover) {

                        scope.popover.show();
                        scope.attachEventsToPopoverContent();
                    }
                }, 200);
            });

            element.bind('mouseout', function (e) {
                $timeout(function () {
                    if (!scope.insidePopover) {

                        scope.popover.hide();
                    }
                }, 400);
            });

        },
        controller: function ($scope, $element, $attrs) {

            //The $attrs will server as the options to the $popover.
            //We also need to pass the scope so that scope expressions are supported in the  popover attributes
            //like title and content.
            $attrs.scope = $scope;
            var popover = $popover($element, $attrs);
            $scope.popover = popover;
            $scope.insidePopover = false;

            $scope.attachEventsToPopoverContent = function () {

                $($scope.popover.$element).on('mouseenter', function () {

                    $scope.insidePopover = true;

                });
                $($scope.popover.$element).on('mouseleave', function () {

                    $scope.insidePopover = false;
                    $scope.popover.hide();

                });
            };
        }
    };
});

Lorsque vous avez un élément popover, vous devez tenir compte du fait que vous avez l'élément qui déclenche le popover et que vous avez également l'élément avec le contenu réel du popover.

L'idée est de garder le popover ouvert lorsque vous passez la souris sur l'élément avec le contenu actuel. Dans le cas de ma directive, la fonction link prend en charge l'élément qui déclenche le popover et attache les gestionnaires d'événements mouseenter/mouseout.

Le contrôleur prend en charge le paramétrage de la portée et du popover lui-même via le service AngularStrap $ popover. Le contrôleur ajoute l'objet popover renvoyé par le service AngularStrap sur l'étendue afin qu'il soit disponible dans la fonction de liaison. Il ajoute également une méthode attachEventsToPopoverContent, qui lie les événements mouseenter/mouseout à l'élément avec le contenu popover.

L'utilisation de cette directive est la suivante:

  <a title="Popover Title" data-placement="left" data-trigger="manual" data-content="{{someScopeObject}}" content-template="idOfTemplateInTemplateCache" hoverablePopover="">
5
Milen Kovachev

Là je passe 1 jour et enfin obtenir la solution.

<button uib-popover="{{dynamicPopover.content}}" 
    popover-trigger="outsideClick" popover-is-open="popoverIsOpen"
    ng-mouseenter="popoverIsOpen = !popoverIsOpen" 
    popover-title="{{dynamicPopover.title}}" type="button" class="btn btn-default">Dynamic Popover</button>

Veuillez vérifier Plunkeer Link Vérifier uniquement le code du bouton Popover dynamique

Merci,

5
Roni

Vous devez mettre le déclencheur entre guillemets simples, car, raisons:

<button uib-popover="I appeared on mouse enter!" popover-trigger="'mouseenter'" type="button" class="btn btn-default">Mouseenter</button>
3
programmer

démo: 

https://jsbin.com/fuwarekeza/1/edit?html,output

directif:

myAppModule.directive('popoverHoverable', ['$timeout', '$document', function ($timeout, $document) {
    return {
        restrict: 'A',
        scope: {
            popoverHoverable: '=',
            popoverIsOpen: '='
        },
        link: function(scope, element, attrs) {
            scope.insidePopover = false;

            scope.$watch('insidePopover', function (insidePopover) {
                togglePopover(insidePopover);
            })

            scope.$watch('popoverIsOpen', function (popoverIsOpen) {
                scope.insidePopover = popoverIsOpen;
            })

            function togglePopover (isInsidePopover) {
                $timeout.cancel(togglePopover.$timer);
                togglePopover.$timer = $timeout(function () {
                    if (isInsidePopover) {
                        showPopover();
                    } else {
                        hidePopover();
                    }
                }, 100)
            }

            function showPopover () {
                if (scope.popoverIsOpen) {
                    return;
                }

                $(element[0]).click();
            }

            function hidePopover () {
                scope.popoverIsOpen = false;
            }

            $(document).bind('mouseover', function (e) {
                var target = e.target;
                if (inside(target)) {
                    scope.insidePopover = true;
                    scope.$digest();
                }
            })

            $(document).bind('mouseout', function (e) {
                var target = e.target;
                if (inside(target)) {
                    scope.insidePopover = false;
                    scope.$digest();
                }
            })

            scope.$on('$destroy', function () {
                $(document).unbind('mouseenter');
                $(document).unbind('mouseout');
            })

            function inside (target) {
                return insideTrigger(target) || insidePopover(target);
            }

            function insideTrigger (target) {
                return element[0].contains(target);
            }

            function insidePopover (target) {
                var isIn = false;
                var popovers = $('.popover-inner');
                for (var i = 0, len = popovers.length; i < len; i++) {
                    if (popovers[i].contains(target)) {
                        isIn = true;
                        break;
                    }
                }
                return isIn;
            }
        }
    }
}]);

html:

<span class="icon-globe visibility" 
      id="visibilityFor{{post.metaData.assetId}}" 
      popover="{{post.visibilityListStr}}" 
      popover-is-open="{{post.$open}}"
      popover-trigger="click" 
      popover-hoverable="true"
      visibility>
</span>
1
b3bkids

Cette fonctionnalité a été ajoutée dans Angular UI Bootstrap 0.14.0 et est documentée ici . Désactivez les déclencheurs et utilisez la propriété popover-is-open pour dicter manuellement l'état ouvert/fermé.

0
icfantv

Meilleure façon d'avoir un événement de souris utilisant uib-popover Regardez l'exemple de travail ci-dessous! Vous n'avez pas besoin d'un uib-tabset , j'ai rencontré un problème avec uib-tabset et ainsi ajouté cet exemple.

<uib-tabset>
      <uib-tab>
        <uib-tab-heading>
          Tab 1
        </uib-tab-heading>
        <div>

          <span ng-mouseover="popoverIsOpen = true" 
                ng-mouseleave="popoverIsOpen = false">
            <button uib-popover-template="'includeFile.html'"
                    popover-trigger="outsideClick" 
                    popover-is-open="popoverIsOpen"
                    popover-placement="right"
                    type="button" class="btn btn-default">
              Dynamic Popover
            </button>
        </span>

        </div>
        <p> tab 1</p>
      </uib-tab>
      <uib-tab>
        <uib-tab-heading>
          Tab 2
        </uib-tab-heading>

        <p> tab 2</p>
      </uib-tab>
    </uib-tabset>

Modèle: includeFile.html

<div>
  <span>This is for tesitng</span>
  <strong> <a href="www.google.com">www.google.com</a></strong>

</div>
0

html

 <span class="icon-globe" id="visibilityFor" popover="hello how are you" 
       popover-placement="right" popover-trigger="mouseenter" 
       popover-popup-delay="50" viz>
</span>

directive

myAppModule.directive('viz', function ($rootScope,$timeout){
    return{

        restrict:"A",
        link: function (scope, element, attrs) {
            $rootScope.insidePopover = false;

            element.bind('mouseenter', function (e) {
                $timeout(function () {
                    if (!$rootScope.insidePopover) {
                        element.popover('show');
                     //  attachEvents(element);
                    }
                }, 200);
            });

            element.bind('mouseout', function (e) {
                $timeout(function () {
                    if (!$rootScope.insidePopover) {
                        element.popover('show');
                     //   attachEvents(element);
                    }
                }, 200);
            });

        }
    }
});

Remarque: - N'oubliez pas d'inclure angular-strap after jQuery.js & angular.js  

0
Nishchit Dhanani

Ce que j’ai fait pour que ma réponse soit définie dans 0.13.X consiste à définir l’élément pouvant être survolé sur un <button>, puis à définir le paramètre popover-trigger = "focus". Stylez ensuite le bouton comme vous le souhaitez et concentrez-vous sur celui-ci en cliquant dessus. Vous pouvez survoler la fenêtre et cliquer sur un lien, tout ce que je dois faire.

0
httpete