最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - AngularJS bootstrap popover custom directive - Stack Overflow

programmeradmin1浏览0评论

I have created a directive using bootstrap custom popover. That works taking an input from a user for a group name and it has two buttons for apply that value to model and show that value on tooltip and a button to close the popover. I am using popover java script events , Problem is that single popover works perfectly but when I open another one this popover not closing itself. Need help in closing other popovers while one is open. Here is the plnk showing the directive.

Here is the code

var app = angular.module('myApp',[]);
app.directive('customEditPopover', function () {
        return {
            restrict: 'A',
            template: '<span><i class="fa fa-tags" aria-hidden="true"></i></span>',
            scope: {
                'myModel': '=',
            },
            link: function (scope, el, attrs) {
                scope.label = attrs.popoverLabel;
                var btnsave = '#' + attrs.popoverSave;
                var btncancel = '#' + attrs.popoverCancel;
                var index = attrs.index;
                $(el).tooltip({
                    title: '' + (scope.myModel == undefined) ? "" : scope.myModel,
                    container: 'body',
                    placement: 'top'
                });
                $(el).popover({
                    trigger: 'click',
                    html: true,
                    content: attrs.popoverHtml,
                    placement: attrs.popoverPlacement,
                    container: 'body'
                })
                .on('inserted.bs.popover', function (e) {
                    bindevents();
                    $('#popovertext' + index).val(scope.myModel);
                }).on('hidden.bs.popover', function () {
                    Unbindevents();
                });
                function bindevents() {
                    $(btnsave).bind('click', function () {
                        var text = $('#popovertext' + index).val();
                        scope.myModel = text;
                        $(el).tooltip('hide')
                       .attr('data-original-title', text)
                       .tooltip('fixTitle')
                        toggle();
                    });
                    $(btncancel).bind('click', function () {
                        toggle();
                    });
                }
                function Unbindevents() {
                    $(btnsave).unbind('click');
                    $(btncancel).unbind('click');
                }
                function toggle() {
                    $(el).popover('hide');
                    $(el).click();
                }

            }
        };
    });
app.controller('MyController',['$scope',function($scope){
  $scope.list=[
    {
      name:'ABC'
    },
     {
      name:'DEF'
    },
     {
      name:'GHI'
    },
     {
      name:'KLM'
    }
    ];

}]);

Need help closing other popover while opening next one.

I have created a directive using bootstrap custom popover. That works taking an input from a user for a group name and it has two buttons for apply that value to model and show that value on tooltip and a button to close the popover. I am using popover java script events , Problem is that single popover works perfectly but when I open another one this popover not closing itself. Need help in closing other popovers while one is open. Here is the plnk showing the directive.

Here is the code

var app = angular.module('myApp',[]);
app.directive('customEditPopover', function () {
        return {
            restrict: 'A',
            template: '<span><i class="fa fa-tags" aria-hidden="true"></i></span>',
            scope: {
                'myModel': '=',
            },
            link: function (scope, el, attrs) {
                scope.label = attrs.popoverLabel;
                var btnsave = '#' + attrs.popoverSave;
                var btncancel = '#' + attrs.popoverCancel;
                var index = attrs.index;
                $(el).tooltip({
                    title: '' + (scope.myModel == undefined) ? "" : scope.myModel,
                    container: 'body',
                    placement: 'top'
                });
                $(el).popover({
                    trigger: 'click',
                    html: true,
                    content: attrs.popoverHtml,
                    placement: attrs.popoverPlacement,
                    container: 'body'
                })
                .on('inserted.bs.popover', function (e) {
                    bindevents();
                    $('#popovertext' + index).val(scope.myModel);
                }).on('hidden.bs.popover', function () {
                    Unbindevents();
                });
                function bindevents() {
                    $(btnsave).bind('click', function () {
                        var text = $('#popovertext' + index).val();
                        scope.myModel = text;
                        $(el).tooltip('hide')
                       .attr('data-original-title', text)
                       .tooltip('fixTitle')
                        toggle();
                    });
                    $(btncancel).bind('click', function () {
                        toggle();
                    });
                }
                function Unbindevents() {
                    $(btnsave).unbind('click');
                    $(btncancel).unbind('click');
                }
                function toggle() {
                    $(el).popover('hide');
                    $(el).click();
                }

            }
        };
    });
app.controller('MyController',['$scope',function($scope){
  $scope.list=[
    {
      name:'ABC'
    },
     {
      name:'DEF'
    },
     {
      name:'GHI'
    },
     {
      name:'KLM'
    }
    ];

}]);

Need help closing other popover while opening next one.

Share Improve this question asked Dec 21, 2016 at 16:43 Ghazanfar KhanGhazanfar Khan 3,7188 gold badges46 silver badges90 bronze badges 3
  • 1 I can see in the plunk nothing seems to work! – Aravind Commented Dec 28, 2016 at 17:29
  • There is bootstrap for angular directives readily available. I would remend using that over wiring up your own jquery functionality .angular-ui.github.io/bootstrap – gh9 Commented Dec 28, 2016 at 17:56
  • If @suzo answered your question you should award the bounty to him/her – gh9 Commented Jan 4, 2017 at 15:58
Add a ment  | 

2 Answers 2

Reset to default 5 +50

You can close the other popovers when show.bs.popover is triggered as shown below : Updated Plunkr

$(el).popover({
                trigger: 'click',
                html: true,
                content: attrs.popoverHtml,
                placement: attrs.popoverPlacement,
                container: 'body'
            })
             .on('show.bs.popover', function () {
              var siblings = $(el).parent().parent().siblings();
              siblings.each(function (each){
                $(siblings[each]).find('span').popover('hide');
              });
            });

IMO, the most modular way would be to use a service to track all opened PopUps.

This gives multiple benefits.

  1. You can extend the service to track different types of popups, allowing you to close all or open all or do whatever you need

  2. It removes the logic from the controls and directives on keeping track of popups. Thus they can focus on 1 specific thing. You can also run multiple controllers and popups on a page allowing each controller/popup to be a discrete unit of work and not needing to worry about other controllers/popups stomping on their items.

The cons of doing this

  1. As I mented earlier you can use the angular bootstrap directives for this. Making your code "cleaner", because all this is done for you. What is not done for you is closing all active popups. You can take the same service approach I have used and just plug it into the ng-bootstrap directives.
  2. Binding/Unbinding the JQUERY events seems to bee unresponsive when you click 8+ times. I do not have an answer for why that is, but the overall idea of using a service to keep track is still a valid one.

You shoudl be able to cut and paste this code into the plnkr or your dev box and it will work.

// Code goes here
var app = angular.module('myApp',[]);

app.factory('popUpService', function() {
  var activePopups = [];
  // factory function body that constructs shinyNewServiceInstance

  return {
  AddPopup : function(el)
  {
  activePopups.push(el);
  },
  CloseAllPopups : function(closeFunction){
  for (var i = 0; i < activePopups.length; i++)
  { 
           closeFunction(activePopups[i])

  }
  }
  }

});
app.directive('customEditPopover',['popUpService', function (popUpService) {
        return {
            restrict: 'A',
            template: '<span><i class="fa fa-tags" aria-hidden="true"></i></span>',
            scope: {
                'myModel': '=',
            },
            link: function (scope, el, attrs) {
                scope.label = attrs.popoverLabel;
                var btnsave = '#' + attrs.popoverSave;
                var btncancel = '#' + attrs.popoverCancel;
                var index = attrs.index;
                $(el).tooltip({
                    title: '' + (scope.myModel == undefined) ? "" : scope.myModel,
                    container: 'body',
                    placement: 'top'
                });
                $(el).popover({
                    trigger: 'click',
                    html: true,
                    content: attrs.popoverHtml,
                    placement: attrs.popoverPlacement,
                    container: 'body'
                })
                .on('inserted.bs.popover', function (e) {
                    bindevents();
                    $('#popovertext' + index).val(scope.myModel);
                }).on('hidden.bs.popover', function () {
                    Unbindevents();
                });
                function bindevents() {

                CloseAll();

                popUpService.AddPopup($(el));

                    $(btnsave).bind('click', function () {
                        var text = $('#popovertext' + index).val();
                        scope.myModel = text;
                        $(el).tooltip('hide')
                       .attr('data-original-title', text)
                       .tooltip('fixTitle')
                    closeCurrent();
                    });
                    $(btncancel).bind('click', function () {
                    closeCurrent();
                    });
                }
                function Unbindevents() {
                    $(btnsave).unbind('click');
                    $(btncancel).unbind('click');
                }
                function closeCurrent(){
                   $(el).popover('hide');
                 //   $(el).click();
                }
                function CloseAll() {

                popUpService.CloseAllPopups(function(popup){ 

                   popup.popover('hide');
                //    popup.click();
              });

            }
        }
        }
    }]);
app.controller('MyController',['$scope',function($scope){
  $scope.list=[
    {
      name:'ABC'
    },
     {
      name:'DEF'
    },
     {
      name:'GHI'
    },
     {
      name:'KLM'
    }
    ];

}]);
发布评论

评论列表(0)

  1. 暂无评论