Skip to content
This repository was archived by the owner on May 29, 2019. It is now read-only.

Commit 05f4bbe

Browse files
committed
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
1 parent 4a06adb commit 05f4bbe

File tree

7 files changed

+73
-11
lines changed

7 files changed

+73
-11
lines changed

Diff for: src/modal/docs/demo.html

+1
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ <h3 class="modal-title">I'm a modal!</h3>
2020
<button class="btn btn-default" ng-click="open()">Open me!</button>
2121
<button class="btn btn-default" ng-click="open('lg')">Large modal</button>
2222
<button class="btn btn-default" ng-click="open('sm')">Small modal</button>
23+
<button class="btn btn-default" ng-click="toggleAnimation()">Toggle Animation ({{ animationsEnabled }})</button>
2324
<div ng-show="selected">Selection from a modal: {{ selected }}</div>
2425
</div>

Diff for: src/modal/docs/demo.js

+8
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,12 @@ angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope
22

33
$scope.items = ['item1', 'item2', 'item3'];
44

5+
$scope.animationsEnabled = true;
6+
57
$scope.open = function (size) {
68

79
var modalInstance = $modal.open({
10+
animation: $scope.animationsEnabled,
811
templateUrl: 'myModalContent.html',
912
controller: 'ModalInstanceCtrl',
1013
size: size,
@@ -21,6 +24,11 @@ angular.module('ui.bootstrap.demo').controller('ModalDemoCtrl', function ($scope
2124
$log.info('Modal dismissed at: ' + new Date());
2225
});
2326
};
27+
28+
$scope.toggleAnimation = function () {
29+
$scope.animationsEnabled = !$scope.animationsEnabled;
30+
};
31+
2432
});
2533

2634
// Please note that $modalInstance represents a modal window (instance) dependency.

Diff for: src/modal/docs/readme.md

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ The `$modal` service has only one method: `open(options)` where available option
99
* `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`
1010
* `controllerAs` - an alternative to the controller-as syntax, matching the API of directive definitions. Requires the `controller` option to be provided as well
1111
* `resolve` - members that will be resolved and passed to the controller as locals; it is equivalent of the `resolve` property for AngularJS routes
12+
* `animation` - set to false to disable animations on new modal/backdrop. Does not toggle animations for modals/backdrops that are already displayed.
1213
* `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.
1314
* `keyboard` - indicates whether the dialog should be closable by hitting the ESC key, defaults to true
1415
* `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
3536
preventDefault on the event, then the modal will remain open. The $close and $dismiss methods return true if the
3637
event was allowed. The event itself includes a parameter for the result/reason and a boolean parameter that indicates
3738
whether the modal is being closed (true) or dismissed.
39+
40+
The `modalConfig` exposes the following global option for all modals/backdrops:
41+

Diff for: src/modal/modal.js

+31-9
Original file line numberDiff line numberDiff line change
@@ -62,17 +62,20 @@ angular.module('ui.bootstrap.modal', [])
6262
restrict: 'EA',
6363
replace: true,
6464
templateUrl: 'template/modal/backdrop.html',
65-
link: function (scope, element, attrs) {
66-
scope.backdropClass = attrs.backdropClass || '';
67-
68-
scope.animate = false;
69-
70-
//trigger CSS transitions
71-
$timeout(function () {
72-
scope.animate = true;
73-
});
65+
compile: function (tElement, tAttrs) {
66+
tElement.addClass(tAttrs.backdropClass);
67+
return linkFn;
7468
}
7569
};
70+
71+
function linkFn(scope, element, attrs) {
72+
scope.animate = false;
73+
74+
//trigger CSS transitions
75+
$timeout(function () {
76+
scope.animate = true;
77+
});
78+
}
7679
}])
7780

7881
.directive('modalWindow', ['$modalStack', '$q', function ($modalStack, $q) {
@@ -144,6 +147,17 @@ angular.module('ui.bootstrap.modal', [])
144147
};
145148
}])
146149

150+
.directive('modalAnimationClass', [
151+
function () {
152+
return {
153+
compile: function (tElement, tAttrs) {
154+
if (tAttrs.modalAnimation) {
155+
tElement.addClass(tAttrs.modalAnimationClass);
156+
}
157+
}
158+
};
159+
}])
160+
147161
.directive('modalTransclude', function () {
148162
return {
149163
link: function($scope, $element, $attrs, controller, $transclude) {
@@ -268,6 +282,9 @@ angular.module('ui.bootstrap.modal', [])
268282
backdropScope.index = currBackdropIndex;
269283
var angularBackgroundDomEl = angular.element('<div modal-backdrop></div>');
270284
angularBackgroundDomEl.attr('backdrop-class', modal.backdropClass);
285+
if (modal.animation) {
286+
angularBackgroundDomEl.attr('modal-animation', 'true');
287+
}
271288
backdropDomEl = $compile(angularBackgroundDomEl)(backdropScope);
272289
body.append(backdropDomEl);
273290
}
@@ -280,6 +297,9 @@ angular.module('ui.bootstrap.modal', [])
280297
'index': openedWindows.length() - 1,
281298
'animate': 'animate'
282299
}).html(modal.content);
300+
if (modal.animation) {
301+
angularDomEl.attr('modal-animation', 'true');
302+
}
283303

284304
var modalDomEl = $compile(angularDomEl)(modal.scope);
285305
openedWindows.top().value.modalDomEl = modalDomEl;
@@ -336,6 +356,7 @@ angular.module('ui.bootstrap.modal', [])
336356

337357
var $modalProvider = {
338358
options: {
359+
animation: true,
339360
backdrop: true, //can be also false or 'static'
340361
keyboard: true
341362
},
@@ -422,6 +443,7 @@ angular.module('ui.bootstrap.modal', [])
422443
deferred: modalResultDeferred,
423444
renderDeferred: modalRenderDeferred,
424445
content: tplAndVars[0],
446+
animation: modalOptions.animation,
425447
backdrop: modalOptions.backdrop,
426448
keyboard: modalOptions.keyboard,
427449
backdropClass: modalOptions.backdropClass,

Diff for: src/modal/test/modal.spec.js

+24
Original file line numberDiff line numberDiff line change
@@ -558,6 +558,30 @@ describe('$modal', function () {
558558
expect($document.find('div.modal-dialog')).toHaveClass('modal-custom');
559559
});
560560
});
561+
562+
describe('animation', function () {
563+
564+
it('should have animation fade classes by default', function () {
565+
open({
566+
template: '<div>Small modal dialog</div>',
567+
});
568+
569+
expect($document.find('.modal')).toHaveClass('fade');
570+
expect($document.find('.modal-backdrop')).toHaveClass('fade');
571+
});
572+
573+
it('should not have fade classes if animation false', function () {
574+
open({
575+
template: '<div>Small modal dialog</div>',
576+
animation: false
577+
});
578+
579+
expect($document.find('.modal')).not.toHaveClass('fade');
580+
expect($document.find('.modal-backdrop')).not.toHaveClass('fade');
581+
});
582+
583+
});
584+
561585
});
562586

563587
describe('multiple modals', function () {

Diff for: template/modal/backdrop.html

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
<div class="modal-backdrop fade {{ backdropClass }}"
1+
<div class="modal-backdrop"
2+
modal-animation-class="fade"
23
ng-class="{in: animate}"
34
ng-style="{'z-index': 1040 + (index && 1 || 0) + index*10}"
45
></div>

Diff for: template/modal/window.html

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
<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)">
1+
<div modal-render="{{$isRendered}}" tabindex="-1" role="dialog" class="modal"
2+
modal-animation-class="fade"
3+
ng-class="{in: animate}" ng-style="{'z-index': 1050 + index*10, display: 'block'}" ng-click="close($event)">
24
<div class="modal-dialog" ng-class="size ? 'modal-' + size : ''"><div class="modal-content" modal-transclude></div></div>
35
</div>

0 commit comments

Comments
 (0)