Javascript/Jquery Callback for Fancybox Yes No Confirm

I'm trying to implement a fancy Yes No confirm and I'm having problems getting the callback to work as needed. The example below is using Fancybox v2.

The problem with the code below is that the function "do_something" is being call when HREF "Test" is clicked and not being called when the user clicks #fancyConfirm_ok.

function fancyConfirm(msg,callback) {
    var ret;
    jQuery.fancybox({
        'modal' : true,
        'content' : "<div style=\"margin:1px;width:240px;\">"+msg+"<div style=\"text-align:right;margin-top:10px;\"><input id=\"fancyconfirm_cancel\" style=\"margin:3px;padding:0px;\" type=\"button\" value=\"Cancel\"><input id=\"fancyConfirm_ok\" style=\"margin:3px;padding:0px;\" type=\"button\" value=\"Ok\"></div></div>",
        'afterShow' : function() {
            jQuery("#fancyconfirm_cancel").click(function() {
                ret = false;
                //jQuery.fancybox.close();
                $.fancybox.close();
            })
            jQuery("#fancyConfirm_ok").click(function() {
                ret = true;
                jQuery.fancybox.close();
            })
        },
        'afterClose' : function() { 
            if (typeof callback == 'function'){ 
                callback.call(this, ret); 
            } else {
                var callback_type = typeof callback;
                alert(callback_type);
            }
        }
    });
}
<a href="#" onclick="fancyConfirm('Are you sure you want to delete?',  do_something('a', 'b') );return false;">Test</a>

Answers


Your method "do_something('a', 'b')" will be executed whenever user clicks on the link and the returned result will be passed as the second parameter to the "fancyConfirm" method. This is why your parameter "callback" is always "undefined".

There is also a problem with fancyBox - "afterClose" callback gets called twice - before opening and after closing (this will be changed in the next release).

I would bind a click event on the link and call a callback when user clicks on one of the buttons, like - http://jsfiddle.net/xcJFY/1/


Not a big fan of the double callback method (Sorry Janis).

So while trying to find a solution to this myself played around with similar code and found that as long my return value wasn't defined inside the scope of the function it works fine, when my return value was defined inside the function I would get weird behaviour where it would work for a time then revert to undefined.

Effectively the return value needs to be outside the scope of the function, global, closure etc.

$(document).ready(function() {
    $(".fancybox").on("click", function(e){   
        e.preventDefault();
        confirm("Do you wish to continue?", true, function(resp) {
            alert("You clicked " + resp);
        });
    });
});

function confirm(msg, modal, callback) {
    $.fancybox("#confirm",{
        modal: modal,
        beforeShow: function() {
            $(".title").html(msg);
        },
        afterShow: function() {
            $(".confirm").on("click", function(event){
                if($(event.target).is(".yes")){
                    ret = true;
                } else if ($(event.target).is(".no")){
                    ret = false;
                }
                $.fancybox.close();
            });
        },
        afterClose: function() {
            callback.call(this, ret);
        }
    });  
}

Here is a jsfiddle example

Thanks to Francisco Diaz who's post on Google Groups FancyBox forum pointed me in the right direction.

UPDATE:

Have now extended my example to use dynamically built buttons and custom return values, so you are not just limited to true and false.

$(document).ready(function() {
    $(".fancybox").on("click", function(e){   
        e.preventDefault();
        confirm("Do you wish to continue?", {
                /* 
                Define your buttons here, can handle multiple buttons 
                with custom title and values
                */
                buttons: [
                    { class: "yes", type: "button", title: "Yes", value: "yes" },
                    { class: "no", type: "button", title: "No", value: "no" },
                    { class: "maybe", type: "button", title: "Maybe?", value: "maybe" }
                ],
                modal: true
            }, 
            function(resp) {
                alert("You clicked " + resp);
            }
        );
    });
});

function confirm(msg, options, callback) {
    $.fancybox("#confirm",{
        modal: options.modal,
        beforeShow: function() {
            this.content.prepend("<p class=\"title\"></p>");
            $(".title").html(msg);

            for (i = 0; i < options.buttons.length; i++) {
                this.content.append($("<input>", { 
                    type: "button", class: "confirm " + options.buttons[i].class, 
                    value: options.buttons[i].title
                  }).data("index", i));
            }
        },
        afterShow: function() {
            $(".confirm").on("click", function(event){
                ret = options.buttons[$(event.target).data("index")].value;
                $.fancybox.close();
            });
        },
        afterClose: function() {
            this.content.html("");
            callback.call(this, ret);
        }
    });
}

Added jsfiddle example


Need Your Help

Android : Listadapter loading downloaded images

android listview listadapter baseadapter custom-adapter

I trying to create custom Listadapter using BaseAdapter , in this adapter the images are URLs and the adapter must download every thing then update the view ..

"Not enough memory..." error when attempting to start windows phone emulator

windows-phone-8 windows-phone-8-emulator

I actually got this error (image below) sometimes (not always), which means my hardware is fine (?).