Make $ionicPopup behave like a modal (catch click events of backdrop) - angularjs

I'm using $ionicPopup.confirm() in a list to ask whether to delete the row or not.
Unfortunately a second popup opens if the user ignores the popup and taps on another Delete-icon. Then only a reload of the app helps, since the first popup stays open and isn't closable.
Is there a way to lock the backdrop so no clicks come through to the underlying page while popup is open?
(Using ionic v1.0.1)
Code
controller:
this.deleteModule = function (index, item) {
return $ionicPopup.confirm({
title: $translate.instant('moduleplan.deleteModuleTitle'),
template: $translate.instant('moduleplan.deleteModuleText'),
cancelText: $translate.instant('moduleplan.deleteModuleCancel'),
okText: $translate.instant('moduleplan.deleteModuleOk')
}).then(function (response) {
if (response) {
return deleteModule(item.id);
}
});
};
view (shortened):
<ion-content scroll="true">
<ion-list type="list-inset"
show-delete="monthCtrl.isEditing"
show-reorder="monthCtrl.isEditing">
<ion-item class="item-timeline"
ng-repeat="module in monthCtrl.modules track by $index"
option-sort
option-sort-disabled="monthCtrl.optionSortDisabled(module)">
<!-- some content -->
<ion-delete-button
class="ion-minus-circled"
ng-click="monthCtrl.deleteModule($index, module)"
ng-hide="monthCtrl.optionDeleteDisabled(module)">
</ion-delete-button>
</ion-item>
</ion-list>
</ion-content>
Edit
While popup is opened, when I click on other buttons, they don't react (and in browser the cursor does not change to hand).
Analyzing one of the delete-buttons in the DOM:
<div class="item-left-edit item-delete enable-pointer-events visible active">
<ion-delete-button class="ion-minus-circled button icon button-icon" ng-click="monthCtrl.deleteModule($index, module)" ng-hide="monthCtrl.optionDeleteDisabled(module)">
</ion-delete-button>
</div>
When I remove enable-pointer-events class from div.item-delete, then hovering the element doesn't show hand and the delete-buttons are not clickable => no second popup is opened.
enable-pointer-events is defined by { pointer-events: auto; }.
div.popup-container has z-index: 12
div.item-delete has z-index: 0
ion-item has computed z-index: 2
found a few other z-index, but the sibling near backdrop (z-index: 11) and popup-container (z-index: 12) containing my list has only z-index: 2.

Related

How to prevent menu from opening anywhere except under button

On a tablet (iPad Pro shown), if I double tap the screen to zoom in on the page, and then click to open the Menu, the menu opens under the search box but should open below the header but aligned with the logged in user.
The expected behavior is that it will always open below the logged in user offset vertically below the header.
The html pretty much looks like below. I am using flex to position the items in the header (e.g., logo, search, user) but that shouldn't impact the menu. According to the material docs (v1.1.8) By default, md-menu will attempt to align the md-menu-content by aligning designated child elements in both the trigger and the menu content. Which implies that the menu will line up as desired to the div which wraps the button,icons, and name even if I didn't already have the md-menu-origin attribute.
What would cause a zoomed tablet to cause the menu to open in the wrong location?
<md-menu-bar>
<md-menu hide show-sm show-md md-offset="0 9">
<div
class="md-icon-button"
ng-click="vm.openMenu($mdMenu, $event)"
aria-label="Open portal menu"
md-menu-origin
md-menu-align-target
role="button"
aria-label="Portal menu"
>
<span class="fa fa-user-o"></span>
<span class="user-name" ng-bind="vm.userName"></span>
<span class="fa fa-caret-down" ng-if="!$mdMenuIsOpen"></span>
<span class="fa fa-caret-up" ng-if="$mdMenuIsOpen"></span>
</div>
<md-menu-content layout="column" layout-align="start stretch" width="3">
<span>Portal Menu</span>
<md-menu-item>...</md-menu-item>
<md-menu-item>...</md-menu-item>
<md-menu-item>...</md-menu-item>
</md-menu-content>
</md-menu>
</md-menu-bar>
Check with css property set for the same.
Use position to two elements and set z-index to the two elements on which opened dropdown is getting overlapped.
Example:
(parent element)
.class1 {
position: relative;
z-index: -1;
}
(child element)
.class2 {
position: absolute;
z-index: 16;
}
Once, check with this. This answer is from CSS point of view.

ionic button on list item without ui-sref list item navigation

I've created an ionic list with a ui-sref so that when an item is clicked on, it navigates to a specific page. I have also placed a button in the upper right corner of each list item that toggles on and off (sort of like a bookmark). However, when I click the button to toggle the bookmark, the ui-sref is also triggered, causing an unwanted page navigation. Is there any way to isolate the button in an ionic list item so when clicked, the list item navigation is not triggered?
Here is my list item code with the button:
<ion-item ng-class="{'save': item.save}" collection-repeat="item in items" ui-sref="tab.page({id:item.$id})">
<button class="icon button top-right" ng-click="item.save = !item.save" ng-class="{'ion-ios-heart button-clear button-assertive':item.save, 'ion-ios-heart-outline button-clear button-stable':!item.save}"></button>
</ion-item>
You used ui-sref directive in your ion-item, that make it as a link ( like <a> tag ) and then you add your button in between, so of-course when you click on the button, it will do the page navigation.
You need to define your button outside.
<ion-item ng-class="{'save': item.save}" collection-repeat="item in items" ui-sref="tab.page({id:item.$id})">
</ion-item>
<button class="icon button top-right" ng-click="item.save = !item.save" ng-class="{'ion-ios-heart button-clear button-assertive':item.save, 'ion-ios-heart-outline button-clear button-stable':!item.save}"></button>
Update :
basically, when you have button inside a link tag, button called first and right after the link triggered. so what you need to do is somehow return false for your ui-sref eveent if button clicked.
Since you are using angularjs, you can do this ( I didn't test it, but it should work, let me know if this worked ) :
1 - add ng-click on your ion-item
<ion-item ng-click="isNavigation()" ng-class="{'save': item.save}" collection-repeat="item in items" ui-sref="tab.page({id:item.$id})">
2 - change your button ng-click to use a function
<button class="icon button top-right" ng-click="myFunctionName(item.save)" ng-class="{'ion-ios-heart button-clear button-assertive':item.save, 'ion-ios-heart-outline button-clear button-stable':!item.save}"></button>
3 - in your controller :
$rootScope.isNavigation=true;
$scope.isNavigation=function(){
if($rootScope.isNavigation)
return true;
else
return false;
}
$scope.myFunctionName(item){
$rootScope.isNavigation=false;
return item.save = !item.save;
}

ion-slides not showing inside of ion-content and div

Am new to Ionic framework (Hybrid application development) from iOS native app development. I have to design a screen which should have two button like "Recent and All". If we click "Recent" the recent items should be displayed in list and if we click the "All", it should display the all items in the list. Am trying to use the "ion-slides" control to use two different lists.
I have implemented the ion-slides in the html page inside the "ion-view", it is overlapping the two buttons (Recent, All buttons are overlapping and not clickable). If I add the "ion-slides" in "ion-content" or "div", the slides are not in visible. Also, I need to change the slides based on the button actions if I click the "Recent" button need to show the first slide. I have implemented the "ionicSlideBoxDelegate" but, it is not working. How can I fix this issue? Can you please help?
<ion-view view-title="Slide Box" ng-controller='homeViewController'>
<ion-content>
<div>
<button ng-click="nextSlide()">Recent</button>
<button ng-click="previousSlide()">All</button>
</div>
<div class="slide-wrapper1">
<ion-slides pager="false" options="sliderOptions">
<ion-slide-page>
<ion-content>
<h1>First Slide</h1>
</ion-content>
</ion-slide-page>
<ion-slide-page>
<ion-content>
<h1>Second Slide</h1>
</ion-content>
</ion-slide-page>
</ion-slides>
</div>
</ion-content>
</ion-view>
Am able see the log "Next Button clicked" but, the action is not performing.
.controller('homeViewController', function($scope, $ionicSlideBoxDelegate) {
$scope.nextSlide = function() {
console.log("Next Button clicked", $ionicSlideBoxDelegate);
$ionicSlideBoxDelegate.next();
//$ionicSlideBoxDelegate.$getByHandle('burgers').next();
}
$scope.sliderOptions = {
effect: 'slide',
pagination: false,
initialSlide: 0
}
})
It doesn't work inside the div. Keep it outside of the div it will work fine.

how to stop click event on ion-item for conditional items ionic

I am trying to disable click on ion-item for some items.
The code is something like this
<ion-item class="item (app.app_id==='isDivider')?'item-divider':'' no-border padding-20-10"
collection-repeat="app in apps"
item-width="(app.app_id==='isDivider')?5000:90"
item-height="(app.app_id==='isDivider')?70:105"
ng-click="(app.app_id==='isDivider')||listDetailsOfApps();item.clicked = true"
stop-event="click">
It is actually now not calling if app.app_id is isDivider but still clickable.
How to make it not clickable as it is header and should not be clickable
Put it inside a $scope function in your controller to detect and run other actions for clickable item:
Controller:
$scope.clickCheck = function(app){
if(app.app_id==='isDivider'){
//action for the divider. (should do nothing)
}else{
//action for the clickable item. (set item.clicked=true)
}
}
View :
Repeat item inside <div> tag and using ng-if:
<div collection-repeat="app in apps">
<ion-item ng-if="app.app_id==='isDivider'" class="item-divider no-border padding-20-10"
item-width="5000"
item-height="70">
<ion-item ng-if="app.app_id!=='isDivider'" class="no-border padding-20-10"
collection-repeat="app in apps"
item-width="90"
item-height="105"
ng-click="item.clicked=true">
</div>

Ionic side menu bar not hide properly

I have a ion menu which contain 2 links , Dashboard, favorite.
At the very first time Dashboard page is loaded for application with content. Now when i switch to another menu item. My Content seems populated first after that side menu hides. This causes user experience using the app is bad.
Can we hide side menu first then populated content.
I also tried following steps
<ion-list>
<ion-item menu-close href="#/app/articles" ng-click="toggleLeft()">
Dashboard
</ion-item>
<ion-item menu-close href="#/app/favourite" ng-click="toggleLeft()">
Favorite
</ion-item>
</ion-list>
and
$scope.toggleLeft = function() {
$ionicSideMenuDelegate.toggleLeft();
};
which also doesn't make any effect .
Here is my Dashboard page:-
<ion-view>
<ion-content>
<ion-list can-swipe="true">
<ion-item class="list article-list" ng-repeat="article in articles">
my divs
</ion-item>
</ion-list>
</ion-content>
</ion-view>
and controller is :
.controller('ArticleCtrl', function($scope, $rootScope ,articleService) {
//This is fetching data from database (**Sql lite**)
articleService.fetchArticles().then(function(articles){
$rootScope.articles = articles;
}
});
Similar code for Favorite with different controller.
Any suggestions?
Thanks
This is actually default behaviour but it can be changed. Ionic offers a few events that can be watched and you can than control when to do something. In your case I would populate the $scope only after the view fully enters the screen.
$scope.$on('$ionicView.enter', function (viewInfo, state) {
$scope.data = _getData();
});
So basically the data that you are filling the view with needs to be associated with the $scope only when the view is fully visible.
Edit:
.controller('ArticleCtrl', function($scope, $rootScope ,articleService) {
//This is fetching data from database (**Sql lite**)
var _articles;
articleService.fetchArticles().then(function(articles){
_articles = articles;
}
$scope.$on('$ionicView.enter', function (viewInfo, state) {
$scope.articles = _articles;
});
});

Resources