Items seem to vanish into thin air and become immovable when attempting to relocate them

I am attempting to create a unique grid layout with 3x3 dimensions, where each grid item represents a fragment of a single image. These items should have the capability to be dragged and dropped inside another 3x3 grid, in any desired sequence.

I have hit a obstacle while working on this task, and I have been trying to resolve it for quite some time now.

Directory structure:

.
├── Project/
│   └── Res/
│       ├── Media/
│       │   └── Images/
│       │       └── image.jpg
│       ├── Scripts/
│       │   └── anim3.js
│       ├── Styles/
│       │   └── anim3.css
│       └── Pages/
│           └── animPage3.html
└── index.html(not relevant)

animPage3.html:

<body>
<head>
<link 
rel="stylesheet" href="Res/Styles/anim3.css">
</head>

<div class="draggable-grid">
  <div class="box" draggable="true"></div>
  ...There's a total of 9 these...
</div>

<div class="droppable-grid">

<div class="droppable-box"></div> 
<!--There's a total of 9 of these "droppable-box" divs-->

</div>
<script src="Res/Scripts/anim3.js">
</body>

anim3.css:

.grid-cont {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.draggable-grid, .droppable-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  grid-template-rows: repeat(3, 1fr);
  gap: 10px;
}
.box {
  width: 100px; 
  height: 100px; 
  background-image: url('../Media/Images/image.jpg');
  background-size: 300% 300%;
}
.droppable-box {
  border: 2px dashed #ccc;
  height: 100px; 
}

anim3.js:

const draggableBoxes = document.querySelectorAll('.draggable-grid .box');
const droppableBoxes = document.querySelectorAll('.droppable-grid .droppable-box');
draggableBoxes.forEach(box => {
  box.addEventListener('dragstart', dragStart);
});
droppableBoxes.forEach(droppableBox => {
  droppableBox.addEventListener('dragover', dragOver);
  droppableBox.addEventListener('dragenter', dragEnter);
  droppableBox.addEventListener('dragleave', dragLeave);
  droppableBox.addEventListener('drop', drop);
});
let draggedItem = null;
function dragStart() {
  draggedItem = this;
  setTimeout(() => this.style.display = 'none', 0);
}
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');
  this.append(draggedItem);
  draggedItem.style.display = 'block';
  draggedItem = null;
}

I attempted to comment out the following line:

//setTimeout(() => this.style.display = 'none', 0);
However, it did not fix the issue with dragging functionality.

Desired outcome of the code: Create two 3x3 grids. The first grid contains draggable items, where each item represents a portion of a single image. The second grid serves as the drop zone for the items, allowing placement in any of the 9 boxes within the grid.

Answer №1

It can be a bit confusing to use this. Instead, try using e.target. Then, create event listeners for the parent elements and check if e.target is the correct element.

const draggableGrid = document.querySelector('.draggable-grid');
const droppableGrid = document.querySelector('.droppable-grid');

draggableGrid.addEventListener('dragstart', dragStart);

droppableGrid.addEventListener('dragover', dragOver);
droppableGrid.addEventListener('dragenter', dragEnter);
droppableGrid.addEventListener('dragleave', dragLeave);
droppableGrid.addEventListener('drop', drop);

let draggedItem = null;

function dragStart(e) {
  draggedItem = e.target;
  setTimeout(() => draggedItem.style.display = 'none', 0);
}

function dragOver(e) {
  e.preventDefault();
}

function dragEnter(e) {
  e.preventDefault();
  if (e.target.classList.contains('droppable-box')) {
    e.target.classList.add('hovered');
  }
}

function dragLeave(e) {
  e.target.classList.remove('hovered');
}

function drop(e) {
  if (e.target.classList.contains('droppable-box')) {
    e.target.classList.remove('hovered');
    e.target.append(draggedItem);
    draggedItem.style.display = 'block';
    draggedItem = null;
  }
}
.grid-cont {
  display: grid; 
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}

.draggable-grid,
.droppable-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr); 
  grid-template-rows: repeat(3, 1fr); 
  gap: 10px;
}

.box {
  width: 100px;
  height: 100px;
  background-color: orange;
}

.droppable-box {
  border: 2px dashed #ccc;
  height: 100px;
}

.hovered {
  border-style: solid;
}
<div class="draggable-grid">
  <div class="box" draggable="true">1</div>
  <div class="box" draggable="true">2</div>
  <div class="box" draggable="true">3</div>
  <div class="box" draggable="true">4</div>
  <div class="box" draggable="true">5</div>
  <div class="box" draggable="true">6</div>
  <div class="box" draggable="true">7</div>
  <div class="box" draggable="true">8</div>
  <div class="box" draggable="true">9</div>
</div>

<div class="droppable-grid">
  <div class="droppable-box"></div>
  <div class="droppable-box"></div>
  <div class="droppable-box"></div>
  <div class="droppable-box"></div>
  <div class="droppable-box"></div>
  <div class="droppable-box"></div>
  <div class="droppable-box"></div>
  <div class="droppable-box"></div>
  <div class="droppable-box"></div>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Accessing the hidden input value of an HTML page in Android with DefaultHttpClient

I previously inquired about a similar issue, but did not provide enough information. So here is the question again, but this time with more detail. On a webpage with html, there exists: <input name="__RequestVerificationToken" type="hidden" value="the_ ...

What is the best way to transfer data from Material UI to Formik?

I'm facing an issue when trying to integrate a Material UI 'Select' component into my Formik form. It seems like I am unable to pass the selected values from the Material UI component to Formik's initialValues. const [selectedHours, se ...

"Learn the process of sending a post request using a combination of JQuery, Ajax

I am attempting to send a post request with the following code - var app = angular.module('myApp', []); app.controller('myCtrl', function ($scope) { $scope.data = {}; $scope.reqCalling = function () { ...

What could be causing the issue of loading text not appearing in Vue.js?

I have the following code snippet in my application: <div id="app"> <button v-if="!isPrepared && !isLoading" @click="startLoading()">Start Loading</button> <div v-if="isLoading">Lo ...

The combination of sass-loader and Webpack fails to produce CSS output

Need help with setting up sass-loader to compile SCSS into CSS and include it in an HTML file using express.js, alongside react-hot-loader. Check out my configuration file below: var webpack = require('webpack'); var ExtractTextPlugin = require ...

Quick fix for obtaining only one response

I'm facing a dilemma where I need to redirect the user to the dashboard page after they log in, but also send their JSON details to my client-side JavaScript. While I know that there can only be one res.send/end/json in a response and dynamic data can ...

Transforming JSON/XML into a hierarchical display

I've come across the following XML file: <Person attribute1="value1" attribute2="value2"> value3 <Address street="value4" city="value5">value6</Address> <Phone number="value7" type="value8">value9</Phone> </Pers ...

Activate the button when a checkbox is ticked or when using the "select all" checkbox

I'm facing an issue with a script that should enable a button when at least one checkbox is selected and a checkbox for selecting all checkboxes is used. The problem arises when I select the "select all" checkbox as it activates the button, but if I ...

Maintaining the active state in Bootstrap, even when manually entering a URL, is essential for smooth

Check out this fully functional plnkr example: http://plnkr.co/edit/p45udWaLov388ZB23DEA?p=preview This example includes a navigation with 2 links (routing to 2 ui-router states), and a jQuery method that ensures the active class remains on the active lin ...

reason behind text styling: thick 12 pixels height with line spacing of 25 pixels using "Arial" font

Question about CSS Size: Understanding font sizes in CSS {font: 14px/24px Arial, Helvetica, sans-serif} I've noticed some CSS code like this on the website .selector {font: bold 12px/25px "Arial";} I know that 'bold' refers to font w ...

Ensure the filelist resets each time the bootstrap-modal is hidden or closed

Context I am in the process of developing a form where users can input data and upload an image file. The information entered into the form, along with the file name, is stored in a MySQL database. To style the website, I am utilizing Bootstrap. When a u ...

Invoking numerous functions through the (click)= event

When it comes to removing a user from my site, I find myself having to execute multiple database queries to delete the user's ID across approximately 10 different tables. Currently, I am resorting to what I consider a messy workaround where I have mu ...

How to eliminate properties from a nested array using D3

I've been attempting to filter out specific attributes from an array using D3. The array consists of values from a CSV file. Everything went smoothly for a small CSV file when I did it like this: d3.csv("foods.csv", function(data) { data.forEach(fun ...

"Submitting an HTML form and displaying the response without redirecting to a

I created a basic portlet for Liferay that includes a form for inputting parameters to send to an external webservice. However, when I submit the form, I am redirected to the URL of the webservice. Is there a method to prevent this redirection and instead ...

Certain CSS styles do not function properly, requiring me to include them directly in the HTML code

After successfully creating a button in HTML and applying CSS to add border effects, I ran into an issue when trying to change the background color or text color. Despite adding styles directly to the HTML file, these specific changes did not take effect. ...

Best practice for managing asynchronous calls and returns in TypeScript

I’ve recently started working on an Ionic 4 project, delving into the realms of Javascript / Typescript for the first time. Understanding async / await / promise seems to be a bit challenging for me. Here’s the scenario: In one of the pages of my app ...

Encountering problems when attempting to effectively filter a list of products using data

<div id="prod"> <div class="content" data-brand="Andrew" data-price="1000" data-store="JCPenny">Andrew</div><br /> <div class="content" data-brand="Hill" d ...

Problem with vueJS List Transition not being triggered

Within my Vue JS App, I encountered a situation where I have a list of items that change order randomly when the user clicks a button. Despite successfully using Vue.set to dynamically reposition the list elements, I faced an issue with adding a transition ...

What is the best way to assign attributes to multiple HTML elements using an array?

Seeking assistance to hide various sections in my HTML file upon button click, with the exception of one specific section. Encountered an error message: Uncaught TypeError: arr[i].setAttribute is not a function Here's a snippet of my code: const hide ...

Display the Angular UI grid containing data from the textboxes once the information has been submitted

I recently started working on an angularjs application and I am facing some challenges in finding the solution. Any advice or suggestions would be greatly appreciated. My goal is to dynamically display an angular UI-grid based on the text selected in the ...