Change onclick function

3

Personal I have a question.

I have a button:

<button type="button" class="btn btn-success btn-xs" onclick="vincularContato($(this))"><span class="glyphicon glyphicon-ok"></span></button>

And two functions, one linkContact and another removeContact passing the button itself as parameter:

function removerContato(botao) {

    var tempIdContato = botao.closest("tr")
                             .find(".idContato")
                             .text();

    botao.removeClass('btn-danger');
    botao.addClass('btn-success');
    botao.html('<span class="glyphicon glyphicon-remove"></span>');
    //    botao.prop('onclick', null).off('click');
    //    botao.prop('onclick', vincularContato(botao)).off('click');

}

function vincularContato(botao) {

    var tempIdContato = botao.closest("tr")
                             .find(".idContato")
                             .text();

    botao.removeClass('btn-success');
    botao.addClass('btn-danger');
    botao.html('<span class="glyphicon glyphicon-remove"></span>');
    //    botao.prop('onclick', null).off('click');
    //    botao.prop('onclick', removerContato(botao)).off('click');

}

What I need is to change the onclick function of my button whenever it is clicked, switching from one function to another.

The button is changing the span and class, but I can not change the onclick.

I commented one of my tests, I did some other ways but without success.

Could you help me?

    
asked by anonymous 14.08.2017 / 21:59

5 answers

3

A very simple way to solve this is to use the .attr() method on each function, changing onclick :

With jQuery

function removerContato(botao) {
  alert("vincularContato");
  botao.attr('onclick', 'vincularContato($(this));');
}

function vincularContato(botao) {
  alert("removerContato");
  botao.attr('onclick', 'removerContato($(this));');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script><inputtype="button" onclick="removerContato($(this))" value="Clique aqui">

No jQuery

function removerContato(botao) {
  alert("função removerContato");
  botao.setAttribute("onclick","vincularContato(this);");
}

function vincularContato(botao) {
  alert("função vincularContato");
  botao.setAttribute("onclick","removerContato(this);");
}
<input type="button" onclick="vincularContato(this)" value="Clique aqui">
    
14.08.2017 / 22:41
3

Something like:

var aux = true;
function acaoContato(botao) {
    aux ? removerContato(botao) : vincularContato(botao);
}

At the end of each of the functions you perform the state change of the aux, and the button calls the actionContact.

Or you can put the actions all within the same function:

var aux = true;
function acaoContato(botao) {
    aux ? {
        // Conteúdo do removerContato
    } : {
        // Conteúdo do vincularContato
    };
}
    
14.08.2017 / 22:24
2

In particular I think you'd better have two buttons, one for each action, and the moment you click on one, hide the other, and so on, look at the example:

  • .on('click', function () { ... } : assigns the click event to the button as it is rendered in HTML.
  • .toggle() : Toggles the visibility of the element, if it is visible hidden and if hidden it makes it visible.
  • .show() : Changes the visibility of the element to visible.

$('#botao1').on('click', function() {
  console.log('Evento 1');
  $(this).toggle();
  $('#botao2').show();
});

$('#botao2').on('click', function() {
  console.log('Evento 2');
  $(this).toggle();
  $('#botao1').show();
});
#botao2 {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><buttonid="botao1">Ação 1</button>
<button id="botao2">Ação 2</button>
    
14.08.2017 / 22:07
2

One of the tricks for this to work is the innerHTML function that performs a content swap on a specified div tag.

So with pure javascript:

function removerContato(botao) {

   console.log("clicou na função removerContato");
    
   document.getElementById("dibotao").innerHTML =('<button type="button" class="btn btn-success btn-xs" onclick="vincularContato(this)"><span class="glyphicon glyphicon-ok">Vincular</span></button>');

}

function vincularContato(botao) {

   console.log("clicou na função vincularContato");

   document.getElementById("dibotao").innerHTML =('<button type="button" class="btn btn-success btn-xs" onclick="removerContato(this)"><span class="glyphicon glyphicon-ok">Remover</span></button>');

}
<div id="dibotao"><button type="button" class="btn btn-success btn-xs" onclick="vincularContato(this)"><span class="glyphicon glyphicon-ok">Vincular</span></button></div>

So with jquery

  

The .html () method overrides content

function removerContato(botao) {
  console.log("clicou na função removerContato");
  botao.parent().html('<button type="button" class="btn btn-success btn-xs" onclick="vincularContato($(this))"><span class="glyphicon glyphicon-ok">Vincular</span></button>');

}

function vincularContato(botao) {
  console.log("clicou na função vincularContato");
  botao.parent().html('<button type="button" class="btn btn-success btn-xs" onclick="removerContato($(this))"><span class="glyphicon glyphicon-ok">Remover</span></button>');

  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script><divid="dibotao"><button type="button" class="btn btn-success btn-xs" onclick="vincularContato($(this))"><span class="glyphicon glyphicon-ok">Vincular</span></button></div>
    
14.08.2017 / 22:40
2

In particular, I try to write reusable, optimized, and easy-to-maintain code (unfortunately, it is not always possible!). The benefits are obvious: you can simply copy and paste anywhere it will work. Of course we should consider the dependencies, etc.

The solutions mentioned here are valid , but I suggest you create a plugin to solve your problem, something simple that takes care of only the UI and is flexible enough for you to apply in different contexts.

I wrote quickly, you can certainly improve.

Consider:

  • Js is a functional language, enjoy;
  • Whenever possible, separate the application logic;
  • Smaller, standalone codes are easier to test and maintain;
  • Schedule things you can reuse in other projects;

/*

index.js

Considerando que você importou o plugin, basta iniciar. Você pode 
passar duas funções que serão executadas quando tiver alteração 
no status. O contexto do this é o $(this), ou seja o 
próprio elemento,dessa forma você pode recuperar atributos, ou 
fazer qualquer coisa com o botão...
*/

$(function(){
  $('.contact').statusButton({
    enabled: function() {
      console.log('ENABLED', this.data('contact'));
    },
    disabled: function() {
      console.log('DISABLED', this.data('contact'));
    }
  });
});




/*

status-button.js

*/

(function($) {

  /**
  * statusButton
  * @param Object options
  */
  $.fn.statusButton = function(options) {


    /**
    * settings
    */
    var settings = $.extend({
      template: {
        add: {
          'class': 'btn-success',
          'icon': 'glyphicon-ok',
        },
        remove: {
          'class': 'btn-danger',
          'icon': 'glyphicon-remove',
        },
      },
      enabled: function() {},
      disabled: function() {}
    }, options);


    /**
    * changeStatus
    */
    var changeStatus = {

      enabled: function($icon) {
        this.removeClass('btn-danger').addClass('btn-success');
        this.find('.glyphicon').removeClass('glyphicon-remove').addClass('glyphicon-ok');
      },

      disabled: function ($icon) {
        this.removeClass('btn-success').addClass('btn-danger');
        this.find('.glyphicon').removeClass('glyphicon-ok').addClass('glyphicon-remove');
      }
    };


    /**
    * For each Element...
    */
    return this.each(function() {

      var status = $(this).data('status') || 'enabled';

      changeStatus[status].call($(this));

      $(this).click(function(){
        status = status === 'enabled' ? 'disabled' : 'enabled';
        changeStatus[status].call($(this));
        settings[status].call($(this));
      });
    })

  }

}(jQuery));
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>


<!--
index.html

Insira uma classe pra você usar no plugin. Além disso 
você pode usar o data-status="disabled" caso precise 
que inicie desabilitado.
-->

<button data-contact="100" type="button" class="btn btn-success btn-xs contact">
  <span class="glyphicon glyphicon-ok"></span>
</button>

<button data-status="disabled" data-contact="321" type="button" class="btn btn-success btn-xs contact">
  <span class="glyphicon glyphicon-ok"></span>
</button>


<button data-contact="123" type="button" class="btn btn-success btn-xs contact">
  <span class="glyphicon glyphicon-ok"></span>
</button>


<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    
15.08.2017 / 02:01