Within the HTMLDivElement.drop, the parent element now encapsulates the new child element

I've encountered a DOM exception that has me stuck. My issue involves div elements and a button - when the user clicks the button, a random div is selected and another div with a background-color class is appended to it. Essentially, clicking the button fills a random div container with a randomly colored div. The goal is for users to be able to drag this newly created and colored div to an empty one. However, this is where things get tricky. Below is my HTML markup:

<div class="row">
    <div class="empty border"></div>
    <div class="empty border"></div>
    <div class="empty border"></div>
    <div class="empty border"></div>
    <div class="empty border"></div>
    <div class="empty border"></div>
</div>

After the button click (which appends a new div), the structure changes to:

<div class="row">
    <div class="empty border"></div>
    <div class="empty border">
        <div class="filled" draggable="true" id="test" style="background-color: rgb(242, 202, 185);"></div>
    </div>
    <div class="empty border"></div>
    <div class="empty border"></div>
    <div class="empty border"></div>
    <div class="empty border"></div>
 </div>

The problem arises when attempting to drop the "filled" div into a dropzone (an empty div), resulting in an uncaught exception. Here's my JS code snippet:

const prepareForDrag =  () => {
let divElements = Array.from(document.getElementsByTagName('div'));
let emptyCubes = divElements.filter(cube =>    cube.classList.contains('empty'));
let filledCubes = divElements.filter(cube => cube.classList.contains('filled'));

emptyCubes.forEach(function (cube) {
    cube.addEventListener('dragover', dragOver);
    cube.addEventListener('drop', drop);
})

filledCubes.forEach(function (cube) {
    cube.addEventListener('dragstart', dragStart);
})

function dragStart (e) {
    emptyCubes.forEach(cube => cube.classList.add('dropzone-border'));
    e.dataTransfer.setData('text/plain', e.target.getAttribute('id'));
}

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


function drop (e) {
    let coloredCube = e.dataTransfer.getData('text/plain');
    e.target.appendChild(document.getElementById(coloredCube));
    emptyCubes.forEach(cube => cube.classList.remove('dropzone-border'));
}
}

When releasing the mouse button, both the parent div and the "filled" one seem to be appended which I'm struggling to resolve. Any help or constructive feedback would be greatly appreciated :)

Answer №1

My approach to the problem involves saving the currently dragged div in a variable called dragged. I then attach a drop event to the entire document, allowing me to use the dragged variable to remove it from its parent node and append it to the dropped element.

I suspect that the issue may stem from having multiple elements with the same id, causing confusion in the JavaScript code. Additionally, there could be a problem with the coloredCube variable returning an unexpected value in the drop function. To troubleshoot this, I recommend adding a console.log statement for the coloredCube variable. Furthermore, when running the getData method on the dataTransfer property, I am receiving an empty string which might be contributing to the error you are experiencing.

let dragged;

function appendDiv(e) {
    e.preventDefault();
    const emptyDivs = Array.from(document.getElementsByClassName('empty'));
    const newDiv = document.createElement('div');
    newDiv.classList = 'filled';
    newDiv.draggable = true;
    newDiv.style.backgroundColor="red";
    newDiv.style.height = "50px";
    newDiv.style.width = "50px";
    newDiv.addEventListener('dragstart', dragStart);
    newDiv.addEventListener('dragend', dragEnd);
    // Should add to a random empty div. I just picked one to add it.
    emptyDivs[1].appendChild(newDiv); 
}

function dragStart(e){
    dragged = e.target;
    e.target.style.opacity = .5;
    e.dataTransfer.setData('text/plain', null);
}

function dragEnd(e){
    e.target.style.opacity = "";
}

function handleDrop(e){
    e.preventDefault();
    dragged.parentNode.removeChild(dragged);
    e.target.appendChild(dragged);
}

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

document.addEventListener('drop', handleDrop);

Array.from(document.getElementsByClassName('empty')).forEach(emptyDiv => {
    emptyDiv.addEventListener('dragover', dragOver);
});


document.getElementById('btn-append').addEventListener('click', appendDiv);

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

When passing req.body to another file for processing, it is displaying as undefined in node.js

Currently tackling an issue with a project involving nodejs where the request body is showing up as undefined Fetching some data on the client side, but encountering difficulties Received an error pointing out that the property is either undefined or nul ...

How can I use jQuery to automatically redirect to a different HTML page after updating a dynamic label?

When I click on a button in first.html, a function is called to update labels in second.html. However, despite being able to see second.html, I am unable to see the updated values in the labels. Can someone please advise me on how to achieve this? functi ...

Tips for aligning div columns in HTML and CSS

My divs are displaying different heights based on content. I need a solution to make them all the same height without using bootstrap framework. Is there a way to achieve this with plain html/css, or perhaps with javascript/jquery/angularjs? Take a look ...

jQuery Menu shuts down with a .slideToggle load when clicked away from the menu

I have encountered similar questions regarding my menu open/close functionality, which is operated by slideToggle() instead of a class. I prefer not to modify my CSS to make it functional. The requirement is for the menu to close when the user clicks anyw ...

Click event to reset the variable

The code snippet in Javascript below is designed to execute the function doSomethingWithSelectedText, which verifies if any text is currently selected by utilizing the function getSelectedObj. The getSelectedObj function returns an object that contains in ...

Is it possible to validate input only during insertion in Objectionjs without validation during updates?

const BaseModel = require("./base_model.js"); class CustomerModel extends BaseModel { static get tableName() { return "customers"; } static get jsonSchema() { return { type: "object", required: ['na ...

Tips for showcasing five inputs in a single row on a webpage using a customized width in Bootstrap

I am struggling to align 5 inputs in a single row on a page with custom widths. For example, I want the amount input to be smaller than the offer input. I attempted to use columns and apply different classes for size, but the submit button ended up not bei ...

JavaScript forEach functionality is not compatible with Dynamics CRM 2016

I'm currently working on writing some JavaScript code for a ribbon button in Dynamics CRM 2016 that will extract phone numbers from a list of Leads displayed in the Active Leads window. However, I've encountered an error message when attempting ...

Recoil: Executing a function when an atom is modified

My goal is to store a user object in an atom and cache it in localStorage every time it changes to avoid having the user sign in repeatedly if the app crashes: localStorage.setItem('user', JSON.stringify(user)) Previously, with useContext, I ach ...

Structure of Divs with Bootstrap

Looking to create a layout with two divs side by side like the image below: Example However, when the screen width increases, the layout changes to this: Current Here is the code: Is there anyone skilled in this area who can guide me through it? Your a ...

Text area containing an unspecified value within a webpage featuring interactive forms

I'm struggling to understand why I can't access the field values on forms that are generated dynamically through AJAX and MySQL. The structure of the form template is as follows: <form class="dishform" id='" + d.dish_id + "FF' acti ...

"Issue with Material-ui Autocomplete where the defaultValue does not function properly

The defaultValue was set to "Chairs" but it doesn't seem to be working as expected. Here is the code snippet: import React, { useState } from "react"; import TextField from "@mui/material/TextField"; import Autocomplete from "@mui/material/Autocomple ...

Steps to Incorporate Whitespace in a Mailto Link for Generating a Hyperlink

I am currently using Outlook 2007 and I need to include a hyperlink to a website in the body section of an email link. The URL of the site contains spaces. When I try to use %20 to represent the whitespace, it does display as expected but there is an issu ...

Is there a way to remove data from the database if a specific insert statement is unsuccessful?

My website consists of 5 inputs and an html table. The goal is to check the checkboxes in the table by looping through it and fetching the data. Since the inputs and data in the table are interconnected, a failed insert statement can pose a problem. Curre ...

The selected text on the webpage is not showing up highlighted

Encountering an unusual issue that is challenging to comprehend and difficult to find a solution for using Google search. I have created a website with multiple web pages. Each page follows the same format: header with links at the top, content area in th ...

Tips for obtaining accurate response from axios

When utilizing axios, I receive my query response in the format of response.data.response.object. Is there a way to access the answer directly without going through response.data first? ...

Prevent the underlining of the :before content of a link from being affected by a rule applied to the link

I have a hyperlink that becomes underlined when hovered over. I want to add a > symbol before the link, but I don't want it to be underlined when the link is hovered. Here's the code I'm using: .box.blueb a { color: #0098aa; } .box.blueb ...

The phenomenon of an invisible Absolute or relative position leading to grid components overlapping in Next.js

I've been struggling with this issue for over 48 hours now. I've attempted to troubleshoot by commenting out everything except the affected components and even swapping entire components around, but the problem persists. Oddly enough, rearranging ...

JavaScript library for creating animated car movements on a map using JPG images

Looking for a way to animate a car's movement on a map? I have a map image in jpg format (not svg) and a sequence of (x,y) points ready to go! If you could recommend a JavaScript library that can help me easily create an HTML page with this animation ...

Exploring a collection of objects housed in a json document

Currently, I'm looking to retrieve a collection of objects using JavaScript from a JSON file that resides on my website. While I could easily embed the array of objects directly into my JavaScript code, I am interested in understanding how to work wit ...