// 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 to add drag and drop functionality to redPieces
function addDragDrop(redPieceId) {
const redPiece = document.getElementById(redPieceId);
redPiece.setAttribute('draggable', true);
redPiece.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text', event.target.id);
});
}
// Add drag and drop functionality to all redPieces
const redPieceIds = ['redPiece5', 'redPiece4', 'redPiece3-1', 'redPiece3-2', 'redPiece2'];
redPieceIds.forEach((redPieceId) => {
addDragDrop(redPieceId);
});
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');
// Function to rotate the pieces
function rotatePieces() {
const squares = document.querySelectorAll('.square');
squares.forEach((square) => {
square.classList.toggle('vertical');
});
const redPiecesContainer = document.getElementById('redPieces');
redPiecesContainer.classList.toggle('vertical');
}
// Event listener for the rotate button
const redRotate = document.getElementById('redRotate');
redRotate.addEventListener('click', rotatePieces);
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;
}
.vertical {
transform: rotate(90deg);
}
.vertical #redPieces {
flex-direction: column;
}
/* #redRotate.vertical {
transform: rotate(-90deg);
} */
<!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> <button id="redRotate">Rotate</button>
<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>
The above snippet only includes Horzitonal dropping.
When the pieces are horizontal, use the existing drop function, but when it is vertical add a drop that adds pieces into the grid in vertical positioning. So for adding I gave row class. which is the parent of the dropping grid piece. You can see in the HTML. so when it is vertical, we will add the next piece in the same element index but in the next row. Use if-else for toggling and drop
// 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 to add drag and drop functionality to redPieces
function addDragDrop(redPieceId) {
const redPiece = document.getElementById(redPieceId);
redPiece.setAttribute('draggable', true);
redPiece.addEventListener('dragstart', (event) => {
event.dataTransfer.setData('text', event.target.id);
});
}
// Add drag and drop functionality to all redPieces
const redPieceIds = ['redPiece5', 'redPiece4', 'redPiece3-1', 'redPiece3-2', 'redPiece2'];
redPieceIds.forEach((redPieceId) => {
addDragDrop(redPieceId);
});
function drop(event) {
event.preventDefault();
const data = event.dataTransfer.getData('text');
const draggableElement = document.getElementById(data);
const target = event.target;
// Check if the redRotate button is in vertical position
const isVertical = redRotate.classList.contains('vertical');
// If in horizontal position, use the existing drop function
if (!isVertical) {
// Check if the target is a grid square and doesn't have child nodes
if (target.classList.contains('square') && target.childElementCount === 0) {
const originalChild = draggableElement.children[0].cloneNode(true);
target.appendChild(originalChild);
draggableElement.removeChild(originalChild);
// Remove redPiece element if all children are dropped
if (draggableElement.childElementCount === 0) {
const redPiecesDiv = document.getElementById('redPieces');
redPiecesDiv.removeChild(draggableElement);
}
}
} else {
// If in vertical position, add the piece to the grid vertically
if (target.classList.contains('row')) {
const row = target;
const squares = row.querySelectorAll('.square');
let emptySquare = null;
squares.forEach(square => {
if (square.childElementCount === 0 && emptySquare === null) {
emptySquare = square;
}
});
// If an empty square is found, drop the piece
if (emptySquare !== null) {
const originalChild = draggableElement.children[0].cloneNode(true);
emptySquare.appendChild(originalChild);
draggableElement.removeChild(originalChild);
// Remove redPiece element if all children are dropped
if (draggableElement.childElementCount === 0) {
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');
// Function to rotate the pieces
function rotatePieces() {
const squares = document.querySelectorAll('.square');
squares.forEach((square) => {
square.classList.toggle('vertical');
});
const redPiecesContainer = document.getElementById('redPieces');
redPiecesContainer.classList.toggle('vertical');
// Toggle the class for the redRotate button
redRotate.classList.toggle('vertical');
}
// Event listener for the rotate button
const redRotate = document.getElementById('redRotate');
redRotate.addEventListener('click', rotatePieces);
function drop(event) {
event.preventDefault();
const data = event.dataTransfer.getData('text');
const draggableElement = document.getElementById(data);
const target = event.target;
// Check if the redRotate button is in vertical position
const isVertical = redRotate.classList.contains('vertical');
// If in horizontal position, use the existing drop function
if (!isVertical) {
// Existing drop function logic
// ...
} else {
// If in vertical position, add the piece to the grid vertically
if (target.classList.contains('row')) {
// Append the original div (with only one child) to the target row
const originalChild = draggableElement.children[0];
target.appendChild(originalChild);
}
}
}
I tried this in else for vertical but it does not work.