4

I have a firework detonation system which uses JQuery to connect to a PHP script via AJAX to detonate the fireworks. The only problem is that if you click one launch button straight after another, there is a possibility of setting off more fireworks than you want.

I need a way to disable all other links on the page until the ajax has finished and received a response. I have tried:

//Prevent clicks
$("body").find("a").click(function (e) { e.preventDefault(); });
//Re-enable clickable links
$("body").find("a").unbind("click");

My current ajax script is:

$(document).ready(function() {
$(".button").on("click",function() {
    //Disable all other links
    $.ajax({
        type: "POST",
        url: "launch.php",
        data: {FID:$(this).attr('id'),Length:$('#FireLength').val()},
        success: function(e) {
            //Re-enable other links once ajax is complete
        }
    });
    return false;
});
});

What would be even better is, if the buttons were to grey out whilst waiting for the response. I have a demo script at http://joshblease.co.uk/firework/

Blease
  • 1,380
  • 4
  • 38
  • 64
  • It's not as simple as that. You need to remember which link was bound to which callback, and then re-bind it. `unbind()` unbinds **all** bound events, not just the last one. – Eduard Luca Nov 19 '13 at 21:07
  • Haha, this sounds really dangerous. My initial thought is that in addition to anything on the client side, you should put some code on the server side to limit the launches. – sbking Nov 19 '13 at 21:07
  • @Cuberto it could be, but it's quite simple and its designed to remove the danger so they can be remotely activated, over LAN of course, not the web ;) now that would be stupid! I will definitely look into using the server to deny to many detonations at once – Blease Nov 19 '13 at 21:28

4 Answers4

4

One way using a variable disabled

$(document).ready(function() {
var disabled = false;
$('a').css('opacity','0.4');
$(".button").on("click",function() {
    //Disable all other links
    disabled = true;
    $.ajax({
        type: "POST",
        url: "launch.php",
        data: {FID:$(this).attr('id'),Length:$('#FireLength').val()},
        success: function(e) {
            //Re-enable other links once ajax is complete
            disabled = false;
            $('a').css('opacity','1');
        }
    });
    return false;
});
});

$('a').click(function(event){
    if(disabled)
        event.preventDefault();
});

Update

Changed link opacity for a disabled effect.

Trevor
  • 16,080
  • 9
  • 52
  • 83
4

I would use actual buttons, not links, and disable them when one is clicked. Use a class on the button distinguish it from other buttons that might be on the page.

<input type="button" class="launch" ... >
  ...
$(document).ready(function() {
    $("input[type=button].launch").on("click",function(event) {
        // We will handle the button, prevent the standard button press action.
        event.preventDefault();
        //Disable all other links
        $('input[type=button].launch').disable();
        $.ajax({
            type: "POST",
            url: "launch.php",
            data: {FID:$(this).attr('id'),Length:$('#FireLength').val()},
            success: function(e) {
                //Re-enable other links once ajax is complete
                $('input[type=button].launch').enable();
            }
        });
        return false;
    });
});

Further manage it with a flag as @MonkeyZeus suggests.

Stephen P
  • 14,422
  • 2
  • 43
  • 67
2

I'd manage this with a class (assuming there might be some links you want to work). All the links that you want to not work give them the class blockable.

You can also then style your a.disabled class in your css to grey out the links (or whatever you want)

$(document).ready(function() {
$(a.blockable).click(function(e) {
    if($(this).hasClass('disabled'))
    {
        e.preventDefault();
    }
}
$(".button").on("click",function() {
    $('a.blockable').addClass('disabled');
    $.ajax({
        type: "POST",
        url: "launch.php",
        data: {FID:$(this).attr('id'),Length:$('#FireLength').val()},
        success: function(e) {
            $('a').removeClass('disabled');
        }
    });
    return false;
});
});
Code Magician
  • 23,217
  • 7
  • 60
  • 77
1

I would approach this by declaring a variable and only allowing AJAX to fire if variable has not been tripped:

$(document).ready(function() {

    var launch_processing = false;

    $(".button").on("click",function() {
        if(launch_processing === false){

            launch_processing = true;

            $.ajax({
                type: "POST",
                url: "launch.php",
                data: {FID:$(this).attr('id'),Length:$('#FireLength').val()},
                success: function(data) {

                },
                complete: function(){
                    launch_processing = false;
                }
            });
        }
        else{
            alert('Are you mad?!?! Fireworks are in progress!');
        }
    });
});
MonkeyZeus
  • 20,375
  • 4
  • 36
  • 77