I'm trying to create a todo list then use drag and drop to arrange it as I want. I have a dummy data (list items) which I can arrange as I want. the problem I am having is any new todo I add to the list item can not be dragged or rearrange.
here is my code below
var form = document.getElementById('addForm');
var itemList = document.getElementById('items');
form.addEventListener('submit', addTodo);
itemList.addEventListener('click', removeItem)
function addTodo(e) {
e.preventDefault()
// get input value
var newTodo = document.getElementById('todo');
// create new li element
var li = document.createElement('li')
//add class draggable property
li.className = 'draggable';
li.draggable = true
// add textnode with input value
li.appendChild(document.createTextNode(newTodo.value))
// delete button
var delBtn = document.createElement('button')
delBtn.className = 'btn btn-danger btn-sm float-right del';
delBtn.appendChild(document.createTextNode('X'))
li.appendChild(delBtn)
itemList.appendChild(li)
newTodo.value = ""
}
function removeItem(e) {
if (e.target.classList.contains('del')) {
if (confirm('Are you sure?')) {
var li = e.target.parentElement
itemList.removeChild(li)
}
}
}
const draggables = document.querySelectorAll('.draggable')
draggables.forEach(draggable => {
draggable.addEventListener('dragstart', () => {
draggable.classList.add('dragging')
})
draggable.addEventListener('dragend', () => {
draggable.classList.remove('dragging')
})
})
itemList.addEventListener('dragover', (e) => {
e.preventDefault()
const draggable = document.querySelector('.dragging')
const afterElement = getDragAfterElement(draggable, e.clientY)
console.log(afterElement);
if (afterElement == null) {
itemList.appendChild(draggable)
} else {
itemList.insertBefore(draggable, afterElement)
}
})
function getDragAfterElement(draggables, y) {
const draggableElements = [...document.querySelectorAll('.draggable:not(.dragging)')]
console.log('Dragable', draggableElements);
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
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Todo task</title>
<!-- Font Awesome -->
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.2/css/all.css">
<!-- Google Fonts -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap">
<!-- Bootstrap core CSS -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet">
<!-- Material Design Bootstrap -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/css/mdb.min.css" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container mt-2">
<div class="row justify-content-center">
<div class="col-md-8">
<h1>Todo Task</h1>
<div class="card">
<div class="card-header bg-grey">
<h4>What Todo</h4>
</div>
<div class="card-body">
<form action="" id="addForm">
<div class="form-group mt-2 pl-5">
<label for="">Title of Task</label>
<input type="text" id="todo" placeholder="Enter todo..." class="form-control">
</div>
<button type="submit" id="submit" class="btn btn-primary btn-sm">Submit</button>
</form>
</div>
</div>
<div class="jumb mt-4">
<h2>Todo Lists</h2>
<ul class="list-group" id="items">
<li class="draggable" draggable="true">Item 1 <button class="btn btn-danger btn-sm float-right del">X</button></li>
<li class="draggable" draggable="true">Item 2 <button class="btn btn-danger btn-sm float-right del">X</button></li>
<li class="draggable" draggable="true">Item 3 <button class="btn btn-danger btn-sm float-right del">X</button></li>
</ul>
</div>
</div>
</div>
</div>
<!-- JQuery -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<!-- Bootstrap tooltips -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.4/umd/popper.min.js"></script>
<!-- Bootstrap core JavaScript -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.min.js"></script>
<!-- MDB core JavaScript -->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mdbootstrap/4.19.1/js/mdb.min.js"></script>
<script src="app.js"></script>
</body>
</html>