96

So I have this button which adds a new row to the table, however my problem is that it does not listen to the .new_participant_form click event anymore after the append method has taken place.

http://jsfiddle.net/cTEFG/

Click Add New Entry then click on the Form name.

$('#add_new_participant').click(function() {


    var first_name = $('#f_name_participant').val();
    var last_name = $('#l_name_participant').val();
    var role = $('#new_participant_role option:selected').text();
    var email = $('#email_participant').val();


    $('#registered_participants').append('<tr><td><a href="#" class="new_participant_form">Participant Registration</a></td><td>'+first_name+ ' '+last_name+'</td><td>'+role+'</td><td>0% done</td></tr>');

    });

    $('.new_participant_form').click(function() {

        var $td = $(this).closest('tr').children('td');

        var part_name = $td.eq(1).text();
        alert(part_name);

    });
});

HTML

<table id="registered_participants" class="tablesorter">

<thead>
<tr> 
<th>Form</th>
<th>Name</th>
<th>Role</th>
<th>Progress </th>


</tr> 
</thead>


<tbody>
<tr> 
<td><a href="#" class="new_participant_form">Participant Registration</a></td>
<td>Smith Johnson</td>
<td>Parent</td>
<td>60% done</td>


</tr> 
</tbody>

</table>

<button id="add_new_participant"></span>Add New Entry</button> 
1
  • The problem is that the event is only attached to the new_participant_form element that is already in the document. To make it work for elements you will add later as well, you can use event delegation, as dystroy has demonstrated, or attach the handler to each anchor before you insert it (the former is more efficient). Commented Mar 14, 2013 at 21:34

5 Answers 5

241

Use on :

$('#registered_participants').on('click', '.new_participant_form', function() {

So that the click is delegated to any element in #registered_participants having the class new_participant_form, even if it's added after you bound the event handler.

Sign up to request clarification or add additional context in comments.

3 Comments

Is there any disadvantage regarding performance, if you use $(document).on('click', '.new_participant_form', function() {}); ?
@basZero There's one, as jQuery would then have to handle all clicks and not just the one on the #registered_participants but to be fair this slowdown is so small it's irrelevant. It's mostly better to target the right element because it's cleaner.
Can i use on a new appended element have a same class name?
43

The .on() method is used to delegate events to elements, dynamically added or already present in the DOM:

// STATIC-PARENT              on  EVENT    DYNAMIC-CHILD
$('#registered_participants').on('click', '.new_participant_form', function() {

  var $td = $(this).closest('tr').find('td');
  var part_name = $td.eq(1).text();
  console.log( part_name );

});


$('#add_new_participant').click(function() {

  var first_name = $.trim( $('#f_name_participant').val() );
  var last_name  = $.trim( $('#l_name_participant').val() );
  var role       = $('#new_participant_role').val();
  var email      = $('#email_participant').val();
  
  if(!first_name && !last_name) return;

  $('#registered_participants').append('<tr><td><a href="#" class="new_participant_form">Participant Registration</a></td><td>' + first_name + ' ' + last_name + '</td><td>' + role + '</td><td>0% done</td></tr>');

});
<table id="registered_participants" class="tablesorter">
  <thead>
    <tr>
      <th>Form</th>
      <th>Name</th>
      <th>Role</th>
      <th>Progress </th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><a href="#" class="new_participant_form">Participant Registration</a></td>
      <td>Smith Johnson</td>
      <td>Parent</td>
      <td>60% done</td>
    </tr>
  </tbody>
</table>

<input type="text" id="f_name_participant" placeholder="Name">
<input type="text" id="l_name_participant" placeholder="Surname">
<select id="new_participant_role">
  <option>Parent</option>
  <option>Child</option>
</select>
<button id="add_new_participant">Add New Entry</button>

<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Read more: http://api.jquery.com/on/

Comments

15

This problem could be solved as mentioned using the .on on jQuery 1.7+ versions.

Unfortunately, this didn't work within my code (and I have 1.11) so I used:

$('body').delegate('.logout-link','click',function() {

http://api.jquery.com/delegate/

As of jQuery 3.0, .delegate() has been deprecated. It was superseded by the .on() method since jQuery 1.7, so its use was already discouraged. For earlier versions, however, it remains the most effective means to use event delegation. More information on event binding and delegation is in the .on() method. In general, these are the equivalent templates for the two methods:

// jQuery 1.4.3+
$( elements ).delegate( selector, events, data, handler );
// jQuery 1.7+
$( elements ).on( events, selector, data, handler );

This comment might help others :) !

Comments

3
$(document).on("click", '.mylink', function(event) { 
alert("new link clicked!");});

1 Comment

While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. You can find more information on how to write good answers in the help center: stackoverflow.com/help/how-to-answer . Good luck 🙂
2

** Here is the solution, that might help you **

// Changed to delegate() method to use delegation from the body

$("body").delegate("#boundOnPageLoaded", "click", function(){
   alert("Delegated Button Clicked")
});

1 Comment

The delegate() method was deprecated in version 3.0. So use the on() method instead.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.