on () and bind () are not working

2

I am using off() in an element to disable its functionality and need to enable it again with on() . But it is not working when on() is executed ...

Here's the code, I'm trying to prevent a form from being sent 2 times when a button is clicked:

$("#meuBotao").click(function (e) {
    $(this).off("click");
    $.ajax({
    url: "/page",
    type: "POST",
    complete: function() {
                    $(this).on("click");
    },
                ...

What am I doing wrong? I tried with on() and off() , and with bind() and unbind() also (which are deprecated for the old versions now, but should work anyway).

    
asked by anonymous 24.05.2014 / 20:03

2 answers

3

From what I understand you want to disable the button while AJAX is running so the user can not fire multiple requests, right? In this case it could be done like this:

 $("#meuBotao").on('click',function(){
    var el = $(this);
    el.prop('disabled',true); //desabilita o botão
    $.ajax({
    url: "/page",
    type: "POST",
    complete: function(){
        el.prop('disabled',false); //habilita botão novamente
    },
    //...

Note that I created a new variable el to handle the $(this) element, so that it works correctly even within other scopes (as in the case of the function triggered in% AJAX%). >

I've also changed complete to .click() because this second is most recommended by various reasons .

    
25.05.2014 / 17:32
2

The main problem here is that this inside the ajax function is not the same as this outside the function. The scope is different ... This has an easy solution, which is to create an intermediate variable that points to the same object:

$("#meuBotao").click(function (e) {
    $(this).off("click");
    var self = this; // assim guardamos o apontador no "self"
    $.ajax({
        url: "/page",
        type: "POST",
        complete: function() {
            $(self).on("click"); // aqui usa o "self". Já agora, aqui falta a função a correr quando o click fôr gerado
        },
            ...

Apart from this detail there are other ways more used to prevent clicks, instead of removing and adding events. One of them is to create a flag / flag as a property in the element or a variable that holds the information whether or not the element can be clicked.

An example of this would be:

$("#meuBotao").click(function (e) {
    if (!$(this).data('clicavel')) return false;
    $(this).data('clicavel', false);
    var self = this; // assim guardamos o apontador no "self"
    $.ajax({
    url: "/page",
    type: "POST",
    complete: function() {
          $(self).data('clicavel', true);
    },
                ...

You can even do the same by adding CSS pointer-events: none; to a class, or directly to the element. You can see more ideas in this answer: link

Note: In your code $(this).on("click"); is missing the second parameter of the function that indicates which code to run when the click is received ...

    
25.05.2014 / 19:50