Search code examples
javascripthtmlcssfont-awesomeremovechild

How can a list tag(or any other HTML element) be removed using an icon inserted in innerHTML of the parent element by JavaScript?


To-do List

Here I am trying to delete a task which is a list element originally using the 'trash' icon from FontAwesome. I am trying to figure out how to add this icon when a new task(list element) is created. Besides this, i also want to delete a task when a user clicks on the icon positioned inside that particular list element. I am sharing a codepen link here - https://codepen.io/tsiruot/pen/yLOVyGg

   var list = document.getElementById('task-list');
var btnInput = document.getElementById('submit-btn');

btnInput.addEventListener('click', addlist);

var inputBox = document.getElementById('todo-task');

inputBox.addEventListener('keyup', function(e){
    var keyCode = e.keyCode;
    if(keyCode === 13)
    {
        addlist();
    }
})

function addlist(){
    var newElement = document.createElement('li');
    var inputValue = document.getElementById('todo-task').value;
    if(inputValue !== null && inputValue !==undefined && inputValue !=='')
    {
    newElement.appendChild(document.createTextNode(inputValue));
    list.appendChild(newElement);
    document.getElementById('todo-task').value = '';
    }
    else{
        alert('Please Add valid input value');
    }
}

function createNewNode(){
    var newElement = document.createElement('li');
    var inputValue = document.getElementById('todo-task').value;
    if(inputValue !== null && inputValue !==undefined && inputValue !=='')
    {
    newElement.appendChild(document.createTextNode(inputValue));
    return newElement;
    }
    else{
        alert('Please Add valid input value');
    }
}

var btnUpdate = document.getElementById('btn-update');

btnUpdate.addEventListener('click', function(){
    var firstElement = list.firstElementChild;
    var updatedNode = createNewNode();
    list.replaceChild(updatedNode, firstElement);
    document.getElementById('todo-task').value = '';
});

var btnRemove = document.getElementById('btn-remove');

btnRemove.addEventListener('click', function(){
    var firstElement = list.firstElementChild;
    list.removeChild(firstElement);
});

Solution

  • General stuff:

    • I suggest to use let and const instead of var as better practice: Differences let, const, var.
    • Always check for the number of elements in the list to make sure you will not try to delete or replace elements that do not exist, I added such controls in the code below.

    Now, let's come to your requests. After these brief explanation you'll find the working, tested code below:

    • To add the trash icon to every new element is sufficient to create an <i> element, add the correct class and append it to the new element that is being appended to the list.
    • To make the trash icon delete the element just add an event listener to it.

    I also added pieces of code so that new elements added to the list get a unique ID. I don't know if this may be useful to you, but if it's not you can just remove it.
    Now enough with the explanations, let's get to the code:

    const list = document.getElementById('task-list');
    const btnInput = document.getElementById('submit-btn');
    //Variable to keep track of all the elements ever created.
    let elementCounter = list.children.length;
    
    btnInput.addEventListener('click', addlist);
    
    const inputBox = document.getElementById('todo-task');
    
    inputBox.addEventListener('keyup', function(e) {
        const keyCode = e.keyCode;
        if(keyCode === 13)
        {
            addlist();
        }
    });
    
    function addlist()
    {
        const inputValue = document.getElementById('todo-task').value;
        if(inputValue !== null && inputValue !== undefined && inputValue !== '')
        {
            //Moved the creation of the new element here so that it's not created when not necessary.
            const newElement = document.createElement('li');
            //Element for the trash icon.
            const trashIcon = document.createElement('i');
            //Add class to the element.
            trashIcon.className = 'fas fa-trash';
            //Add even listener so that when the element is clicked newElement is removed.
            trashIcon.addEventListener('click', function() {
                list.removeChild(newElement);
            });
            //Add unique ID to the new element.
            newElement.id = 'item' + ++elementCounter;
            newElement.appendChild(document.createTextNode(inputValue));
            newElement.appendChild(trashIcon);
            list.appendChild(newElement);
            document.getElementById('todo-task').value = '';
        }
        else
        {
            alert('Please Add valid input value');
        }
    }
    
    function createNewNode()
    {
        const inputValue = document.getElementById('todo-task').value;
        if(inputValue !== null && inputValue !== undefined && inputValue !== '')
        {
            //Moved the creation of the new element here so that it's not created when not necessary.
            const newElement = document.createElement('li');
            //Element for the trash icon.
            const trashIcon = document.createElement('i');
            //Add class to the element.
            trashIcon.className = 'fas fa-trash';
            //Add even listener so that when the element is clicked newElement is removed.
            trashIcon.addEventListener('click', function() {
                list.removeChild(newElement);
            });
            //Add unique ID to the new element.
            newElement.id = 'item' + ++elementCounter;
            newElement.appendChild(document.createTextNode(inputValue));
            newElement.appendChild(trashIcon);
            return newElement;
        }
        else
        {
            alert('Please Add valid input value');
            //If the new element was not created, return false.
            return false;
        }
    }
    
    const btnUpdate = document.getElementById('btn-update');
    
    btnUpdate.addEventListener('click', function() {
        //Do the following code only if there's at least one element in the list.
        if(list.children.length > 0)
        {
            const firstElement = list.firstElementChild;
            const updatedNode = createNewNode();
            //Do the following code only if the new node was created.
            if(updatedNode != false)
            {
                list.replaceChild(updatedNode, firstElement);
                document.getElementById('todo-task').value = '';
            }
        }
        else
        {
            alert('List is empty');
        }
    });
    
    const btnRemove = document.getElementById('btn-remove');
    
    btnRemove.addEventListener('click', function() {
        //Do the following code only if there's at least one element in the list.
        if(list.children.length > 0)
        {
            const firstElement = list.firstElementChild;
            list.removeChild(firstElement);
        }
        else
        {
            alert('List is empty');
        }
    });
    

    Also in the HTML file I removed the already present elements in the list so that all the elements are dynamically created by the javascript code above and the event listeners are present and work properly.
    Hope this is what you were looking for, feel free to ask any question.