$ionicPopup: e.preventDefault() gets ignored - javascript

I'm using the following code for some validation stuff using both $ionicPopup and Firebase:
onTap: function(e) {
firebase.auth().applyActionCode($scope.data.emailcnfrm)
.then(function() {
return $scope.data.emailcnfrm;
},
function(error) {
alert("wrong code");
e.preventDefault();
});
}
But In the case of error, and after I get the "wrong code" alert, the popup gets closed, as e.preventDefault(); has been ignored.
So what's exactly wrong in my code? and how can I fix this problem?

Your call to firebase.auth().applyActionCode is asynchronous, and e.preventDefault will be called asynchronously in the error callback. This happens after the user has already invoked onTap, thus e.preventDefault won't have any effect.
Edit (a proposed fix)
To fix it, you could separate the async logic from the onTap method:
var myPopup = $ionicPopup.show({
onTap: function(e) {
// always keep the popup open, because we'll decide when to close it later
e.preventDefault();
}
});
myPopup.then(function(res) {
firebase.auth().applyActionCode($scope.data.emailcnfrm)
.then(function() {
// if successful, imperatively close the popup
myPopup.close();
}, function(err) {
// log the error, or something
});
});

Finally I solved the problem by using my own trick:
-outside Async:
$scope.myPopup = $ionicPopup.show({
scope: $scope, buttons: [
{ text: 'Cancel' },
{
text: '<b>Done</b>',
type: 'button-positive',
onTap: function(e)
{
// always keep the popup open, because we'll decide when to close it later
e.preventDefault();
$AsyncCallback();
}
}
]
});
$scope.myPopup.then(function(){},
function(error)
{
$ionicPopup.alert({
title: 'Internal error!',
template: error
});
});
-inside async:
$scope.myPopup.close();

Related

How to prevent closing bootbox while using async function?

What I'm trying to get is if an user gets any validation error, then bootbox will show that "this is required". Till now, I've achieved this. But the main problem is that - it closes the window of boot box if the user clicks "Yes" button.
I'm getting this because I had to use g async callback in bootbox. For this reason, even after returning false, the bootbox is closing. But I want users to show the box until they press the cancel button. If they click Yes, then it should show the validation, with the box opened. This is my code:
bootbox.confirm({
message: 'Test',
buttons: {
confirm: {
label: 'Yes',
className: 'btn-primary'
},
cancel: {
label: 'No',
className: 'btn-danger'
}
},
callback: async function (result) {
var isValid = $('#form').valid();
if (result && !isValid) {
return false; //it's not working. It's closing the bootbox
}
if (result && isValid) {
/* for this await function I had to use async callback,
without this bootbox is opend
*/
var data = await self.createData();
$.ajax({
type: "POST",
success: function (result) {
},
}).then(function () {
});
}
}
});
How can I resolve this?
It does not appear to me that bootbox.confirm() has any sort of support for async callbacks like you are trying to use. The bootbox closes when your callback returns which will be at the point you hit your first await unless you explicitly return false, but an async callback function ALWAYS returns a promise which is not explicitly false. You cannot change that.
What you can do is make your callback a regular callback function, not async that can return false if validation fails and then create an embedded async function where you can use await that you call from within that first callback like is shown below. Note that the bootbox will close before your asynchronous code completes so if there are any errors in the bootbox code, you will need to new way to present those errors, perhaps putting up a new bootbox. Here's one way to do this code while still using await.
bootbox.confirm({
message: 'Test',
buttons: {
confirm: {
label: 'Yes',
className: 'btn-primary'
},
cancel: {
label: 'No',
className: 'btn-danger'
}
},
callback: function (result) {
var isValid = $('#form').valid();
if (result) {
if (!isValid) {
// keep prompt open until user presses Cancel
return false;
}
async function run() {
const data = await self.createData();
const result = await $.ajax({ ... });
// do something with result
}
// now call async function here (dialog will close)
run().catch(err => {
// do something with an error here
console.log(err);
});
}
return true;
}
});
Alternatively, you could avoid using await and only use .then() and .catch() and then you wouldn't need this extra layer of function:
bootbox.confirm({
message: 'Test',
buttons: {
confirm: {
label: 'Yes',
className: 'btn-primary'
},
cancel: {
label: 'No',
className: 'btn-danger'
}
},
callback: function (result) {
var isValid = $('#form').valid();
if (result) {
if (!isValid) {
// keep prompt open until user presses Cancel
return false;
}
self.createData().then(data => {
return $.ajax({ ... }).then(result => {
// do something with result
});
}).catch(err => {
// do something with error here
console.log(err);
});
}
return true;
}
});

Electron app close dialog with message box confirmation

I use Electron v13.0.1 from this repo
Need close confirmation, use this implementation:
win.on('close', function (e) {
require('electron').dialog.showMessageBox(this, {
type: 'question',
buttons: ['Yes', 'No'],
title: 'Confirm',
message: 'Are you sure you want to quit?'
}).then(function (data) {
if (data.response === 0) {
e.preventDefault();
}
});
});
But when I click on the close button dialog appeared on second and the application close without any confirmation or rejection. In other words, the dialog does not create conjunction for close.
What is the problem with my solution?
The problem is that you are calling an asynchronous method and the event function continues execution and eventually returns, before any user input is given.
One way to solve this is to use the showMessageBoxSync function for synchronous operation. This will wait until user selects an option before continuing execution. Like below:
const { dialog } = require('electron');
win.on('close', function (e) {
let response = dialog.showMessageBoxSync(this, {
type: 'question',
buttons: ['Yes', 'No'],
title: 'Confirm',
message: 'Are you sure you want to quit?'
});
if(response == 1) e.preventDefault();
});

PreventDefault SweetAlert2

I got this function that override my native js alerts:
function alert(message, title = 'Test', type = 'info')
{
// event.preventDefault();
if(typeof(swal) != 'undefined') {
swal({
html: message,
title: title,
type: type,
width: '24rem',
}).then((result) => {
return result.value;
});
}
else {
alert(message);
}
}
At the end of my PHP functions, i have an alert('success'), and then i redirect to another page. With the native JS alert, it waits me to click the OK button to continue. Now with this swal function, it shows the alert and redirects immediatly. Is there a way to avoid this behavior and act like the native alert, without changing the function signature?
The difference is that the alert() is modal. This means it blocks all other input and output until it's dismissed. The Sweetalert is not.
You can make it behave in a similar manner by using a callback function which you execute when the OK button is clicked in the Sweetalert. You can do that by passing the function to alert(), then calling it in the then() block, like this:
function alert(message, title = 'Test', type = 'info', callback) {
if (typeof(swal) != 'undefined') {
swal({
html: message,
title: title,
type: type,
width: '24rem',
}).then(() => {
callback && callback();
});
} else {
alert(message);
callback && callback();
}
}
// example usage:
alert('foo bar', 'title', 'info', function() {
window.location.assign('somewhere_else.php');
});

how to close sweet alert on ajax request completion

I am using Sweet-alert in my angular app.
function GetDataFromServer(url) {
SweetAlert.swal(
{
title: "",
text: "Please wait.",
imageUrl: "../../app/app-img/loading_spinner.gif",
showConfirmButton: false
});
return $http.get(url)
.then(success)
.catch(exception);
function success(response) {
//SweetAlert.swal(
// {
// title: "",
// text: "data loaded",
// });
return response.data;
}
function exception(ex) {
return (ex);
}
}
Req #1 (Main Objective of my this post)
What I am looking for is when the ajax request completes i.e.,
controls enters in the then(), Sweet alert should automatically hide.
Req #2
Also while request processing, I don't want to have the Close pop-up button (Ok button) in the sweet alert.
As per the documentation,showConfirmButton: false should hide it but it's not.
Any help/suggestion highly appreciated.
Thanks.
For automatically hiding the pop-over when it's done, you should set your initial pop-over to a variable so you can access it later. Maybe:
function GetDataFromServer(url) {
SweetAlert.swal({
title: "",
text: "Please wait.",
imageUrl: "../../app/app-img/loading_spinner.gif",
showConfirmButton: false
});
return $http.get(url)
.then(success)
.catch(exception);
function success(response) {
swal.close()
return response.data;
}
function exception(ex) {
return (ex);
}
}
It's right on: https://t4t5.github.io/sweetalert/ in the methods section near the bottom.
Since you don't have a specific 'way' you want to do hide the ok button and you're just looking for suggestions, you could always just use a little CSS to target it and give it the ol display: none; setup.
You can close current showing sweetalert by using below line of code anywhere you want.
swal.close();
That's it!
You can use the close method over the sweet object see the documentation in down part
https://t4t5.github.io/sweetalert/
swal.close(); --> Close the currently open SweetAlert programmatically.
self.showProgress = function(message) {
swal({ title: message });
swal.showLoading();
};
self.hideProgress = function() {
swal.close();
};
SweetAlert has close method if you check the docs at http://t4t5.github.io/sweetalert/
You can use SweetAlert.close() to close the sweetalert in angular.
If you use swal2 you can close it using Swal.close() from anywhere inside your code for closing it when ajax is complete I think the code below is an easy way:
$(document).ajaxComplete(function () {
Swal.close();
});
swal does not work with sync function (ex. get), you need make call get async
swal({
type: 'warning',
text: 'Please wait.',
showCancelButton: false,
confirmButtonText: "ok",
allowOutsideClick: false,
allowEscapeKey: false
}).then(function (result) {
if (result) {
setTimeout(function () {
$http.get(url)
}, 500);
}
});
if you are using the AngularJS library known as angular-sweetalert then use swal.close(); to close the alert window.
angular-sweetalert is a wrapper on the core sweetalert library package.
Cache the swal() to trigger it later.
function GetDataFromServer(url) {
let swalAlert = SweetAlert.swal; // cache your swal
swalAlert({
title: "",
text: "Please wait.",
imageUrl: "../../app/app-img/loading_spinner.gif",
showConfirmButton: false
});
return $http.get(url)
.then(success)
.catch(exception);
function success(response) {
swalAlert.close(); // this is what actually allows the close() to work
return response.data;
}
function exception(ex) {
return (ex);
}
}

record being deleted without confirmation?

I am using bootbox dialogs for confirming before deleting records.
here is my jQuery script for confirmation before deleting record.
<a class="btn btn-xs btn-danger" id="deleteContent" title="Delete">delete</a>
$('#deletec').click(function (e) {
bootbox.dialog({
message: "you data is save",
title: "Custom title",
buttons: {
success: {
label: "Success!",
className: "btn-success",
callback: function () {
Example.show("great you save it");
}
},
danger: {
label: "Danger!",
className: "btn-danger",
callback: function () {
Example.show("record deleted!");
}
}
}
});
});
it is showing correct dialog but the record being deleted without taking confirmation, can anyone please tell me how can i prevent deletion of record without confirmation ? Thanks in advance.
You can not do what you want because the modal dialog that you are using has no way of pausing the click action. You would need to have to cancel the click action and than make that call.
One way is just to unbind click and call it again
$('#deleteContent').on("click", function (e) {
e.preventDefault();
bootbox.dialog({
message: "you data is save",
title: "Custom title",
buttons: {
success: {
label: "Success!",
className: "btn-success",
callback: function () {
Example.show("great you save it");
}
},
danger: {
label: "Danger!",
className: "btn-danger",
callback: function () {
Example.show("record deleted!");
$('#deleteContent').off("click")[0].click();
}
}
}
});
});
As I said in my comments above, making a delete request with a get is a BAD idea. If a user has a plugin that prefetches pages, say goodbye to all your data in the database.
What happens in the code
e.preventDefault(); Cancels the click event so it will not go to the server
$('#deleteContent').off("click") //removes the click event so it will not be called again
[0].click() //selects the DOM element and calls the click event to trigger the navigation

Categories