Forked from sebastianhenneberg/dropdownServicePatch.js
Last active
December 10, 2017 07:54
-
-
Save alirezamirian/b6cc3d5bc421d6e5338c002acde5e5bc to your computer and use it in GitHub Desktop.
Replaces uibDropdownService 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('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