Home > database >  Elements that were returned from a function don't work with event listeners
Elements that were returned from a function don't work with event listeners

Time:11-18

There is a quest I've been trying to solve for quite a time. In my code, I have a "To-Do List". And there, I want to make the buttons ("doneButton", "deleteButton") workable with "addEventListener".

Somehow, the buttons don't work as expected. When I run this within the code console.log(todoItem.doneButton), it shows the correct button. But just the line below, where I try to "addEventListener" to the same very element, it doesn't work at all.

(function() {
    function createAppTitle(title) {
        let appTitle = document.createElement('h2');
        appTitle.textContent = title;
        appTitle.classList.add('mt-5', 'mb-3');
        return appTitle;
    }

    function createToDoList() {
        let list = document.createElement('ul')
        return list;
    }

    function createToDoForm() {
        let buttonWrapper = document.createElement('div')
        let form = document.createElement('form')
        let input = document.createElement('input')
        let button = document.createElement('button')

        form.classList.add('input-group', 'mb-3');
        input.classList.add('form-control');
        input.placeholder = 'Enter the name of the task';
        buttonWrapper.classList.add('input-group-append');
        button.classList.add('btn', 'btn-primary');
        button.textContent = 'Add a task';

        buttonWrapper.append(button);
        form.append(input);
        form.append(buttonWrapper);

        return {
            form,
            input,
            button
        };
    }

    function createToDoItem (name) {
        let item = document.createElement('li')
        let buttonGroup = document.createElement('div')
        let doneButton = document.createElement('button')
        let deleteButton = document.createElement('button')

        item.classList.add('list-group-item', 'd-flex', 'justify-content-between', 'align-items-center');
        item.textContent = name;

        buttonGroup.classList.add('btn-group','btn-group-sm');
        doneButton.classList.add('btn','btn-success');
        doneButton.textContent = "Done";
        deleteButton.classList.add('btn','btn-danger');
        deleteButton.textContent = 'Delete';

        buttonGroup.append(doneButton);
        buttonGroup.append(deleteButton);
        item.append(buttonGroup);

        return {
            item,
            doneButton,
            deleteButton
        }
    }

    document.addEventListener('DOMContentLoaded', function () {
            let container = document.querySelector('.container');
            let appTitle = createAppTitle('Name of the Target');
            let list = createToDoList();
            let form = createToDoForm();
            let todoItems = [createToDoItem('Book your trip'), createToDoItem('Fly to Dubai'), createToDoItem('Book'  
                ' your trip')];
            container.append(appTitle);
            container.append(form.form);
            container.append(list);
            list.append(todoItems[0].item)
            list.append(todoItems[1].item)
            list.append(todoItems[2].item)

        form.form.addEventListener('submit', (e)=> {
            e.preventDefault();
            if (!form.input.value) {
                return;
            }

            let todoItem = createToDoItem(form.input.value);
            console.log(todoItem.doneButton)
            todoItem.doneButton.addEventListener('click', function () {
                console.log('done button clicked');
            });
            todoItem.deleteButton.addEventListener('click', ()=> {
                console.log('delete button clicked');
            })

            list.append(createToDoItem(form.input.value).item)
            form.input.value = '';
            });
        })
})();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ToDo</title>
    <link
        rel="stylesheet"
        href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
        integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
        crossorigin="anonymous">
    <script src="index.js" defer></script>
</head>
<body>
<div id="toDo" class="container"></div>
</body>
</html>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

CodePudding user response:

You should attach the event inside the createToDoItem()

(function() {
    function createAppTitle(title) {
        let appTitle = document.createElement('h2');
        appTitle.textContent = title;
        appTitle.classList.add('mt-5', 'mb-3');
        return appTitle;
    }

    function createToDoList() {
        let list = document.createElement('ul')
        return list;
    }

    function createToDoForm() {
        let buttonWrapper = document.createElement('div')
        let form = document.createElement('form')
        let input = document.createElement('input')
        let button = document.createElement('button')

        form.classList.add('input-group', 'mb-3');
        input.classList.add('form-control');
        input.placeholder = 'Enter the name of the task';
        buttonWrapper.classList.add('input-group-append');
        button.classList.add('btn', 'btn-primary');
        button.textContent = 'Add a task';

        buttonWrapper.append(button);
        form.append(input);
        form.append(buttonWrapper);

        return {
            form,
            input,
            button
        };
    }

    function createToDoItem (name) {
        let item = document.createElement('li')
        let buttonGroup = document.createElement('div')
        let doneButton = document.createElement('button')
        let deleteButton = document.createElement('button')

        item.classList.add('list-group-item', 'd-flex', 'justify-content-between', 'align-items-center');
        item.textContent = name;

        buttonGroup.classList.add('btn-group','btn-group-sm');
        doneButton.classList.add('btn','btn-success');
        doneButton.textContent = "Done";
        deleteButton.classList.add('btn','btn-danger');
        deleteButton.textContent = 'Delete';

        buttonGroup.append(doneButton);
        buttonGroup.append(deleteButton);
        item.append(buttonGroup);

        doneButton.addEventListener('click', function () {
            console.log('done button clicked');
        });
        deleteButton.addEventListener('click', ()=> {
            console.log('delete button clicked');
        })

        

        return {
            item,
            doneButton,
            deleteButton
        }
    }

    document.addEventListener('DOMContentLoaded', function () {
            let container = document.querySelector('.container');
            let appTitle = createAppTitle('Name of the Target');
            let list = createToDoList();
            let form = createToDoForm();
            let todoItems = [createToDoItem('Book your trip'), createToDoItem('Fly to Dubai'), createToDoItem('Book'  
                ' your trip')];
            container.append(appTitle);
            container.append(form.form);
            container.append(list);
            list.append(todoItems[0].item)
            list.append(todoItems[1].item)
            list.append(todoItems[2].item)

        form.form.addEventListener('submit', (e)=> {
            e.preventDefault();
            if (!form.input.value) {
                return;
            }

            let todoItem = createToDoItem(form.input.value);
            console.log(todoItem.doneButton)
            list.append(createToDoItem(form.input.value).item)
              form.input.value = '';
            });
        })
})();
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ToDo</title>
    <link
        rel="stylesheet"
        href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css"
        integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2"
        crossorigin="anonymous">
    <script src="index.js" defer></script>
</head>
<body>
<div id="toDo" class="container"></div>
</body>
</html>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>

  • Related