Skip to content

Commit c1215aa

Browse files
committed
feat(popover): created popovers
1 parent ddda809 commit c1215aa

File tree

13 files changed

+1028
-13
lines changed

13 files changed

+1028
-13
lines changed

Diff for: demos/service/popover/index.html

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
---
2+
name: popover
3+
component: $ionicPopover
4+
---
5+
6+
<ion-header-bar class="bar-positive" title="Popover" ng-controller="HeaderCtrl">
7+
<div class="buttons">
8+
<button class="button button-icon ion-android-more" ng-click="openPopover($event)" id="icon-btn"></button>
9+
</div>
10+
<h1 class="title">Popover</h1>
11+
<div class="buttons">
12+
<button class="button" ng-click="openPopover2($event)" id="mid-btn">Popover 2</button>
13+
<button class="button" ng-click="openPopover($event)" id="right-btn">Popover</button>
14+
</div>
15+
</ion-header-bar>
16+
17+
<ion-content class="padding has-header" ng-controller="PlatformCtrl">
18+
<p>
19+
<button class="button" ng-click="setPlatform('ios')" id="ios">iOS</button>
20+
<button class="button" ng-click="setPlatform('android')" id="android">Android</button>
21+
<button class="button" ng-click="setPlatform('base')" id="base">Base</button>
22+
</p>
23+
</ion-content>
24+
25+
<script id="popover.html" type="text/ng-template">
26+
<ion-popover-view>
27+
<ion-header-bar>
28+
<h1 class="title">Popover Header</h1>
29+
</ion-header-bar>
30+
<ion-content>
31+
<div class="list">
32+
<label class="item item-input">
33+
<span class="input-label">First Name</span>
34+
<input type="text" placeholder="">
35+
</label>
36+
<label class="item item-input">
37+
<span class="input-label">Last Name</span>
38+
<input type="text" placeholder="">
39+
</label>
40+
<label class="item item-input">
41+
<span class="input-label">Email</span>
42+
<input type="text" placeholder="">
43+
</label>
44+
<button class="button button-block button-positive">Submit</button>
45+
</div>
46+
</ion-content>
47+
</ion-popover-view>
48+
</script>
49+
50+
51+
<script id="popover2.html" type="text/ng-template">
52+
<ion-popover-view>
53+
<ion-content>
54+
<div class="list">
55+
<div class="item">
56+
Item 1
57+
</div>
58+
<div class="item">
59+
Item 2
60+
</div>
61+
<div class="item">
62+
Item 3
63+
</div>
64+
<div class="item">
65+
Item 4
66+
</div>
67+
<div class="item">
68+
Item 5
69+
</div>
70+
<div class="item">
71+
Item 6
72+
</div>
73+
</div>
74+
</ion-content>
75+
</ion-popover-view>
76+
</script>

Diff for: demos/service/popover/index.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
---
2+
name: popover
3+
component: $ionicPopover
4+
---
5+
6+
angular.module('popover', ['ionic'])
7+
8+
.controller('HeaderCtrl', function($scope, $ionicPopover) {
9+
10+
$scope.openPopover = function($event) {
11+
$scope.popover.show($event);
12+
};
13+
$ionicPopover.fromTemplateUrl('popover.html', function(popover) {
14+
$scope.popover = popover;
15+
});
16+
17+
$scope.openPopover2 = function($event) {
18+
$scope.popover2.show($event);
19+
};
20+
$ionicPopover.fromTemplateUrl('popover2.html', function(popover) {
21+
$scope.popover2 = popover;
22+
});
23+
})
24+
25+
.controller('PlatformCtrl', function($scope, $ionicPopover) {
26+
27+
$scope.setPlatform = function(p) {
28+
document.body.classList.remove('platform-ios');
29+
document.body.classList.remove('platform-android');
30+
document.body.classList.add('platform-' + p);
31+
};
32+
33+
});

Diff for: demos/service/popover/test.scenario.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
---
2+
name: popover
3+
component: $ionicPopover
4+
---
5+
6+
it('should open left side ios popover', function(){
7+
element(by.css('#ios')).click();
8+
element(by.css('#icon-btn')).click();
9+
});
10+
11+
it('should close ios popover when clicking backdrop', function(){
12+
element(by.css('.popover-backdrop.active')).click();
13+
});
14+
15+
it('should open middle ios popover', function(){
16+
element(by.css('#mid-btn')).click();
17+
});
18+
19+
it('should open right ios popover', function(){
20+
element(by.css('.popover-backdrop.active')).click();
21+
element(by.css('#right-btn')).click();
22+
});
23+
24+
it('should open left side android popover', function(){
25+
element(by.css('.popover-backdrop.active')).click();
26+
element(by.css('#android')).click();
27+
element(by.css('#icon-btn')).click();
28+
});
29+
30+
it('should close android popover when clicking backdrop', function(){
31+
element(by.css('.popover-backdrop.active')).click();
32+
});
33+
34+
it('should open middle android popover', function(){
35+
element(by.css('#mid-btn')).click();
36+
});
37+
38+
it('should open right android popover', function(){
39+
element(by.css('.popover-backdrop.active')).click();
40+
element(by.css('#right-btn')).click();
41+
});

Diff for: js/angular/directive/popover.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
/*
2+
* We don't document the ionPopover directive, we instead document
3+
* the $ionicPopover service
4+
*/
5+
IonicModule
6+
.directive('ionPopover', [function() {
7+
return {
8+
restrict: 'E',
9+
transclude: true,
10+
replace: true,
11+
controller: [function(){}],
12+
template: '<div class="popover-backdrop">' +
13+
'<div class="popover-wrapper" ng-transclude></div>' +
14+
'</div>'
15+
};
16+
}]);

Diff for: js/angular/directive/popoverView.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
IonicModule
2+
.directive('ionPopoverView', function() {
3+
return {
4+
restrict: 'E',
5+
compile: function(element) {
6+
element.append( angular.element('<div class="popover-arrow"></div>') );
7+
element.addClass('popover');
8+
}
9+
};
10+
});

Diff for: js/angular/service/modal.js

+18-13
Original file line numberDiff line numberDiff line change
@@ -112,27 +112,30 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
112112
* @description Show this modal instance.
113113
* @returns {promise} A promise which is resolved when the modal is finished animating in.
114114
*/
115-
show: function() {
115+
show: function(target) {
116116
var self = this;
117117

118118
if(self.scope.$$destroyed) {
119-
$log.error('Cannot call modal.show() after remove(). Please create a new modal instance using $ionicModal.');
119+
$log.error('Cannot call ' + self.viewType + '.show() after remove(). Please create a new ' + self.viewType + ' instance.');
120120
return;
121121
}
122122

123123
var modalEl = jqLite(self.modalEl);
124124

125125
self.el.classList.remove('hide');
126126
$timeout(function(){
127-
$document[0].body.classList.add('modal-open');
127+
$document[0].body.classList.add(self.viewType + '-open');
128128
}, 400);
129129

130-
131130
if(!self.el.parentElement) {
132131
modalEl.addClass(self.animation);
133132
$document[0].body.appendChild(self.el);
134133
}
135134

135+
if(target && self.positionView) {
136+
self.positionView(target, modalEl);
137+
}
138+
136139
modalEl.addClass('ng-enter active')
137140
.removeClass('ng-leave ng-leave-active');
138141

@@ -149,7 +152,7 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
149152
$timeout(function(){
150153
modalEl.addClass('ng-enter-active');
151154
ionic.trigger('resize');
152-
self.scope.$parent && self.scope.$parent.$broadcast('modal.shown', self);
155+
self.scope.$parent && self.scope.$parent.$broadcast(self.viewType + '.shown', self);
153156
self.el.classList.add('active');
154157
}, 20);
155158

@@ -183,15 +186,15 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
183186

184187
self.$el.off('click');
185188
self._isShown = false;
186-
self.scope.$parent && self.scope.$parent.$broadcast('modal.hidden', self);
189+
self.scope.$parent && self.scope.$parent.$broadcast(self.viewType + '.hidden', self);
187190
self._deregisterBackButton && self._deregisterBackButton();
188191

189192
ionic.views.Modal.prototype.hide.call(self);
190193

191194
return $timeout(function(){
192-
$document[0].body.classList.remove('modal-open');
195+
$document[0].body.classList.remove(self.viewType + '-open');
193196
self.el.classList.add('hide');
194-
}, 500);
197+
}, self.hideDelay || 500);
195198
},
196199

197200
/**
@@ -202,7 +205,7 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
202205
*/
203206
remove: function() {
204207
var self = this;
205-
self.scope.$parent && self.scope.$parent.$broadcast('modal.removed', self);
208+
self.scope.$parent && self.scope.$parent.$broadcast(self.viewType + '.removed', self);
206209

207210
return self.hide().then(function() {
208211
self.scope.$destroy();
@@ -224,6 +227,8 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
224227
// Create a new scope for the modal
225228
var scope = options.scope && options.scope.$new() || $rootScope.$new(true);
226229

230+
options.viewType = options.viewType || 'modal';
231+
227232
extend(scope, {
228233
$hasHeader: false,
229234
$hasSubheader: false,
@@ -234,19 +239,19 @@ function($rootScope, $document, $compile, $timeout, $ionicPlatform, $ionicTempla
234239
});
235240

236241
// Compile the template
237-
var element = $compile('<ion-modal>' + templateString + '</ion-modal>')(scope);
242+
var element = $compile('<ion-' + options.viewType + '>' + templateString + '</ion-' + options.viewType + '>')(scope);
238243

239244
options.$el = element;
240245
options.el = element[0];
241-
options.modalEl = options.el.querySelector('.modal');
246+
options.modalEl = options.el.querySelector('.' + options.viewType);
242247
var modal = new ModalView(options);
243248

244249
modal.scope = scope;
245250

246-
// If this wasn't a defined scope, we can assign 'modal' to the isolated scope
251+
// If this wasn't a defined scope, we can assign the viewType to the isolated scope
247252
// we created
248253
if(!options.scope) {
249-
scope.modal = modal;
254+
scope[ options.viewType ] = modal;
250255
}
251256

252257
return modal;

0 commit comments

Comments
 (0)