2020-10-20 00:14:33 +02:00
|
|
|
const todoField = document.getElementById("todoField");
|
|
|
|
const todoButton = document.getElementById("todoButton");
|
|
|
|
const todoSummary = document.getElementById("todoSummary");
|
|
|
|
const todoList = document.getElementById("todoList");
|
|
|
|
|
|
|
|
/**
|
|
|
|
* A task for the todolist
|
|
|
|
* @typedef {Object} Task
|
|
|
|
* @property {number} createdAt - Timestamp of the time that the task was created.
|
|
|
|
* @property {string} description - Description of the task.
|
|
|
|
* @property {boolean} isCompleted - Whether or not the task is completed.
|
|
|
|
*/
|
|
|
|
|
|
|
|
const tasks = [];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add task to both tasks and DOM
|
|
|
|
*/
|
|
|
|
addTask = () => {
|
|
|
|
tasks.push({
|
|
|
|
createdAt: Date.now(),
|
|
|
|
description: todoField.value,
|
2020-10-20 12:23:35 +02:00
|
|
|
isCompleted: false
|
2020-10-20 00:14:33 +02:00
|
|
|
});
|
|
|
|
|
|
|
|
const taskElement = createTaskElement(tasks[tasks.length - 1]);
|
|
|
|
todoList.prepend(taskElement);
|
|
|
|
|
|
|
|
todoField.value = '';
|
2020-10-20 12:23:35 +02:00
|
|
|
todoField.focus();
|
2020-10-20 00:14:33 +02:00
|
|
|
|
|
|
|
updateSummary();
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Generate HTML element for a task
|
|
|
|
* @param {Task} task - The task to be converted into an html element
|
|
|
|
* @return {HTMLLIElement} The <li> element
|
|
|
|
*/
|
|
|
|
createTaskElement = (task) => {
|
|
|
|
const listItem = document.createElement('li');
|
|
|
|
|
|
|
|
const checkbox = document.createElement('input');
|
|
|
|
checkbox.type = 'checkbox';
|
|
|
|
checkbox.name = tasks.length - 1
|
|
|
|
checkbox.addEventListener('change', updateCheckbox);
|
|
|
|
listItem.appendChild(checkbox);
|
|
|
|
|
|
|
|
const description = document.createElement('span');
|
|
|
|
description.innerText = task.description;
|
|
|
|
listItem.appendChild(description);
|
|
|
|
|
|
|
|
return listItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Function to react to change on a checkbox
|
|
|
|
* @param {Event} event - the event raised by the eventlistener
|
|
|
|
*/
|
|
|
|
updateCheckbox = (event) => {
|
|
|
|
const index = tasks.length - event.target.name - 1;
|
|
|
|
tasks[index].isCompleted = event.target.checked;
|
|
|
|
|
|
|
|
const descriptionSpanClasses = todoList
|
|
|
|
.children[index]
|
|
|
|
.getElementsByTagName('span')[0]
|
|
|
|
.classList
|
|
|
|
|
|
|
|
if (event.target.checked) descriptionSpanClasses.add('strikethrough');
|
|
|
|
else descriptionSpanClasses.remove('strikethrough');
|
|
|
|
|
|
|
|
updateSummary();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Update the summary span with new task values
|
|
|
|
*/
|
|
|
|
updateSummary = () => {
|
|
|
|
const tasksCompleted = tasks.filter(task => task.isCompleted).length;
|
|
|
|
todoSummary.innerText = `${tasksCompleted}/${tasks.length} completed.`;
|
|
|
|
}
|
|
|
|
|
2020-10-20 12:23:35 +02:00
|
|
|
/**
|
|
|
|
* Handle the global keypresses and react on certain ones.
|
|
|
|
*/
|
|
|
|
handleKeys = (event) => {
|
|
|
|
if (event.which === 13 && document.activeElement === todoField) addTask();
|
|
|
|
}
|
|
|
|
|
|
|
|
todoButton.addEventListener('click', addTask);
|
|
|
|
document.addEventListener('keyup', handleKeys);
|