Как клонировать строку клонированной таблицы? - PullRequest
1 голос
/ 23 января 2020

У меня есть таблица, в которой уже есть 5 строк, я добавил код js, чтобы, когда пользователь вводит что-то в последней строке, он клонируется (работает нормально), но когда пользователь вводит что-то в клонированном строка не клонируется Может кто-нибудь, пожалуйста, помогите мне, почему он не работает?

$(document).ready(function() {
  $(".keynum").change(function(event) {
    $("#frmOK").val("1");
    var pid = $('#p').val();

    lastval = $(".keynum").last().val();
    if (lastval != "") {
      var $tableBody = $('#tblKeyNumQty').find("tbody"),
        $trLast = $tableBody.find("tr:last"),
        $trNew = $trLast.clone();
      $trLast.after($trNew);
    }
  });
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<table id="tblKeyNumQty" class="table table-responsive table-striped table-bordered">
  <tbody>
    <tr>
      <th align="center">Key Number</th>
      <th align="center">Quantity</th>
    </tr>
    <tr>
      <td><input name="keynum[]" placeholder="SKU-123" class="form-control keynum" value="" onkeypress="return event.keyCode != 13;" /></td>
      <td><input name="qty[]" type="number" min="2" class="form-control" value="2" onkeypress="return event.keyCode != 13;" /></td>
    </tr>
    <tr>
      <td><input name="keynum[]" placeholder="SKU-123" class="form-control keynum" value="" onkeypress="return event.keyCode != 13;" /></td>
      <td><input name="qty[]" type="number" min="2" class="form-control" value="2" onkeypress="return event.keyCode != 13;" /></td>
    </tr>
    <tr>
      <td><input name="keynum[]" placeholder="SKU-123" class="form-control keynum" value="" onkeypress="return event.keyCode != 13;" /></td>
      <td><input name="qty[]" type="number" min="2" class="form-control" value="2" onkeypress="return event.keyCode != 13;" /></td>
    </tr>
    <tr>
      <td><input name="keynum[]" placeholder="SKU-123" class="form-control keynum" value="" onkeypress="return event.keyCode != 13;" /></td>
      <td><input name="qty[]" type="number" min="2" class="form-control" value="2" onkeypress="return event.keyCode != 13;" /></td>
    </tr>
    <tr>
      <td><input name="keynum[]" placeholder="SKU-123" class="form-control keynum" value="" onkeypress="return event.keyCode != 13;" /></td>
      <td><input name="qty[]" type="number" min="2" class="form-control" value="2" onkeypress="return event.keyCode != 13;" /></td>
    </tr>
  </tbody>
</table>

Ответы [ 2 ]

2 голосов
/ 23 января 2020

При работе с динамически добавляемыми элементами DOM необходимо делегировать события элементу-предку, существовавшему с момента загрузки веб-страницы. В этой ситуации <form> (не указано в HTML вопроса - но очевидно, что оно существует согласно предоставленному jQuery). Хотя <table> (даже document в этом отношении - хотя и не рекомендуется) также является элементом-предком всех <input> с, событие "change" применяется только к элементам <form> и элементам управления формой (например, <input>, <select> и др. c.).

99% времени метод .on() является наилучшим способом делегирования событий. Ниже приведен наиболее эффективный шаблон:

$("selectorOfAncestor").on("eventType", "selectorOfTargets", eventHandler);
// So if you had <form id="OK"> wrapped around the <table>...
$("#OK").on("change", ".keynum:last", cloneLast)
// When defining the event handler (ex. function cloneLast(e) {... ) ".keynum:last" = this

jQuery позволяет удобно "покрывать" многие элементы 1016 * очень гибким и точным способом, поэтому вам следует никогда не используйте атрибуты по событию как эта мерзость:

<input ... onkeypress="return event.keyCode != 13;">

Используйте одну строку кода, а не 100 строк одного и того же кода:

 $('input').on('keypress', function(e) {
    return e.keyCode != 13
 });

Также обратите внимание, что я немного исправил <table>, обернув <thead> вокруг <th> и применив Bootstrap class .text-center к <thead>. Атрибут [align] устарел, и если у вас нет Bootstrap, используйте вместо него свойство CSS text-align.

Еще один совет: если вы разместите свой jQuery / JavaScript перед закрывающим тегом body (ie </body>) вам не нужно все оборачивать в $(document).ready({...}). Независимо от того, делаете вы это или нет, размещение <script> перед закрывающим тегом </body> является на 99% наиболее эффективным местом для его установки.

Demo

$('#OK').on('change', '.keynum:last', cloneLast);

function cloneLast(e) {
  if ($(this).val() !== '') {
    $(this).closest('tr').clone().appendTo($(this).closest('tbody'));
  }
}

$('input').on('keypress', function(e) {
  return e.keyCode != 13
});
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">


<form id='OK'>
  <table id="tblKeyNumQty" class="table table-responsive table-striped table-bordered">
    <thead class='text-center'>
      <tr>
        <th>Key Number</th>
        <th>Quantity</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td><input name="keynum[]" placeholder="SKU-123" class="form-control keynum"></td>
        <td><input name="qty[]" type="number" min="2" class="form-control" value="2"></td>
      </tr>
      <tr>
        <td><input name="keynum[]" placeholder="SKU-123" class="form-control keynum"></td>
        <td><input name="qty[]" type="number" min="2" class="form-control" value="2"></td>
      </tr>
      <tr>
        <td><input name="keynum[]" placeholder="SKU-123" class="form-control keynum"></td>
        <td><input name="qty[]" type="number" min="2" class="form-control" value="2"></td>
      </tr>
      <tr>
        <td><input name="keynum[]" placeholder="SKU-123" class="form-control keynum"></td>
        <td><input name="qty[]" type="number" min="2" class="form-control" value="2"></td>
      </tr>
    </tbody>
  </table>
</form>

<script src='https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js'></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.3.1/js/bootstrap.min.js"></script>
1 голос
/ 23 января 2020

Также добавьте обработчик изменений во вновь созданные строки таблицы:

function keynumChange(event) {
        $("#frmOK").val("1");
        var pid = $('#p').val();

        lastval = $(".keynum").last().val();
        if (lastval != "") { 
            var $tableBody = $('#tblKeyNumQty').find("tbody"),
            $trLast = $tableBody.find("tr:last"),
            $trNew = $trLast.clone();
            $trNew.change(keynumChange); // <- mind this!
            $trLast.after($trNew);
        }

}
$( document ).ready(function() {
    $( ".keynum" ).change(keynumChange);
});

Так как они были добавлены после $(document).ready, это не будет применяться к этим вновь добавленным строкам по умолчанию.

...