dbinott
dbinott

Reputation: 911

Wait for document mousedown to complete before element onclick can start

I have a panel that slides open on an element click called "details" and populates the panel via ajax depending on the data attribute value. I also have it setup that if you close outside that panel, it will close. If the panel is open and the user clicks on a different "details" element, I want the panel to close and open again populated with the data from the new data attribute.

Problem is that the codes checks if the panel is visible and won't load the ajax if it is. How can I change this so the click event knows the mousedown event is completed before it does it's thing?

// SLIDING PANEL
$(".details").on("click", function(e){
    e.preventDefault();
    var panel = $("#DetailsPanel");
    var mkey = $(this).data("masterkey-id");
    var _self = $(this);
        // fetch data ONLY when panel is hidden...
        // otherwise it fetches data when the panel is closing
        if (!panel.is(':visible')) {
            panel.load("/com/franchise/leads.cfc?method=getLeadDetails", { mkey: mkey }, function(response, status, xhr) {
                // if the ajax source wasn't loaded properly
                if (status !== "success") {
                    var msg = "<p>Sorry, but there was an error loading the document.</p>";
                    panel.html(msg);
                };
                // this is part of the .load() callback so it fills the panel BEFORE opening it
                panel.toggle("slide", { direction: "right" }, "fast", function(){
                    _self.parent().parent().addClass("warning");
                });
            });
        } else {
            panel.toggle("slide", { direction: "right" }, "fast", function(){
                _self.parent().parent().removeClass("warning");
            });
        };

    return false;
});

$(document).on("mousedown", function(){
    $("#DetailsPanel").hide("slide", { direction: "right" }, "fast", function(){
        //_self.parent().parent().removeClass("warning");
    });
});
// don't close panel when clicking inside it
$(document).on("mousedown","#DetailsPanel",function(e){e.stopPropagation();});

$(document).on("click", "#ClosePanel", function(){
    $("#DetailsPanel").hide("slide", { direction: "right" }, "fast", function(){
        $("#LeadsTable tr").removeClass("warning");
    });
});
// END SLIDING PANEL

Upvotes: 0

Views: 1309

Answers (3)

dbinott
dbinott

Reputation: 911

Ok, so I found this little nugget http://www.gmarwaha.com/blog/2009/06/09/jquery-waiting-for-multiple-animations-to-complete/ and it works pretty good. No issues so far.

Here is the new code

    $(".details").on("click", function(e){
        e.preventDefault();
        var panel = $("#DetailsPanel");
        var mkey = $(this).data("masterkey-id");
        var _self = $(this);
            // fetch data ONLY when panel is hidden...
            // otherwise it fetches data when the panel is closing
        var wait = setInterval(function() {
            if( !$("#DetailsPanel").is(":animated") ) {
                clearInterval(wait);
                // This piece of code will be executed
                // after DetailsPanel is complete.
                if (!panel.is(':visible')) {
                    panel.load("/com/franchise/leads.cfc?method=getLeadDetails", { mkey: mkey }, function(response, status, xhr) {
                        // if the ajax source wasn't loaded properly
                        if (status !== "success") {
                            var msg = "<p>Sorry, but there was an error loading the document.</p>";
                            panel.html(msg);
                        };
                        // this is part of the .load() callback so it fills the panel BEFORE opening it
                        panel.toggle("slide", { direction: "right" }, "fast", function(){
                            _self.parent().parent().addClass("warning");
                        });
                    });
                } else {
                    panel.toggle("slide", { direction: "right" }, "fast", function(){
                        _self.parent().parent().removeClass("warning");
                    });
                };
            }
        }, 200);
        return false;
    });

Upvotes: 0

Marcos Gonz&#225;lez
Marcos Gonz&#225;lez

Reputation: 172

I'm not totally sure about this but if you use "mouseup" instead "click" could work as you expect. Try it and let me know if I'm wrong.

Upvotes: 0

nkadwa
nkadwa

Reputation: 859

Setting a timeout worked for me in another context:

onclick="window.setTimeout( function(){ DO YOUR STUFF }, 2);"

This solves many problems of this type.

Upvotes: 1

Related Questions