Skip to content

Commit f06df5b

Browse files
committed
CH 36: TASKLIST - START with files from previous ch
1 parent 6f50080 commit f06df5b

File tree

4 files changed

+358
-0
lines changed

4 files changed

+358
-0
lines changed

SEC_4/ch_36/_final/app.js

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
// Define UI Vars
2+
const form = document.querySelector('#task-form');
3+
const taskList = document.querySelector('.collection');
4+
const clearBtn = document.querySelector('.clear-tasks');
5+
const filter = document.querySelector('#filter');
6+
const taskInput = document.querySelector('#task');
7+
8+
// Load all event listeners
9+
loadEventListeners();
10+
11+
// Load all event listeners
12+
function loadEventListeners() {
13+
// DOM Load event
14+
document.addEventListener('DOMContentLoaded', getTasks);
15+
// Add task event
16+
form.addEventListener('submit', addTask);
17+
// Remove task event
18+
taskList.addEventListener('click', removeTask);
19+
// Clear task event
20+
clearBtn.addEventListener('click', clearTasks);
21+
// Filter tasks event
22+
filter.addEventListener('keyup', filterTasks);
23+
}
24+
25+
// Get Tasks from LS
26+
function getTasks() {
27+
let tasks;
28+
if(localStorage.getItem('tasks') === null){
29+
tasks = [];
30+
} else {
31+
tasks = JSON.parse(localStorage.getItem('tasks'));
32+
}
33+
34+
tasks.forEach(function(task){
35+
// Create li element
36+
const li = document.createElement('li');
37+
// Add class
38+
li.className = 'collection-item';
39+
// Create text node and append to li
40+
li.appendChild(document.createTextNode(task));
41+
// Create new link element
42+
const link = document.createElement('a');
43+
// Add class
44+
link.className = 'delete-item secondary-content';
45+
// Add icon html
46+
link.innerHTML = '<i class="fa fa-remove"></i>';
47+
// Append the link to li
48+
li.appendChild(link);
49+
50+
// Append li to ul
51+
taskList.appendChild(li);
52+
});
53+
}
54+
55+
// Add Task
56+
function addTask(e) {
57+
if(taskInput.value === '') {
58+
alert('Add a task');
59+
}
60+
61+
// Create li element
62+
const li = document.createElement('li');
63+
// Add class
64+
li.className = 'collection-item';
65+
// Create text node and append to li
66+
li.appendChild(document.createTextNode(taskInput.value));
67+
// Create new link element
68+
const link = document.createElement('a');
69+
// Add class
70+
link.className = 'delete-item secondary-content';
71+
// Add icon html
72+
link.innerHTML = '<i class="fa fa-remove"></i>';
73+
// Append the link to li
74+
li.appendChild(link);
75+
76+
// Append li to ul
77+
taskList.appendChild(li);
78+
79+
// Store in LS
80+
storeTaskInLocalStorage(taskInput.value);
81+
82+
// Clear input
83+
taskInput.value = '';
84+
85+
e.preventDefault();
86+
}
87+
88+
// Store Task
89+
function storeTaskInLocalStorage(task) {
90+
let tasks;
91+
if(localStorage.getItem('tasks') === null){
92+
tasks = [];
93+
} else {
94+
tasks = JSON.parse(localStorage.getItem('tasks'));
95+
}
96+
97+
tasks.push(task);
98+
99+
localStorage.setItem('tasks', JSON.stringify(tasks));
100+
}
101+
102+
// Remove Task
103+
function removeTask(e) {
104+
if(e.target.parentElement.classList.contains('delete-item')) {
105+
if(confirm('Are You Sure?')) {
106+
e.target.parentElement.parentElement.remove();
107+
108+
// Remove from LS
109+
removeTaskFromLocalStorage(e.target.parentElement.parentElement);
110+
}
111+
}
112+
}
113+
114+
// Remove from LS
115+
function removeTaskFromLocalStorage(taskItem) {
116+
let tasks;
117+
if(localStorage.getItem('tasks') === null){
118+
tasks = [];
119+
} else {
120+
tasks = JSON.parse(localStorage.getItem('tasks'));
121+
}
122+
123+
tasks.forEach(function(task, index){
124+
if(taskItem.textContent === task){
125+
tasks.splice(index, 1);
126+
}
127+
});
128+
129+
localStorage.setItem('tasks', JSON.stringify(tasks));
130+
}
131+
132+
// Clear Tasks
133+
function clearTasks() {
134+
// taskList.innerHTML = '';
135+
136+
// Faster
137+
while(taskList.firstChild) {
138+
taskList.removeChild(taskList.firstChild);
139+
}
140+
141+
// https://jsperf.com/innerhtml-vs-removechild
142+
143+
// Clear from LS
144+
clearTasksFromLocalStorage();
145+
}
146+
147+
// Clear Tasks from LS
148+
function clearTasksFromLocalStorage() {
149+
localStorage.clear();
150+
}
151+
152+
// Filter Tasks
153+
function filterTasks(e) {
154+
const text = e.target.value.toLowerCase();
155+
156+
document.querySelectorAll('.collection-item').forEach(function(task){
157+
const item = task.firstChild.textContent;
158+
if(item.toLowerCase().indexOf(text) != -1){
159+
task.style.display = 'block';
160+
} else {
161+
task.style.display = 'none';
162+
}
163+
});
164+
}

SEC_4/ch_36/_final/index.html

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
7+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/css/materialize.min.css">
8+
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
9+
<title>Task List</title>
10+
</head>
11+
<body>
12+
<div class="container">
13+
<div class="row">
14+
<div class="col s12">
15+
<div id="main" class="card">
16+
<div class="card-content">
17+
<span class="card-title">Task List</span>
18+
<div class="row">
19+
<form id="task-form">
20+
<div class="input-field col s12">
21+
<input type="text" name="task" id="task">
22+
<label for="task">New Task</label>
23+
</div>
24+
<input type="submit" value="Add Task" class="btn">
25+
</form>
26+
</div>
27+
</div>
28+
<div class="card-action">
29+
<h5 id="task-title">Tasks</h5>
30+
<div class="input-field col s12">
31+
<input type="text" name="filter" id="filter">
32+
<label for="filter">Filter Tasks</label>
33+
</div>
34+
<ul class="collection"></ul>
35+
<a href="#" class="clear-tasks btn black">Clear Tasks</a>
36+
</div>
37+
</div>
38+
</div>
39+
</div>
40+
</div>
41+
42+
<script
43+
src="https://code.jquery.com/jquery-3.2.1.js"
44+
integrity="sha256-DZAnKJ/6XZ9si04Hgrsxu/8s717jcIzLy3oi35EouyE="
45+
crossorigin="anonymous"></script>
46+
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.100.2/js/materialize.min.js"></script>
47+
<script src="app.js"></script>
48+
</body>
49+
</html>

SEC_4/ch_36/tasklist/app.js

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
// GOTCHA: Materialize needs jQuery as a dependency
2+
3+
// DEFINE UI VARS
4+
const form = document.querySelector('#task-form')
5+
const taskList = document.querySelector('.collection')
6+
const clearBtn = document.querySelector('.clear-tasks')
7+
const filter = document.querySelector('#filter')
8+
const taskInput = document.querySelector('#task')
9+
10+
// Load all event listeners
11+
loadEventListeners()
12+
13+
function loadEventListeners() {
14+
// Add task event
15+
form.addEventListener('submit', addTask)
16+
// Remove task event
17+
taskList.addEventListener('click', removeTask)
18+
// Clear task event
19+
clearBtn.addEventListener('click', clearTasks)
20+
// Filter tasks event (keyup)
21+
filter.addEventListener('keyup', filterTasks)
22+
}
23+
24+
// Add task
25+
function addTask(e) {
26+
if (taskInput.value === "") {
27+
alert('Add task')
28+
}
29+
30+
// Create li element
31+
const li = document.createElement('li')
32+
// Add Class
33+
li.className = 'collection-item'
34+
// Create text node and append to li (with the value of task input field)
35+
li.appendChild(document.createTextNode(taskInput.value))
36+
// Create new delete link element
37+
const link = document.createElement('a')
38+
// Add class
39+
link.className = 'delete-item secondary-content'
40+
// Add icon html
41+
link.innerHTML = '<i class="fa fa-remove"></i>'
42+
// Append link to li
43+
li.appendChild(link)
44+
45+
// Append li to ul
46+
taskList.appendChild(li)
47+
48+
// Clear input
49+
taskInput.value = ""
50+
51+
52+
e.preventDefault()
53+
}
54+
55+
// Remove Task
56+
function removeTask(e) {
57+
if (e.target.parentElement.classList.contains('delete-item')) {
58+
if (confirm('Are You Sure?')) {
59+
e.target.parentElement.parentElement.remove()
60+
}
61+
}
62+
63+
console.log(e.target)
64+
}
65+
66+
// Clear Tasks
67+
function clearTasks(e) {
68+
// taskList.innerHTML = '' // one way
69+
70+
// GOTCHA: Looping with a while is actually faster for some reason
71+
while(taskList.firstChild) {
72+
taskList.removeChild(taskList.firstChild)
73+
}
74+
}
75+
76+
// Filter Tasks
77+
function filterTasks(e){
78+
const text = e.target.value.toLowerCase()
79+
80+
document.querySelectorAll('.collection-item').forEach(function(task){
81+
const item = task.firstChild.textContent
82+
if (item.toLowerCase().indexOf(text) != -1 ) {
83+
task.style.display = 'block'
84+
} else {
85+
task.style.display = 'none'
86+
}
87+
})
88+
89+
console.log(text)
90+
}

SEC_4/ch_36/tasklist/index.html

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/css/materialize.min.css">
9+
<script src="https://kit.fontawesome.com/8423d2c5b0.js" crossorigin="anonymous"></script>
10+
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet"
11+
integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
12+
<title>Task List</title>
13+
</head>
14+
15+
<body>
16+
<div class="container">
17+
<div class="row">
18+
<div class="col s12">
19+
<div id="main" class="card">
20+
<div class="card-content">
21+
<span class="card-title cyan-text lighten-2"
22+
style="font-weight: bold;font-family: Roboto,'Arial Rounded MT', arial, sans-serif;text-transform: uppercase;">Tasklist</span>
23+
<div class="row">
24+
<form id="task-form">
25+
<div class="input-field col s12">
26+
<input type="text" name="task" id="task">
27+
<label for="task">New Task</label>
28+
</div>
29+
30+
<input type="submit" value="Add Task" class="btn">
31+
</form>
32+
</div>
33+
</div>
34+
<div class="card-action">
35+
<h5 id="task-title">Tasks</h5>
36+
<div class="input-field col s12">
37+
<input type="text" name="filter" id="filter">
38+
<label for="filter">Filter Tasks</label>
39+
</div>
40+
<ul class="collection"></ul>
41+
<a href="#" class="clear-tasks btn black">Clear Tasks</a>
42+
</div>
43+
</div>
44+
</div>
45+
</div>
46+
</div>
47+
48+
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk="
49+
crossorigin="anonymous"></script>
50+
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/1.0.0/js/materialize.min.js"></script>
51+
<script src="app.js"></script>
52+
53+
</body>
54+
55+
</html>

0 commit comments

Comments
 (0)