0

I am trying to use callbacks in order to effectively "overwrite" the standard alert and confirm actions in JavaScript.

The code I am using is a bit long winded so I jotted it into a working jsfiddle

I am trying to get it so that a callback is used to determine true or false, but it is coming back as undefined as the callback function is fired before a click is

My questions, is how can I change this to effectively overcome the functions value being returned before the click is called via jQuery?

Example usage:

<button onclick="confirm('This is a test')">Show dialog (confirm)</button>

Example jQuery events:

if (confirm("This is a test")) {
    alert("Confirmed")
}
else {
    alert("Did not confirm")
}

Edit
Using a loop within the callback messed it us a lot...

2 Answers 2

2

You are mixing things up when waiting for the return value.

You are passing dialog.checkForInput as the callback. But in the dialog.show() function you do:

var ret = callback();
...
return ret;

But the dialog.checkForInput function doesn't return anything, it merely sets event listeners.

As events all run "asynchronously" it would be more sensible to give your dialog a callback function which will be run when there actually would be an event. Meaning: in your checkForInput function (I would name it differently, but whatever) run the callback and pass the action as a parameter. Something like:

checkForInput: function () {
    $(document).ready(function () {
        $(".dialog_confirm_okay").on("click", function () {
            dialog.hide();
            callback('confirm');
        })
        $(".dialog_confirm_cancel").on("click", function () {
            dialog.hide();
            callback('cancel');
        })
        $(".dialog_alert_okay").on("click", function () {
            dialog.hide();
            callback('alert');
        })
    })
}

And your callback could look like this (assuming your callback was called dialogCallback):

function dialogCallback ( action ) {
    alert('Dialog closed with action: ' + action);
};
Sign up to request clarification or add additional context in comments.

2 Comments

Would this work for if(confirm("An Action")) { alert("Confirmed"); } else { alert("Did not confirm"); }?
short answer: no. slightly less short answer: you don't want that. You could get such a result with the Window.confirm() function, but that's blocking the whole browser (which is considered bad practice nowadays. I agree on that). But you can of course inside your callback do something like: if ( action == 'An Action' ) { doThis(); } else { doThat(); }
2

Some points I conclude from your code:

  • The reason why statement callback() return undefined value is because dialog.checkForInput return nothing.
  • The $(document).ready inside checkForInput is async, so returned value from that block is meaningless (it won't become the return value of the checkForInput as well).
  • And also you put the return statement inside event declaration, it'll become return value of the event (when the event triggered), not the checkForInput.

I did some modification on your code, this one working. Basically I create new method called onclick, which will be called every time button yes or no is clicked.

show: function (e_type, e_content) {
    var d = dialog;
    var d_head = e_type == "confirm" ? "Confirm Action" : "Error";
    var d_buttons = e_type = "confirm" ? d.parts.buttons.okay + d.parts.buttons.cancel : d.dparts.buttons.alert_okay;
    var _dialog = d.parts.main + d.parts.head.replace("{DIV_HEADER}", d_head) + d.parts.body + e_content + "<div class='dialog_button_container'>" + d_buttons + "</div>" + d.parts.footer;

    $("body").append(_dialog);
},

onclick: function (ret) {
    $(".errors").text("Return value was: " + ret);
},

showError: function (e_content) {
    dialog.show("alert", e_content);
    dialog.checkForInput();
},

showConfirm: function (e_content) {
    dialog.show("confirm", e_content);
    dialog.checkForInput();
},

checkForInput: function () {
    var self = this;

    $(".dialog_confirm_okay").on("click", function () {
        dialog.hide();
        self.onclick(true);
    })
    $(".dialog_confirm_no").on("click", function () {
        dialog.hide();
        self.onclick(false);
    })
    $(".dialog_alert_okay").on("click", function () {
        dialog.hide();
        self.onclick(false);
    })
},

Working example: https://jsfiddle.net/p83uLeop/1/

Hope this will help you.

EDITED

From the comment section I assume that you want this alert to become a blocking function like window.confirm, so you can do something like if (confirm('Are you sure')).

But sadly it's impossible to achieve this case.

I have some suggestion, you can encapsulate your code better, and implement clean callbacks or promises. Maybe something like this:

showConfirm(function (ok) {
    if (ok) {
        // "yes" clicked
    } else {
        // "no" clicked
    }
})

// or

showConfirm(function () {
    // "yes" clicked
}, function () {
    // "no clicked"
})

// or 

var customConfirm = showConfirm()
customConfirm.on('yes', function () {
    // "yes" clicked
})
customConfirm.on('no', function () {
    // "no" clicked
})

3 Comments

As per the other answer in this question, would this work for if(confirm("An Action")) { alert("Confirmed"); } else { alert("Did not confirm"); }?
alert function is blocking, so it'll directly return value when it's done. your issue is different, your custom alert is not blocking, so need some effor to get the return value
That's what I am not getting how to do, I can get it to return using standard onclicks outside any functions, but when it comes to saying "if this button clicked, do this, otherwise don't" the it becomes an enormous pain

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.