web-dev-qa-db-ja.com

angular-ui-bootstrapを使用してホバリング可能なポップオーバーを作成する

テンプレートファイルにポップオーバーを作成する次のコードがあります。

<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>

ポップオーバーにクリック可能なリンクがいくつかあります。しかし問題は、作成されたポップオーバーにカーソルを合わせることができないことです。私はリンク http://jsfiddle.net/xZxkq/ を参照して、ディレクティブvizを作成しようとしました。この目的のための「可視性」。

これがコードです:

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);
        });

    }
  }
});

しかし、「element.popover」は定義されていないため、例外が発生します。私が間違っていること、およびディレクティブからangular uiポップオーバーを表示/非表示にするにはどうすればよいかを指摘してください。 angular ui bootstrap JSファイルを使用しています。

12
Adarsh Konchady

私はそれを非常にクリーンな方法で解決し、それを共有しようと考えました:

。popoveruib-popoverの子として作成されていませんしたがって、アイデアは親でuib-popoverをラップし、親をホバーするときに表示と非表示を制御することです。

。popoveruib-popoverはこの親の子なので、そのまま残しますpopover-trigger = noneを設定すると、希望どおりの結果になります。

私は プランクの例 を作成しました:

<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>

楽しい。

8
oded

これがOPに関連しているかどうかはわかりませんが、同じ問題があり、幸いにも解決できました。

未定義エラー

まず、開発バージョンのui-bootstrapを使用しているため、(少なくとも私の場合は)未定義のエラーが発生している可能性があります。私の場合、element.popoverをバインドしようとしたときにこのエラーが発生しました。ライブラリの縮小版を追加した後、エラーはなくなりました。

ホバーするときにポップオーバーを開いたままにします

これを行うために、ui-bootstrapライブラリのpopoverを使用するカスタムディレクティブを作成しました。

ディレクティブ

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');
            });
        }
    }
};
});

このディレクティブは、ポップオーバーのカスタムテンプレートも受け入れるため、タイトルとその中のテキストだけに限定されません。独自のhtmlテンプレートを作成して、コントロールにフィードできます。

用途

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

これが将来誰かを助けることを願っています:)

編集

要求通り、ここに フィドルリンク があります。それはスタイルを欠いていますが、それが機能する方法を示す必要があります。

8
Cosmin Ionascu

Cosminにはホバーリング可能なポップオーバーの権利があると思いますが、Twitter Bootstrap popover methodを使用しているようです。このホバーリング可能なポップオーバーをAngularJSとBootstrap I Bootstrap または AngularStrap であるAngularJSのラッパー)。

したがって、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();

                });
            };
        }
    };
});

ポップオーバー要素がある場合、ポップオーバーをトリガーする要素があること、および実際のポップオーバーコンテンツを含む要素があることを考慮する必要があります。

アイデアは、実際のポップオーバーコンテンツのある要素の上にマウスを置いたときにポップオーバーを開いたままにすることです。私のディレクティブの場合、リンク関数がポップオーバーをトリガーする要素を処理し、mouseenter/mouseoutイベントハンドラーをアタッチします。

コントローラーは、AngularStrap $ popoverサービスを介してスコープとポップオーバー自体を設定します。コントローラーは、AngularStrapサービスによって返されたポップオーバーオブジェクトをスコープに追加して、リンク関数で使用できるようにします。また、メソッドattachEventsToPopoverContentを追加します。このメソッドは、popoverコンテンツを持つ要素にmouseenter/mouseoutイベントをアタッチします。

このディレクティブの使用法は次のとおりです。

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

そこで1日を費やし、ようやく解決策を見つけました。

<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>

確認してください Plunkeer Link 動的なポップオーバーボタンのコードのみを確​​認してください

おかげで、

5
Roni

トリガーは一重引用符で囲む必要があります。理由は次のとおりです。

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

デモ:

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

指令:

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

この機能はAngular UI Bootstrap 0.14.0 and documented here で追加されました。トリガーを無効にしてpopover-is-openプロパティを使用して、開閉状態を手動で指示します。

0
icfantv

ib-popoverを使用してマウスイベントを作成する最も簡単な方法以下の作業例を見てください! ib-tabsetを使用する必要はありません。私はuib-tabsetで問題に直面したため、その例を追加しました。

<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>

テンプレート:includeFile.html

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

</div>

html

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

ディレクティブ

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);
            });

        }
    }
});

注:-jQuery.js&angular.jsの後にangular-strapを含めることを忘れないでください

0

0.13.Xで私がやったことは、要素をホバーリング可能に<button>に設定してから、popover-trigger = "focus"を設定することです。次に、ボタンのスタイルを設定し、クリックしてボタンをフォーカスします。ポップオーバーにカーソルを合わせてリンクをクリックするだけです。

0
httpete