From 2f118c25ec43bff47771cef6d4d09fe7f4507427 Mon Sep 17 00:00:00 2001 From: Mario Casciaro Date: Mon, 30 Mar 2015 12:20:13 +0100 Subject: [PATCH] feat(dropdown): Make Auto-Close Dropdowns optional. Fixes #2218 Closes #3045 --- src/dropdown/docs/readme.md | 5 ---- src/dropdown/dropdown.js | 41 +++--------------------------- src/dropdown/test/dropdown.spec.js | 31 +++------------------- 3 files changed, 7 insertions(+), 70 deletions(-) diff --git a/src/dropdown/docs/readme.md b/src/dropdown/docs/readme.md index 02970d0a5f..5f42e0e829 100644 --- a/src/dropdown/docs/readme.md +++ b/src/dropdown/docs/readme.md @@ -2,13 +2,8 @@ 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 inner `dropdown-menu` to the body. -This is useful when the dropdown button is inside a div with `overflow: hidden`, and the menu would otherwise be hidden. - By default the dropdown will automatically close if any of its elements is clicked, you can change this behavior by setting the `auto-close` option as follows: * `always` - (Default) automatically closes the dropdown when any of its elements is clicked. * `outsideClick` - closes the dropdown automatically only when the user clicks any element outside the dropdown. * `disabled` - disables the auto close. You can then control the open/close status of the dropdown manually, by using `is-open`. Please notice that the dropdown will still close if the toggle is clicked, the `esc` key is pressed or another dropdown is open. - diff --git a/src/dropdown/dropdown.js b/src/dropdown/dropdown.js index eba46c4798..b469b0bec5 100644 --- a/src/dropdown/dropdown.js +++ b/src/dropdown/dropdown.js @@ -1,4 +1,4 @@ -angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position']) +angular.module('ui.bootstrap.dropdown', []) .constant('dropdownConfig', { openClass: 'open' @@ -40,14 +40,11 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position']) return; } -<<<<<<< HEAD var $element = openScope.getElement(); if( evt && openScope.getAutoClose() === 'outsideClick' && $element && $element[0].contains(evt.target) ) { return; } -======= ->>>>>>> fix(dropdown): Fix $digest:inprog on dropdown dismissal openScope.isOpen = false; if (!$rootScope.$$phase) { @@ -63,14 +60,13 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position']) }; }]) -.controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', '$position', '$document', function($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate, $position, $document) { +.controller('DropdownController', ['$scope', '$attrs', '$parse', 'dropdownConfig', 'dropdownService', '$animate', function($scope, $attrs, $parse, dropdownConfig, dropdownService, $animate) { 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, - appendToBody = false; + toggleInvoker = $attrs.onToggle ? $parse($attrs.onToggle) : angular.noop; this.init = function( element ) { self.$element = element; @@ -83,15 +79,6 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position']) scope.isOpen = !!value; }); } - - appendToBody = angular.isDefined($attrs.dropdownAppendToBody); - - if ( appendToBody && self.dropdownMenu ) { - $document.find('body').append( self.dropdownMenu ); - element.on('$destroy', function handleDestroyEvent() { - self.dropdownMenu.remove(); - }); - } }; this.toggle = function( open ) { @@ -122,15 +109,6 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position']) }; scope.$watch('isOpen', function( isOpen, wasOpen ) { - if ( appendToBody && self.dropdownMenu ) { - var pos = $position.positionElements(self.$element, self.dropdownMenu, 'bottom-left', true); - self.dropdownMenu.css({ - top: pos.top + 'px', - left: pos.left + 'px', - display: isOpen ? 'block' : 'none' - }); - } - $animate[isOpen ? 'addClass' : 'removeClass'](self.$element, openClass); if ( isOpen ) { @@ -164,19 +142,6 @@ angular.module('ui.bootstrap.dropdown', ['ui.bootstrap.position']) }; }) -.directive('dropdownMenu', function() { - return { - restrict: 'AC', - require: '?^dropdown', - link: function(scope, element, attrs, dropdownCtrl) { - if ( !dropdownCtrl ) { - return; - } - dropdownCtrl.dropdownMenu = element; - } - }; -}) - .directive('dropdownToggle', function() { return { require: '?^dropdown', diff --git a/src/dropdown/test/dropdown.spec.js b/src/dropdown/test/dropdown.spec.js index 0ca600d0c8..5e7c7dab9e 100644 --- a/src/dropdown/test/dropdown.spec.js +++ b/src/dropdown/test/dropdown.spec.js @@ -9,10 +9,6 @@ describe('dropdownToggle', function() { $document = _$document_; })); - afterEach(function() { - element.remove(); - }); - var clickDropdownToggle = function(elm) { elm = elm || element; elm.find('a[dropdown-toggle]').click(); @@ -54,6 +50,7 @@ describe('dropdownToggle', function() { var optionEl = element.find('ul > li').eq(0).find('a').eq(0); optionEl.click(); expect(element.hasClass('open')).toBe(false); + element.remove(); }); it('should close on document click', function() { @@ -69,6 +66,7 @@ describe('dropdownToggle', function() { triggerKeyDown($document, 27); expect(element.hasClass('open')).toBe(false); expect(isFocused(element.find('a'))).toBe(true); + element.remove(); }); it('should not close on backspace key', function() { @@ -180,29 +178,6 @@ describe('dropdownToggle', function() { expect(element.hasClass('open')).toBe(false); }); -<<<<<<< HEAD - }); - - 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]); - }); - - it('removes the menu when the dropdown is removed', function() { - element.remove(); - $rootScope.$digest(); - expect($document.find('#dropdown-menu').length).toEqual(0); - }); -======= ->>>>>>> fix(dropdown): Fix $digest:inprog on dropdown dismissal }); describe('integration with $location URL rewriting', function() { @@ -281,6 +256,7 @@ describe('dropdownToggle', function() { $rootScope.isopen = true; $rootScope.$digest(); expect(isFocused(element.find('a'))).toBe(true); + element.remove(); }); }); @@ -420,6 +396,7 @@ describe('dropdownToggle', function() { triggerKeyDown($document, 27); expect(element.hasClass('open')).toBe(false); expect(isFocused(element.find('a'))).toBe(true); + element.remove(); }); it('should close anyway if another dropdown is opened', function() {