diff --git a/css/style.css b/css/style.css new file mode 100644 index 000000000..b67fd0ac6 --- /dev/null +++ b/css/style.css @@ -0,0 +1,169 @@ +/* Basic Style */ +.page { + background-color: #f8f8f8; + color: #333; + font-family: Lato, sans-serif; +} + +.header { + width: 500px; + margin: 0 auto; + display: block; + text-align: right; +} + +.header__logo { + width: 100%; +} + +.header__link { + font-family: fantasy, cursive; +} + +.main { + display: block; + width: 500px; + margin: 0 auto 0; +} + +.task { + width: 56%; + display: inline-block; + flex-grow: 1; +} + +.task-row-wrapper { + display: flex; +} + +.task__list { + margin: 0; + padding: 0px; +} + +li, +.main__heading { + list-style: none; +} + +input, +button { + outline: none; +} + +button { + background: none; + border: 0px; + color: #888; + font-size: 15px; + width: 60px; + font-family: Lato, sans-serif; + cursor: pointer; +} + +button:hover { + color: #3a3a3a; +} +/* Heading */ +.main__heading, +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; +} + +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; +} + +input[type="text"]:focus { + color: #333; +} + +/* New Task */ +label[for="new-task"] { + display: block; + margin: 0 0 20px; +} + +#new-task { + width: 318px; +} + +/* Task list */ +.task__list-item { + overflow: hidden; + padding: 20px 0; + border-bottom: 1px solid #eee; + display: flex; + justify-content: space-between; + align-items: center; +} + +.task__list-item > * { + vertical-align: middle; +} + +.task__list-item > input[type="checkbox"] { + margin: 0 10px; +} + +.task__list-item > label { + padding-left: 10px; + box-sizing: border-box; + font-size: 18px; + width: 226px; +} + +.task__list-item > input[type="text"] { + width: 226px; +} + +.delete img { + height: 2em; + transform: rotateZ(45deg); + transition: transform 200ms ease-in; +} + +.delete img:hover { + transform: rotateZ(0); +} + +/* Completed */ +#completed-tasks label { + text-decoration: line-through; + color: #888; +} + +/* Edit Task */ +.task__list-item input[type="text"] { + display: none; +} + +.editMode input[type="text"] { + display: inline-block; + width: 224px; +} + +.editMode label { + display: none; +} + +@media screen and (max-width: 768px) { + .header__link { + text-align: center; + } +} diff --git a/eisenhower-matrix.jpg b/img/eisenhower-matrix.jpg similarity index 100% rename from eisenhower-matrix.jpg rename to img/eisenhower-matrix.jpg diff --git a/remove.svg b/img/remove.svg similarity index 96% rename from remove.svg rename to img/remove.svg index 4a527ef5a..da6eb3df4 100644 --- a/remove.svg +++ b/img/remove.svg @@ -1,46 +1,46 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/index copy.html b/index copy.html new file mode 100644 index 000000000..557fff19a --- /dev/null +++ b/index copy.html @@ -0,0 +1,63 @@ + + + + + + Todo App + + + + +
+ + + Want more details? + +
+
+

+ +

+ + +
+

+

Todo

+ +

Completed

+ +
+ + + \ No newline at end of file diff --git a/index.html b/index.html index ef4aa1f60..49b688847 100644 --- a/index.html +++ b/index.html @@ -1,19 +1,63 @@ - -Todo App - - - - -
Want more details?
-

-

Todo

-

Completed

-
- - + + + + + + Todo App + + + + +
+ + + Want more details? + +
+
+

+ + + + + +

+

Todo

+ +

Completed

+ +
+ + \ No newline at end of file diff --git a/app.js b/js/app copy.js similarity index 98% rename from app.js rename to js/app copy.js index ab737a600..e70738d0d 100644 --- a/app.js +++ b/js/app copy.js @@ -10,7 +10,7 @@ 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 incompleteTaskHolder=document.getElementById("incomplete-tasks");//ul of #incompleteTasks var completedTasksHolder=document.getElementById("completed-tasks");//completed-tasks diff --git a/js/app.js b/js/app.js new file mode 100644 index 000000000..0a794539f --- /dev/null +++ b/js/app.js @@ -0,0 +1,164 @@ +//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. + +const taskInput = document.querySelector("#new-task"); //Add a new task. +const addButton = document.querySelector(".main__button"); //first button +const incompleteTaskHolder = document.querySelector("#incomplete-tasks"); //ul of #incompleteTasks +const completedTasksHolder = document.querySelector("#completed-tasks"); //completed-tasks + +const createNewTaskElement = (taskString) => { + const listItem = document.createElement("li"); + listItem.className = "task__list-item"; + + listItem.innerHTML = ` + + + + + + `; + + return listItem; +}; + +const addTask = () => { + console.log("Add Task..."); + + // Check if taskInput is defined + if (!taskInput || !taskInput.value) return; + + // Create a new list item with the text from the #new-task + const listItem = createNewTaskElement(taskInput.value); + + // Append listItem to incompleteTaskHolder + incompleteTaskHolder.appendChild(listItem); + + // Bind events to the new task + bindTaskEvents(listItem, taskCompleted); + + // Clear the input field + taskInput.value = ""; +}; + +//Edit an existing task. + +const editTask = function () { + console.log("Edit Task..."); + console.log("Change 'edit' to 'save'"); + + const listItem = this.parentNode; + + const editInput = listItem.querySelector("input[type=text]"); + const label = listItem.querySelector("label"); + const editBtn = listItem.querySelector(".edit"); + + if (!editInput || !label || !editBtn) { + console.error("Missing required elements"); + return; + } + + const containsClass = listItem.classList.contains("editMode"); + + // If class of the parent is .editmode + if (containsClass) { + // Switch to .editmode + // Label becomes the input's value. + label.textContent = editInput.value; + editBtn.innerText = "Edit"; + } else { + editInput.value = label.textContent; + editBtn.innerText = "Save"; + } + + // Toggle .editmode on the parent. + listItem.classList.toggle("editMode"); +}; + +//Delete task. +const deleteTask = function () { + console.log("Delete Task..."); + + const listItem = this.parentNode; + + if (listItem && listItem.parentNode) { + // Remove the parent list item from the ul. + listItem.parentNode.removeChild(listItem); + } +}; + +//Mark task completed +const taskCompleted = function () { + console.log("Complete Task..."); + + //Append the task list item to the #completed-tasks + const listItem = this.parentNode; + completedTasksHolder.appendChild(listItem); + bindTaskEvents(listItem, taskIncomplete); +}; + +const taskIncomplete = function () { + console.log("Incomplete Task..."); + + const listItem = this.parentNode; + + if (listItem && listItem.parentNode) { + // Remove the "completed" class + listItem.classList.remove("completed"); + + // Append the task list item to the container for incomplete tasks + listItem.parentNode.appendChild(listItem); + + // Rebind events for the task (now in a new container) + bindTaskEvents(listItem, taskCompleted); + } +}; + +const ajaxRequest = () => { + console.log("AJAX Request"); +}; + +//The glue to hold it all together. + +//Set the click handler to the addTask function. +addButton.addEventListener("click", addTask); +addButton.addEventListener("click", ajaxRequest); + +const bindTaskEvents = (taskListItem, checkBoxEventHandler) => { + console.log("bind list item events"); + // Select ListItems children + const checkBox = taskListItem.querySelector("input[type=checkbox]"); + const editButton = taskListItem.querySelector("button.edit"); + const deleteButton = taskListItem.querySelector("button.delete"); + + // Bind editTask to edit button. + editButton.addEventListener("click", editTask); + // Bind deleteTask to delete button. + deleteButton.addEventListener("click", deleteTask); + // Bind taskCompleted to checkBoxEventHandler. + checkBox.addEventListener("change", checkBoxEventHandler); +}; + +//cycle over incompleteTaskHolder ul list items +//for each list item +for (let i = 0; i < incompleteTaskHolder.children.length; i++) { + //bind events to list items chldren(tasksCompleted) + bindTaskEvents(incompleteTaskHolder.children[i], taskCompleted); +} + +//cycle over completedTasksHolder ul list items +for (let i = 0; i < completedTasksHolder.children.length; i++) { + //bind events to list items chldren(tasksIncompleted) + bindTaskEvents(completedTasksHolder.children[i], taskIncomplete); +} + +// Issues with usability don't get seen until they are in front of a human tester. + +//prevent creation of empty tasks. + +//Change edit to save when you are in edit mode. diff --git a/style.css b/style.css deleted file mode 100644 index ab3622770..000000000 --- a/style.css +++ /dev/null @@ -1,148 +0,0 @@ -/* Basic Style */ -body { - background-color: #f8f8f8; - color: #333; - font-family: Lato, sans-serif; -} -.aaa { - width: 500px; - margin: 0 auto; - display: block; - text-align: right; -} -.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; -} -ul { - margin:0; - padding: 0px; -} -li, h3 { - list-style:none; -} -input,button{ - outline:none; -} -button { - background: none; - border: 0px; - color: #888; - font-size: 15px; - width: 60px; - font-family: Lato, sans-serif; - cursor: pointer; -} -button:hover { - color: #3a3A3a; -} -/* 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; -} -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; -} -input[type="text"]:focus { - color: #333; -} - -/* New Task */ -label[for='new-task'] { - display: block; - margin: 0 0 20px; -} -input#new-task { - width: 318px; -} - -/* Task list */ -li { - overflow: hidden; - padding: 20px 0; - border-bottom: 1px solid #eee; - - display: flex; - justify-content: space-between; - align-items: center; -} -li > * { - vertical-align: middle; -} - -li > input[type="checkbox"] { - margin: 0 10px; -} -li > label { - padding-left: 10px; - box-sizing: border-box; - font-size: 18px; - width: 226px; -} -li > input[type="text"] { - width: 226px -} -button.delete img { - height: 2em; - transform: rotateZ(45deg); - transition: transform 200ms ease-in; -} -button.delete img:hover { - transform: rotateZ(0); -} - -/* Completed */ -ul#completed-tasks label { - text-decoration: line-through - color: #888; -} - -/* Edit Task */ -ul li input[type=text] { - display:none -} - -ul li.editMode input[type=text] { - display:inline-block; - width:224px -} - -ul li.editMode label { - display:none; -} \ No newline at end of file