skip to Main Content

I want the red pieces’ children to be draggable and droppable onto the grid. Specifically, I want the pieces to be dropped separately. For example, when I drag redPiece5 and drop it onto a grid, not all pieces should go onto a single grid cell. Instead, I want them to be divided separately. When I drag and drop it, the middle piece should go to the place where I drop it, and the two elements should go to the grid pieces before it and the other two pieces should go after it. I also don’t want the pieces dragged one by one in pieces. I want the pieces to add as a child to the grid piece. Later I will replace the pieces with an image.

// Function to create grid
function createGrid(containerId, numRows, numCols, colorClass) {
  const gridContainer = document.getElementById(containerId);
  for (let i = 0; i < numRows; i++) {
    const row = document.createElement('div');
    row.classList.add('row');
    for (let j = 0; j < numCols; j++) {
      const square = document.createElement('div');
      square.classList.add('square', colorClass);
      row.appendChild(square);
    }
    gridContainer.appendChild(row);
  }
}

// Define the number of rows and columns
const rows = 7;
const columns = 9;

// Create red grid
createGrid('redGrid', rows, columns, 'red');

// Create blue grid
createGrid('blueGrid', rows, columns, 'blue');

// // Create green grid
// createGrid('greenGrid', rows, columns, 'green');

// // Create yellow grid
// createGrid('yellowGrid', rows, columns, 'yellow');
body {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100vh;
  margin: 0;
}

#wrapper {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: row;
  width: 100%;
}

.colourContainer {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: row;
}

.piecesBox {
  width: 210px;
  height: 210px;
  border: 1px dashed black;
}

.gridContainer {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 30px;
}

.grid {
  display: flex;
  flex-direction: column;
  gap: 3px;
  margin: 10px;
}

.row {
  display: flex;
  gap: 3px;
}

.square {
  width: 30px;
  height: 30px;
  border-radius: 5px;
}

.red {
  background-color: crimson;
}

.blue {
  background-color: royalblue;
}

.green {
  background-color: green;
}

.yellow {
  background-color: rgb(241, 241, 14);
}

#greenPieces,
#yellowPieces {
  display: none;
}

.lightcoral {
  background-color: lightcoral;
}

.piecesBox {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  border-radius: 15px;
}

.redPieceses {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: row;
  margin: 5px;
  margin-block: 2px;
}

.bluePieceses {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: row;
  margin: 5px;
  margin-block: 2px;
}

.pieceses {
  margin-right: 3px;
}

#redPiece5 {
  order: 4;
}

#redPiece4 {
  order: 5;
}

#redPiece3-1 {
  order: 2;
}

#redPiece3-2 {
  order: 3;
}

#redPiece2 {
  order: 1;
}

#bluePiece5 {
  order: 4;
}

#bluePiece4 {
  order: 5;
}

#bluePiece3-1 {
  order: 2;
}

#bluePiece3-2 {
  order: 3;
}

#bluePiece2 {
  order: 1;
}
<div id="wrapper">
  <div class="gridContainer">
    <div id="redContainer" class="colourContainer">
      <div id="redPieces" class="piecesBox">
        <div id="redPiece5" class="redPieceses" draggable="true">
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
        </div>
        <div id="redPiece4" class="redPieceses" draggable="true">
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
        </div>
        <div id="redPiece3-1" class="redPieceses" draggable="true">
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
        </div>
        <div id="redPiece3-2" class="redPieceses" draggable="true">
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
        </div>
        <div id="redPiece2" class="redPieceses" draggable="true">
          <div class="square lightcoral pieceses"></div>
          <div class="square lightcoral pieceses"></div>
        </div>
      </div>
      <div class="grid" id="redGrid"></div>
    </div>
    <div id="blueContainer" class="colourContainer">
      <div class="grid" id="blueGrid"></div>
      <div id="bluePieces" class="piecesBox">
        <div id="bluePiece5" class="bluePieceses" draggable="true">
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
        </div>
        <div id="bluePiece4" class="bluePieceses" draggable="true">
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
        </div>
        <div id="bluePiece3-1" class="bluePieceses" draggable="true">
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
        </div>
        <div id="bluePiece3-2" class="bluePieceses" draggable="true">
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
        </div>
        <div id="bluePiece2" class="bluePieceses" draggable="true">
          <div class="square blue pieceses"></div>
          <div class="square blue pieceses"></div>
        </div>
      </div>
    </div>
    <!-- <div class="grid" id="greenGrid"></div>
      <div class="grid" id="yellowGrid"></div> -->
  </div>
</div>

I tried to directly append the child, but all the pieces went into a single grid piece.

2

Answers


  1. Chosen as BEST ANSWER

    // Function to create grid
    function createGrid(containerId, numRows, numCols, colorClass) {
      const gridContainer = document.getElementById(containerId);
      for (let i = 0; i < numRows; i++) {
        const row = document.createElement('div');
        row.classList.add('row');
        for (let j = 0; j < numCols; j++) {
          const square = document.createElement('div');
          square.classList.add('square', colorClass);
          // Enable dropping on the square
          square.setAttribute('ondrop', 'drop(event)');
          square.setAttribute('ondragover', 'allowDrop(event)');
          row.appendChild(square);
        }
        gridContainer.appendChild(row);
      }
    }
    
    function allowDrop(event) {
      event.preventDefault();
    }
    
    function drop(event) {
      event.preventDefault();
      const data = event.dataTransfer.getData('text');
      const draggableElement = document.getElementById(data);
      const target = event.target;
      // Check if the target is a grid square and doesn't have child nodes
      if (target.classList.contains('square') && target.childElementCount === 0) {
        console.log('Dropped redPiece5 into square:', target);
    
        let emptySquareCount = 1; // Initialize with 1 to include the dropped square itself
        let prevSquare = target.previousElementSibling;
        // Count the number of empty grid squares before the dropped square
        while (prevSquare && prevSquare.childElementCount === 0) {
          emptySquareCount++;
          prevSquare = prevSquare.previousElementSibling;
        }
    
        // Move the second and subsequent children based on emptySquareCount
        if (emptySquareCount <= 1) {
          // Move the second and subsequent children to the next grid squares
          let nextSquare = target.nextElementSibling;
          for (let i = 1; i < draggableElement.children.length; i++) {
            // Check if there are no more adjacent squares
            if (!nextSquare || nextSquare.childElementCount > 0) {
              break;
            }
            const child = draggableElement.children[i].cloneNode(true);
            nextSquare.appendChild(child);
            nextSquare = nextSquare.nextElementSibling;
          }
        } else {
          // Move the second and subsequent children to the previous and next grid squares
          prevSquare = target.previousElementSibling;
          let nextSquare = target.nextElementSibling;
          for (let i = 1; i < draggableElement.children.length; i++) {
            // Move the child to the previous square if available
            if (prevSquare && prevSquare.childElementCount === 0) {
              const child = draggableElement.children[i].cloneNode(true);
              prevSquare.appendChild(child);
              prevSquare = prevSquare.previousElementSibling;
            }
            // Move the child to the next square if available
            else if (nextSquare && nextSquare.childElementCount === 0) {
              const child = draggableElement.children[i].cloneNode(true);
              nextSquare.appendChild(child);
              nextSquare = nextSquare.nextElementSibling;
            }
          }
        }
    
        // Append the original div (with only one child) to the target
        const originalChild = draggableElement.children[0];
        target.appendChild(originalChild);
    
        // Remove redPiece5 from redPieces div
        const redPiecesDiv = document.getElementById('redPieces');
        redPiecesDiv.removeChild(draggableElement);
      }
    }
    
    // Define the number of rows and columns
    const rows = 7;
    const columns = 9;
    
    // Create red grid
    createGrid('redGrid', rows, columns, 'red');
    
    // Create blue grid
    createGrid('blueGrid', rows, columns, 'blue');
    
    // Drag and drop functionality for redPiece5
    const redPiece5 = document.getElementById('redPiece5');
    redPiece5.setAttribute('draggable', true);
    redPiece5.addEventListener('dragstart', (event) => {
      event.dataTransfer.setData('text', event.target.id);
    });
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh; 
      margin: 0; 
    }
    
    #wrapper {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: row; 
      width: 100%; 
    }
    
    .colourContainer{
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: row; 
    }
    
    .piecesBox {
      width: 210px;
      height: 210px;
      border: 1px dashed black;
    }
    
    .gridContainer {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 30px;
    }
    
    .grid {
      display: flex;
      flex-direction: column;
      gap: 3px; 
      margin: 10px;
    }
    
    .row {
      display: flex;
      gap: 3px;
    }
    
    .square {
      width: 30px; 
      height: 30px; 
      border-radius: 5px;
    }
    
    .red {
      background-color: crimson; 
    }
    
    .blue {
      background-color: royalblue; 
    }
    
    .green {
      background-color: green; 
    }
    
    .yellow {
      background-color: rgb(241, 241, 14); 
    }
    
    #greenPieces, #yellowPieces {
      display: none;
    }
    .lightcoral {
      background-color: lightcoral;
    }
    
    .piecesBox{
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column; 
      border-radius: 15px;
    }
    
    .redPieceses{
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: row; 
      margin: 5px;
      margin-block: 2px;
    }
    .bluePieceses{
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: row; 
      margin: 5px;
      margin-block: 2px;
    }
    
    .pieceses{
      margin-right: 3px;
    }
    
    #redPiece5{
      order: 4;
    }
    #redPiece4{
      order: 5;
    }
    #redPiece3-1{
      order: 2;
    }
    #redPiece3-2{
      order: 3;
    }
    #redPiece2{
      order: 1;
    }
    
    #bluePiece5{
      order: 4;
    }
    #bluePiece4{
      order: 5;
    }
    #bluePiece3-1{
      order: 2;
    }
    #bluePiece3-2{
      order: 3;
    }
    #bluePiece2{
      order: 1;
    }
    <!DOCTYPE html>
    <html lang="en">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Grid Example</title>
      <link rel="stylesheet" href="./styles/main.css">
    </head>
    <body>
    
    
      <div id="wrapper">
    
    
        
        <div class="gridContainer">
    
    
          <div id="redContainer" class="colourContainer">
            <div id="redPieces" class="piecesBox">
              <div id="redPiece5" class="redPieceses" draggable="true">
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
              </div>
            
              <div id="redPiece4" class="redPieceses" draggable="true">
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
              </div>
            
              <div id="redPiece3-1" class="redPieceses" draggable="true">
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
              </div>
            
              <div id="redPiece3-2" class="redPieceses" draggable="true">
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
              </div>
            
              <div id="redPiece2" class="redPieceses" draggable="true">
                <div class="square lightcoral pieceses"></div>
                <div class="square lightcoral pieceses"></div>
              </div>
            </div>
            <div class="grid" id="redGrid"></div>
          </div>
    
          <div id="blueContainer" class="colourContainer">
            <div class="grid" id="blueGrid"></div>
            <div id="bluePieces" class="piecesBox">
              <div id="bluePiece5" class="bluePieceses" draggable="true">
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
              </div>
            
              <div id="bluePiece4" class="bluePieceses" draggable="true">
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
              </div>
            
              <div id="bluePiece3-1" class="bluePieceses" draggable="true">
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
              </div>
            
              <div id="bluePiece3-2" class="bluePieceses" draggable="true"> 
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
              </div>
            
              <div id="bluePiece2" class="bluePieceses" draggable="true">
                <div class="square blue pieceses"></div>
                <div class="square blue pieceses"></div>
              </div>
            </div>
          </div>
    
          <!-- <div class="grid" id="greenGrid"></div>
          <div class="grid" id="yellowGrid"></div> -->
        </div>
    
    
    
      </div>
    
      <script src="./scripts/main.js"></script>
    
    </body>
    </html>

    I first added the redPiece5 into a single grid, and move the children into the other grid pieces.


  2. document.addEventListener('DOMContentLoaded', function() {
      const draggableElements = document.querySelectorAll('.draggable');
      const gridSquares = document.querySelectorAll('.square');
    
      let draggedElement = null;
    
      draggableElements.forEach(element => {
        element.addEventListener('dragstart', dragStart);
        element.addEventListener('dragend', dragEnd);
      });
    
      gridSquares.forEach(square => {
        square.addEventListener('dragover', dragOver);
        square.addEventListener('dragenter', dragEnter);
        square.addEventListener('dragleave', dragLeave);
        square.addEventListener('drop', drop);
      });
    
      function dragStart() {
        draggedElement = this;
        setTimeout(() => this.style.display = 'none', 0);
      }
    
      function dragEnd() {
        draggedElement.style.display = 'flex';
        draggedElement = null;
      }
    
      function dragOver(e) {
        e.preventDefault();
      }
    
      function dragEnter(e) {
        e.preventDefault();
        this.classList.add('hovered');
      }
    
      function dragLeave() {
        this.classList.remove('hovered');
      }
    
      function drop() {
        this.classList.remove('hovered');
        const gridPiece = this;
        const squares = gridPiece.querySelectorAll('.square');
        const index = Array.from(squares).indexOf(this);
        draggedElement.querySelectorAll('.square').forEach((square, i) => {
          const targetSquare = squares[index + i];
          if (targetSquare) {
            targetSquare.appendChild(square);
          }
        });
      }
    });
    body {
      display: flex;
      justify-content: center;
      align-items: center;
      height: 100vh;
      margin: 0;
    }
    
    #wrapper {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: row;
      width: 100%;
    }
    
    .colourContainer {
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: row;
    }
    
    .piecesBox {
      width: 210px;
      height: 210px;
      border: 1px dashed black;
      display: flex;
      justify-content: center;
      align-items: center;
      flex-direction: column;
    }
    
    .gridContainer {
      display: grid;
      grid-template-columns: repeat(2, 1fr);
      gap: 30px;
    }
    
    .grid {
      display: flex;
      flex-direction: column;
      gap: 3px;
      margin: 10px;
    }
    
    .row {
      display: flex;
      gap: 3px;
    }
    
    .square {
      width: 30px;
      height: 30px;
      border-radius: 5px;
    }
    
    .red {
      background-color: crimson;
    }
    
    .blue {
      background-color: royalblue;
    }
    
    .green {
      background-color: green;
    }
    
    .yellow {
      background-color: rgb(241, 241, 14);
    }
    
    #greenPieces,
    #yellowPieces {
      display: none;
    }
    
    .lightcoral {
      background-color: lightcoral;
    }
    
    .pieceses {
      margin-right: 3px;
    }
    
    .hovered {
      border: 2px dashed black;
    }
    <div id="wrapper">
      <div class="gridContainer">
        <div id="redContainer" class="colourContainer">
          <div id="redPieces" class="piecesBox">
            <div id="redPiece5" class="redPieceses draggable" draggable="true">
              <div class="square lightcoral pieceses"></div>
              <div class="square lightcoral pieceses"></div>
              <div class="square lightcoral pieceses"></div>
              <div class="square lightcoral pieceses"></div>
              <div class="square lightcoral pieceses"></div>
            </div>
            <!-- Similar structure for other red pieces -->
          </div>
          <div class="grid" id="redGrid"></div>
        </div>
        <!-- Similar structure for blue pieces and grid -->
      </div>
    </div>

    To achieve the desired behavior where each draggable piece is dropped separately onto the grid, you can utilize the HTML Drag and Drop API along with some JavaScript to handle the drag and drop events.

    With this code, each draggable piece will be dropped separately onto the grid, with its child squares distributed across adjacent grid squares. Adjust the CSS as needed to ensure proper styling and layout.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search