Created
June 8, 2015 15:48
-
-
Save sebastianhenneberg/acb0a5e7b0e63006c699 to your computer and use it in GitHub Desktop.
Monkey patch for dropdownService of angular-ui/bootstrap to support nested dropdowns
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function() { | |
'use strict'; | |
/** | |
* This monkey-patch for the dropdownService enables to nest dropdowns. | |
* Issue: https://github.com/angular-ui/bootstrap/issues/2421 | |
* PR: https://github.com/angular-ui/bootstrap/pull/3776 | |
*/ | |
angular | |
.module('arctictenApp') | |
.config(dropdownServiceDecorator) | |
.service('nestedDropdownService', nestedDropdownService); | |
function dropdownServiceDecorator($provide) { | |
$provide.decorator('dropdownService', function($delegate, nestedDropdownService) { | |
return nestedDropdownService; | |
}); | |
} | |
function nestedDropdownService($document, $rootScope) { | |
var openScopes = []; | |
this.open = function(dropdownScope) { | |
var upperScope = getUpperScope(); | |
if (!upperScope) { | |
$document.bind('click', closeDropdown); | |
$document.bind('keydown', escapeKeyBind); | |
} | |
while(upperScope && upperScope !== dropdownScope) { | |
// contained dropdown, do not close dropdown | |
if (upperScope.getElement()[0].contains(dropdownScope.getElement()[0])) { | |
break; | |
} | |
openScopes.pop().isOpen = false; | |
upperScope = getUpperScope(); | |
} | |
openScopes.push(dropdownScope); | |
}; | |
this.close = function(dropdownScope) { | |
if (openScopes.indexOf(dropdownScope) > -1) { | |
var upperScope = getUpperScope(); | |
while (upperScope) { | |
openScopes.pop().isOpen = false; | |
if (upperScope === dropdownScope) { | |
break; | |
} | |
} | |
} | |
if ( !getUpperScope() ) { | |
$document.unbind('click', closeDropdown); | |
$document.unbind('keydown', escapeKeyBind); | |
} | |
}; | |
var getUpperScope = function() { | |
if (openScopes.length === 0) { | |
return null; | |
} | |
return openScopes[openScopes.length-1]; | |
}; | |
var closeDropdown = function(evt) { | |
var upperScope = getUpperScope(); | |
while (upperScope) { | |
// This method may still be called during the same mouse event that | |
// unbound this event handler. So check upperScope before proceeding. | |
if (!upperScope) { break; } | |
if (evt && upperScope.getAutoClose() === 'disabled' ) { break; } | |
var toggleElement = upperScope.getToggleElement(); | |
if (evt && toggleElement && toggleElement[0].contains(evt.target) ) { | |
break; | |
} | |
var $element = upperScope.getElement(); | |
if (evt && upperScope.getAutoClose() === 'outsideClick' && $element && $element[0].contains(evt.target) ) { | |
break; | |
} | |
upperScope.isOpen = false; | |
openScopes.pop(); | |
if (!$rootScope.$$phase) { | |
upperScope.$apply(); | |
} | |
// just close upper dropdown if ESC was pressed | |
if (angular.isUndefined(evt)) { | |
break; | |
} | |
upperScope = getUpperScope(); | |
} | |
}; | |
var escapeKeyBind = function(evt) { | |
if (evt.which === 27) { | |
getUpperScope().focusToggleElement(); | |
closeDropdown(); | |
} | |
}; | |
} | |
})(); |
As an older programmer late to the party, the language in current programming is hilarious. I would never dream that saying I can monkey-patch looks good on a resume. I noticed that ui.bootstrap.dropdown is deprecated along with alot of angular things in Version: 0.14.2 - 2015-10-13. So are you going to monkey patch the uibDropdownService as well? Old green horn.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
FYI... this doesn't work if minified.
Here is the same code with $inject property annotation included. The code below works with minification.