4

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 :/

Community
  • 1
  • 1
Noob
  • 1,077
  • 2
  • 14
  • 16
  • 1
    It's hard to understand what you are up to. Try using jsfiddle.net to reproduce your problem, then give us a link to that code. – Deele Jul 25 '11 at 11:56
  • @Deele, I'm not familirized with jsfiddle, but I'll take a look. Thanks :) – Noob Jul 26 '11 at 10:19
  • 1
    @Buitrako: You might also look at http://jsbin.com, which is like jsFiddle but works in a broader range of browsers. – T.J. Crowder Jul 26 '11 at 10:35
  • @T.J. Crowder: that's a very interesting and helpful page. Thank you. – Noob Jul 27 '11 at 07:48

5 Answers5

2

Use the following code to do it:

$('a').bind('click', false);
Nikola K.
  • 7,093
  • 13
  • 31
  • 39
Darm
  • 5,581
  • 2
  • 20
  • 18
  • I find your answer useful, but with this method the problem is to re-enable the click event later. – Noob Jul 26 '11 at 09:56
2

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.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 1
    You explained your answer very well and it works perfectly. Thank you **very** much! :) – Noob Jul 26 '11 at 08:37
  • Only a little comment: your solution disables the .delete-answer anchors, so I made a little modification to disable all links: $('a').click(function(event) { if (!deleteAnswerEnabled) { event.preventDefault(); } }); You can add this to your response if you want. Again, thank you very much. – Noob Jul 26 '11 at 10:21
1

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.

Kon
  • 27,113
  • 11
  • 60
  • 86
  • I didn't understand it either :/ My upvote for you, thanks for your contribution and for the tip! – Noob Jul 26 '11 at 07:36
0

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

Community
  • 1
  • 1
SeaBass
  • 464
  • 6
  • 13
0

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

northtree
  • 8,569
  • 11
  • 61
  • 80