0

I have a list of items that have two event listeners each, one for clicking on them and making them greyed out and one for the X button that deletes the item.

I have implemented drag and drop functionality using HTML5 api. After two items have switched positions the delete item event listener is removed while the grey event listener still works.

The delete item event listener

li.querySelector(".delete-todo-item").addEventListener("click", deletetodoEventListener)

function deletetodoEventListener(e) {
    e.stopPropagation();
    const toDo = this.parentElement;
    const itemID = toDo.getAttribute("data-id")
    todos = todos.filter(function (item) {
        return item.timeCreated != itemID;
    })
    addToLocalStorage(todos);
    toDo.remove()
    emptyTodoList()
}

The "grey item out" event listener

function toDoEventListener(e) {

    console.log("click listner ")
    const itemID = this.getAttribute("data-id")
    const itemImg = this.querySelector(".todo-image");
    if (this.classList.contains("completed")) {
        this.classList.remove("completed");
        itemImg.src = "media/circle.svg";
        todos.forEach(function (item) {
            if (item.timeCreated == itemID) {

                item.completed = false;
            }
        });
    } else {
        this.classList.add("completed");
        itemImg.src = "media/check.svg";
        todos.forEach(function (item) {
            if (item.timeCreated == itemID) {
                item.completed = "completed";
            }
        });
    }
    addToLocalStorage(todos);
}

The drag and drop functions


function handleDragStart(e) {
    this.style.opacity = '0.2';
    dragSrcEl = this;
    e.dataTransfer.effectAllowed = 'move';
    e.dataTransfer.setData('text/html', this.innerHTML);
    console.log(e.dataTransfer)
}

function handleDrop(e) {
    e.stopPropagation();
    e.preventDefault();
    const tempId = dragSrcEl.getAttribute("data-id");
    const tempClassList = dragSrcEl.classList.value
    dragSrcEl.className = this.classList.value;
    dragSrcEl.setAttribute("data-id", this.getAttribute("data-id"))
    this.className = tempClassList;
    this.setAttribute("data-id", tempId)
    if (dragSrcEl !== this) {
        dragSrcEl.innerHTML = this.innerHTML;
        this.innerHTML = e.dataTransfer.getData('text/html');
    }
    return false;
}

A todo item

<li class="todo-item" data-id="1634245326430" draggable="true">
  <div class="todo-item-container">
     <div class="img-container">
       <img class="todo-image" src="media/circle.svg" alt="">
     </div>
    <span class="todo-item-content">test</span>
  </div>
  <span class="delete-todo-item">×</span>
</li>

Full code here: https://github.com/xhuljanoduli/todo-app This is my first time posting, i always find a solution on my own but this time it is driving me crazy after countless hours of troubleshooting.

Any help will be much appreciated.

Xh Nox
  • 1
  • 1
  • It would be helpful to have a working [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example), but have you considered [event delegation](https://stackoverflow.com/questions/1687296/what-is-dom-event-delegation)? It would remove the hassle of individual listeners. – pilchard Oct 14 '21 at 22:29
  • @pilchard Thank you so much, this was exactly what i needed and didn't know it! I refactored my code to use event delegation and moved all the event listeners to the parent element container. Everything is so much simpler now and just works! It still baffles me why the initial solution didn't work althouth it's not the best practice. – Xh Nox Oct 15 '21 at 10:12
  • I'm glad it helped! – pilchard Oct 15 '21 at 10:43

0 Answers0