Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alirezamirian/b6cc3d5bc421d6e5338c002acde5e5bc to your computer and use it in GitHub Desktop.
Save alirezamirian/b6cc3d5bc421d6e5338c002acde5e5bc to your computer and use it in GitHub Desktop.
Replaces uibDropdownService of angular-ui/bootstrap to support nested dropdowns
(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('nested-ui-bootstrap-dropdown', ['ui.bootstrap.dropdown'])
.decorator('uibDropdownService', dropdownServiceDecorator)
.service('uibNestedDropdownService', nestedDropdownService);
function dropdownServiceDecorator(uibNestedDropdownService) {
return uibNestedDropdownService;
}
dropdownServiceDecorator.$inject = ['uibNestedDropdownService'];
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.getDropdownElement()[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) {
if (evt.target.id != '_nci_') {
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();
}
};
}
nestedDropdownService.$inject = ['$document', '$rootScope'];
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment