Change function of onclick

Asked

Viewed 7,507 times

2

Guys I’m having 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 the other 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 my button’s onclick function whenever it is clicked, switching from one function to another.

The button is changing span and class, but I can’t change onclick.

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

Could you help me?

5 answers

2

Particularly I think it is better to have two buttons, one for each action, and the moment you click on one, hide the other, and so on, see in the example:

  • .on('click', function () { ... }: assigns the event click to the button as soon as it is rendered in HTML.
  • .toggle(): Toggles the element’s visibility if it is hidden and hidden makes it visible.
  • .show(): Changes the visibility of the widget 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>
<button id="botao1">Ação 1</button>
<button id="botao2">Ação 2</button>

  • or maybe he can create a variable and increase it and if the variable %2 returns 1 he does one thing or another.

  • 1

    Good idea Pedro, tomorrow I will do just that, I hadn’t thought about it! Haha... Thanks

  • It can be done yes @Viniciusputtimorais, however, you are saying yourself that you will have an "extra" job to do criar uma variavel e ir incrementando ela. Agrees?

  • really, actually depends on the taste.

2

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 aux, and the button calls the acaoContact.

Or you can put all actions within the same function:

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

2

One of the tricks to make this work is the innerHTML function that performs a content exchange in 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 replaces 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>
<div id="dibotao"><button type="button" class="btn btn-success btn-xs" onclick="vincularContato($(this))"><span class="glyphicon glyphicon-ok">Vincular</span></button></div>

  • @Marceloboni, Xuxu beauty

2


A very simple way to solve this is to use the method .attr() in each function, changing the 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>
<input type="button" onclick="removerContato($(this))" value="Clique aqui">

Without 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">

  • I will add my 2 cents in your reply, why was exactly what I would answer, only using pure js, without jQuery :)

  • If you feel uncomfortable with the changes made, you can reverse the answer to your original answer

  • now yes it is beautiful :)

2

I particularly try to write reusable, optimized and easily maintained codes (unfortunately it is not always possible!). The benefits are obvious: you can just copy and paste anywhere it will work. Of course we should consider dependencies, etc.

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

I wrote quickly, surely you can improve.

Consider:

  • Js is a functional language, enjoy;
  • Whenever possible separate logic from application;
  • Smaller, independent codes are easier to test and maintain;
  • Program 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>

Browser other questions tagged

You are not signed in. Login or sign up in order to post.