Reputation:
Hi im trying to create a form builder im approaching this by making creating elements putting them is a list group then making them draggable. This works so far however when i drag in item and place it the it disappears from the elements section this makes sense but i would like it to find the id of the item that has been selected and then copy the element but with a different id.
This is my code so far JavaScript
function drag(ev) {
ev.dataTransfer.setData("text", ev.target.id);
console.log("Component Selected")
var elem = document.querySelector(ev.target.id);
var clone = elem.cloneNode(true);
clone.id = ('drag9');
elem.after(clone);
}
<div class="row">
<div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)">
<ul class="list-group">
<li draggable="true" ondragstart="drag(event)" id="drag1" class="list-group-item">
<label for="exampleFormControlInput1" class="form-label">Input</label>
<button type="button" class="fa-solid fa-pen-to-square fa-lg"></button>
<input type="email" class="form-control" id="ControlInput1" placeholder="">
</li>
</ul>
</div>
</div>
Upvotes: 0
Views: 94
Reputation: 23396
This type of dynamic page creation functionality has to be done without id
attributes, they are error prone and a nightmare to maintain.
Drag'n'Drop functionality consists of multiple events. You shouldn't do everything on dragstart
, dropping has its own event - drop
- during which you're supposed to append the element to the target element. And, never use inline listeners for elements. In this case it's usefull to delegate dragstart
event to the ul
container.
When you drag an element, it should be dropped only on an element, which is an allowed parent to the element to drop (the only allowed parents of li
element are menu
, ul
and ol
, it shouldn't be dropped on a div
).
As Drag'n'Drop API doesn't provide a property where you can store a live reference to the actually dragged element, it's best to store it in a variable when dragstart
event fires. This tackles the need of id
attributes and all unnecessary DOM traversing.
All this in mind, I've created a fully id
less example code of how to implement a simple drag'n'drop, you can develope it further for your needs.
const dragSrc = document.body.querySelector('.dragSrc'),
dropPad = document.body.querySelector('.dropTarget');
let draggedElement = null;
dragSrc.addEventListener('dragstart', e => {
draggedElement = e.target;
});
dropPad.addEventListener('dragover', e => {
e.preventDefault();
e.dataTransfer.dropEffect = 'copy';
});
dropPad.addEventListener('drop', e => {
e.preventDefault();
const clone = draggedElement.cloneNode(true);
e.target.appendChild(clone);
});
.dropTarget {
position: relative;
width: 400px;
height: 100px;
border: 1px solid #000;
}
<div class="row">
<ul class="list-group dragSrc">
<li draggable="true" class="list-group-item">
<label class="form-label">Email:
<input type="email" class="form-control" placeholder="">
</label>
<button type="button" class="fa-solid fa-pen-to-square fa-lg">Button</button>
</li>
</ul>
</div>
<ul class="list-group dropTarget"></ul>
Upvotes: 1