Skip to content

Commit 6ebfe77

Browse files
committed
fix(popup): Ensure popup is usable on top of a modal, closes #838
1 parent 26c8f30 commit 6ebfe77

File tree

4 files changed

+60
-17
lines changed

4 files changed

+60
-17
lines changed

js/ext/angular/src/service/ionicPopup.js

+10-8
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
106106
});
107107
```
108108
109-
109+
110110
*/
111111
.factory('$ionicPopup', ['$rootScope', '$q', '$document', '$compile', '$timeout', '$ionicTemplateLoader',
112112
function($rootScope, $q, $document, $compile, $timeout, $ionicTemplateLoader) {
@@ -199,11 +199,13 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
199199
var el = $compile('<ion-popup-backdrop></ion-popup-backdrop>')($rootScope.$new(true));
200200
$document[0].body.appendChild(el[0]);
201201
backdropEl = el;
202+
$document[0].body.classList.add('popup-open');
202203
};
203204

204205
// Remove the backdrop element
205206
var removeBackdrop = function() {
206207
backdropEl.remove();
208+
$document[0].body.classList.remove('popup-open');
207209
};
208210

209211
// Push the new popup onto the stack with the given data and scope.
@@ -259,8 +261,8 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
259261
}
260262

261263
var buildPopupTemplate = function(opts, content) {
262-
return '<ion-popup title="' + opts.title + '" buttons="buttons" on-button-tap="onButtonTap(button, event)" on-close="onClose(button, result, event)">'
263-
+ (content || '') +
264+
return '<ion-popup title="' + opts.title + '" buttons="buttons" on-button-tap="onButtonTap(button, event)" on-close="onClose(button, result, event)">'
265+
+ (content || '') +
264266
'</ion-popup>';
265267
};
266268

@@ -346,7 +348,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
346348
* subTitle: '', // String (optional). The sub-title of the popup
347349
* templateUrl: '', // URL String (optional). The URL of a template to load as the content (instead of the `content` field)
348350
* scope: null, // Scope (optional). A scope to apply to the popup content (for using ng-model in a template, for example)
349-
* buttons:
351+
* buttons:
350352
* [
351353
* {
352354
* text: 'Cancel',
@@ -369,7 +371,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
369371
* }
370372
* }
371373
* ]
372-
*
374+
*
373375
* }
374376
* ```
375377
*/
@@ -386,7 +388,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
386388
*
387389
* ```javascript
388390
* $ionicPopup.alert({
389-
* title: 'Hey!;,
391+
* title: 'Hey!',
390392
* content: 'Don\'t do that!'
391393
* }).then(function(res) {
392394
* // Accepted
@@ -479,7 +481,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
479481
* @ngdoc method
480482
* @name $ionicPopup#prompt
481483
* @description show a simple prompt dialog.
482-
*
484+
*
483485
* ```javascript
484486
* $ionicPopup.prompt({
485487
* title: 'Password Check',
@@ -532,7 +534,7 @@ angular.module('ionic.service.popup', ['ionic.service.templateLoad'])
532534
]
533535
});
534536
}
535-
537+
536538
};
537539
}]);
538540

js/ext/angular/test/modal.html

+9-1
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ <h1 class="title">New Contact</h1>
5959
<button class="button button-block button-positive" ng-click="hideModal()">Hide Modal</button>
6060
<button class="button button-block button-positive" ng-click="removeModal()">Remove Modal</button>
6161
<button class="button button-block button-positive" ng-click="openActionSheet()">ActionSheet</button>
62+
<button class="button button-block button-positive" ng-click="openPopup()">Popup</button>
6263
</div>
6364
</div>
6465
</ion-content>
@@ -86,7 +87,7 @@ <h1 class="title">New Contact</h1>
8687

8788
})
8889

89-
.controller('ModalCtrl', function($scope, $ionicActionSheet) {
90+
.controller('ModalCtrl', function($scope, $ionicActionSheet, $ionicPopup) {
9091
$scope.hideModal = function() {
9192
$scope.modal.hide();
9293
};
@@ -132,6 +133,13 @@ <h1 class="title">New Contact</h1>
132133
});
133134
};
134135

136+
$scope.openPopup = function() {
137+
$ionicPopup.alert({
138+
title: 'Hey!',
139+
content: 'Don\'t do that!'
140+
}).then(function(res) {});
141+
};
142+
135143
});
136144

137145
domTrace.observe();

js/ext/angular/test/service/ionicPopup.unit.js

+29-8
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
describe('Ionic Popup', function() {
2-
var popup, timeout, scope;
2+
var popup, timeout, scope, document;
33

44
beforeEach(module('ionic'));
55

6-
beforeEach(inject(function($ionicPopup, $rootScope, $timeout) {
6+
beforeEach(inject(function($ionicPopup, $rootScope, $timeout, $document) {
77
ionic.requestAnimationFrame = function(cb) { cb(); }
88
scope = $rootScope;
99
popup = $ionicPopup;
1010
timeout = $timeout;
11+
document = $document;
12+
document[0].body.className = '';
1113
}));
1214

1315
it('Should show popup', function() {
@@ -22,13 +24,13 @@ describe('Ionic Popup', function() {
2224
}
2325
]
2426
});
25-
27+
2628
timeout.flush();
2729

28-
var popupBackdropEl = document.body.querySelector('.popup-backdrop');
30+
var popupBackdropEl = document[0].body.querySelector('.popup-backdrop');
2931
expect(popupBackdropEl).not.toEqual(null);
3032

31-
var popupEl = document.body.querySelector('.popup');
33+
var popupEl = document[0].body.querySelector('.popup');
3234
expect(popupEl.classList.contains('active')).toBe(true);
3335
expect(popupEl.classList.contains('popup-showing')).toBe(true);
3436

@@ -43,11 +45,11 @@ describe('Ionic Popup', function() {
4345
}
4446
]
4547
});
46-
48+
4749
timeout.flush();
4850

4951
// Make sure there are two popups
50-
expect(document.body.querySelectorAll('.popup').length).toEqual(2);
52+
expect(document[0].body.querySelectorAll('.popup').length).toEqual(2);
5153
});
5254

5355
it('Should set correct element data', function() {
@@ -63,8 +65,27 @@ describe('Ionic Popup', function() {
6365
]
6466
});
6567

66-
var popupEl = document.body.querySelector('.popup');
68+
var popupEl = document[0].body.querySelector('.popup');
6769
expect(popupEl.querySelector('.popup-title').innerText).toEqual('Cats');
6870
expect(popupEl.querySelector('.popup-body').innerText).toEqual('Dogs');
6971
});
72+
73+
it('Should add .popup-open from body', function() {
74+
expect(document[0].body.classList.contains('popup-open')).toEqual(false);
75+
76+
popup.show({
77+
title: 'Cats',
78+
content: 'Dogs',
79+
buttons: [
80+
{
81+
text: 'Okay',
82+
type: 'button-balanced',
83+
onTap: function(e) {}
84+
}
85+
]
86+
});
87+
88+
timeout.flush();
89+
expect(document[0].body.classList.contains('popup-open')).toEqual(true);
90+
});
7091
});

scss/_popup.scss

+12
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,18 @@
7777
}
7878
}
7979

80+
.popup-open {
81+
pointer-events: none;
82+
83+
&.modal-open .modal {
84+
pointer-events: none;
85+
}
86+
87+
.popup-backdrop, .popup {
88+
pointer-events: auto;
89+
}
90+
}
91+
8092
.popup-backdrop {
8193
@include animation-name(fadeIn);
8294
@include animation-duration($popup-backdrop-fadein-duration);

0 commit comments

Comments
 (0)