0

In the following snippet I have a input and a delete button next to it. They can be cloned and each delete button has a function that tells me which input is trying to be deleted.

The weird thing is that it works perfectly when I run the snippet.

In my browser the cloned buttons are not calling the function, only the original one does. Also, the title "Remove" appears only on the first button, even when I hover the mouse on any other button.

What could be causing this issue?

I am using the same versions of everything in the snippet.

$("#clone").click(function() {
  var currentCount = $("#tablePhones tbody tr").length;
  var newCount = currentCount + 1;

  $('#tablePhones tbody>tr:last').clone(true).insertAfter('#tablePhones tbody>tr:last');
  $('#tablePhones tbody>tr:last').find("input, a").each(function() {
    var newId = $(this).attr("id").replace("_" + currentCount, "_" + newCount);
    var newName = $(this).attr("name").replace("_" + currentCount, "_" + newCount);
    $(this).attr("id", newId).attr("name", newName);
    if ($(this).is("input")) {
      $(this).val("");
    }
  });
});

$(".btn.remove").click(function() {
  name = $(this).attr("name");
  console.log(name);
});
td .btn.aligned {
  position: absolute;
  margin-top: 7px;
  float: right;
  margin-left: 5px;
}

td input {
  float: left;
  margin-bottom: 10px;
}
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://use.fontawesome.com/a06b1c7829.js"></script>

<a id="clone" class="btn btn-primary">
  <i class="fa "></i> Clone
</a>

<table id="tablePhones" class="table table-hover">
  <thead class="thead-inverse">
    <th>Phone numbers</th>
  </thead>
  <tbody>
    <tr>
      <td>
        <div class="row col-xs-3">
          <input type="text" name="phone_1" id="telefono1_1" class="form-control" />
          <a title="Remove" name="removephone_1" id="removephone_1" class="btn btn-danger btn-xs aligned remove"><span class="fa fa-times">
          </span>
          </a>
        </div>
      </td>
    </tr>
  </tbody>
</table>
raptorandy
  • 225
  • 5
  • 21
  • 1
    You code works perfectly in my Chrome 58. – wannadream May 19 '17 at 19:40
  • `.clone(true)` should also clone any event listeners that are attached, so you're doing it right - and your snippet works. Can you reproduce the error for us? – mhodges May 19 '17 at 19:41
  • It's very difficult to debug working code. There has to be something different between the snippet and your project code. Does the javascript get interrupted? Does the javascript console report any errors or warnings? – Joseph Marikle May 19 '17 at 19:43
  • How is your javascript included in your code? Does it wait for the DOM to be ready? – Joseph Marikle May 19 '17 at 19:44

3 Answers3

2

Must be an issue related to event listener attachment to newly created/inserted DOM element. Try using event delegation technique as follows:

$(document).on("click", ".btn.remove" ,function() {
  name = $(this).attr("name");
  console.log(name);
});
vijayP
  • 11,432
  • 5
  • 25
  • 40
  • Thanks! This fixes the problem. Do you know how to fix the problem with the button title? – raptorandy May 19 '17 at 19:47
  • could you please inspect the newly clonned DOM element and check whether they have `title` attribute. Logically it should be as it is because you are not touching it via your JS code. You are just modifying `id` to avoid duplicate ids. – vijayP May 19 '17 at 19:52
  • They have title attribute but it is just 'title', not 'title="Remove"' – raptorandy May 19 '17 at 19:59
2

When you clone the object, the click handler is not cloned.

Try installing a single click handler on a containing object: instead of $(".btn.remove").on('click'), use $('#tablePhones').on('click', 'a.btn.remove').

LSerni
  • 55,617
  • 10
  • 65
  • 107
0

After clonig find your new button and assign the click function to it:

var newRow = $('#tablePhones tbody>tr:last').clone(true).insertAfter('#tablePhones tbody>tr:last');
$(newRow).find(".btn.remove").click(function(){
    name = $(this).attr("name");
    console.log(name);
});
Todor Simeonov
  • 806
  • 1
  • 6
  • 11