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