Question

My question is related about disabling links/click events with jQuery, and it's probably easier than it seems to me. I commented the important code to make it easier.

I have the following code in a .js file:

$('.delete-answer').click(function(event) {
    event.preventDefault();

    // some actions modifying the tags    
    $('.output').closest('li').remove();
    var idMsg = ...;
    var action = ...;
    var answers = ...;
    $(this).closest('li').children('p').remove();
    $(this).closest('.tr').before('<tr><td><div class="output">Deleting message...</div></td></tr>');
    $(this).closest('.tr').remove();

    // While the servlet is deleting the message, I want to disable the links
    // but I can't, so my problem is just here

    // METHOD 1
    //$('a').unbind('click');

    // METHOD 2
    //$('a').bind('click', function(e){
    //    e.preventDefault();
    //});

    $.post("../app/ForumCampus", {action:action, idMsg:idMsg}, function(data) { 
    });

    // METHOD 1
    //$('a').bind('click');

    // METHOD 2
    //$('a').unbind('click');

    $('.output').empty();
    $('.output').append('Message deleted successfully.');

});

And In my HTML I have some list items like these:

<li>
    <p class="text">Some text.</p>
    <table class="answer-details" style="width: 100%">
    <tbody>
        <tr class="tr">
            <td style="width: 50%;">
                <div class="msg-modification" display="inline" align="right">
                    <a id="modify" class="delete-answer" href="#">Delete</a>
                </div>
            </td>
        </tr>                               
    </tbody>
    </table>
</li>

As you can see, I tried two methods to disable the click event:

Method 1: I tried the following method: how to unbind all event using jquery

Result: It works, unbinding the click event from the anchors with delete-answer class, but:

1) It only deactivate the anchors with delete-answer class. I will prefer to disable all links while the servlet is doing it's stuff.

2) I can't (or I don't know how to) re-enable the links.

Method 2: I tried the following method: How do I dynamically enable/disable links with jQuery?

Result: It works for normal anchors, but not for the anchors with class delete-answer.

Both seem incompatible, so I'd really appreciate some help.


Note: also tried to change the class doing this: $('.delete-answer').addClass('delete-disabled').removeClass('delete-answer');

It changes the class and leaves the anchors only with delete-disabled class, but when I click them again, they're still deleting the message and I don't know why :/

Was it helpful?

Solution

Wrap all of that code in a function and use a flag.

  1. Add this at the top:

    (function() {
    
  2. Add this at the bottom:

    })();
    
  3. Just under the top line above, add:

    // Flag for whether "delete answer" is enabled
    var deleteAnswerEnabled = true;
    
  4. In your click handler, right at the top:

    if (!deleteAnswerEnabled) {
        return false;
    }
    
  5. Change your post to:

    // Disable deleting answers while we're doing it
    deleteAnswerEnabled = false;
    $.post("../app/ForumCampus", {action:action, idMsg:idMsg}, function(data) { 
         // Enable it again now we're done
        deleteAnswerEnabled = true;
    });
    

Bringing that all together:

// (1)
(function() {
    // (3)
    // Flag for whether "delete answer" is enabled
    var deleteAnswerEnabled = true;


    $('.delete-answer').click(function(event) {
        event.preventDefault();

        // (4)
        // Don't do it if we're disabled
        if (!deleteAnswerEnabled) {
            return false;
        }

        // some actions modifying the tags    
        $('.output').closest('li').remove();
        var idMsg = ...;
        var action = ...;
        var answers = ...;
        $(this).closest('li').children('p').remove();
        $(this).closest('.tr').before('<tr><td><div class="output">Deleting message...</div></td></tr>');
        $(this).closest('.tr').remove();

        // (5)
        // Disable deleting answers while we're doing it
        deleteAnswerEnabled = false;
        $.post("../app/ForumCampus", {action:action, idMsg:idMsg}, function(data) { 
             // Enable it again now we're done
            deleteAnswerEnabled = true;
        });

        $('.output').empty();
        $('.output').append('Message deleted successfully.');

    });
// (2)
})();

If you're feeling sufficiently paranoid, you might use a counter rather than a boolean, but the concept is the same.

OTHER TIPS

Use the following code to do it:

$('a').bind('click', false);

Define a separate variable that keeps track of your deleting state:

var isDeleting = false; 

$('.delete-answer').click(function(event) {
   if (!isDeleting) {
      isDeleting = true;

      $.post("../app/ForumCampus", {action:action, idMsg:idMsg}, function(data) { 
          isDeleting = false;
      });      
   }
});

Also, you don't need an href attribute inside the anchor if it doesn't actually contain a URL. Just remove it altogether.

Another simple solution is just .hide() / .show() your click element.

Since I can't leave a comment, this is solution for Noob's question on Darm's post (LINK).

I believe the page uses whichever .bind was first implemented if two .binds are used for the same element. So you have to .unbind it first if you want to change the setting from FALSE to TRUE. To re-enable the click add the latter code to whichever function/event you would want to re-enable it.

DISABLE

$('a').bind('click', true);

RE-ENABLE

$('a').unbind('click', false);
$('a').bind('click', true);`

ALSO, I'm not sure why, setting back to TRUE wouldn't work unless I included "jquery-ui.js".

Hope this helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top