From 419f5a02cfe0ba310192f8216c2f8cb7c8833027 Mon Sep 17 00:00:00 2001 From: Ryan Silva Date: Thu, 19 Mar 2015 08:24:31 -0400 Subject: [PATCH 1/4] feat(dropdown): Append dropdown menu to body --- src/dropdown/docs/demo.html | 14 ++++++++++++++ src/dropdown/docs/readme.md | 3 +++ src/dropdown/dropdown.js | 27 ++++++++++++++++++++++++--- src/dropdown/test/dropdown.spec.js | 14 ++++++++++++++ 4 files changed, 55 insertions(+), 3 deletions(-) diff --git a/src/dropdown/docs/demo.html b/src/dropdown/docs/demo.html index 6487f24cfa..68b0a0945b 100644 --- a/src/dropdown/docs/demo.html +++ b/src/dropdown/docs/demo.html @@ -42,6 +42,20 @@ + +
+ + +
+

diff --git a/src/dropdown/docs/readme.md b/src/dropdown/docs/readme.md index e7bf152cf0..7f5ac7f5f0 100644 --- a/src/dropdown/docs/readme.md +++ b/src/dropdown/docs/readme.md @@ -2,3 +2,6 @@ Dropdown is a simple directive which will toggle a dropdown menu on click or programmatically. You can either use `is-open` to toggle or add inside a `` element to toggle it when is clicked. There is also the `on-toggle(open)` optional expression fired when dropdown changes state. + +Add `dropdown-append-to-body` to the `dropdown` element to append to the containing `.dropdown-menu` on the body. +This is useful when the dropdown button is inside a div with `overflow: hidden`. \ No newline at end of file diff --git a/src/dropdown/dropdown.js b/src/dropdown/dropdown.js index e01c830847..c64db922b0 100644 --- a/src/dropdown/dropdown.js +++ b/src/dropdown/dropdown.js @@ -1,4 +1,4 @@ -angular.module('ui.bootstrap.dropdown', []) +angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position']) .constant('dropdownConfig', { openClass: 'open' @@ -51,13 +51,15 @@ angular.module('ui.bootstrap.dropdown', []) }; }]) -.controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', function($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate) { +.controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', '$position', '$document', function($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate, $position, $document) { var self = this, scope = $scope.$new(), // create a child scope so we are not polluting original one openClass = dropdownConfig.openClass, getIsOpen, setIsOpen = angular.noop, - toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop; + toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop, + menu, + appendToBody = false; this.init = function( element ) { self.$element = element; @@ -70,6 +72,17 @@ angular.module('ui.bootstrap.dropdown', []) scope.isOpen = !!value; }); } + + appendToBody = angular.isDefined($attrs.dropdownAppendToBody); + + if ( appendToBody ) { + menu = element.find('.dropdown-menu'); + $document.find('body').append( menu ); + + element.on('$destroy', function handleDestroyEvent() { + menu.remove(); + }); + } }; this.toggle = function( open ) { @@ -92,6 +105,14 @@ angular.module('ui.bootstrap.dropdown', []) }; scope.$watch('isOpen', function( isOpen, wasOpen ) { + if ( appendToBody ) { + var pos = $position.positionElements(self.$element, menu, 'bottom-left', true); + pos.top += 'px'; + pos.left += 'px'; + menu.css(pos); + menu.toggle(isOpen); + } + $animate[isOpen ? 'addClass' : 'removeClass'](self.$element, openClass); if ( isOpen ) { diff --git a/src/dropdown/test/dropdown.spec.js b/src/dropdown/test/dropdown.spec.js index 262549aeea..60cb60ab9c 100644 --- a/src/dropdown/test/dropdown.spec.js +++ b/src/dropdown/test/dropdown.spec.js @@ -168,6 +168,20 @@ describe('dropdownToggle', function() { }); }); + describe('using dropdown-append-to-body', function() { + function dropdown() { + return $compile('

  • ')($rootScope); + } + + beforeEach(function() { + element = dropdown(); + }); + + it('adds the menu to the body', function() { + expect($document.find('#dropdown-menu').parent()[0]).toBe($document.find('body')[0]); + }); + }); + describe('integration with $location URL rewriting', function() { function dropdown() { From c1d610d54dceffa53f4ab112cac4fcc357e06c23 Mon Sep 17 00:00:00 2001 From: Ryan Silva Date: Thu, 19 Mar 2015 09:02:56 -0400 Subject: [PATCH 2/4] feat(dropdown): Use a directive to identify the dropdown-menu --- src/dropdown/docs/demo.html | 2 +- src/dropdown/docs/readme.md | 2 +- src/dropdown/dropdown.js | 45 +++++++++++++++++++----------- src/dropdown/test/dropdown.spec.js | 2 +- 4 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/dropdown/docs/demo.html b/src/dropdown/docs/demo.html index 68b0a0945b..f4feaa9588 100644 --- a/src/dropdown/docs/demo.html +++ b/src/dropdown/docs/demo.html @@ -45,7 +45,7 @@