Skip to content

Commit

Permalink
feat(modal): Create a modal backdrop wrapper w/ internal modal direct…
Browse files Browse the repository at this point in the history
…ive, closes #605
  • Loading branch information
adamdbradley committed Mar 11, 2014
1 parent dcbe378 commit 7d076bd
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 23 deletions.
21 changes: 21 additions & 0 deletions js/ext/angular/src/directive/ionicModal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(function() {
'use strict';

angular.module('ionic.ui.modal', [])

/*
* We don't document the ionModal directive, we instead document
* the $ionicModal service
*/
.directive('ionModal', [function() {
return {
restrict: 'E',
transclude: true,
replace: true,
template: '<div class="modal-backdrop">' +
'<div class="modal-wrapper" ng-transclude></div>' +
'</div>'
};
}]);

})();
43 changes: 24 additions & 19 deletions js/ext/angular/src/service/ionicModal.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,34 @@
angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.service.platform', 'ngAnimate'])
angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.service.platform', 'ionic.ui.modal'])


.factory('$ionicModal', ['$rootScope', '$document', '$compile', '$animate', '$q', '$timeout', '$ionicPlatform', '$ionicTemplateLoader', function($rootScope, $document, $compile, $animate, $q, $timeout, $ionicPlatform, $ionicTemplateLoader) {
.factory('$ionicModal', ['$rootScope', '$document', '$compile', '$timeout', '$ionicPlatform', '$ionicTemplateLoader',
function( $rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTemplateLoader) {

var ModalView = ionic.views.Modal.inherit({
initialize: function(opts) {
ionic.views.Modal.prototype.initialize.call(this, opts);
this.animation = opts.animation || 'slide-in-up';
},

// Show the modal
show: function() {
var self = this;
var element = angular.element(self.el);
var modalEl = angular.element(self.modalEl);

document.body.classList.add('modal-open');
$document[0].body.classList.add('modal-open');

self._isShown = true;

if(!element.parent().length) {
self.el.classList.add(self.animation);
if(!self.el.parentElement) {
modalEl.addClass(self.animation);
$document[0].body.appendChild(self.el);
}

element.addClass('ng-enter active');
element.removeClass('ng-leave ng-leave-active');
modalEl.addClass('ng-enter active')
.removeClass('ng-leave ng-leave-active');

$timeout(function(){
element.addClass('ng-enter-active');
modalEl.addClass('ng-enter-active');
self.scope.$parent && self.scope.$parent.$broadcast('modal.shown');
}, 20);

Expand All @@ -34,25 +37,26 @@ angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.serv
}, 200);

},

// Hide the modal
hide: function() {
this._isShown = false;
var element = angular.element(this.el);
var modalEl = angular.element(this.modalEl);

element.addClass('ng-leave');
modalEl.addClass('ng-leave');

$timeout(function(){
element.addClass('ng-leave-active');
element.removeClass('ng-enter ng-enter-active active');
modalEl.addClass('ng-leave-active')
.removeClass('ng-enter ng-enter-active active');
}, 20);

$timeout(function(){
document.body.classList.remove('modal-open');
}, 400);
$document[0].body.classList.remove('modal-open');
}, 350);

ionic.views.Modal.prototype.hide.call(this);

this.scope.$parent.$broadcast('modal.hidden');
this.scope.$parent && this.scope.$parent.$broadcast('modal.hidden');

this._deregisterBackButton && this._deregisterBackButton();
},
Expand All @@ -61,12 +65,12 @@ angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.serv
remove: function() {
var self = this;
self.hide();
self.scope.$parent.$broadcast('modal.removed');
self.scope.$parent && self.scope.$parent.$broadcast('modal.removed');

$timeout(function(){
self.scope.$destroy();
self.el && self.el.parentElement && self.el.parentElement.removeChild(self.el);
}, 1000);
}, 750);
},

isShown: function() {
Expand All @@ -79,9 +83,10 @@ angular.module('ionic.service.modal', ['ionic.service.templateLoad', 'ionic.serv
var scope = options.scope && options.scope.$new() || $rootScope.$new(true);

// Compile the template
var element = $compile(templateString)(scope);
var element = $compile('<ion-modal>' + templateString + '</ion-modal>')(scope);

options.el = element[0];
options.modalEl = options.el.querySelector('.modal');
var modal = new ModalView(options);

modal.scope = scope;
Expand Down
10 changes: 6 additions & 4 deletions js/ext/angular/test/service/ionicModal.unit.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@ describe('Ionic Modal', function() {
var template = '<div class="modal"></div>';
var modalInstance = modal.fromTemplate(template);
modalInstance.show();
expect(modalInstance.el.classList.contains('modal')).toBe(true);
expect(modalInstance.el.classList.contains('slide-in-up')).toBe(true);
expect(modalInstance.el.classList.contains('modal-backdrop')).toBe(true);
expect(modalInstance.modalEl.classList.contains('modal')).toBe(true);
expect(modalInstance.modalEl.classList.contains('slide-in-up')).toBe(true);
});

it('Should show for dynamic template', function() {
Expand All @@ -30,8 +31,9 @@ describe('Ionic Modal', function() {
var modalInstance = modal.fromTemplateUrl('modal.html', function(modalInstance) {
done = true;
modalInstance.show();
expect(modalInstance.el.classList.contains('modal')).toBe(true);
expect(modalInstance.el.classList.contains('active')).toBe(true);
expect(modalInstance.el.classList.contains('modal-backdrop')).toBe(true);
expect(modalInstance.modalEl.classList.contains('modal')).toBe(true);
expect(modalInstance.modalEl.classList.contains('active')).toBe(true);
});

timeout.flush();
Expand Down

0 comments on commit 7d076bd

Please sign in to comment.