How to prevent Ionic modal from hidding - ionic-framework

I catch modal.hidden event, and do some check on it. When the check is false, I want to prevent the modal from hiding. I use e.preventDefault(). But it doesn't work.
My code & CodePen:
$scope.$on('modal.hidden', function(event) {
var isPassed = false;
// do some check
if (isPassed == false) {
event.preventDefault();
}
});

You can use the backdropClickToClose and hardwareBackButtonClose option when setting up the modal and also hide the back button. This will prevent the modal from being closed:
// Load the modal from the given template URL
$scope.modal = {};
$ionicModal.fromTemplateUrl('my-modal.html', {
scope: $scope,
animation: 'slide-in-up',
backdropClickToClose: false,
hardwareBackButtonClose: false
}).then(function(modal) {
$scope.modal = modal;
});
You can then do some check and set those values to true again, and also show the back button. This will still be user friendly and the user can close the modal in a proper way.
function checkSomething(){
// The timeout is only to demonstrate, do your check here
$timeout(function(){
console.log("Now user can close modal")
$scope.isPassed = true;
$scope.modal.backdropClickToClose = true;
$scope.modal.hardwareBackButtonClose = true;
}, 3000)
}
Updated codepen here

Related

TinyMCE Focus Issue with Popups

I'm using TinyMCE text editor and I would like to upload an image by clicking on a toolbar button. But when the popup window was opened..:
I can't select the input element.
I can't type any image URL into the input field.
You can access my code from this link. Please take a look at the screenshot below.
What should I do in this situation?
I've solved my issue by using the following code. I hope it helps someone else who stuck with this kind of issue
openAddCommentDialog: function(oEvent,args) {
var _this = this;
if(sap.ui.getCore().byId("codeEditorContainer")){
sap.ui.getCore().byId("codeEditorContainer").removeAllItems();
}
var commentEditor = new RTE({
editorType: sap.ui.richtexteditor.EditorType.TinyMCE4,
width:'100%',
height:'100%',
customToolbar: false,
showGroupFont: true,
showGroupLink: true,
showGroupInsert: true,
beforeEditorInit:function(oEvent){
var config = oEvent.getParameter("configuration");
config["setup"] = function(editor){
editor.on('init', function(){
if(args && args.commentMessage){
editor.setContent(args.commentMessage);
oModel.setProperty("/TicketItemModel/CommentTitle",args.commentTitle);
}
else{
if(args && args.commentTitle){
oModel.setProperty("/TicketItemModel/CommentTitle",args.commentTitle);
editor.setContent(args.commentMessage);
}
else{
oModel.setProperty("/TicketItemModel/CommentTitle","");
editor.setContent("");
}
}
})
}
}
});
if (!this._oDialogAddCommentWindow) {
this._oDialogAddCommentWindow = sap.ui.xmlfragment("BnetPortal.Application.ToDo.fragments.addComment",this);
}
sap.ui.getCore().byId("codeEditorContainer").addItem(commentEditor);
this._oDialogAddCommentWindow.open();
},

What is the need of $scope.closeModal?

Here is my code..If I remove close modal function,there is no effect. If I click any where outside the modal, the modal closes. But I need this close modal function as I need to set a flag in it for further use. How can I proceed further?
$scope.$on('$ionicView.afterEnter', function() {
$scope.openModal();
}
$ionicModal.fromTemplateUrl("settings/settingsModal.html", {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.openModal = function(){
$scope.modal.show();
}
$scope.closeModal = function(){
$scope.modal.hide();
};
}
There are a two ways of implementing modal in Ionic. One way is to add separate template and the other is to add it on top of the regular HTML file, inside script tags. First thing we need to do is to connect our modal to our controller using angular dependency injection. Then we need to create modal. We will pass in scope and add animation to our modal.
After that we are creating functions for opening, closing, destroying modal and the last two functions are place where we can write code that will be triggered if modal is hidden or removed. If you don't want to trigger any functionality when modal is removed or hidden you can delete the last two functions.
Controller's Code:
.controller('MyController', function($scope, $ionicModal) {
$ionicModal.fromTemplateUrl('my-modal.html', {
scope: $scope,
animation: 'slide-in-up'
}).then(function(modal) {
$scope.modal = modal;
});
$scope.openModal = function() {
$scope.modal.show();
};
$scope.closeModal = function() {
$scope.modal.hide();
};
//Cleanup the modal when we're done with it!
$scope.$on('$destroy', function() {
$scope.modal.remove();
});
// Execute action on hide modal
$scope.$on('modal.hidden', function() {
// Execute action
});
// Execute action on remove modal
$scope.$on('modal.removed', function() {
// Execute action
});
});
HTML Code :
<script id = "my-modal.html" type = "text/ng-template">
<ion-modal-view>
<ion-header-bar>
<h1 class = "title">Modal Title</h1>
</ion-header-bar>
<ion-content>
<button class = "button icon icon-left ion-ios-close-outline"
ng-click = "closeModal()">Close Modal</button>
</ion-content>
</ion-modal-view>
</script>
There are also other options for modal optimization. I already showed how to use scope and animation. The table below shows other options.
Modal options
The close modal function is meant for situations where you would like to close the modal manually. For example after a certain time it has been open or if something happens/the user does something for example presses a button.
There are ways of listening to when the modal is hidden/removed which will suit your situation and needs. For example:
// Execute action on hide modal
$scope.$on('modal.hidden', function() {
// Execute action
console.log('modal was hidden');
});
// Execute action on remove modal
$scope.$on('modal.removed', function() {
// Execute action
console.log('modal was removed');
});
With these you should be able to do what I understood you are wanting to do.
Straight from the documentation: http://ionicframework.com/docs/api/service/$ionicModal/

ionic how to call function when specific view load?

i need to show /hide buttons at specific ion view
and this buttons appearance depend on function
as my sample:
.controller('IntroCtrl', function ($scope, $state, $ionicSlideBoxDelegate) {
$scope.showalbums=false;
$scope.showalbums_new=true;
checkfolders();
if(hasalbums==1)
{
$scope.showalbums=true;
$scope.showalbums_new=false;
}
and in html page:
<i class="ion-images font-ion margin-right-8" ng-click="myAlbums()" ng-show="showalbums"></i>
<button class="button button-positive button-clear no-animation"
ng-click="showAlert2()" ng-if="slideIndex == 2" ng-show="showalbums_new" >
and my method in js:
var hasalbums=0;
function checkfolders()
{
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0,
function(fileSystem){ // success get file system
directoryEntry = fileSystem.root;
if( !directoryEntry.isDirectory ) {
hasalbums=0;
}
currentDir = directoryEntry; // set current directory
directoryEntry.getParent(function(par){ // success get parent
parentDir = par; // set parent directory
}, function(error){ // error get parent
hasalbums=0;
});
var directoryReader = directoryEntry.createReader();
directoryReader.readEntries(function(entries){
alert(hasalbums);
if(entries.length>0)
{
hasalbums=1;
}else{
hasalbums=0;
}
}, function(error){
hasalbums=0;
});
}, function(evt){ // error get file system
hasalbums=0;
}
);
alert(hasalbums);
}
but method not called and can't show/hide buttons as i need
while this function is working correctly
In Ionic, controllers normally only load once. So we need to use ionic's lifecycle events to trigger some logic in your controller everytime you arrive at this view. Example:
.controller('IntroCtrl', function ($scope, $state, $ionicSlideBoxDelegate) {
$scope.$on('$ionicView.loaded', function () {
checkfolders();
});
Now your checkfolders() method will be executed everytime you arrive at this view, after your content has loaded. Refer this for other lifecycle events in ionic: http://ionicframework.com/docs/api/directive/ionView/

Problems using $ionicLoading and modal view

Something strange is happening to my app. I'm using $ionicLoading to show and hide the loading template when I go to a page of my app. Everything works fine in the current page after the loading template appears, but if I open a modal page in the current view, it'll be showed but I won't be able to interact with the modal view, everything seems frozen. The app continues running but I can't select anything in the modal. I'm pretty sure that $ionicLoading is what is making this problem appears because if I eliminate it, everything works fine.
So, How could I solve it?.
.controller('AppCtrl', function($scope, $ionicModal, $timeout, $http, $ionicPopover, $rootScope,$ionicLoading) {
$ionicModal.fromTemplateUrl('templates/nuevoEvento.html', {
scope: $scope,
animation: 'slide-in-right'
}).then(function(modal) {
$scope.modalEvento = modal;
});
// Open the login modal
$scope.evento = function() {
$scope.modalEvento.show();
};
$scope.closeEvento = function() {
$scope.modalEvento.hide();
};
$scope.showLoading = function() {
$ionicLoading.show({
template: 'Loading...'
});
};
$scope.hideLoading = function(){
$ionicLoading.hide();
};
})
.controller('EventosCtrl', function($scope, $stateParams, $http, $timeout,$ionicLoading ) {
$scope.init=function(){
$scope.showLoading();
$http({method: 'GET', url: BASEPATH + '/eventos'})
.success(function(data){
$scope.hideLoading();
$scope.eventos = data;
console.log(data);
var evLeft = [];
var evRight = [];
for(var i = 0; i < data.length; i = i + 2){
evLeft.push(data[i]);
if(data[i+1]){
evRight.push(data[i+1]);
}
}
$scope.tarjetasLeft = evLeft;
$scope.tarjetasRight = evRight;
})
You said you cannot interact with the modal view.
Try the option noBackdrop (or even maybe hideOnStateChange)
More info at the docs

Closing only particular FancyBox when having multiple Fancybox

In a given page, I have multiple instances of Fancybox items that will show up an video when clicked on a link.
Apart from those, I have a function running every 5 seconds to get data from a URL and display another fancybox based on the return value.
The problem is that, as the setInterval function runs always, even if the actual video is played, it closes that video as I use $.fancybox.close().
All I wanted is to close only the fanybox identified by myModal.
This is the jQuery that I use.
$(document).ready(function() {
function myplugin() {
$.getJSON("get-status.php", function (data) {
$.each(data, function (key, status) {
if(status > 0) {
$("#myModal").fancybox().click();
}else{
$.fancybox.close(); // Works. But closes other open Fancybox if any
//$("#myModal").fancybox().close(); // Does not work
}
});
});
};
$(function() {
setInterval(function() { myplugin() }, 5000);
});
});
Well, I am not completely sure I understood your question, however since it's not very easy to know if #myModal is currently opened in fancybox (outside of the fancybox function itself), I would create a flag or switch that would be enabled from within a fancybox callback IF #myModal is the current element opened.
Then, from myplugin() I would validate if the switch is true (#myModal is the current element) and if so, close fancybox.
The script would look something like this (not tested because I don't really know what myplugin() does) :
// declare a switch to set if #myModal is open in fancybox
var myModal = false;
$(document).ready(function () {
function myplugin() {
$.getJSON("get-status.php", function (data) {
$.each(data, function (key, status) {
if (status > 0) {
$("#myModal").fancybox({
// use a callback to set the switch = true
afterShow: function () {
$(this.element).attr("id") == "myModal" ? myModal = true : myModal = false;
}
}).click();
} else {
// close fancybox if myModal == true
if (myModal) {
$.fancybox().close();
myModal = false; // reset switch ?
}
}
});
});
};
// you don't need $(function(){ }); since you have declaread .ready() above
setInterval(function () {
myplugin()
}, 5000);
});
I tried this below one and it worked.
$("#myModal").parents("div .fancybox-skin").hide();
Please advice if there any other better way to do this.