Add assignment 7
This commit is contained in:
parent
0983b959ab
commit
d6acf623c0
|
@ -0,0 +1,67 @@
|
||||||
|
body {
|
||||||
|
background-color: #272822;
|
||||||
|
color: #F8F8F8;
|
||||||
|
margin: 5% 20%;
|
||||||
|
}
|
||||||
|
|
||||||
|
#title {
|
||||||
|
text-align: center;
|
||||||
|
color: #A6E22E;
|
||||||
|
font-size: 4em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#todoField {
|
||||||
|
display: block;
|
||||||
|
padding: 1em;
|
||||||
|
margin: 0 auto;
|
||||||
|
color: #F8F8F8;
|
||||||
|
background-color: #494b41;
|
||||||
|
font-size: 2em;
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
#todoButton {
|
||||||
|
display: block;
|
||||||
|
padding: 1em;
|
||||||
|
margin: 1em auto;
|
||||||
|
color: black;
|
||||||
|
background-color: #FD971F;
|
||||||
|
font-size: 1.5em;
|
||||||
|
filter: drop-shadow(0.5em 0.5em 2px #191a16);
|
||||||
|
}
|
||||||
|
|
||||||
|
#todoSummary {
|
||||||
|
font-size: 3em;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#todoList {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=checkbox] {
|
||||||
|
width: 2em;
|
||||||
|
height: 2em;
|
||||||
|
margin-right: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#todoList>li>span {
|
||||||
|
font-size: 3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#todoList>li {
|
||||||
|
margin-bottom: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Monokai rainbow list :DDD */
|
||||||
|
#todoList>li:nth-child(7n+1) {color: #F92672;}
|
||||||
|
#todoList>li:nth-child(7n+2) {color: #FD971F;}
|
||||||
|
#todoList>li:nth-child(7n+3) {color: #E69F66;}
|
||||||
|
#todoList>li:nth-child(7n+4) {color: #E6DB74;}
|
||||||
|
#todoList>li:nth-child(7n+5) {color: #A6E22E;}
|
||||||
|
#todoList>li:nth-child(7n+6) {color: #66D9EF;}
|
||||||
|
#todoList>li:nth-child(7n) {color: #AE81FF;}
|
||||||
|
|
||||||
|
.strikethrough {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Todo</title>
|
||||||
|
<link rel="stylesheet" href="./todo.css">
|
||||||
|
<script src="./todo.js" defer></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1 id="title">Todo-list</h1>
|
||||||
|
<textarea id="todoField" cols="60" rows="2" autofocus ></textarea>
|
||||||
|
<button id="todoButton">Add task</button>
|
||||||
|
<div id="todoSummary"></div>
|
||||||
|
<ul id="todoList"></ul>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,83 @@
|
||||||
|
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,
|
||||||
|
completed: false
|
||||||
|
});
|
||||||
|
|
||||||
|
const taskElement = createTaskElement(tasks[tasks.length - 1]);
|
||||||
|
todoList.prepend(taskElement);
|
||||||
|
|
||||||
|
todoField.value = '';
|
||||||
|
|
||||||
|
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;
|
||||||
|
console.log(event);
|
||||||
|
|
||||||
|
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.`;
|
||||||
|
}
|
||||||
|
|
||||||
|
todoButton.addEventListener('click', addTask);
|
Loading…
Reference in New Issue