Search code examples
javascripthtmljquerydrag-and-drop

Copy, Drag and drop table cells only within a table column - JS


I have a table and I can only drag/drop cells across different columns. However, I want the functionality to copy the cell while dragging and dropping it in the same column. If a column already has a value, we need to replace that value with the pasted value. Please advice.

This is my code:

$(document).ready(function() {
  $('.event-1').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('col-1'));
      de = $('#' + data).detach();
      de.appendTo($(this));
    };
  });
  $('.event-2').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('col-2'));
      de = $('#' + data).detach();
      de.appendTo($(this));
    };
  });
})
table th,
table td {
  height: 30px;
  width: 200px;
}

table span {
  display: block;
  background-color: #09C;
  height: 100%;
  width: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table id="#our_table" border="1">
  <tr>
    <th>head1</th>
    <th>head1</th>
    <th>head1</th>
  </tr>
  <tr>
    <td><span class="event-1" id="col-1" draggable="true">aaa</span></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td>sample</td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td><span class="event-2" id="col-2" draggable="true">bbb</span></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
  <tr>
    <td></td>
    <td></td>
    <td></td>
  </tr>
</table>

Any help is appreciated.


Solution

  • Whenever any element is drag you can get index() of tdand tr tag and save them in setData() method . Now , when you are going to drop that element check if the td(where you need to drop) and td(from where span is taken) are same if they match simply get the data which is set in setData method using that data we can detach() that element and append to new td .

    Demo Code :

    $(document).on("dragstart", 'td span', function(event) {
      var dt = event.originalEvent.dataTransfer;
      dt.setData('Text', $(this).closest("td").index() + " , " + $(this).closest("tr").index()); //save index of td & tr
    });
    $('table td').on("dragenter dragover drop", function(event) {
      event.preventDefault();
      var index_ = $(this).index() //get index of td where we are dropping..
      if (event.type === 'drop') {
        var data = event.originalEvent.dataTransfer.getData('Text');
        var new_data = data.split(",") //get data which is set
        //check if the index of td from where span is taken and td where span is to drop is same..
        if (new_data[0] == index_) {
          $(this).text("") //clear if any text before...
          de = $(`tr:eq(${new_data[1]}) td:eq(${new_data[0]}) span`).clone() //detach() //get that element 
          $(de[0]).appendTo($(this)); //append
        }
      };
    });
    table th,
    table td {
      height: 30px;
      width: 200px;
    }
    
    table span {
      display: block;
      background-color: #09C;
      height: 100%;
      width: 100%;
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <table id="#our_table" border="1">
      <tr>
        <th>head1</th>
        <th>head1</th>
        <th>head1</th>
      </tr>
      <tr>
        <td><span draggable="true">aaa</span></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td>sample</td>
        <td></td>
        <td><span draggable="true">ccc</span></td>
      </tr>
      <tr>
        <td></td>
        <td><span draggable="true">bbb</span></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
      <tr>
        <td></td>
        <td></td>
        <td></td>
      </tr>
    </table>