3

I am making dynamic buttons using jQuery. Now I want to use this buttons as any other buttons. Here is my HTML:

<label class='twobuttons'><div id="submit-button" >GO!</div></label>
<div id='result'></div>

And here is my JavaScript:

$(document).ready(function(){
    $('#submit-button').click(function(){
        $('#result').append("<label><div id='share' class='longbutton'>Share this route</div></label>");

        $('#result').append("<label><div id='goback' class='longbutton'>Create another one !</div></label>");
    });

    $('#share').on("click",function(){
        alert('hi');
    });

    $('#goback').on("click",function(){
        alert('hello');
    })
});

I'm specifically having trouble with the $('#share').on( part.

I tried the on() function as suggested here. But it is not working. Here is the fiddle of my code. Please correct me if I am wrong somewhere.

Ian
  • 50,146
  • 13
  • 101
  • 111
user1263375
  • 663
  • 3
  • 18
  • 35

4 Answers4

6

That isn't how .on() works, if you are dynamically creating elements, you can't bind an event handler to it, because at the point the code runs (document.ready), the element doesn't exist. So to "get around" that, you bind the event to a parent element (that exists) and then add the actual element you'll be clicking on as a parameter like this:

    $('body').on("click", "#share", function(){
        alert('hi');
    });

    $('body').on("click", "#goback",function(){
     alert('hello');
    })

DEMO

Andy
  • 14,427
  • 3
  • 52
  • 76
  • 3
    `.on()` should be used to attach event handlers regardless if dynamically created or not. http://api.jquery.com/on/ – Jack Jun 11 '13 at 15:41
  • @Andy I think Jack is referring to you saying `That isn't how .on() works` and suggesting you must always `bind the event to a parent element and then add the actual element you'll be clicking on as a parameter`. Because that isn't required. – Ian Jun 11 '13 at 15:44
  • 1
    @Ian That is correct. – Jack Jun 11 '13 at 15:45
  • @Ian I didn't say a dynamically created element was required, did I? :o – Andy Jun 11 '13 at 15:48
  • I got a question. Why adding '#share' in on() didnt worked ? – user1263375 Jun 11 '13 at 15:50
  • @Andy The way it's worded, it's what it sounds like. You seem to suggest that delegation is required when using `on()`. I'm guessing you didn't mean that, it just sounds like it. I think you meant to explain it more as it is related to dynamic elements and binding events – Ian Jun 11 '13 at 15:50
  • @user1263375 Because the way on works is it binds the event handler to the element inside the selector, `#share` in this case, but it didn't exist when document was ready (because you created it after document ready). Whereas my code binds the event handle to the body, which does exist at doc ready. – Andy Jun 11 '13 at 15:53
  • @Ian Attempted to clear it up, TL;DR: `if you are dynamically creating elements...` – Andy Jun 11 '13 at 15:59
  • 1
    @Andy Much better :) I just didn't want the OP or others to get the wrong idea. Again, you obviously know what you're talking about, it just sounded weird – Ian Jun 11 '13 at 15:59
  • Why are you binding the event handler to `'body'` if `'#result'` is already there at page load? Blindly using the catch-all element to register your event handlers will eventually come to haunt you. Btw, different Jack :) – Ja͢ck Jun 11 '13 at 16:01
5

You should setup event delegation on #result instead, because by the time you're trying to setup the click handlers on #share, the element itself has not been added yet.

$('#result').on('click', '#share', function() {
    // your code here
});

Try not to bind the event handler to $(document) by default; the closest element that will not get removed is the prime candidate.

Alternatively, only bind the click handlers after you've added the new elements.

Update

You're appending elements with a fixed identifier at every click of your button; note that identifiers should be unique per document, so you should make sure that the action is performed at most once.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
3

The way the .on() method works changes according to how you use it. In your example the .on() method behaves similar to bind and will only work on elements that already exist.
Try this:

 $(document).on("click",'#share',function(){
              alert('hi');
          });

DEMO

Alessandro Minoccheri
  • 35,521
  • 22
  • 122
  • 171
2

It's not enough to use .on(). You have to use event delegation with an element (such as document) that existed before your dynamically-created elements:

$(document).on('click', '#share', function () {
    alert('hi');
});

(Based on your fiddle, you can use #result instead of document.)

Fiddle

Derek Henderson
  • 9,388
  • 4
  • 42
  • 71