Как я могу перетащить содержимое ячейки в таблицу с динамически добавленными строками и ячейками? - PullRequest
0 голосов
/ 29 апреля 2020

У меня проблемы с перетаскиванием с динамически сгенерированной таблицей. Интерфейс отображает сетку строк и ячеек таблицы на основе выбора пользователя.

Что я хотел бы сделать, это позволить пользователю перетаскивать содержимое одной ячейки, div или span, в другую ячейку.

Этот почти шестилетний разговор go приближается к тому, что я хочу сделать. Но он не справляется со случаем, когда в таблице есть строки, которые добавляются динамически. Перетаскивание содержимого ячейки таблицы

$(function() {
  $('.event').on("dragstart", function(event) {
    var dt = event.originalEvent.dataTransfer;
    dt.setData('Text', $(this).attr('id'));
  });
  $('table td').on("dragenter dragover drop", function(event) {
    event.preventDefault();
    if (event.type === 'drop') {
      var data = event.originalEvent.dataTransfer.getData('Text', $(this).attr('id'));
      de = $('#' + data).detach();
      de.appendTo($(this));
    };
  });
  $('#addRow').on('click', function() {
    $('#targetTable > tbody:last-child').append('<tr><td></td><td></td><td></td></tr>');
  });
});

Этот пример, основанный на этом коде, демонстрирует мою проблему. https://jsfiddle.net/Stormjack/osvu6mea/11/

Вы можете успешно перетащить синий блок в любую ячейку в первых двух строках. Но добавьте новую строку с помощью кнопки «Добавить строку», и вы не сможете поместить этот блок в любую новую строку. Вы все еще можете переместить перетаскиваемый интервал в разные ячейки в первых двух строках. Но его не удается перетащить в новый ряд.

Как мне преодолеть это ограничение? Я счастлив использовать любую комбинацию HTML5 или JavaScript или jQuery или другую клиентскую библиотеку. Спасибо за вашу помощь.


Вот мое решение, основанное на помощи святого.

$(function() {
 initDragAndDrop();
 $('#addRow').on('click', function() {
    $('#targetTable > tbody:last-child').append('<tr><td></td><td></td><td></td></tr>');
    clearDragAndDrop();
    initDragAndDrop();
 });
});

function clearDragAndDrop() {
 $('.event').off();
 $('table td').off('dragenter dragover drop');
}

function initDragAndDrop() {
 $('.event').on('dragstart', function(event) {
    var dt = event.originalEvent.dataTransfer;
    dt.setData('Text', $(this).attr('id'));
 });
 $('table td').on('dragenter dragover drop', function(event) {
    event.preventDefault();
    if (event.type === 'drop') {
      var data = event.originalEvent.dataTransfer.getData('Text', $(this).attr('id'));
      de = $('#' + data).detach();
      de.appendTo($(this));
    }
 });
}

https://jsfiddle.net/Stormjack/osvu6mea/15/

1 Ответ

1 голос
/ 29 апреля 2020

Проблема в том, что при добавлении прослушивателя событий "dragenter dragover drop" было только 2 строки, что означает, что для каждой добавленной новой строки вам необходимо будет добавить в нее прослушиватели событий.

ВНИМАНИЕ : Если вы будете запускать процесс прослушивания событий каждый раз, когда добавляется новая строка, вы получите старые строки с двумя или более прослушивателями событий, которые не являются производительными и могут вызвать проблемы.

Решением было бы добавить новые строки с классом new-row, а затем добавить прослушиватели событий в new-row s, а затем удалить new-row идентификаторы.

JSFiddle: https://jsfiddle.net/rcf4qp85/

  $(function() {
    $('.event').on("dragstart", function(event) {
      var dt = event.originalEvent.dataTransfer;
      dt.setData('Text', $(this).attr('id'));
    });
    initnewrows();
    $('#addRow').on('click', function() {
      $('#targetTable > tbody:last-child').append('<tr class="new-row"><td></td><td></td><td></td></tr>'); initnewrows();
    });
  });

function initnewrows() {
    $('table tr.new-row td').on("dragenter dragover drop", function(event) {
      event.preventDefault();
      if (event.type === 'drop') {
        var data = event.originalEvent.dataTransfer.getData('Text', $(this).attr('id'));
        de = $('#' + data).detach();
        de.appendTo($(this));
      }
    });
   $('table tr.new-row').removeClass('new-row');
}

Вы также должны добавить класс new-row к изначально присутствующему trs.

  <table id="targetTable" border="1">
    <thead>
      <tr class="new-row">
        <th>Col 1</th>
        <th>Col 2</th>
        <th>Col 3</th>
      </tr>
    </thead>
    <tbody>
      <tr class="new-row">
        <td><span class="event" id="a" draggable="true">Move Me</span></td>
        <td></td>
        <td></td>
      </tr>
      <tr class="new-row">
        <td></td>
        <td></td>
        <td></td>
      </tr>
    </tbody>
  </table>

  <p><button id='addRow'>Add Row</button></p>
  <p>
  You can successfully drag the "Move Me" block to any cell in the first two rows.<br/>But add a new row with the "Add Row" button, and you can't drop that block into any new row.
  </p>

JSFiddle: https://jsfiddle.net/rcf4qp85/

...