├── Brave_Browser_2024-07-10_8.08.50_PM.png ├── CSS └── style.css ├── JS └── script.js ├── README.md ├── Task-Management.html └── check.png /Brave_Browser_2024-07-10_8.08.50_PM.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y3KHOA/TodoListWeb/0a05fd7f73434843ddd4284a1c16b78848658226/Brave_Browser_2024-07-10_8.08.50_PM.png -------------------------------------------------------------------------------- /CSS/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | padding: 0; 3 | margin: 0; 4 | box-sizing: border-box; 5 | } 6 | body { 7 | /* background-color: #0b87ff; */ 8 | } 9 | #logo { 10 | width: 20vw; /* Sử dụng đơn vị viewport width để logo co giãn theo chiều rộng của trang */ 11 | max-width: 300px; /* Đặt giới hạn kích thước tối đa cho logo */ 12 | min-width: 100px; /* Đặt giới hạn kích thước tối thiểu cho logo */ 13 | position: absolute; 14 | transform: translate(-50%, 0); 15 | top: 10px; 16 | left: 50%; 17 | } 18 | .container { 19 | width: 90%; 20 | max-width: 600px; 21 | position: absolute; 22 | transform: translate(-50%, -50%); 23 | top: 50%; 24 | left: 50%; 25 | } 26 | #new-task { 27 | position: relative; 28 | background-color: #ffffff; 29 | padding: 30px 20px; 30 | /* border-radius: 5px; */ 31 | box-shadow: 0 20px 30px rgba(1, 24, 48, 0.15); 32 | display: grid; 33 | grid-template-columns: 9fr 3fr; 34 | gap: 16px; 35 | } 36 | #new-task input { 37 | font-family: "Poppins", sans-serif; 38 | font-size: 16px; 39 | border: none; 40 | border-bottom: 2px solid #d1d3d4; 41 | padding: 13px 8px; 42 | color: #111111; 43 | font-weight: 500; 44 | } 45 | #new-task input:focus { 46 | outline: none; 47 | border-color: #0fff13; 48 | } 49 | #new-task button { 50 | font-family: "Poppins", sans-serif; 51 | font-weight: 500; 52 | font-size: 16px; 53 | background-color: #0fff13; 54 | color: #ffffff; 55 | outline: none; 56 | border: none; 57 | /* border-radius: 5px; */ 58 | cursor: pointer; 59 | } 60 | #tasks { 61 | background-color: #ffffff; 62 | position: relative; 63 | padding: 30px 20px; 64 | /* margin-top: 600px; */ 65 | width: 100%; 66 | box-shadow: 0 20px 30px rgba(1, 24, 48, 0.15); 67 | /* border-radius: 10px; */ 68 | } 69 | .task { 70 | background-color: #ffffff; 71 | padding: 5px 10px; 72 | margin-top: 10px; 73 | display: flex; 74 | align-items: center; 75 | border-bottom: 2px solid #d1d3d4; 76 | cursor: pointer; 77 | } 78 | .task span { 79 | font-family: "Poppins", sans-serif; 80 | font-size: 15px; 81 | font-weight: 400; 82 | } 83 | .task button { 84 | color: #ffffff; 85 | padding: 13px 0; 86 | width: 45px; 87 | /* border-radius: 5px; */ 88 | border: none; 89 | outline: none; 90 | cursor: pointer; 91 | } 92 | .delete { 93 | background-color: #0fff13; 94 | /* margin: auto; */ 95 | } 96 | .edit { 97 | background-color: #0fff13; 98 | margin-left: auto; 99 | margin-right: 10px; 100 | } 101 | .completed { 102 | text-decoration: line-through; 103 | } 104 | .edit, .delete { 105 | font-size: 14px; /* Giảm kích thước chữ */ 106 | padding: 10px 5px; /* Giảm padding */ 107 | width: auto; /* Đặt chiều rộng tự động */ 108 | min-width: 70px; /* Đặt chiều rộng tối thiểu */ 109 | } 110 | .checkbox { 111 | margin-right: 10px; 112 | } 113 | 114 | .completed span { 115 | text-decoration: line-through; 116 | } 117 | 118 | .completed .edit { 119 | visibility: hidden; 120 | } -------------------------------------------------------------------------------- /JS/script.js: -------------------------------------------------------------------------------- 1 | // Initial References 2 | const newTaskInput = document.querySelector("#new-task input"); 3 | const tasksDiv = document.querySelector("#tasks"); 4 | let deleteTasks, editTasks, tasks; 5 | let updateNote = ""; 6 | let count; 7 | 8 | // Window onload function 9 | window.onload = () => { 10 | updateNote = ""; 11 | count = Object.keys(localStorage).length; 12 | displayTasks(); 13 | }; 14 | 15 | // Function to display tasks 16 | const displayTasks = () => { 17 | if (Object.keys(localStorage).length > 0) { 18 | tasksDiv.style.display = "inline-block"; 19 | } else { 20 | tasksDiv.style.display = "none"; 21 | } 22 | 23 | // Clear tasks 24 | tasksDiv.innerHTML = ""; 25 | 26 | // Fetch all keys in local storage 27 | let tasks = Object.keys(localStorage); 28 | tasks = tasks.sort(); 29 | 30 | for (let key of tasks) { 31 | let classValue = ""; 32 | 33 | // Get all values 34 | let value = localStorage.getItem(key); 35 | let taskInnerDiv = document.createElement("div"); 36 | taskInnerDiv.classList.add("task"); 37 | taskInnerDiv.setAttribute("id", key); 38 | 39 | // Add checkbox to mark task as completed 40 | let checkbox = document.createElement("input"); 41 | checkbox.type = "checkbox"; 42 | checkbox.classList.add("checkbox"); 43 | checkbox.checked = JSON.parse(value); // Set checkbox based on value 44 | taskInnerDiv.appendChild(checkbox); 45 | 46 | taskInnerDiv.innerHTML += `${key.split("_")[1]}`; 47 | 48 | let editButton = document.createElement("button"); 49 | editButton.classList.add("edit"); 50 | // editButton.textContent = "Edit " 51 | editButton.innerHTML = ``; 52 | taskInnerDiv.appendChild(editButton); 53 | 54 | let deleteButton = document.createElement("button"); 55 | deleteButton.classList.add("delete"); 56 | // deleteButton.textContent = "Delete " 57 | deleteButton.innerHTML = ``; 58 | taskInnerDiv.appendChild(deleteButton); 59 | 60 | if (JSON.parse(value)) { 61 | taskInnerDiv.classList.add("completed"); 62 | } 63 | 64 | tasksDiv.appendChild(taskInnerDiv); 65 | } 66 | 67 | // Add event listeners to tasks 68 | tasks = document.querySelectorAll(".task"); 69 | tasks.forEach((element, index) => { 70 | element.querySelector(".checkbox").onclick = () => { 71 | if (element.classList.contains("completed")) { 72 | updateStorage(element.id.split("_")[0], element.innerText, false); 73 | } else { 74 | updateStorage(element.id.split("_")[0], element.innerText, true); 75 | } 76 | }; 77 | }); 78 | 79 | // Edit tasks 80 | editTasks = document.getElementsByClassName("edit"); 81 | Array.from(editTasks).forEach((element, index) => { 82 | element.addEventListener("click", (e) => { 83 | e.stopPropagation(); 84 | disableButtons(true); 85 | let parent = element.parentElement; 86 | newTaskInput.value = parent.querySelector("#taskname").innerText; 87 | updateNote = parent.id; 88 | parent.remove(); 89 | }); 90 | }); 91 | 92 | // Delete tasks 93 | deleteTasks = document.getElementsByClassName("delete"); 94 | Array.from(deleteTasks).forEach((element, index) => { 95 | element.addEventListener("click", (e) => { 96 | e.stopPropagation(); 97 | let parent = element.parentElement; 98 | removeTask(parent.id); 99 | parent.remove(); 100 | count -= 1; 101 | }); 102 | }); 103 | }; 104 | 105 | // Disable edit button 106 | const disableButtons = (bool) => { 107 | let editButtons = document.getElementsByClassName("edit"); 108 | Array.from(editButtons).forEach((element) => { 109 | element.disabled = bool; 110 | }); 111 | }; 112 | 113 | // Remove task from local storage 114 | const removeTask = (taskValue) => { 115 | localStorage.removeItem(taskValue); 116 | displayTasks(); 117 | }; 118 | 119 | // Add tasks to local storage 120 | const updateStorage = (index, taskValue, completed) => { 121 | localStorage.setItem(`${index}_${taskValue}`, completed); 122 | displayTasks(); 123 | }; 124 | 125 | // Function to add new task 126 | document.querySelector("#push").addEventListener("click", () => { 127 | disableButtons(false); 128 | if (newTaskInput.value.length == 0) { 129 | alert("Please Enter A Task"); 130 | } else { 131 | if (updateNote == "") { 132 | updateStorage(count, newTaskInput.value, false); 133 | } else { 134 | let existingCount = updateNote.split("_")[0]; 135 | removeTask(updateNote); 136 | updateStorage(existingCount, newTaskInput.value, false); 137 | updateNote = ""; 138 | } 139 | count += 1; 140 | newTaskInput.value = ""; 141 | } 142 | }); 143 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y3KHOA/TodoListWeb/0a05fd7f73434843ddd4284a1c16b78848658226/README.md -------------------------------------------------------------------------------- /Task-Management.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ToDo List 6 | 7 | 11 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 |
24 | 25 | 26 |
27 |
28 |
29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /check.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y3KHOA/TodoListWeb/0a05fd7f73434843ddd4284a1c16b78848658226/check.png --------------------------------------------------------------------------------