Wait for jquery confirm execution ends - javascript

I have a JSF commandButton that calls onclick function to confirm the action. See:
<h:commandButton actionListener="#{myMB.go}" onclick="return confirmYesOrNo('Remove Row','Are you sure ?')" />
The problem is my commandButton is clicked independent of result in confirmYesOrNo function. See:
function confirmYesOrNo(title, content, actionYes, actionNo) {
var confirmReturn;
if (!actionYes){
actionYes = function(){
return true;
}
}
$.confirm({
theme: themeDefault,
title: title,
content: content,
buttons: {
sim: {
text: 'Sim',
action: confirmReturn = actionYes,
},
nao: {
text: 'Não',
action: confirmReturn = actionNo
}
}
});
return confirmReturn;
}
AS you can see i'm trying to catch the return of button Yes(Sim) and Button No(não) to send as a return (confirmReturn). The problem is that variable confirmReturn returns before user can click in a option.
If i use normal confirm() everything works fine, the javascript waits for a option and return to onclick, but i need a more "pretty" component than default confirm().

I think you should add for both buttons :
action: function () {
return actionYes
}
action: function () {
return actionNo
}
and remove the return from below

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;
}
});

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 add a disabled button to ionic 2 alert

I created an ionic2 alert and I have to disable a button according to a condition.
This is a simple structure of my code:
import { AlertController } from 'ionic-angular';
export class MyPage {
constructor(public alertCtrl: AlertController) {
}
showCheckbox(condition) {
let alert = this.alertCtrl.create();
alert.setTitle('Which planets have you visited?');
alert.addInput({
type: 'checkbox',
label: 'Alderaan',
value: 'value1',
checked: true
});
alert.addInput({
type: 'checkbox',
label: 'Bespin',
value: 'value2'
});
alert.addButton('Cancel');
alert.addButton({
text: 'Okay',
handler: data => {
console.log('Checkbox data:', data);
this.testCheckboxOpen = false;
this.testCheckboxResult = data;
}
});
alert.present();
}
}
I have to disable Okay button if given condition is true (parameter 'condition' that passed to the showCheckbox() function).
I know the question was asked over a year ago, just in case someone other needs it.
I've created a little, I would say, "workaround", which works like a charm.
alert.present() offers a Promise, so we can listen to it, after the alert was successfully created.
Now, here's what I've done:
alert.present().then(() => {
/** disable the confirm button initial */
document.querySelector('ion-alert div.alert-button-group button:nth-of-type(2)').setAttribute('disabled', 'true');
return;
});
It's a bit hacky to access the confirm button via document.querySelector(); and the above query, but the confirm button does not has a unique identifier as I've seen it, something like role="confirm" or so.
So You need to write a function, which will be triggered on each click on Your inputs (via handler).
alert.addInput({
type: 'checkbox',
label: 'testLabel',
value: 'testValue',
handler: () => {
functionToCheckConfirmButtonState();
}
});
There You need to check Your checkbox values inside the functionToCheckConfirmButtonState(); function and enable the confirm button with:
document.querySelector('ion-alert div.alert-button-group button:nth-of-type(2)').removeAttribute('disabled');
or disable it again with:
document.querySelector('ion-alert div.alert-button-group button:nth-of-type(2)').setAttribute('disabled', 'true');
Hope I could help.
Cheers
Unkn0wn0x

noty, call a function on button click

This is a prototype function I use for displaying confirmation with buttons using noty.
function confirmation(message, call_func)
{
var m=noty(
{
text: message,
modal: true,
layout : 'center',
theme: 'notifications',
buttons: [
{
addClass: 'general-button red', text: 'Yes', onClick: function($noty)
{
call_func;
$noty.close();
}
},
{
addClass: 'general-button', text: 'No', onClick: function($noty)
{
$noty.close();
}
}]
});
return m;
}
I am calling this function with the syntax,
confirmation("Are you sure want to delete this item?", "delete("+id+")");
So on clicking the Yes button, another function delete(id) have to be called. But it does not, why?
I checked with alert, alert(call_func). I alerts as delete(10) where 10 is ID at the instance.
Well here you are not calling the function
call_func;
you are just referencing it
And here you are just building a string
"delete("+id+")")
it is not a reference to a function call.
What you need to do is pass in an actual function and execute the function.
confirmation("Are you sure want to delete this item?", function(){ delete(id); });
and
call_func();

Why won't my jQuery-ui modal dialog display two custom buttons?

I have a generic Javascript function for displaying a jQuery-ui modal dialog with two buttons -- essentially "Continue" and "Cancel", though the text varies. I'm calling it in three places in my application. What's happening is that only the second button, the "Cancel" button is being displayed. Here's the function: (String.Format is an external function I always use since Javascript doesn't have one built-in - I know it isn't the problem.)
function DisplayModalDialog(titleText, bodyText, continueText, cancelText) {
//add the dialog div to the page
$('body').append(String.Format("<div id='theDialog' title='{0}'><p>{1}</p></div>", titleText, bodyText));
//create the dialog
$('#theDialog').dialog({
width: 400,
height: "auto",
modal: true,
resizable: false,
draggable: false,
close: function (event, ui) {
$('body').find('#theDialog').remove();
$('body').find('#theDialog').destroy();
},
buttons: [
{
text: continueText,
click: function () {
$(this).dialog('close');
return true;
},
text: cancelText,
click: function () {
$(this).dialog('close');
return false;
}
}]
});
return false;
}
And here's a snippet showing how I'm calling it:
if(CheckFormDataChanged() {
var changeTitle = "Data has been changed";
var changeText = "You have updated information on this form. Are you sure you wish to continue without saving?";
var changeContinue = "Yes, continue without saving";
var changeCancel = "No, let me save";
if (DisplayModalDialog(changeTitle, changeText, changeContinue, changeCancel)) {
if (obj) obj.click();
return true;
}
}
What's wrong with my function (or the call)?
UPDATE: Here's what I'm working with now. I realized that on one of the modal dialogs I didn't need a cancel button, just an acknowledge button:
function DisplayModalDialog(titleText, bodyText, continueText, cancelText, suppressCancel) {
var def = new $.Deferred();
//add the dialog div to the page
$('body').append(String.Format("<div id='theDialog' title='{0}'><p>{1}</p></div>", titleText, bodyText));
//create the button array for the dialog
var buttonArray = [];
buttonArray.push({ text: continueText, click: function () { $(this).dialog('close'); def.resolve(); } });
if (!suppressCancel) {
buttonArray.push({ text: cancelText, click: function () { $(this).dialog('close'); def.reject(); } });
}
//create the dialog
$('#theDialog').dialog({
... dialog options ...
close: function (event, ui) { $('body').find('#theDialog').remove(); },
buttons: buttonArray
});
return def.promise();
}
And the usage:
DisplayModalDialog(changeTitle, changeText, changeContinue, changeCancel, false)
.done(function () { if (obj) obj.click(); return true; })
.fail(function () { return false; });
Just to give you some context, obj is an ASP.Net Button being passed to the client-side function; if the function returns true, the server-side OnClick event is triggered; if false, it isn't. In this case, the server-side OnClick advances to the next tab in a TabContainer (among other things). What's happening is that it's moving to the next tab anyway, even though I'm returning false in the fail() function.
Your curly braces are off:
[{
text: continueText,
click: function () {
$(this).dialog('close');
return true;
}
}, {
text: cancelText,
click: function () {
$(this).dialog('close');
return false;
}
}]
As you have it, you only have one object in your buttons array.
I can't tell yet why the button doesn't display EDIT, ah, yes I can, there's a missing curly brace.
What I can tell you that your return lines simply won't work.
The dialog box gets displayed, your function returns immediately, and processing continues, so the click callback return values are completely ignored.
What you can do instead is return a promise:
function DisplayModalDialog(titleText, bodyText, continueText, cancelText) {
var def = $.Deferred();
...
buttons: [
{
text: continueText,
click: function () {
$(this).dialog('close');
def.resolve();
}
},
{ // ah - here's your button bug - a missing brace
text: cancelText,
click: function () {
$(this).dialog('close');
def.reject();
}
}
...
return def.promise();
}
with usage:
DisplayModalDialog(changeTitle, changeText, changeContinue, changeCancel)
.done(function() {
// continue was clicked
}).fail(function() {
// cancel was clicked
});

Categories