i am creating a to-do app tha uses drag and drop to reorder the elements in the list, the problem is that the function for swaping the elements works fine in the first 5 elements of the list, in the 6th element I get these errors when dragging the element itself and when dragging others to this element :
listItems[fromIndex] is undefined
listItems[toIndex] is undefined
I am not sure what is wrong and why it only happens in the last element as everything is created in the same way
Here it is the HTML:
<body>
<main>
<div >
<h1 >TODO</h1>
<div onclick="changeTheme()" ></div>
</div>
<div >
<div ></div>
<input type="text" value="" id="todo-input">
</div>
<div >
<ul id="draggable-list">
</ul>
<div id="footer-div"></div>
</div>
<p >Drag and drop to reorder list</p>
</main>
<script src="./index.js"></script>
</body>
And here the JS code:
const draggableElement = document.getElementById('draggable-list');
const TodoList = [
'Complete online Javascript course',
'Jog around the park 3x',
'10 minutes meditation',
'Read for 2hr',
'Pick up the groceries',
'Complete todo list',
];
//store items
const listItems =[];
let dragStartIndex;
createList();
//insert items into dom
function createList(){
[...TodoList]//copies array
.forEach((todo,index)=>{
const listItem = document.createElement('li');
// listItem.setAttribute('id','draggable');
listItem.setAttribute('data-index',index 1);
listItem.setAttribute('className','draggable');
listItem.innerHTML=`
<label for="showRatings${index 1}" >
<input type="checkbox" name="showRatings${index 1}" id="showRatings${index 1}">
</label>
<span >${index 1 "-"}</span>
<div draggable="true">
<p >${todo}</p>
</div>`;
listItems.push(listItem);
draggableElement.appendChild(listItem);
});
}
addEventListeners();
function dragStart() {
dragStartIndex = this.closest('li').getAttribute('data-index');
// console.log('index',dragStartIndex)
}
function dragEnter() {
this.classList.add('over');
}
function dragLeave() {
this.classList.remove('over');
}
function dragOver(e) {
e.preventDefault();
// console.log('over')
}
///////////////////////////////////////////////////////
function dragDrop() {
const dragEndIndex= this.getAttribute('data-index');
swapItems(dragStartIndex, dragEndIndex);
this.classList.remove('over');
}
function swapItems(fromIndex, toIndex) {
const itemOne = listItems[fromIndex].querySelector('.draggable');
const itemTwo = listItems[toIndex].querySelector('.draggable');
// console.log(itemOne,itemTwo);
// console.log(listItems[fromIndex])
listItems[fromIndex].appendChild(itemTwo);
listItems[toIndex].appendChild(itemOne);
}
function addEventListeners() {
const draggables = document.querySelectorAll('.draggable');
const dragListItems = document.querySelectorAll('.draggable-list li');
draggables.forEach(draggable =>{
draggable.addEventListener('dragstart',dragStart);
});
dragListItems.forEach(item =>{
item.addEventListener('dragover',dragOver);
item.addEventListener('drop',dragDrop);
item.addEventListener('dragenter',dragEnter);
item.addEventListener('dragleave',dragLeave);
});
}
Hope you can help me and thank you in advance
CodePudding user response:
You just change dragDrop function . All is ok, I think.
function dragDrop() {
const dragEndIndex= this.getAttribute('data-index');
swapItems(dragStartIndex-1, dragEndIndex-1);
this.classList.remove('over');
}
just change this line.
swapItems(dragStartIndex-1, dragEndIndex-1);
your index overflow.