1

I am trying close my drop downs which are multiselect. below is the code I am trying :

element.bind('click', function (event) {
    event.stopPropagation();
});

$document.bind('click', function () {
    $scope.opened = false;
    $scope.$apply();
});

but once I click outside the drop down window. one click is triggering multiple click event and for each click below block of code is getting called n number of times like = 40, 90 etc I guess it is equal to number of element in the window:

$document.bind('click', function () {
    $scope.opened = false;
    $scope.$apply();
});

I tried even event.stopPropagation() just after document.bind but it did not work.

These chunk of code I have written inside the link function of directive which I created for multiselect.

dfsq
  • 191,768
  • 25
  • 236
  • 258
Krishna
  • 179
  • 3
  • 17
  • I recommend adding demo of this weird behavior. Otherwise it's hard to help you. http://plnkr.co/edit – dfsq Dec 24 '14 at 09:25

2 Answers2

3

i think this will solve your problem

post: function ($scope, element, attrs, controller) { 
  element.on("click", function(){
    console.log("in element Click event");
    $scope.onElementClick = true;
    $document.on("click", $scope.onClick);
  });

  $scope.onClick = function (event) {
    if($scope.onElementClick)
    {
      $scope.onElementClick = false;
      return;
    }
    $scope.$apply(attrs.clickAnywhereButHere)
    $document.off("click", $scope.onClick);
  };
}
Vaibhav Raut
  • 472
  • 3
  • 12
  • Hi Vaibhav, Thanks for replying but the above code close the dropdown even I click on dropdown arrow as it is internally calling onDocumentClick() method. so I cant see dropdown menu itself – Krishna Jan 02 '15 at 09:25
  • I am still waiting for solution. – Krishna Jan 05 '15 at 10:43
  • i can not understand your problem, as your information is not complete. If you provide plunker for it, then i will be able to help you. – Vaibhav Raut Jan 05 '15 at 19:28
  • [link for dropdown plnkr](http://jsfiddle.net/4sjvc/3/) is the similar plnkr link, also I found same question in stack overflow with the link below [Question](http://stackoverflow.com/questions/20186438/angular-click-outside-of-an-element-event) on which solution B is same as mine and I am facing same performance impact. Once click leads to more than 50 click event. – Krishna Jan 11 '15 at 06:01
  • Hi Vibhav, This solution really improved the performance and everytime it is causing one click event only. But I still find one issue with this if you click on drop down say D1 and close it by clicking on dropdown itself(e.g you select something from menu and drop down gets closed). Now if you again click D1 it will not open, I tried debugging it and found that $scope.onClick = function (event) is getting triggered twice – Krishna Jan 11 '15 at 10:01
0

I have solved my problem using below solution for single Select and Multi Select dropdown.

  1. Below solution can be used in production as it does not has any performance impact as such

My Approach of design I have create directive for single select as below:

.directive("selection", ['$document',
        function ($document) {
       -- your variable initialization--
       --any other method if you have like I have --
         $scope.change = function (item) {
          -------- my implementation 
     };
     $scope.selected = function (item) {
         -------- my implementation
    };
//Actual click event should be handled in link function
function link($scope, element, attributes, ngModel) {
   --other methods if you have any--
            element.bind('click', function(event) {
                    $scope.onElementClick = true;
                    $document.on("click", $scope.onClick);
                });

                 $scope.onClick = function (event) {
                    if($scope.onElementClick && $scope.opened)
                    {
                      $scope.onElementClick = false;
                      return;
                    }
                    $scope.opened = false;
                    $scope.$apply(attributes.selection);
                    $document.off("click", $scope.onClick);
                  };
                }
                return {
                restrict: 'E',
                controller: controller,
                link: link,
               scope: true,
               require: "ngModel",
               templateUrl: 'your template file(e.g: filename.tpl.html)'
        };

So above code will bind the click event with document only when you click on any single select drop down and it will unbind as soon as it gets closed because of $document.off("click", $scope.onClick);

for multi select drop down you need to handle special case like drop down should not get closed if you click on the element other wise you can not select more than one option at a time. so you have to stop the propagation of click event if it is clicked inside the element. please make below change in you click event handling inside link function:

.directive("multiSelection", ['$document',
        function ($document) {
       -- your variable initialization--
       --any other method if you have like I have --
         $scope.change = function (item) {
          -------- my implementation 
     };
     $scope.selected = function (item) {
         -------- my implementation
    };
//Actual click event should be handled in link function
function link($scope, element, attributes, ngModel) {
   --other methods if you have any--
element.bind('click', function(event) {
                $document.on("click", $scope.onClick);
                event.stopPropagation();
            });

            $scope.onClick = function (event) {
                $scope.opened = false;
                $scope.$apply(attributes.multiSelect);
                $document.off("click", $scope.onClick);
            };
         }

        return {
            restrict: 'E',
            controller: controller,
            link: link,
            require: "ngModel",
            templateUrl: 'your template file(e.g: filename.tpl.html)'
        };

Hope it helps

Krishna
  • 179
  • 3
  • 17