I'm trying to use alertify.js as a confirmation dialog for all my confirm scripts. But it just isn't working like regular JS confirm does. In the code below I never get a return true
function aConf ( mes ) {
alertify.confirm( mes, function (e) {
return e;
});
}
Delete
Of course if I replace aConf with JS' confirm it works. So why is alertify not sending me back it's outcome?
Because confirm is a blocking function (no javascript will run until it returns true/false), and alertify is non-blocking (JS keeps executing). Alertify does not immediately return a true/false, but instead, it probably returns undefined immediately, then it calls a callback function later, after the user clicks OK or Cancel. The return value from that callback function has no effect in your example, because the onclick code has already finished running (because it is non-blocking).
Assuming you are using this: https://github.com/fabien-d/alertify.js/
This is how it actually works with a callback function, not a return value:
alertify.confirm( message, function (e) {
if (e) {
//after clicking OK
} else {
//after clicking Cancel
}
});
For your code sample, you might try something like this:
function performDelete ( a_element ) {
// perform your delete here
// a_element is the <a> tag that was clicked
}
function confirmAction ( a_element, message, action ) {
alertify.confirm(message, function(e) {
if (e) {
// a_element is the <a> tag that was clicked
if (action) {
action(a_element);
}
}
});
}
Delete
EDIT: updated to be a generic confirm dialog that calls a callback function if the user clicks ok.
Related
Please check out my diagram, and the pseudo-code below. I'm trying to figure out how to pass a function between two event listeners.
Basically, I want to execute some code if "Availability" is less than 0, OR when a user clicks "confirm" in a bootstrap dialog. If the Availability is greater than 0, you'll get the special bootstrap dialog.
I'm trying to avoid writing the same code twice. I'm also trying to avoid using trigger $("#btnConfirm").trigger("click", fn1); --- my assumption is that there is a sexier way, like a callback, or something...
So.... how do I get the code I want to execute into the other 'button click' event listener --OR-- how do I return "btnConfirm" back to the event listener that called the dialog?
$("#Select").on("change", function(e) {
fn1 = function() {
//stuff I want to do
};
//a check that must be passed
currAvail = $("#Availability").val();
if (currAvail > 0) {
//show a message, "Are you sure you want to make the thing?"
//if YES, execute fn1()
//fn1() needs to be available to btnConfirm click listener
// use trigger("click", fn1) ????
} else {
//execute the code
fn1();
};
});
$("#btnConfirm").on("click", function(e, param1) {
//Ok, well, they said YES...
//so I need to execute fn1();
});
Since the requirement is to call fn1() in both cases, you can separate the logic out into a method and call when it is needed
function fn1() {
//code to execute on no goes here
}
$("#Select").on("change", function(e) {
let currAvail = $("#Availability").val();
if (currAvail > 0) {
//show modal window
} else {
//execute the code
fn1();
};
});
$("#btnConfirm").on("click", function(e, param1) {
fn1()
});
Why not just move the function definition to outside the change callback?
$("#Select").on("change", function(e) {
//a check that must be passed
currAvail = $("#Availability").val();
if (currAvail > 0) {
//show a message, "Are you sure you want to make the thing?"
//if YES, execute fn1()
//fn1() needs to be available to btnConfirm click listener
// use trigger("click", fn1) ????
} else {
//execute the code
fn1();
};
});
$("#btnConfirm").on("click", function(e, param1) {
//Ok, well, they said YES...
//so I need to execute fn1();
});
// Function move to here.
function fn1() {
//stuff I want to do
};
I made confirm function which shows special div to confirm or not. The task is, when I confirm some action I need to call another function, which I need to write into onClick attribute in my button.
There is what I want:
<button onClick="jsShowConfirmDiv(); jsMyFunction()">
<span>Edit</span>
</button>
This is one button, but another will be something like this:
<button onClick="jsShowConfirmDiv(); jsAnotherFunction()">
<span>Detail</span>
</button>
I need to call my functions (jsMyFunction() and jsAnotherFunction() only when I click on button yes.
For better imagination there is function in actual version (working, but limitless by parameter, and I think, than that is bad solution):
function jsShowConfirmMessage(content, yesFunction, par1, par2, par3) {
$("id_confirm_message").setAttribute("classType", "confirm");
$("id_popup_confirm_content").innerHTML = content;
$("id_confirm_message_overlay").className = "popup_visible";
window.location.hash = "#id_confirm_message_overlay";
$("id_confirm_yes").stopObserving('click');
$("id_confirm_yes").observe('click', function() {
jsHideConfirmMessage();
if (!par1) {
yesFunction();
} else if (!par2) {
yesFunction(par1);
} else if (!par3) {
yesFunction(par1, par2);
} else {
yesFunction(par1, par2, par3);
}
});
}
And I call it like this:
<button onClick="jsShowConfirmMessage('Really?', jsSpecialFunction, 'param')">
<span>Edit</span>
</button>
Thank you for your answer.
If user click no (or cancel, ...) you can throw an exception. Exception stop executing commands and second (third, ....) function will not be called.
Is there anyway to call a function when for example pressing a close button on a modal window that will take different action depending on the function that opened the modal window?
So say for example we had a landing page with items to click on that showed a image of that item in a modal window and a certain function was called when the image was opened from this context and we had a search side nav-bar that displayed items and when these were clicked the function that opened the modal windows was different from the first. Now when closing the modal window, and depending on the function that was called to open the modal, I would like to write a condition that would allow me to either go back to landing page or return to side nav-bar.
I don't have any code to show, but I was wondering if such a thing is possible; writing a condition based on the function that was previously called? What would be the command for that condition?
So
function 1 () {
doSomething;
}
function 2 () {
doAnotherThing;
}
$("closeButton").on('click', function () {
if (function 1 was called) {
// do something else
} else if (function2 was called) {
// do another thing
}
}
Could something like that be possible?
var fnClicked = null
function fn1() {
fnClicked = fn1;
doSomething();
}
function fn2() {
fnClicked = fn2;
doAnotherThing();
}
$('closeButton').on('click', function(){
if (fnClicked === fn1) {
//do something else
} else if (fnClicked === fn2) {
//do another thing
}
});
Alternatively you could hav fn1 and fn2 unbind the closebutton click event and rebind it to the appropriate followup.
In an MVC framework, you can bind a property to the related view. If not, you can always keep bind state to the window object.
If you also don't want to do that, you can keep the state in the DOM (the close button) as an attribute. For example, a data-attribute.
$("closeButton").on('click', function (e) {
var state = $(e.currentTarget).data("state");
}
You can use data attributes on the modal element to store info that indicates what area the modal was opened from. Then when closing the modal, look in that attribute and decide what to do based on the value stored there when the modal was opened.
Variables can store references to functions in Javascript. So I would have function1 set some internal variable that would be checked when you close the modal:
var calledBy;
function1 () {
calledBy = function1;
//open modal
}
function2 () {
calledBy = function2;
//open modal
}
$("closeButton").on("click", function () {
if(calledBy === function1) {
//...
} else if(calledBy === function2) {
//...
}
});
But as hyperstack pointed out, it's better organization to have one function for opening the modal and pass in an argument. I would have an object for the modal:
var modal = {
//...
calledBy: null,
open: functio (calledBy) {
this.calledBy = calledBy;
}
};
You can use the 'this' special keyword to refer to the object on which a method is being invoked.
EG.
<div class="cval">
test
</div>
<script>
$(".cval").click(function (e) {
e.preventDefault();
alert($(this).attr('class'));
if($(this).attr('class') == 'cval')
//dosomething
else
//dosomething
});
</script>
Interrogating any of the elements attribute(s) for value and then using a conditional to control flow.
We have this code (using DHTMLX and DHTMLXMESSAGE):
myCheckBox.attachEvent('onEditCell', function(stage,rId,cInd,nValue,oValue){
dhtmlx.confirm({
type:"confirm",
text: "Are you sure?",
callback: function(result){
if(result) {
return true;
}
return false;
}
});
});
OnEditCell event should return "true" or "false" to validate action.
Now my code always check my checkbox and then show the confirm popup.
You cannot return anything to attachEvent callback. Based on the result of your confirm checkbox, execute the relevant code
> callback: function(result){
> if(result) {
> //don't returnfrom here
// execute your code here only.
> }
>
Hope this helps.
You can't make JavaScript block on asynchronous functions.
Have your event handler always return false.
Then trigger its functionality inside the callback instead of trying to return true.
Initially, I had a problem that a click event was firing multiple times, but I have managed to overcome that with a probably over use of unbind() and one() as you'll see in my code below!
What I have here is some code which opens up a universally usable Modal window which I use for various things, including, in some cases a password form.
I don't think you need the HTML so I won't post that.
When a button, or an action causes the window to be required, I call the function like this:
showModalAlert(type, theWidth, theHeight, title, html, confirmThis, denyThis)
The first three variables determine how the window will look, title and html determine the content and confirmThis and denyThis are functions set immediately prior to calling this function and determine what the action should be if this is a confirm window and the confirm or deny buttons are press.
In the case of a security window, the confirm button is replace by a "sign it" button which submits a simple password form and returns a User Id from database. If a User Id is successfully returned, the script programatically presses the confirm button and in turn runs it's function as per the call to the inital opening of the modal window.
My problem is that if an incorrect password is entered, or a user cancels the window and then later without refreshing the browser window, re-enters the password correctly, the confirmThis() function is performed twice (or as many times as the incorrect password/cancel action was performed).
So, clearly, what it is doing is "remembering" the confirmThis function each time.
As I said, initially, the password success function was clicking confirmIt twice, copious use of one() has fixed this, it is now definitely only clicking confirmIt once, but it is still performing the function multiple time.
How can I clear this function and ensure it is only performed once?
The function from which I am calling the modal window looks like this:
$('#saveDelivery').click(function () {
function confirmIt() {
formData = (JSON.stringify($('#delDetail').serializeObject()));
saveData(formData);
$('#saveDelivery').removeClass('centreLoader');
};
showModalAlert('security', '300px', '185px', 'Security!', 'You need to "Sign" this action.', confirmIt, '');
});
It's simply a click on the saveDelivery element, the confirmThis function is declared at this point and submits an AJAX form
the actual showModalAlert function is below:
function showModalAlert(type, theWidth, theHeight, title, html, confirmThis, denyThis) {
// stuff that opens the alert window \\
if (confirmThis == '') {
$('#confirmIt').one('click', function () { $('#closeAlert').one('click').click(); });
} else {
$('#confirmIt').one('click', function () { confirmThis(); $('#closeAlert').one('click').click(); });
};
if (denyThis == '') {
$('#denyIt').one('click', function () { $('#closeAlert').one('click').click(); $('#signIt').unbind(); });
} else {
$('#denyIt').one('click', function () { denyThis(); $('#closeAlert').one('click').click(); $('#signIt').unbind(); });
};
if (type == "confirm") {
$('.closeAlert, .signItForm').hide();
};
if (type == "alert") {
$('.alertConfirm, .signItForm').hide();
};
if (type == "fixedAlert") {
$('.closeAlert, .alertConfirm, .signItForm').hide();
};
if (type == "security") {
$('.signItForm').show();
$('.closeAlert').hide();
$('#confirmIt').hide();
$('#signIt').unbind().fadeTo('fast',1);
};
};
$('#signIt').live('click', function () {
var formData = (JSON.stringify($('.secureSign').serializeObject()));
var signitPwd = $('#signItpwd').val();
var jsonURL = "/jsonout/getdata.aspx?sql=SELECT id, password FROM users WHERE password ='" + signitPwd + "' LIMIT 1&output=json&usedb=new&labelName=any&fileName=";
$.getJSON(jsonURL, function (data) {
if (data.length > 0) {
$('.savingUserID').val(data[0].id);
$('#confirmIt').one('click').click();
$('#signIt').fadeTo('fast', 0);
$('#confirmIt').show();
} else {
$('#signIt').fadeTo('fast', 0);
$('#confirmIt').one('click').show();
$('.closeAlert').show();
$('.alertConfirm, .signItForm').hide();
$('#alertTitle').html("Error!");
$('#alertContent').css({ 'text-align': 'center' }).html("Password Denied");
};
});
});
From my understanding of $.one, it merely runs the event ONCE. If you bind it twice to the event, it will run twice instantaneously, but no more.
Example: http://jsfiddle.net/qCwMH/ (click the button, and it will run the event 4 times).
Each time you click saveDelivery, you are infact, binding another $.one event to #confirmIt.
What you could do is unbind your events from confirmIt and denyIt at the start of the modal function (i.e. $('#confirmIt, #denyIt').unbind('click');, and then you will assign them fresh each time that function is called, rather than building on top of them. Not ideal, as binding/unbinding uses more resources than other options, but just give that a try to start with perhaps?