blue-sky
blue-sky

Reputation: 53806

jQuery click event not firing when appending new button

When I click the 'Show' button the show listener is invoked and a new hide button is displayed. But why is the hide button not invoked when I then click 'Hide' ?

 $('.myCss').append('<input type="button" class="show" value="Show"/>');

$('.show').on('click', function () {
        console.log('show clicked');
    $('.myCss').append('<input type="button" class="hide" value="Hide"/>');
});

    $('.hide').on('click', function () {
    console.log('hide clicked');
    $('.myCss').append('<input type="button" class="show" value="Show"/>');
    });

Upvotes: 1

Views: 2013

Answers (5)

Joe
Joe

Reputation: 436

Several people have correctly answered that the hide button is created after the event is bound to the controls. I suggest a different approach of using a handler at a higher level (document, in my example) that will attach to future controls (the current approach to the now deprecated .live).

Example: http://jsfiddle.net/kQ2JA/1/

This will better match your expectations of binding the event to all current and future controls.

Upvotes: 0

iwiznia
iwiznia

Reputation: 1679

Because when you set the event, the .hide element doesn't exist. You could try setting the events like:

$('.myCss').append('<input type="button" class="show" value="Show"/>');

$('.myCss').on('click', '.show', function () {
  console.log('show clicked');
  $('.myCss').append('<input type="button" class="hide" value="Hide"/>');
});

$('.myCss').on('click', '.hide', function () {
  console.log('hide clicked');
  $('.myCss').append('<input type="button" class="show" value="Show"/>');
});

This attaches the click to the .myCss element (shich always exists), but only fires the function when the click was fired on .hide element inside it.

This solution is more efficent that creating the event everytime the element is created.

Upvotes: 1

Iain
Iain

Reputation: 4203

When the '.hide' event handler is created, the 'Hide' button doesn't exist yet.

You could set up the event handler after creating the element, use event bubbling, or use use .live.

Upvotes: 0

Pixou
Pixou

Reputation: 1769

the problem is that you "hide" button does not exist when you try to define the onclick event on it. I would suggest that you add it, set display=none, and then show it

Upvotes: 0

j08691
j08691

Reputation: 207861

It has to do with the order of elements being added to the page. If you drop the hide code within the show code it works (although you should check your logic):

$('.show').on('click', function() {
    console.log('show clicked');
    $('.myCss').append('<input type="button" class="hide" value="Hide"/>');
    $('.hide').on('click', function() {
        console.log('hide clicked');
        $('.myCss').append('<input type="button" class="show" value="Show"/>');
    });
});​

jsFiddle example

In your original code, the code to bind the click event to the hide button exists prior to the actual hide button, so it isn't actually bound to anything. By moving it within the other code block you delay the execution of that chunk. You could also use .on() to bind the click event to an event higher up in the DOM but it's really basically the same final result.

From the docs:

Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call to .on(). To ensure the elements are present and can be selected, perform event binding inside a document ready handler for elements that are in the HTML markup on the page. If new HTML is being injected into the page, select the elements and attach event handlers after the new HTML is placed into the page. Or, use delegated events to attach an event handler, as described next.

Upvotes: 5

Related Questions