diff --git a/app.js b/app.js index ab737a6002..e07e141161 100644 --- a/app.js +++ b/app.js @@ -1,195 +1,167 @@ -//Document is the DOM can be accessed in the console with document.window. -// Tree is from the top, html, body, p etc. - -//Problem: User interaction does not provide the correct results. -//Solution: Add interactivity so the user can manage daily tasks. -//Break things down into smaller steps and take each step at a time. - - -// Event handling, user interaction is what starts the code execution. - -var taskInput=document.getElementById("new-task");//Add a new task. -var addButton=document.getElementsByTagName("button")[0];//first button -var incompleteTaskHolder=document.getElementById("incompleteTasks");//ul of #incompleteTasks -var completedTasksHolder=document.getElementById("completed-tasks");//completed-tasks - - -//New task list item -var createNewTaskElement=function(taskString){ - - var listItem=document.createElement("li"); - - //input (checkbox) - var checkBox=document.createElement("input");//checkbx - //label - var label=document.createElement("label");//label - //input (text) - var editInput=document.createElement("input");//text - //button.edit - var editButton=document.createElement("button");//edit button - - //button.delete - var deleteButton=document.createElement("button");//delete button - var deleteButtonImg=document.createElement("img");//delete button image - - label.innerText=taskString; - label.className='task'; - - //Each elements, needs appending - checkBox.type="checkbox"; - editInput.type="text"; - editInput.className="task"; - - editButton.innerText="Edit"; //innerText encodes special characters, HTML does not. - editButton.className="edit"; - - deleteButton.className="delete"; - deleteButtonImg.src='./remove.svg'; - deleteButton.appendChild(deleteButtonImg); - - - //and appending. - listItem.appendChild(checkBox); - listItem.appendChild(label); - listItem.appendChild(editInput); - listItem.appendChild(editButton); - listItem.appendChild(deleteButton); - return listItem; +// --------------------------- +// Get necessary DOM elements +// --------------------------- +const taskInput = document.getElementById("new-task"); +// In your HTML, the add button has class "todo-app__add-button" +const addButton = document.querySelector(".todo-app__add-button"); +// ID in the HTML: "incomplete-tasks" +const incompleteTaskHolder = document.getElementById("incomplete-tasks"); +// ID in the HTML: "completed-tasks" +const completedTasksHolder = document.getElementById("completed-tasks"); + +// ------------------------------------------------------- +// Function to create a new task list item (
  • element) +// ------------------------------------------------------- +function createNewTaskElement(taskText) { + // Create a new
  • element with the "todo-app__item" class + const listItem = document.createElement("li"); + listItem.className = "todo-app__item"; + + // Create a checkbox (type="checkbox") with "todo-app__checkbox" class + const checkBox = document.createElement("input"); + checkBox.type = "checkbox"; + checkBox.className = "todo-app__checkbox"; + + // Create a
  • + listItem.appendChild(checkBox); + listItem.appendChild(label); + listItem.appendChild(editInput); + listItem.appendChild(editButton); + listItem.appendChild(deleteButton); + + return listItem; } +// ----------------------------- +// Function to add a new task +// ----------------------------- +function addTask() { + // Prevent adding an empty string + if (!taskInput.value) return; + // Create the new
  • element + const listItem = createNewTaskElement(taskInput.value); -var addTask=function(){ - console.log("Add Task..."); - //Create a new list item with the text from the #new-task: - if (!taskInput.value) return; - var listItem=createNewTaskElement(taskInput.value); - - //Append listItem to incompleteTaskHolder - incompleteTaskHolder.appendChild(listItem); - bindTaskEvents(listItem, taskCompleted); - - taskInput.value=""; - -} - -//Edit an existing task. - -var editTask=function(){ - console.log("Edit Task..."); - console.log("Change 'edit' to 'save'"); - - - var listItem=this.parentNode; + // Append the new task to the "incomplete tasks" list + incompleteTaskHolder.appendChild(listItem); - var editInput=listItem.querySelector('input[type=text]'); - var label=listItem.querySelector("label"); - var editBtn=listItem.querySelector(".edit"); - var containsClass=listItem.classList.contains("editMode"); - //If class of the parent is .editmode - if(containsClass){ - - //switch to .editmode - //label becomes the inputs value. - label.innerText=editInput.value; - editBtn.innerText="Edit"; - }else{ - editInput.value=label.innerText; - editBtn.innerText="Save"; - } - - //toggle .editmode on the parent. - listItem.classList.toggle("editMode"); -}; - - -//Delete task. -var deleteTask=function(){ - console.log("Delete Task..."); - - var listItem=this.parentNode; - var ul=listItem.parentNode; - //Remove the parent list item from the ul. - ul.removeChild(listItem); + // Bind event handlers (e.g., edit, delete, checkbox) + bindTaskEvents(listItem, markTaskCompleted); + // Clear the input field + taskInput.value = ""; } - -//Mark task completed -var taskCompleted=function(){ - console.log("Complete Task..."); - - //Append the task list item to the #completed-tasks - var listItem=this.parentNode; - completedTasksHolder.appendChild(listItem); - bindTaskEvents(listItem, taskIncomplete); - +// ----------------------------- +// Function to edit a task +// ----------------------------- +function editTask() { + const listItem = this.parentNode; + const editInput = listItem.querySelector('input[type="text"]'); + const label = listItem.querySelector("label"); + const editBtn = this; + + // Check if
  • currently has the "todo-app__item--edit-mode" class + const isInEditMode = listItem.classList.contains("todo-app__item--edit-mode"); + + if (isInEditMode) { + // If already in edit mode, save the input value into the label + label.innerText = editInput.value; + editBtn.innerText = "Edit"; + } else { + // If not in edit mode, switch to edit mode and populate input with label text + editInput.value = label.innerText; + editBtn.innerText = "Save"; + } + + // Toggle the edit mode class + listItem.classList.toggle("todo-app__item--edit-mode"); } - -var taskIncomplete=function(){ - console.log("Incomplete Task..."); -//Mark task as incomplete. - //When the checkbox is unchecked - //Append the task list item to the #incompleteTasks. - var listItem=this.parentNode; - incompleteTaskHolder.appendChild(listItem); - bindTaskEvents(listItem,taskCompleted); +// ----------------------------- +// Function to delete a task +// ----------------------------- +function deleteTask() { + const listItem = this.parentNode; + const ul = listItem.parentNode; + ul.removeChild(listItem); } +// ------------------------------------------------------ +// Function to mark a task as completed (checkbox checked) +// ------------------------------------------------------ +function markTaskCompleted() { + const listItem = this.parentNode; + // Move the task
  • to the completed tasks list + completedTasksHolder.appendChild(listItem); - -var ajaxRequest=function(){ - console.log("AJAX Request"); + // Re-bind events to handle "markTaskIncomplete" when checkbox is unchecked + bindTaskEvents(listItem, markTaskIncomplete); } -//The glue to hold it all together. - - -//Set the click handler to the addTask function. -addButton.onclick=addTask; -addButton.addEventListener("click",addTask); -addButton.addEventListener("click",ajaxRequest); +// --------------------------------------------------------- +// Function to mark a task as incomplete (checkbox unchecked) +// --------------------------------------------------------- +function markTaskIncomplete() { + const listItem = this.parentNode; + // Move the task
  • back to the "Todo" list + incompleteTaskHolder.appendChild(listItem); - -var bindTaskEvents=function(taskListItem,checkBoxEventHandler){ - console.log("bind list item events"); -//select ListItems children - var checkBox=taskListItem.querySelector("input[type=checkbox]"); - var editButton=taskListItem.querySelector("button.edit"); - var deleteButton=taskListItem.querySelector("button.delete"); - - - //Bind editTask to edit button. - editButton.onclick=editTask; - //Bind deleteTask to delete button. - deleteButton.onclick=deleteTask; - //Bind taskCompleted to checkBoxEventHandler. - checkBox.onchange=checkBoxEventHandler; + // Re-bind events to handle "markTaskCompleted" when checkbox is checked + bindTaskEvents(listItem, markTaskCompleted); } -//cycle over incompleteTaskHolder ul list items -//for each list item -for (var i=0; i +// ------------------------------------------------- +function bindTaskEvents(taskListItem, checkBoxHandler) { + const checkBox = taskListItem.querySelector('input[type="checkbox"]'); + const editButton = taskListItem.querySelector(".todo-app__edit-button"); + const deleteButton = taskListItem.querySelector(".todo-app__delete-button"); + + editButton.onclick = editTask; + deleteButton.onclick = deleteTask; + checkBox.onchange = checkBoxHandler; } +// ----------------------------- +// Initial code execution +// ----------------------------- +// Add task when the "Add" button is clicked +addButton.addEventListener("click", addTask); - -//cycle over completedTasksHolder ul list items -for (var i=0; i -Todo App - - - - - -

    -

    Todo

    -
      -
    • -
    • -

    Completed

    • -
    • -
    -
    - - - \ No newline at end of file + + + + + Todo App + + + + +
    + Eisenhower matrix example + + Want more details? + +
    + +
    + +
    + +
    + + +
    +
    + + +
    +

    Todo

    +
      +
    • + + + + + +
    • +
    • + + + + + +
    • +
    +
    + + +
    +

    Completed

    +
      +
    • + + + + + +
    • +
    +
    +
    + + + + diff --git a/style.css b/style.css index ab36227705..41d7b0b984 100644 --- a/style.css +++ b/style.css @@ -1,148 +1,155 @@ -/* Basic Style */ +/* Global styles */ body { - background-color: #f8f8f8; - color: #333; - font-family: Lato, sans-serif; -} -.aaa { - width: 500px; - margin: 0 auto; - display: block; - text-align: right; + margin: 0; + padding: 0; + background-color: #f8f8f8; + color: #333; + font-family: Lato, sans-serif; } -.aaa img { - width: 100%; -} -.aaa .more_inf { - font-family: fantasy, cursive; -} - -@media (max-width:768px) { -.aaa { text-align: center; -} -} -.centered-main-page-element { - display: block; - width: 500px; - margin: 0 auto 0; -} -.task { - width: 56%; - display: inline-block; - flex-grow: 1 -} -.task-row-wrapper { - display: flex; + +/* Hat with matrix */ +.matrix-info { + max-width: 500px; + margin: 0 auto; + text-align: right; + padding: 1rem; } -ul { - margin:0; - padding: 0px; + +.matrix-info__image { + width: 100%; + height: auto; + display: block; } -li, h3 { - list-style:none; + +.matrix-info__link { + display: inline-block; + margin-top: 0.5rem; + font-family: fantasy, cursive; /* If desired, we leave */ + color: #333; + text-decoration: none; } -input,button{ - outline:none; + +.matrix-info__link:hover { + text-decoration: underline; } -button { - background: none; - border: 0px; - color: #888; - font-size: 15px; - width: 60px; - font-family: Lato, sans-serif; - cursor: pointer; + +/* Main Application */ +.todo-app { + max-width: 500px; + margin: 0 auto; + padding: 1rem; } -button:hover { - color: #3a3A3a; + +/* Block for adding a new task */ +.todo-app__new-task { + margin-bottom: 2rem; } -/* Heading */ -h3, -label[for='new-task'] { - color: #333; - font-weight: 700; - font-size: 15px; - border-bottom: 2px solid #333; - padding: 30px 0 10px; - margin: 0; - text-transform: uppercase; + +.todo-app__new-task-label { + display: block; + margin-bottom: 0.5rem; + font-weight: bold; + text-transform: uppercase; } -input[type="text"] { - margin: 0; - font-size: 18px; - line-height: 18px; - height: 21px; - padding: 0 9px; - border: 1px solid #dDd; - background: #FFF; - border-radius: 6px; - font-family: Lato, sans-serif; - color: #888; + +.todo-app__new-task-row { + display: flex; + align-items: center; + gap: 0.5rem; } -input[type="text"]:focus { - color: #333; + +/* Universal elements */ +.todo-app__input, +.todo-app__text-input { + width: 100%; + padding: 0.5rem; + border: 1px solid #ddd; + border-radius: 4px; + font-size: 1rem; + color: #888; + box-sizing: border-box; } -/* New Task */ -label[for='new-task'] { - display: block; - margin: 0 0 20px; +.todo-app__input:focus, +.todo-app__text-input:focus { + color: #333; + outline: 1px solid #333; } -input#new-task { - width: 318px; + +.todo-app__add-button, +.todo-app__edit-button, +.todo-app__delete-button { + background: none; + border: 0; + color: #888; + font-size: 1rem; + cursor: pointer; + padding: 0.5rem 1rem; } -/* Task list */ -li { - overflow: hidden; - padding: 20px 0; - border-bottom: 1px solid #eee; +.todo-app__add-button:hover, +.todo-app__edit-button:hover, +.todo-app__delete-button:hover { + color: #555; +} - display: flex; - justify-content: space-between; - align-items: center; +/* Section Headings */ +.todo-app__section { + margin-bottom: 2rem; } -li > * { - vertical-align: middle; + +.todo-app__title { + margin: 0 0 1rem; + font-weight: bold; + text-transform: uppercase; + border-bottom: 2px solid #333; + padding-bottom: 0.5rem; } -li > input[type="checkbox"] { - margin: 0 10px; +/* List of tasks */ +.todo-app__list { + list-style: none; + margin: 0; + padding: 0; } -li > label { - padding-left: 10px; - box-sizing: border-box; - font-size: 18px; - width: 226px; + +.todo-app__item { + display: flex; + align-items: center; + gap: 0.5rem; + padding: 1rem 0; + border-bottom: 1px solid #eee; } -li > input[type="text"] { - width: 226px + +.todo-app__label { + flex-grow: 1; + font-size: 1rem; } -button.delete img { - height: 2em; - transform: rotateZ(45deg); - transition: transform 200ms ease-in; + +.todo-app__checkbox { + margin-right: 0.5rem; } -button.delete img:hover { - transform: rotateZ(0); + +.todo-app__delete-button img { + width: 1.5rem; + height: 1.5rem; + transition: transform 0.2s ease-in; } -/* Completed */ -ul#completed-tasks label { - text-decoration: line-through - color: #888; +.todo-app__delete-button:hover img { + transform: rotate(45deg); } -/* Edit Task */ -ul li input[type=text] { - display:none +/* Modifiers */ +.todo-app__item--edit-mode .todo-app__label { + display: none; } -ul li.editMode input[type=text] { - display:inline-block; - width:224px +.todo-app__item--edit-mode .todo-app__text-input { + display: block; } -ul li.editMode label { - display:none; -} \ No newline at end of file +.todo-app__item--completed .todo-app__label { + text-decoration: line-through; + color: #888; +}