dimanche 13 février 2022

Toggle class on user-created elements [duplicate]

I have a to-do list which I want to be able to cross out tasks as they're completed, as well as delete them by clicking their corresponding "X" button.

I use a global variable (row) which is added to different elements' ID. This is how I differentiate them from other task entries.

This works fine when deleting a task, but not when the checkbox is checked/unchecked. I want to toggle the add-strikethrough CSS class whenever a task's checkbox is clicked.

When a checkbox is checked, there is an error in console stating :

Uncaught TypeError: Cannot read properties of null (reading 'classList') at strikeTask (script.js:80:7)

Haven't been able to find anything helpful regarding this error from Google.

Relevant HTML:

    <body>
        <h1>To-Do-List</h1>
        <form action="" onsubmit="createElements();return false" id="todo" autocomplete=off>
            <input type="text" maxlength="25" id="enter-task" placeholder="Enter a Task">
            <button type="button" id="submit-task" onClick="createElements()"><span>+</span></button>
        </form>

        <h4 class="hide" id="task-header">current tasks</h4>
            
        <form class="hide" id="container">
            <!--This is where the addTask elements go-->
        </form>
        
        
        <script src="script.js"></script>
    </body>

Relevant CSS:

.add-strikethrough{
    text-decoration: line-through;
    text-decoration-color: black;
}

Javascript:

var row = 0;

function createElements(){ 

    //create Checkbox
    var checkbox = document.createElement("input");
    checkbox.setAttribute("type", "checkbox");
    checkbox.setAttribute("id", "entryCheckbox");
    checkbox.setAttribute("value", "unchecked");
    checkbox.setAttribute("onClick", "strikeTask(" + row +");")

    //create label using value from input box
    var label = document.createElement("label");
    label.setAttribute("id", "entryLabel"+row);
    label = document.getElementById("enter-task").value;

    //create deleteTask img
    var deleteTask = document.createElement("img");
    deleteTask.src = "images/x.svg";
    deleteTask.setAttribute("id", "delete-task");
    deleteTask.setAttribute("onClick", "deleteRow(" + row +");")
    
    addTask(checkbox, label, deleteTask);
}

//This function appends the elements
function addTask(box, label, x){

    
    const tasks = document.getElementById("container");
    
    const newTask = document.createElement('div');
    newTask.classList.add('task-entries');

    const header = document.getElementById('task-header');

    //Makes sure input field is not empty
    if(label !== ""){

        //Show task container and header
        if(tasks.classList.contains("hide")){
            tasks.classList.replace('hide', 'task-container');
            header.classList.replace('hide', 'show-header')
        };
        //Append newTask to tasks container
        tasks.appendChild(newTask);
            newTask.setAttribute("id", "contentDiv"+row);
        newTask.appendChild(box);
        newTask.appendChild(document.createTextNode(label));
        newTask.appendChild(x);
            row++;
        
        //Resets input field after task is added
        document.getElementById("enter-task").value = null; 
    }
}



function deleteRow(ID){

    document.getElementById('contentDiv'+ID).remove();

    tasks = document.getElementById('container');
    header = document.getElementById('task-header');

    //Hide header and task container if no tasks exist
    if(tasks.children.length == 0){
        tasks.classList.replace('task-container', 'hide');
        header.classList.replace('show-header', 'hide');
    }
}

function strikeTask(ID){

    const x = document.getElementById('entryLabel'+ID);

    x.classList.toggle('add-strikethrough');
    
}

I appreciate any help!




Aucun commentaire:

Enregistrer un commentaire