I am dropping some element and move to another list. How to move 2nd element to the second list and stored in the first list. How it work now.
Before moving the 2nd element to the second list.
After moving the 2nd element to the second list.
How it should work
The 2nd element is moved to the second list and stored in the first list.
const draggables = document.querySelectorAll('.draggable');
const containers = document.querySelectorAll('.container');
draggables.forEach(draggable => {
draggable.addEventListener('dragstart', () => {
draggable.classList.add('dragging');
})
draggable.addEventListener('dragend', () => {
draggable.classList.remove('dragging');
})
})
containers.forEach(container => {
container.addEventListener('dragover', e => {
e.preventDefault();
const afterElement = getDragAfterElement(container, e.clientY);
const draggable = document.querySelector('.dragging');
if (afterElement == null) {
container.appendChild(draggable);
} else {
container.insertBefore(draggable, afterElement);
}
})
})
function getDragAfterElement(container, y) {
const draggableElements = [...container.querySelectorAll('.draggable:not(.dragging)')]
return draggableElements.reduce((closest, child) => {
const box = child.getBoundingClientRect();
const offset = y - box.top - box.height / 2;
if (offset < 0 && offset > closest.offset) {
return { offset: offset, element: child }
} else {
return closest
}
}, { offset: Number.NEGATIVE_INFINITY }).element
}
body {
margin: 0;
}
.container {
background-color: #333;
padding: 1rem;
margin-top: 1rem;
}
.draggable {
padding: 1rem;
background-color: white;
border: 1px solid black;
cursor: move;
}
.draggable.dragging {
opacity: .5;
}
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
<title>Document</title>
</head>
<body>
<div >
<p draggable="true">1</p>
<p draggable="true">2</p>
</div>
<div >
<p draggable="true">3</p>
<p draggable="true">4</p>
</div>
</body>
</html>
CodePudding user response:
function drop(ev) {
ev.preventDefault();
var data=ev.dataTransfer.getData("text/html");
/* If you use DOM manipulation functions, their default behaviour it not to
copy but to alter and move elements. By appending a ".cloneNode(true)",
you will not move the original element, but create a copy. */
var nodeCopy = document.getElementById(data).cloneNode(true);
nodeCopy.id = "newId"; /* We cannot use the same ID */
var target = ev.target;
while( !target.classList.contains('container')){
target=target.parentElement;
}
target.appendChild(nodeCopy);
}
function drag(ev) {
/* Here is specified what should be dragged. */
/* This data will be dropped at the place where the mouse button is released */
/* Here, we want to drag the element itself, so we set it's ID. */
ev.target.id="one"
ev.dataTransfer.setData("text/html", ev.target.id);
}
function allowDrop(ev) {
/* The default handling is to not allow dropping elements. */
/* Here we allow it by preventing the default behaviour. */
ev.preventDefault();
}
body {
margin: 0;
}
.container {
background-color: #333;
padding: 1rem;
margin-top: 1rem;
}
.draggable {
padding: 1rem;
background-color: white;
border: 1px solid black;
cursor: move;
}
.draggable.dragging {
opacity: .5;
}
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="styles.css">
<script src="script.js" defer></script>
<title>Document</title>
</head>
<body>
<div onDrop="drop(event)" ondragover="allowDrop(event)">
<p draggable="true" ondragstart="drag(event)">1</p>
<p draggable="true" ondragstart="drag(event)">2</p>
</div>
<div onDrop="drop(event)" ondragover="allowDrop(event)">
<p draggable="true" ondragstart="drag(event)">3</p>
<p draggable="true" ondragstart="drag(event)">4</p>
</div>
</body>
</html>
I managed to put this togheter you can play with it and adjust the styles. I found this very helpful