Home > Enterprise >  Why my table is getting collapsed when I am moving div elements?
Why my table is getting collapsed when I am moving div elements?

Time:02-11

I am trying to make a table in which we can interchange colored boxes via drag and drop with animation. It is working fine sometimes but in some cases the table is getting collapsed .Steps to replicate the problem.

  1. Move 100 - 400
  2. Move 100 -500
  3. Move 100 - 200
  4. Move 100 - 300

You can find my code in this attached link :

https://jsfiddle.net/manikathuria2001/oveq91Lu/6/

HTML

var columns = document.querySelectorAll('.card');
var draggingClass = 'dragging';
var dragSource;

Array.prototype.forEach.call(columns, function (col) {
  col.addEventListener('dragstart', handleDragStart, false);
  col.addEventListener('dragenter', handleDragEnter, false)
  col.addEventListener('dragover', handleDragOver, false);
  col.addEventListener('dragleave', handleDragLeave, false);
  col.addEventListener('drop', handleDrop, false);
  col.addEventListener('dragend', handleDragEnd, false);
});

function handleDragStart (evt) {
  dragSource = this;
  evt.target.classList.add(draggingClass);
  evt.dataTransfer.effectAllowed = 'move';
  
}

function handleDragOver (evt) {
  evt.dataTransfer.dropEffect = 'move';
  evt.preventDefault();
}

function handleDragEnter (evt) {
  this.classList.add('over');
}

function handleDragLeave (evt) {
  this.classList.remove('over');
}

function handleDrop (evt) {
  evt.stopPropagation();
  
  if (dragSource !== this) {
   $(this).swap($(dragSource),300); 
  }
  evt.preventDefault();
}

function handleDragEnd (evt) {
  Array.prototype.forEach.call(columns, function (col) {
    ['over', 'dragging'].forEach(function (className) {
      col.classList.remove(className);
    });
  });
}


(function( $ ){
    $.fn.swap = function(other,speed) {

     
        //get the position
        var position1 = $(this).offset();
        var position2 = other.offset();

        //position this where it is
        $(this).css({
            top: position1.top   'px',
            left: position1.left   'px',
            position: 'absolute'
        });

        //position the other element where it is
        other.css({
            top: position2.top   'px',
            left: position2.left   'px',
            position: 'absolute'
        });

        $(this).animate({
            'top': position2.top   'px',
            'left': position2.left   'px',
            position: 'absolute'
        }, speed, function() {
                // Animation complete.
        });

        other.animate({
            'top': position1.top   'px',
            'left': position1.left   'px',
            position: 'absolute'
        }, speed, function() {
            // Animation complete.
        });
       
    };
})( jQuery );
.container {
  font-family: sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  vertical-align: middle;
  text-align: center;
}

#table1 {
  width: 100%;
  height: 50%;
}

#table1,
.block {
  border: 1px solid black;
  border-collapse: collapse;
}

.block {
  padding: 30px !important;
  margin: 100px !important;
  /* min-width: 200px !important;
    min-height: 400px !important; */
}

.card {
  width: 100px;
  height: 60px;
  border-radius: 25px;
  /* display: inline-block; */
  /* margin-right: 1.2%; */
  box-sizing: border-box;
  font-size: larger;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  vertical-align: middle;
  text-align: center;
  z-index: 100;
}

.card.dragging {
  opacity: 0.5;
}

.card.over {
  border: 3px dashed #000;
}

.box1 {
  background-color: #E74C3C;
}

.box2 {
  background-color: #8E44AD;
}

.box3 {
  background-color: #5DADE2;
}

.box4 {
  background-color: #1ABC9C;
}

.box5 {
  background-color: #F1C40F;
}

.box6 {
  background-color: #F39C12;
}

.box7 {
  background-color: #34495E;
}

.box8 {
  background-color: #FF00FF;
}

.box9 {
  background-color: #008080;
}

[draggable] {
  user-select: none;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
  <link rel="stylesheet" href="./styles.css">
  <title>Document</title>
</head>

<body>
  <div >
    <table id="table1" cellspacing="0" cellpadding="0">
      <tr >
        <td >
          <div  draggable="true">100</div>
        </td>
        <td >
          <div  draggable="true">200</div>
        </td>
        <td >
          <div  draggable="true">300</div>
        </td>
      </tr>
      <tr >
        <td >
          <div  draggable="true">400</div>
        </td>
        <td >
          <div  draggable="true">500</div>
        </td>
        <td >
          <div  draggable="true">600</div>
        </td>
      </tr>
      <tr >
        <td >
          <div  draggable="true">700</div>
        </td>
        <td >
          <div  draggable="true">800</div>
        </td>
        <td >
          <div  draggable="true">900</div>
        </td>
      </tr>
    </table>
  </div>



  <script src="./index.js"></script>
</body>

</html>

CodePudding user response:

The height of .block is dependent on the .card inside it. But when the card is moved it gets position: absolute;, so it's out of the flow, and the block collapses. You don't notice this until all the cards on the same row are moved, then the row collapses.

Give .block a fixed height in CSS and the problem goes away.

There's a similar problem with the column widths if you drag all the cards in the same column, so you also have to give .block a fixed width.

var columns = document.querySelectorAll('.card');
var draggingClass = 'dragging';
var dragSource;

Array.prototype.forEach.call(columns, function (col) {
  col.addEventListener('dragstart', handleDragStart, false);
  col.addEventListener('dragenter', handleDragEnter, false)
  col.addEventListener('dragover', handleDragOver, false);
  col.addEventListener('dragleave', handleDragLeave, false);
  col.addEventListener('drop', handleDrop, false);
  col.addEventListener('dragend', handleDragEnd, false);
});

function handleDragStart (evt) {
  dragSource = this;
  evt.target.classList.add(draggingClass);
  evt.dataTransfer.effectAllowed = 'move';
  
}

function handleDragOver (evt) {
  evt.dataTransfer.dropEffect = 'move';
  evt.preventDefault();
}

function handleDragEnter (evt) {
  this.classList.add('over');
}

function handleDragLeave (evt) {
  this.classList.remove('over');
}

function handleDrop (evt) {
  evt.stopPropagation();
  
  if (dragSource !== this) {
   $(this).swap($(dragSource),300); 
  }
  evt.preventDefault();
}

function handleDragEnd (evt) {
  Array.prototype.forEach.call(columns, function (col) {
    ['over', 'dragging'].forEach(function (className) {
      col.classList.remove(className);
    });
  });
}


(function( $ ){
    $.fn.swap = function(other,speed) {

     
        //get the position
        var position1 = $(this).offset();
        var position2 = other.offset();

        //position this where it is
        $(this).css({
            top: position1.top   'px',
            left: position1.left   'px',
            position: 'absolute'
        });

        //position the other element where it is
        other.css({
            top: position2.top   'px',
            left: position2.left   'px',
            position: 'absolute'
        });

        $(this).animate({
            'top': position2.top   'px',
            'left': position2.left   'px',
            position: 'absolute'
        }, speed, function() {
                // Animation complete.
        });

        other.animate({
            'top': position1.top   'px',
            'left': position1.left   'px',
            position: 'absolute'
        }, speed, function() {
            // Animation complete.
        });
       
    };
})( jQuery );
.container {
  font-family: sans-serif;
  display: flex;
  justify-content: center;
  align-items: center;
  vertical-align: middle;
  text-align: center;
}

#table1 {
  width: 100%;
  height: 50%;
}

#table1,
.block {
  border: 1px solid black;
  border-collapse: collapse;
}

.block {
  padding: 30px !important;
  margin: 100px !important;
  /* min-width: 200px !important;
    min-height: 400px !important; */
  height: 60px; /* prevent collapse when card is moved */
  width: 340px;
}

.card {
  width: 100px;
  height: 60px;
  border-radius: 25px;
  /* display: inline-block; */
  /* margin-right: 1.2%; */
  box-sizing: border-box;
  font-size: larger;
  color: #fff;
  display: flex;
  justify-content: center;
  align-items: center;
  vertical-align: middle;
  text-align: center;
  z-index: 100;
}

.card.dragging {
  opacity: 0.5;
}

.card.over {
  border: 3px dashed #000;
}

.box1 {
  background-color: #E74C3C;
}

.box2 {
  background-color: #8E44AD;
}

.box3 {
  background-color: #5DADE2;
}

.box4 {
  background-color: #1ABC9C;
}

.box5 {
  background-color: #F1C40F;
}

.box6 {
  background-color: #F39C12;
}

.box7 {
  background-color: #34495E;
}

.box8 {
  background-color: #FF00FF;
}

.box9 {
  background-color: #008080;
}

[draggable] {
  user-select: none;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
  <script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
  <link rel="stylesheet" href="./styles.css">
  <title>Document</title>
</head>

<body>
  <div >
    <table id="table1" cellspacing="0" cellpadding="0">
      <tr >
        <td >
          <div  draggable="true">100</div>
        </td>
        <td >
          <div  draggable="true">200</div>
        </td>
        <td >
          <div  draggable="true">300</div>
        </td>
      </tr>
      <tr >
        <td >
          <div  draggable="true">400</div>
        </td>
        <td >
          <div  draggable="true">500</div>
        </td>
        <td >
          <div  draggable="true">600</div>
        </td>
      </tr>
      <tr >
        <td >
          <div  draggable="true">700</div>
        </td>
        <td >
          <div  draggable="true">800</div>
        </td>
        <td >
          <div  draggable="true">900</div>
        </td>
      </tr>
    </table>
  </div>



  <script src="./index.js"></script>
</body>

</html>

  • Related