0

I am trying to change the functionality of a button by changing its ID dynamically.

<srcipt>
$("#old-id").click(function func_P(){
  //Some code
  this.id = "new-id";
});
$("#new-id").click(function func_Q(){
  // some other code
});
$("#clear").click(function func_R(){
  $(".in").attr("id","new-id");
});
</script>

<body>
  <button id="old-id" class="in">Button A</button>
  <button id="clear">Clear</button>
</body>

But the problem I am facing is that when I click "Button A" the id gets changed but when I click "Button A" again func_P() is executed again instead I intend to call func_Q.

Pedram
  • 15,766
  • 10
  • 44
  • 73
Piyush Chauhan
  • 797
  • 1
  • 7
  • 20
  • When you use `.click()` it assigns events to elements *that exist at that time*. If you change the ID after, it didn't exist when you bound the event. So you have to use event delegation. – freedomn-m Dec 23 '17 at 10:14

1 Answers1

2

Use .on function to bind (live) click.

$("#old-id").on('click', function func_P(e) {
  //Some code
  if (this.id == "old-id") {
    this.id = "new-id";
    console.log('old id clicked');
    e.stopPropagation()
  }
});
$(document).on('click', "#new-id", function func_Q() {
  // some other code
  console.log('new id clicked');
});
$("#clear").on('click', function func_R() {
  $(".in").attr("id", "old-id");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="old-id" class="in">Button A</button>
<button id="clear">Clear</button>

And if you want to clear id, you should change:

$(".in").attr("id","new-id");

To:

$(".in").attr("id", "old-id");
Pedram
  • 15,766
  • 10
  • 44
  • 73
  • Have you noticed that the first click also runs the code for `#new-id`? Because when the event bubbles up, the ID has already changed so the delegation test succeeds. You need `event.stopPropagation()` to stop that. – Barmar Dec 23 '17 at 10:29
  • @Barmar `Have you noticed that the first click also runs the code for #new-id?` Actually no, it's ordinary, when you click on `$("#old-id")` it going to change `id` to `new-id` so it execute code for `#new-id`. If OP want to run some other code then change `id` so need to use `.done` or `.then` or etc.. If i use `event.stopPropagation()` it will stop working. feel free to try that on my snippet. – Pedram Dec 23 '17 at 10:39
  • 1
    Yeah, that's because the old event handler keeps running even after the ID is changed, so it still stops propagation. Either change the old handler to use event delegation as well, or put `if (this.id == "old-id")` around the code that changes the ID and stops propagation. – Barmar Dec 23 '17 at 10:46
  • @Barmar Hmm.. you right, that's much better. – Pedram Dec 23 '17 at 10:53