Popover Does Not Display When Opened - javascript

I set up a basic example with Ionic Popover. However, when I open the popover, the opacity stays at zero, preventing the popover from showing. I know the method openPopover is called because I receive the opened console log in my web console. If I remove the opacity property from the console, the popover displays.
My controller..
angular.module('search')
.controller('SearchResultsController', searchResultsController)
searchResultsController.$inject = ['$ionicPopover', '$scope'];
function searchResultsController($ionicPopover, $scope) {
var vm = this;
vm.openPopover = openPopover;
activate();
function activate( ) {
$ionicPopover.fromTemplateUrl('/templates/search/filter-popover.html', {
scope: $scope
}).then(function(popover) {
console.log(popover)
vm.popover = popover;
});
}
function openPopover( $event ) {
console.log("opened")
vm.popover.show($event);
}
}
My view page...
<ion-view hide-nav-bar="true">
<signed-in-header></signed-in-header>
<ion-content class="padding has-header">
<div class="row">
<div class="col col-75 text-left">
<div>4 RESULTS FOR "263355"</div>
</div>
<div class="col col-25 text-right">
<div ng-click="searchResults.openPopover()">
<i class="icon ion-arrow-down-b"></i>
Filter
</div>
</div>
</div>
</ion-content>
<ion-footer-bar>
Ad here 1
</ion-footer-bar>
</ion-view>
My popover template.
<ion-popover-view>
<ion-header-bar>
<h1 class="title">My Popover Title</h1>
</ion-header-bar>
<ion-content>
Hello!
</ion-content>
</ion-popover-view>
Why does the popover not show and how can I fix this?

I did some digging in the ionic CSS for popover, and the opacity is set to 0 by default. You can override the opacity to 1 and the popover will display, but I found this: https://github.com/driftyco/ionic/issues/2343. Basically, you have to pass the event ($event) to popover.show() and it will work. The ionic example shows this but the documentation could be more explicit. In your code, change your template to ng-click="searchResults.openPopover($event)".

In my case i just didn't put the popover component in the entryComponent section in my shared module. I didn’t get an error until I restarted the server, don't know why

Related

Why an ionic modal freezes the UI when it is closed or submitted?

I have a popover which two options -Add Favorite and Add Comment-, the first options is working correctly: it does not freeze the user interface; but the second one once the form is omitted or submitted freezes the interface. This is what is happening:
Note how when I close the form the interface does not respond.
This is the code I have used to create the popover and and modal:
$ionicPopover.fromTemplateUrl('templates/dish-detail-popover.html',{
scope: $scope})
.then(function(popover){
$scope.popover = popover;
});
$scope.openPopover = function($event){
$scope.popover.show($event);
}
$scope.closePopover = function() {
$scope.popover.hide();
};
$ionicModal.fromTemplateUrl('templates/dish-comment.html', {
scope: $scope
}).then(function(modal) {
$scope.commentModal = modal;
});
// Triggered in the reserve modal to close it
$scope.closeAddComment = function() {
$scope.commentModal.hide();
};
// Open the reserve modal
$scope.showCommentModal = function($event) {
$scope.closePopover();
$scope.commentModal.show($event);
};
The template for dish-detail-popover.html:
<ion-popover-view>
<ion-content>
<div class="list">
<a class="item" ng-click="addFavorite(dish.id)">
Add to favorites
</a>
<a class="item" ng-click="showCommentModal()">
Add Comment
</a>
</div>
</ion-content>
</ion-popover-view>
and the template for dish-comment.html:
<ion-modal-view>
<ion-header-bar>
<h1 class="title">Submit Comment on Dish</h1>
<div class="buttons">
<button class="button button-clear" ng-click="closeAddComment()">Close</button>
</div>
</ion-header-bar>
<ion-content>
<form id="comentDishForm" name="comentDishForm" ng-submit="doComment()">
<div class="list">
<label class="item item-input item-select">
<span class="input-label">Rating</span>
<select ng-model="comment.rating">
<option ng-repeat="n in [1,2,3,4,5]" value="{{n}}">{{n}}</option>
</select>
</label>
<label class="item item-input">
<span class="input-label">Your Name</span>
<input type="text" ng-model="comment.author">
</label>
<label class="item item-input">
<span class="input-label">Your Comment</span>
<input type="text" ng-model="comment.comment">
</label>
<label class="item">
<button class="button button-block button-positive" type="submit">Submit</button>
</label>
</div>
</form>
</ion-content>
</ion-modal-view>
NOTE: When the form is called from the Add Comment button (the green one), it works correctly. The failure is related when it called from the popover.
Some suggestions, or ideas,... to solve this?
The screen gets freezed because despite closing the popover before opening the modal, the body tag remains dirty with the class 'popover-open'. A quick solution, but not the neatest, is to close the popover again when closing the modal. This way, ionic framework will remove the class 'popover-open' from the body tag. Example:
$scope.$on('modal.hidden', function() {
$scope.closePopover();
});
Hope it helps.
I also ran into the same issue and had no idea why this was happening. Reading the Ionic docs about ionicPopover, I found that the .hide() method is actually returning a promise which will resolve once the popover is animated out. So, what you can actually do is setup your closePopover() method as follows:
$scope.closePopover = function () {
return $scope.popover.hide();
};
As for the method to be executed when someone clicks the "Add Comment" option, you can implement that as follows:
$scope.addComment = function addComment() {
$scope.closePopover()
.then(function() {
$scope.openAddCommentModal();
});
};
This will ensure that the modal is only shown once the popover is completely animated out and those classes are removed from the body tag. This will clear the dirty states and make the app respond.

Auto scroll to bottom with ng-repeat in Ionic

I have a problem that become a realy nightmare. I build a mobile chat app with Ionic, Angular and Firebase. The message exchange works well, but i have problem with auto scroll do bottom when received new messages, i try use $ionicScrollDelegate, scroll-glue Directive, Jquery function and nothing works.
Page chat
<div ng-controller="ChatController as chatCtrl" id="chats_page" class="upage-content vertical-col left hidden has-subheader">
<div class="bar bar-subheader subheader-chat">
<h2 class="title">{{chatCtrl.status}}</h2>
</div>
<div class="" data-uib="layout/row" data-ver="0" id="chatBox">
<ion-content id="autoscroll" class="widget uib_w_92 d-margins topbar" data-uib="ionic/list" data-ver="0" delegate-handle="mainScroll">
<ion-list scroll-glue>
<ion-item ng-repeat="msg in chatCtrl.messages" class="item widget uib_w_93 chat-cliente item-text-wrap" data-uib="ionic/list_item" data-ver="0" ng-class="chatCtrl.getRole(msg.role)">{{msg.text}}<a class="chat-time">{{msg.time}}</a>
</ion-item>
</ion-list>
</ion-content>
</div>
<div class="bar bar-footer footer-chat" >
<i class="placeholder-icon "></i>
<textarea type="text" name="msg" placeholder="Digite sua mensagem..." class="chat-text" ng-disabled="chatCtrl.msgText()" ng-model="myMsg" ></textarea>
<button class="button ion-paper-airplane btn-chat-send" ng-click="chatCtrl.sendMsg(myMsg)" ng-disabled="chatCtrl.msgText()" id='btn_send_chat'></button>
</div>
</div>
And piece of ChatController
angular.module('myApp')
.controller("ChatController", ['User','FireBaseApp','$firebase','$ionicLoading','$timeout','$ionicPlatform','$location','$ionicHistory','$timeout','$ionicPopup','$ionicScrollDelegate','$scope',function(User, FireBaseApp ,$firebase, $ionicLoading,$timeout,$ionicPlatform,$location,$ionicHistory,$timeout,$ionicPopup,$ionicScrollDelegate,$scope){
var self = this;
... pieces of code ...
self.sendMsg = function(msg){
$scope.myMsg = null;
$ionicScrollDelegate.scrollBottom();
}
You can use.
$ionicScrollDelegate.scrollBottom(true);
Example on codepen
After a year i found a solution: Separate my app in angular template and finally scrollglue works.

ng-click outside form dosen't get data

click i dosen't get the form data when button is outside form
code
<ion-view title="Indstillinger">
<ion-nav-buttons side="right">
<button class="button" form="userForm" ng-click="update()">
Gem
</button>
</ion-nav-buttons>
<ion-content padding="true" class="has-header">
<form id="userForm">
<ion-list>
<label class="item item-input" name="navn">
<span class="input-label">Navn</span>
<input type="text" placeholder={{user.name}} ng-model="name">
</label>
</ion-list>
</form>
</ion-content>
i tried add form id to form and button, but i still dosen't get the form data on ngclick :/
update:
$scope.update = function() {
console.log(this.name);
})
ion-content creates a child scope. The input element is setting the "name" property on this scope, not the scope being used in the ion-nav-buttons section.
This is the classic "dot notation" issue in Angular.
If you are using an "outer" controller:
<div ng-controller="outer as vm">
<ion-view title="Indstillinger">
<ion-nav-buttons side="right">
<button class="button" form="userForm" ng-click="update()">
Gem
</button>
</ion-nav-buttons>
<ion-content padding="true" class="has-header">
<form id="userForm">
<ion-list>
<label class="item item-input" name="navn">
<span class="input-label">Navn</span>
<input type="text" placeholder={{user.name}} ng-model="vm.name">
</label>
</ion-list>
</form>
</ion-content>
</div>
.controller('outer', function($scope) {
$scope.user = {
name: "Joe"
}
$scope.update = function()
{
console.log($scope.vm.name);
}
})
You will want to use:
console.log($scope.name);
instead of:
console.log(this.name);
since you didn't post the rest of HTML or the rest of controller code , this is the only answer I can possibly provide
$scope.update = function() {
console.log($scope.name);
})
I know you said that it doesn't work , but that code is in fact valid and does work. Something else that you refused to post is breaking
Did you check console for errors? I'm sure there are some, did you confirm that angular is properly loaded, did you properly set add ng-app and ng-controller ?
1) Try moving your <button ng-click="update"> outside of your <ion-nav-buttons> container and see if it works.
2) If it works, read this: Transcluding ng-click in a directive

Reset data on click for a different controller

I have two divs - the first contains the second. The contained div has its own controller. When I click an icon button in the container, I change a variable which then affects the visibility of the contained div.
It looks like this:
<div ng-controller="BarController">
<div class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="col-lg-2 page-title">My Page</div>
<div class="col-lg-10">
<span class="actions">
<i class="fa fa-lg fa-download fa-inverse" tooltip="Download"
ng-click="showSecondaryBar=!showSecondaryBar"></i>
</span>
</div>
</div>
</div>
<div class="download navbar download-in download-out"
ng-class="{'myhidden': !showSecondaryBar}"
ng-cloak>
<div class="col-lg-offset-4 col-lg-4 form-inline form-group" ng-controller="TagsController">
<div class="download-label col-lg-6">
<label>Download by tags:</label>
</div>
<div class="download-tags col-lg-6">
<tags-input class="bootstrap" spellcheck="false" min-length="1" ng-model="tags" add-from-autocomplete-only="true">
<auto-complete source="loadTags($query)" min-length="1" load-on-down-arrow="true"
load-on-focus="true" max-results-to-show="5"
highlight-matched-text="false"></auto-complete>
</tags-input>
</div>
</div>
</div>
</div>
The <tags-input> is taken from ng-tags-input and I would like to reset the tags that were already typed to it whenever the icon button is clicked (which changes the visilibyt of the div that contains the ng-tags-input).
Problem is, because I have the TagsController which contains the data (tags) and this data is not visible in the BarController, I'm not sure how I can reset the tags array to become empty.
I thought of using a service but it fills like too much of a coupling. I would prefer to have a function in TagsController which is called upon click. But I can't figure out how to do it from another controller
You are right you have to use a service.
Why don't you use a broadcast as your TagsController is included in BarController?
You can include a scope.broadcast("Event") in BarController
Then a "on" listener on TagsController who will reset the tags array when "Event" Occur.
I would personnaly to this.
https://docs.angularjs.org/api/ng/type/$rootScope.Scope
You can use $broadcast on $rootScope to send an event to TagsController. So TagsController can receive this event by registering an event listener for it. See following example.
Refer to $rootScope API docs
angular.module('app',[])
.controller('ParentController', function($rootScope) {
var parentCtrl = this;
parentCtrl.someFlag = true;
parentCtrl.changeFlag = function() {
parentCtrl.someFlag = !parentCtrl.somFlag;
$rootScope.$broadcast('resettags', {'defaultTags': 'whatever_tag'});
}
})
.controller('ChildController', function($rootScope){
var childCtrl = this;
childCtrl.tags = "Some tags entered by user";
$rootScope.$on('resettags', function(event, args) {
childCtrl.tags = args.defaultTags;
});
});
.myHidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div id="main" ng-controller="ParentController as parentCtrl">
<button type="button" ng-click="parentCtrl.changeFlag()">Toggle</button>
<div ng-class="{'myHidden' : !parentCtrl.someFlag}">
<div ng-controller="ChildController as childCtrl">
<h1>{{childCtrl.tags}}</h1>
</div>
</div>
</div>
</div>

No ion-slide-box update after active-slide changed with $index

This is the controller for the particular view with which I'm having an issue.
.controller('MenuCtrl', ['$rootScope','$scope','$state','$timeout','$ionicSlideBoxDelegate',
function($rootScope, $scope, $state, $timeout, $ionicSlideBoxDelegate) {
$scope.state = { detail: false, selected: 0 };
$scope.stateSwitch = function() {
$scope.state.detail = !$scope.state.detail;
$timeout( function() { $ionicSlideBoxDelegate.update(); }, 50);
}
$scope.activateSlide = function($index) {
$ionicSlideBoxDelegate.slide($index);
}
Here is the view.
<ion-view left-buttons="leftButtons">
<ion-content class="has-header" has-tabs="true" ng-show="!state.detail">
<div class="list menu-list">
<a class="item" ng-repeat="item in items" ng-click="stateSwitch();activateSlide($index)">
...
</a>
</div>
</ion-content>
<ion-content class="has-header padding" has-tabs="true" ng-show="state.detail">
<div class="menu-detail">
<ion-slide-box does-continue="true" show-pager="false">
<ion-slide ng-repeat="item in items">
...
</ion-slide>
</ion-slide-box>
</div>
</ion-content>
</ion-view>
Upon clicking the list item, it triggers the state.detail flag which switches the view to a menu item detail page. From the menu item detail page, I'm using ion-slide-box so that users can paginate through the items as well.
This works great when I don't specify which slide index to start on. Even when I do pick a static number to start the slider on, it works. However, when I use the $index of the menu list as an argument to change the active slide on the slide box, the slide box just smashes all the slides together and their is no swipe functionality.
This happens even after I update the slide box.
Is there something wrong with how I am using $index? Or perhaps this was not the intended way to dynamically set the active slide? Any advice would be appreciated!
on your controller in your function $scope.activateSlide use without $ on index
here code that worked for me:
on html:
<h4 ng-repeat="type in view.menu.itens" ng-click="changeSlide($index)"></h4>
on my controller
$scope.changeSlide = function funChangeSlide(index) {
$ionicSlideBoxDelegate.slide(index);
}

Categories

Resources