Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean code s1e1 #51

Open
wants to merge 24 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
8d47178
refactor: Refactor HTML and update CSS code for Todo App
Sushkov-Maxim Jan 6, 2024
5edaba4
refactor(basic-1.1): change indentation from 4 spaces to 2 spaces in …
Sushkov-Maxim Jan 9, 2024
9e38b32
refactor(basic-1.2): convert some CSS and HTML code to lowercase
Sushkov-Maxim Jan 9, 2024
fa1e403
refactor(basic-1.3): replace single quotes with double quotes
Sushkov-Maxim Jan 9, 2024
e1a4ed9
refactor(basic-2.1): move each block element to a new line and add in…
Sushkov-Maxim Jan 9, 2024
38c3ade
fix(basic-2.2): add HTML5 first tag
Sushkov-Maxim Jan 9, 2024
609a694
refactor(basic-2.3): change the mnemonic symbol to a question mark
Sushkov-Maxim Jan 9, 2024
f443ddc
fix(basic-2.4): remove type attribute when connecting styles and script
Sushkov-Maxim Jan 9, 2024
cf2ee1c
refactor(extended-1.1): change some elements on semantic elements
Sushkov-Maxim Jan 9, 2024
aab4003
fix(extended-1.2): add attribute alt for images
Sushkov-Maxim Jan 9, 2024
4f522a5
refactor(extended-2.1, basic-3.1, 3.2, 3.3, 3.4): rewrite classes by …
Sushkov-Maxim Jan 9, 2024
583c00a
refactor: add line break between CSS blocks
Sushkov-Maxim Jan 9, 2024
32d5fba
refactor(basic-3.5): add indentation for block content
Sushkov-Maxim Jan 9, 2024
c4158e1
refactor(basic-3.6): add spaces after colon in properties
Sushkov-Maxim Jan 9, 2024
3b478e9
refactor(basic-3.7): add semicolon after properties
Sushkov-Maxim Jan 9, 2024
e8c27c8
refactor(basic-3.7): add semicolon after properties
Sushkov-Maxim Jan 9, 2024
af6bad9
refactor(basic-3.8): separate selectors and properties with line breaks
Sushkov-Maxim Jan 9, 2024
efe27f4
refactor(extended-2.1, basic-3.1, 3.2, 3.3, 3.4): rewrite classes by …
Sushkov-Maxim Jan 9, 2024
ccb2c5d
refactor(extended-2.1, basic-3.1, 3.2, 3.3, 3.4): rewrite classes by …
Sushkov-Maxim Jan 9, 2024
5f744e2
refactor: change placement of some CSS blocks for better readability
Sushkov-Maxim Jan 9, 2024
912e1ea
refactor: rewrite some functions to correspond ES5
Sushkov-Maxim Jan 9, 2024
4c765db
fix: add reqiared meta tags and attributes
Sushkov-Maxim Jan 9, 2024
1d9f9dc
fix: add h1 visually hidden heading
Sushkov-Maxim Jan 9, 2024
657d69c
refactor(extended-1.1): change h3 heading on h2 heading to correspond…
Sushkov-Maxim Jan 9, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
244 changes: 87 additions & 157 deletions app.js
Original file line number Diff line number Diff line change
@@ -1,195 +1,125 @@
//Document is the DOM can be accessed in the console with document.window.
// Tree is from the top, html, body, p etc.
//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

const newTaskInput = document.querySelector(".task__input_new"); //Add a new task input
const addButton = document.querySelector(".task__button_add");//Button 'Add'
const todoList = document.querySelector(".task-list_todo");//list todo-tasks
const completedTasksList = document.querySelector(".task-list_completed");//list completed-tasks

function createNewElementWithClass(el, elClasses) {
const element = document.createElement(el);
element.className = elClasses;
return element;
}

//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;
const createNewTaskElement = function(taskString) {

const listItem = createNewElementWithClass("li", "task");//task

const checkBox = createNewElementWithClass("input", "task__checkbox");//checkbox
checkBox.type="checkbox";
const label = createNewElementWithClass("label", "task__label");//label
label.innerText = taskString;
const editInput = createNewElementWithClass("input", "task__input");//input
editInput.type="text";
const editButton = createNewElementWithClass("button", "task__button task__button_edit");//edit button
editButton.innerText="Edit";
const deleteButton = createNewElementWithClass("button", "task__button task__button_delete");//delete button
deleteButton.innerHTML = '<img class="task__delete-img" src="./remove.svg" alt="delete Icon">';

listItem.append(checkBox, label, editInput, editButton,deleteButton);
return listItem;
}

const addTask = function() {
console.log("Add Task...");

//create and append listItem to todoList with the text from the .task-new
if (newTaskInput.value) {
const listItem = createNewTaskElement(newTaskInput.value);
todoList.appendChild(listItem);
bindTaskEvents(listItem);

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="";

newTaskInput.value="";
}
}

//Edit an existing task.

var editTask=function(){
console.log("Edit Task...");
console.log("Change 'edit' to 'save'");


var listItem=this.parentNode;

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");
const editTask = function() {
console.log("Edit Task...");
console.log("Change 'edit' to 'save'");

const listItem = this.parentNode;
const editInput = listItem.querySelector('.task__input');
const label = listItem.querySelector(".task__label");
const editBtn = listItem.querySelector(".task__button_edit");
const containsClass = listItem.classList.contains("task_edit-mode");

//change label and button depending on task_edit-mode
if (containsClass) {
label.innerText = editInput.value;
editBtn.innerText = "Edit";
} else {
editInput.value = label.innerText;
editBtn.innerText = "Save";
}

//toggle .task_edit-mode on the parent.
listItem.classList.toggle("task_edit-mode");
};


//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);
const deleteTask = function() {
console.log("Delete Task...");

const listItem = this.parentNode;
const list = listItem.parentNode;
list.removeChild(listItem);
}


//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 toggleCompleteTask(checkbox) {
const listItem = checkbox.parentNode;
if (checkbox.checked) {
completedTasksList.appendChild(listItem);
} else {
todoList.appendChild(listItem);
}
}


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);
}



var ajaxRequest=function(){
console.log("AJAX Request");
}

//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);

addButton.addEventListener("click", addTask);

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");
const bindTaskEvents = function(taskListItem) {
console.log("bind list item events");

//select ListItems children and bind listeners to them
const checkBox = taskListItem.querySelector(".task__checkbox");
const editButton = taskListItem.querySelector(".task__button_edit");
const deleteButton = taskListItem.querySelector(".task__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;
editButton.addEventListener("click", editTask);
deleteButton.addEventListener("click", deleteTask);
checkBox.addEventListener("change", () => toggleCompleteTask(checkBox));
}

//cycle over incompleteTaskHolder ul list items
//for each list item
for (var i=0; i<incompleteTaskHolder.children.length;i++){

//bind events to list items chldren(tasksCompleted)
bindTaskEvents(incompleteTaskHolder.children[i],taskCompleted);
//bind eventlistener for all interactive elements in every task of todo-tasks list
for (let i = 0; i < todoList.children.length; i += 1) {
bindTaskEvents(todoList.children[i]);
}




//cycle over completedTasksHolder ul list items
for (var i=0; i<completedTasksHolder.children.length;i++){
//bind events to list items chldren(tasksIncompleted)
bindTaskEvents(completedTasksHolder.children[i],taskIncomplete);
//bind eventlistener for all interactive elements in every task of completed-tasks list
for (let i = 0; i < completedTasksList.children.length; i += 1) {
bindTaskEvents(completedTasksList.children[i]);
}




// Issues with usability don't get seen until they are in front of a human tester.

//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.
79 changes: 62 additions & 17 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,64 @@
<html>
<HEAD><title>Todo App</title>
<link href='https://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="style.css" type="text/css" MEDIA="screen" charset="utf-8">
</HEAD>
<body>
<div class="aaa"><img src="./eisenhower-matrix.jpg"><a class='more_inf' href="https://goal-life.com/page/method/matrix-eisenhower">Want more details&quest;</a></div>
<div class="centered-main-page-element"><p id='topSectionForAddingElementToList'><label for="new-task">Add Item</label><div class="task-row-wrapper"><input id='new-task'class="task" type="text"><button>Add</button></div>
</p><h3>Todo</h3>
<ul id='incompleteTasks'>
<li><input type='checkbox'><label class="task">Pay Bills</label><input type="text" class="task"><button class="edit">Edit</button><button class="delete"><img src="./remove.svg"></button></li>
<li class="editMode"><input type="checkbox"><label class="task">Go Shopping</label><input type="text" value="Go Shopping" class="task"><button class='edit'>Save</button><button class="delete"><img src="./remove.svg"></button></li>
</ul><h3>Completed</h3><ul id="completed-tasks"><li><input type="checkbox" checked><label class="task">See the Doctor</label><input type="text" class="task"><button class="edit">Edit</button><button class="delete"><img src="./remove.svg"></button>
</li>
</ul>
</div>
<script type="text/javascript" SRC="app.js"></script>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Todo App</title>
<link href="https://fonts.googleapis.com/css?family=Lato:300,400,700" rel="stylesheet">
<link rel="stylesheet" href="style.css">
</head>
<body class="page">
<header class="header">
<h1 class="visually-hidden">TODO app</h1>
<img class="header__img" src="./eisenhower-matrix.jpg" alt="Eisenhower matrix image">
<a class="header__link" href="https://goal-life.com/page/method/matrix-eisenhower">Want more details?</a>
</header>
<main class="main">
<section class="task-section task-section_new">
<h2 class="task-section__title task-section__title_new">Add Item</h2>
<div class="task task_new">
<input class="task__input task__input_new" type="text">
<button class="task__button task__button_add">Add</button>
</div>
</section>
<section class="task-section">
<h2 class="task-section__title">Todo</h2>
<ul class="task-list task-list_todo">
<li class="task">
<input class="task__checkbox" type="checkbox">
<label class="task__label">Pay Bills</label>
<input class="task__input" type="text" class="task">
<button class="task__button task__button_edit">Edit</button>
<button class="task__button task__button_delete">
<img class="task__delete-img" src="./remove.svg" alt="delete Icon">
</button>
</li>
<li class="task task_edit-mode">
<input class="task__checkbox" type="checkbox">
<label class="task__label">Go Shopping</label>
<input class="task__input" type="text" value="Go Shopping" class="task">
<button class="task__button task__button_edit">Save</button>
<button class="task__button task__button_delete">
<img class="task__delete-img" src="./remove.svg" alt="delete Icon">
</button>
</li>
</ul>
</section>
<section class="task-section">
<h2 class="task-section__title">Completed</h2>
<ul class="task-list task-list_completed">
<li class="task">
<input class="task__checkbox" type="checkbox" checked>
<label class="task__label">See the Doctor</label>
<input class="task__input" type="text" class="task">
<button class="task__button task__button_edit">Edit</button>
<button class="task__button task__button_delete">
<img class="task__delete-img" src="./remove.svg" alt="delete Icon">
</button>
</li>
</ul>
</section>
</main>
<script src="app.js"></script>
</body>
</html>
Loading