12

I am trying to hide a DIV on blur (the focus has been removed from the DIV). I am using angular and bootstrap. So far I have tried setting "focus" on the DIV when it is shown and then an ng-blur function when the user click anywhere else on the screen. This is not working.

Basically the problem is I cannot set focus on my "#lockerBox" through JS, my "hideLocker" function works no problem when focus is given to my DIV with clicking it.

<div class="lock-icon" ng-click="showLocker(result); $event.stopPropagation();"></div>
<div ng-show="result.displayLocker" id="lockerBox" ng-click="$event.stopPropagation();" ng-blur="hideLocker(result)" tabindex="1">

  $scope.displayLocker = false;
  $scope.showLocker = function ( result ) {

    $scope.displayLocker = !$scope.displayLocker;
    node.displayLocker = $scope.displayLocker;

    function setFocus() {
      angular.element( document.querySelector( '#lockerBox' ) ).addClass('focus');
    }

    $timeout(setFocus, 100);
  };


  $scope.hideLocker = function ( node ) {
    $scope.displayLocker = false;
    node.displayLocker = $scope.displayLocker;
  };
user1876246
  • 1,219
  • 5
  • 18
  • 33
  • Did you try passing $event to your hideLocker and then calling $event.target.focus()? Also I would get rid of the stopPropagation business unless you really need it. – Mike Cheel Jul 16 '14 at 14:07
  • No, the target could be any other element on the screen. I need the focus set in the 'showLocker' function. And the element that is the target of that event is another DIV unrelated to the DIV I need to give focus to. – user1876246 Jul 16 '14 at 14:10
  • What about ng-focus and a property on your view model? If you can get ng-focus on the right element then all you have to do is modify your model. – Mike Cheel Jul 16 '14 at 14:19
  • why are you using focus and blur on `div` elements that aren't contenteditable? What is objective? – charlietfl Jul 16 '14 at 15:03

3 Answers3

24

Just add tabindex="-1" attr to the div and it gives it the same behave like an input -

<div tabindex="-1" ng-blur="onBlur()"></div>

https://jsfiddle.net/ast12nLf/1/

(Inspired from here - https://stackoverflow.com/a/17042452/831294)

URL87
  • 10,667
  • 35
  • 107
  • 174
  • tabindex-1 means [here](http://webaim.org/techniques/keyboard/tabindex) A tabindex="-1" value removes the element from the default navigation flow (i.e., a user cannot tab to it), but it allows it to receive programmatic focus, meaning focus can be set to it from a link or with scripting.** This can be very useful for elements that should not be tabbed to, but that may need to have focus set to them. – Anand Rockzz Mar 02 '19 at 08:01
0

I ended up just setting the blur event on the element that has the onclick.

Ralf de Kleine
  • 11,464
  • 5
  • 45
  • 87
user1876246
  • 1,219
  • 5
  • 18
  • 33
0

Even I had the same problem - but was able to resolve it using 'mouseup' event on the entire document in a custom directive following is the code, where I am toggling an accordion contained in a div as pop-up using ng-show()="variable" now this variable is the key here across menu toggle button HTML Element, div pop up HTML Element, and the custom directive to handle mouse up!

var dummyDirective = angular.module(dummyDirective, []);
dummyDirective.directive('hideOnMouseUpElsewhere', function() {
  return {
    restrict: 'A',
    link: function(scope, element, attr) {

      $(document).mouseup(function(e) {
        var container = $(element);

        if (!container.is(e.target) // if the target of the click isn't the container...
          && container.has(e.target).length === 0 && scope.status.menuVisible // ... nor a descendant of the container
          && !(e.target.id === attr.excludeClick)) // do not execute when clicked on this 
        {
          scope.status.menuVisible = false;
          scope.$apply();
        }
      });
    }
  }
})

where container will have the DOM element you applied 'hideOnMouseUpElsewhere' directive on along with added attribute 'excludeClick' and e.target is the one DOM element where you click

Following is the HTML code for a accrodian bootstrap angular popup menu:

<a id="MenuAnchor" href="" data-toggle="dropdown" class="dropdown-toggle" ng-click="status.menuVisible = !status.menuVisible;">
  <i id= "MenuIcon" class="glyphicon glyphicon-cog" style="font-size:20px; color: #428bca; cursor:pointer;"></i>
</a>
<div  id ="MenuPane"  ng-blur="status.menuVisible=false;" hide-on-mouse-up-elsewhere exclude-click='MenuIcon'>
 <div class="btn-group favoritesMenu" style="width: 300px;" ng-show="status.menuVisible"  >
 <accordion close-others="true">
  <accordion-group > 
    <accordion-heading>....</accordion-heading>
    <div ng-click="status.menuVisible=false;">Data</div>
  </accordion-group> 
 </accordion>
user15091
  • 11
  • 1