Alan Alan - 4 months ago 74
AngularJS Question

How can I modify ui.bootstrap.dropdown to respond to a mouse hover over the drop button?

I would like to use the ui.bootstrap.dropdown message box to display text information (not links) in a similar way to the ui.bootstrap.popover. I would like to modify this directive as it does 99% of what I need and I don't want to add all the additional JS that the popover requires.

In other words I would like the "dropdown list area" to display when the user hovers the mouse over the down arrow and then go away when they move the mouse away from the down arrow.

Is there a way that I could add an option to the ui.bootstrap.dropdown so hovering the mouse over the arrow would show and hide the dropdown box. I don't want to place any links in this box.

I hope someone has some ideas that could help me with suggesting how I could change this directive that comes with the ui.bootstrap.dropdown:

.directive('dropdownToggle', function () {
return {
require: '?^dropdown',
link: function (scope, element, attrs, dropdownCtrl) {
if (!dropdownCtrl) {
return;
}

dropdownCtrl.toggleElement = element;

var toggleDropdown = function (event) {
event.preventDefault();

if (!element.hasClass('disabled') && !attrs.disabled) {
scope.$apply(function () {
dropdownCtrl.toggle();
});
}
};

element.bind('click', toggleDropdown);

// WAI-ARIA
element.attr({ 'aria-haspopup': true, 'aria-expanded': false });
scope.$watch(dropdownCtrl.isOpen, function (isOpen) {
element.attr('aria-expanded', !!isOpen);
});

scope.$on('$destroy', function () {
element.unbind('click', toggleDropdown);
});
}
};

Answer

This only requires a little extra CSS to accomplish. You didn't provide your markup in the question, so I'm just using the button group examples from the doc. If you provide your specific markup, I'll adjust this answer accordingly.

@import "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css";


.btn-group:hover>.dropdown-menu {
  display: block;
}
<!doctype html>
<html ng-app="ui.bootstrap.demo">

<head>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular.js"></script>
  <script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.12.0.js"></script>


</head>

<body>

  <div ng-controller="DropdownCtrl">

    <!-- Single button -->
    <div class="btn-group" dropdown is-open="status.isopen">
      <button type="button" class="btn btn-primary dropdown-toggle" dropdown-toggle ng-disabled="disabled">
        Button dropdown <span class="caret"></span>
      </button>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Action</a>
        </li>
        <li><a href="#">Another action</a>
        </li>
        <li><a href="#">Something else here</a>
        </li>
        <li class="divider"></li>
        <li><a href="#">Separated link</a>
        </li>
      </ul>
    </div>

    <!-- Split button -->
    <div class="btn-group" dropdown>
      <button type="button" class="btn btn-danger">Action</button>
      <button type="button" class="btn btn-danger dropdown-toggle" dropdown-toggle>
        <span class="caret"></span>
        <span class="sr-only">Split button!</span>
      </button>
      <ul class="dropdown-menu" role="menu">
        <li><a href="#">Action</a>
        </li>
        <li><a href="#">Another action</a>
        </li>
        <li><a href="#">Something else here</a>
        </li>
        <li class="divider"></li>
        <li><a href="#">Separated link</a>
        </li>
      </ul>
    </div>

  </div>
  <script>
    angular.module('ui.bootstrap.demo', ['ui.bootstrap']);
    angular.module('ui.bootstrap.demo').controller('DropdownCtrl', function($scope, $log) {
      $scope.items = [
        'The first choice!',
        'And another choice for you.',
        'but wait! A third!'
      ];

      $scope.status = {
        isopen: false
      };

      $scope.toggled = function(open) {
        $log.log('Dropdown is now: ', open);
      };

      $scope.toggleDropdown = function($event) {
        $event.preventDefault();
        $event.stopPropagation();
        $scope.status.isopen = !$scope.status.isopen;
      };
    });
  </script>
</body>

</html>

Really all that the dropdown does is add an open class to the parent element when it is clicked. The Bootstrap CSS contains a rule that causes the child element with the .dropdown-menu class to be have it's display property set to block:

.open>.dropdown-menu {
  display: block;
}

Therefore, to cause the menu to display when you hover, you can use the :hover pseudo class in CSS to do the same. In this example, I attached the rule to the .btn-group parent element as such:

.btn-group:hover>.dropdown-menu {
  display: block;
}