feat(modal): add option to disable animations
Note: Move backdropClass logic into compile function because otherwise modifying classes in the compile function is broken when using an interpolated class attribute. Fixes #1007 Closes #2725
This commit is contained in:
@@ -20,5 +20,6 @@
|
||||
<button class="btn btn-default" ng-click="open()">Open me!</button>
|
||||
<button class="btn btn-default" ng-click="open('lg')">Large modal</button>
|
||||
<button class="btn btn-default" ng-click="open('sm')">Small modal</button>
|
||||
<button class="btn btn-default" ng-click="toggleAnimation()">Toggle Animation ({{ animationsEnabled }})</button>
|
||||
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
|
||||
</div>
|
||||
@@ -2,9 +2,12 @@ angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope
|
||||
|
||||
$scope.items = ['item1', 'item2', 'item3'];
|
||||
|
||||
$scope.animationsEnabled = true;
|
||||
|
||||
$scope.open = function (size) {
|
||||
|
||||
var modalInstance = $modal.open({
|
||||
animation: $scope.animationsEnabled,
|
||||
templateUrl: 'myModalContent.html',
|
||||
controller: 'ModalInstanceCtrl',
|
||||
size: size,
|
||||
@@ -21,6 +24,11 @@ angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope
|
||||
$log.info('Modal dismissed at: ' + new Date());
|
||||
});
|
||||
};
|
||||
|
||||
$scope.toggleAnimation = function () {
|
||||
$scope.animationsEnabled = !$scope.animationsEnabled;
|
||||
};
|
||||
|
||||
});
|
||||
|
||||
// Please note that $modalInstance represents a modal window (instance) dependency.
|
||||
|
||||
@@ -9,6 +9,7 @@ The `$modal` service has only one method: `open(options)` where available option
|
||||
* `controller` - a controller for a modal instance - it can initialize scope used by modal. Accepts the "controller-as" syntax in the form 'SomeCtrl as myctrl'; can be injected with `$modalInstance`
|
||||
* `controllerAs` - an alternative to the controller-as syntax, matching the API of directive definitions. Requires the `controller` option to be provided as well
|
||||
* `resolve` - members that will be resolved and passed to the controller as locals; it is equivalent of the `resolve` property for AngularJS routes
|
||||
* `animation` - set to false to disable animations on new modal/backdrop. Does not toggle animations for modals/backdrops that are already displayed.
|
||||
* `backdrop` - controls presence of a backdrop. Allowed values: true (default), false (no backdrop), `'static'` - backdrop is present but modal window is not closed when clicking outside of the modal window.
|
||||
* `keyboard` - indicates whether the dialog should be closable by hitting the ESC key, defaults to true
|
||||
* `backdropClass` - additional CSS class(es) to be added to a modal backdrop template
|
||||
@@ -35,3 +36,6 @@ Finally, a `modal.closing` event is broadcast to the modal scope before the moda
|
||||
preventDefault on the event, then the modal will remain open. The $close and $dismiss methods return true if the
|
||||
event was allowed. The event itself includes a parameter for the result/reason and a boolean parameter that indicates
|
||||
whether the modal is being closed (true) or dismissed.
|
||||
|
||||
The `modalConfig` exposes the following global option for all modals/backdrops:
|
||||
|
||||
|
||||
+32
-10
@@ -62,17 +62,20 @@ angular.module('ui.bootstrap.modal', [])
|
||||
restrict: 'EA',
|
||||
replace: true,
|
||||
templateUrl: 'template/modal/backdrop.html',
|
||||
link: function (scope, element, attrs) {
|
||||
scope.backdropClass = attrs.backdropClass || '';
|
||||
|
||||
scope.animate = false;
|
||||
|
||||
//trigger CSS transitions
|
||||
$timeout(function () {
|
||||
scope.animate = true;
|
||||
});
|
||||
compile: function (tElement, tAttrs) {
|
||||
tElement.addClass(tAttrs.backdropClass);
|
||||
return linkFn;
|
||||
}
|
||||
};
|
||||
|
||||
function linkFn(scope, element, attrs) {
|
||||
scope.animate = false;
|
||||
|
||||
//trigger CSS transitions
|
||||
$timeout(function () {
|
||||
scope.animate = true;
|
||||
});
|
||||
}
|
||||
}])
|
||||
|
||||
.directive('modalWindow', ['$modalStack', '$q', function ($modalStack, $q) {
|
||||
@@ -144,6 +147,17 @@ angular.module('ui.bootstrap.modal', [])
|
||||
};
|
||||
}])
|
||||
|
||||
.directive('modalAnimationClass', [
|
||||
function () {
|
||||
return {
|
||||
compile: function (tElement, tAttrs) {
|
||||
if (tAttrs.modalAnimation) {
|
||||
tElement.addClass(tAttrs.modalAnimationClass);
|
||||
}
|
||||
}
|
||||
};
|
||||
}])
|
||||
|
||||
.directive('modalTransclude', function () {
|
||||
return {
|
||||
link: function($scope, $element, $attrs, controller, $transclude) {
|
||||
@@ -212,7 +226,7 @@ angular.module('ui.bootstrap.modal', [])
|
||||
// Closing animation
|
||||
scope.animate = false;
|
||||
|
||||
if ($animate.enabled()) {
|
||||
if (domEl.attr('modal-animation') && $animate.enabled()) {
|
||||
// transition out
|
||||
domEl.one('$animate:close', function closeFn() {
|
||||
$rootScope.$evalAsync(afterAnimating);
|
||||
@@ -268,6 +282,9 @@ angular.module('ui.bootstrap.modal', [])
|
||||
backdropScope.index = currBackdropIndex;
|
||||
var angularBackgroundDomEl = angular.element('<div modal-backdrop></div>');
|
||||
angularBackgroundDomEl.attr('backdrop-class', modal.backdropClass);
|
||||
if (modal.animation) {
|
||||
angularBackgroundDomEl.attr('modal-animation', 'true');
|
||||
}
|
||||
backdropDomEl = $compile(angularBackgroundDomEl)(backdropScope);
|
||||
body.append(backdropDomEl);
|
||||
}
|
||||
@@ -280,6 +297,9 @@ angular.module('ui.bootstrap.modal', [])
|
||||
'index': openedWindows.length() - 1,
|
||||
'animate': 'animate'
|
||||
}).html(modal.content);
|
||||
if (modal.animation) {
|
||||
angularDomEl.attr('modal-animation', 'true');
|
||||
}
|
||||
|
||||
var modalDomEl = $compile(angularDomEl)(modal.scope);
|
||||
openedWindows.top().value.modalDomEl = modalDomEl;
|
||||
@@ -336,6 +356,7 @@ angular.module('ui.bootstrap.modal', [])
|
||||
|
||||
var $modalProvider = {
|
||||
options: {
|
||||
animation: true,
|
||||
backdrop: true, //can be also false or 'static'
|
||||
keyboard: true
|
||||
},
|
||||
@@ -422,6 +443,7 @@ angular.module('ui.bootstrap.modal', [])
|
||||
deferred: modalResultDeferred,
|
||||
renderDeferred: modalRenderDeferred,
|
||||
content: tplAndVars[0],
|
||||
animation: modalOptions.animation,
|
||||
backdrop: modalOptions.backdrop,
|
||||
keyboard: modalOptions.keyboard,
|
||||
backdropClass: modalOptions.backdropClass,
|
||||
|
||||
@@ -558,6 +558,30 @@ describe('$modal', function () {
|
||||
expect($document.find('div.modal-dialog')).toHaveClass('modal-custom');
|
||||
});
|
||||
});
|
||||
|
||||
describe('animation', function () {
|
||||
|
||||
it('should have animation fade classes by default', function () {
|
||||
open({
|
||||
template: '<div>Small modal dialog</div>',
|
||||
});
|
||||
|
||||
expect($document.find('.modal')).toHaveClass('fade');
|
||||
expect($document.find('.modal-backdrop')).toHaveClass('fade');
|
||||
});
|
||||
|
||||
it('should not have fade classes if animation false', function () {
|
||||
open({
|
||||
template: '<div>Small modal dialog</div>',
|
||||
animation: false
|
||||
});
|
||||
|
||||
expect($document.find('.modal')).not.toHaveClass('fade');
|
||||
expect($document.find('.modal-backdrop')).not.toHaveClass('fade');
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('multiple modals', function () {
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<div class="modal-backdrop fade {{ backdropClass }}"
|
||||
<div class="modal-backdrop"
|
||||
modal-animation-class="fade"
|
||||
ng-class="{in: animate}"
|
||||
ng-style="{'z-index': 1040 + (index && 1 || 0) + index*10}"
|
||||
></div>
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
<div modal-render="{{$isRendered}}" tabindex="-1" role="dialog" class="modal fade" ng-class="{in: animate}" ng-style="{'z-index': 1050 + index*10, display: 'block'}" ng-click="close($event)">
|
||||
<div modal-render="{{$isRendered}}" tabindex="-1" role="dialog" class="modal"
|
||||
modal-animation-class="fade"
|
||||
ng-class="{in: animate}" ng-style="{'z-index': 1050 + index*10, display: 'block'}" ng-click="close($event)">
|
||||
<div class="modal-dialog" ng-class="size ? 'modal-' + size : ''"><div class="modal-content" modal-transclude></div></div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user