├── tutorial ├── assets │ ├── jstodo.gif │ ├── addTasks.gif │ ├── eventTarget.gif │ └── insertAdjacentHTML.png ├── 1-start-here.html ├── 3-js-output.html ├── 4-todo-app.html └── 2-js-input.html ├── final ├── js │ └── scripts.js ├── index.html └── css │ └── styles.css ├── LICENSE └── README.md /tutorial/assets/jstodo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdbootstrap/JS-tutorial-To-Do-List-App-for-beginners/HEAD/tutorial/assets/jstodo.gif -------------------------------------------------------------------------------- /tutorial/assets/addTasks.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdbootstrap/JS-tutorial-To-Do-List-App-for-beginners/HEAD/tutorial/assets/addTasks.gif -------------------------------------------------------------------------------- /tutorial/assets/eventTarget.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdbootstrap/JS-tutorial-To-Do-List-App-for-beginners/HEAD/tutorial/assets/eventTarget.gif -------------------------------------------------------------------------------- /tutorial/assets/insertAdjacentHTML.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mdbootstrap/JS-tutorial-To-Do-List-App-for-beginners/HEAD/tutorial/assets/insertAdjacentHTML.png -------------------------------------------------------------------------------- /final/js/scripts.js: -------------------------------------------------------------------------------- 1 | function addTask() { 2 | let task = document.getElementById('task').value; 3 | 4 | if (!task) 5 | return; 6 | 7 | const text = "
This tutorial will guide you thorough basics of JavaScript by building real TODO application.
6 | 7 |Download and install Visual Studio Code
16 | 17 |Download and install one of the following browser: 20 |
Download lesson files from here and unzip on your computer.
29 |You will see the following files
30 | 31 |
32 | tutorial/
33 | 1-start-here.html
34 | 2-js-input.html
35 | 3-js-output.html
36 | 4-todo-app.html
37 | final
38 | index.html
39 | css/
40 | styles.css
41 | js/
42 | scripts.js
43 |
44 |
45 |
46 | Navigate to tutorial folder and follow lesson files in given order: 50 |
Since we already know how to pass data from our visitors to our JS functions, let's learn how we can use JS to modify data on our page.
10 | 11 | 12 |In the previous lesson we have learn how to get data from different HTML tags using innerHTML, now we will learn how to use the same function to set it.
16 | 17 |Add some div:
18 | 19 |
20 | <form onsubmit="addTask();return false" action="#">
<label for="task">Task:</label>
<input type="text" name="task" id="task">
<input type="submit" id="add" value="Add">
</form>
<div id="todos">List of todos...</div>
21 |
22 |
23 | And update our addTask function:
24 | 25 | 26 |
27 | function addTask() {
28 | var task = document.getElementById('task').value;
29 |
30 | document.getElementById('todos').innerText = task;
31 | }
32 |
33 |
34 | As you can see we can assign value/parameter to different html tags using simple assignment.
35 | 36 |Similarly, we can also create and assign entire HTML structure:
39 | 40 |
41 | document.getElementById('todos').innerHTML = "<ol><li>" + task + "</li></ol>
42 |
43 |
44 |
45 | No!
48 | 49 |You probably noticed that currently we are replacing entire inner html of div. This means, that every time we add new task, the old one get erased.
50 | 51 |In order to append new HTML to existing one we will use another JS function - insertAdjacentHTML()
52 | 53 |The insertAdjacentHTML() method inserts a text as HTML, into a specified position.
54 | 55 |Legal position values are:
56 | 57 |
65 |
66 | Let's use unordered list (ul) inside our div:
67 | 68 |
69 | <div id="todos">
<ul id="list">
</ul>
</div>
70 |
71 |
72 | and add new tasks as a new line items (li):
73 | 74 |
75 | document.getElementById('list').insertAdjacentHTML('beforeend', "<li>" + task + "</li>")
76 |
77 |
78 |
79 |
80 | Now we know how to use JavaScript to manipulate content, but actually we can adjust almost any element of our webpage and it's properties.
83 | 84 |We can adjust classes by adding them:
85 | 86 |
87 | let element = document.getElementById("myDIV");
88 | element.classList.add("new-class");
89 |
90 |
91 | removing:
92 | 93 |
94 | var element = document.getElementById("myDIV");
95 | element.classList.remove("new-class");
96 |
97 |
98 | or toggle (add if not present or remove if present)
99 | 100 |
101 | var element = document.getElementById("myDIV");
102 | element.classList.toggle("new-class");
103 |
104 |
105 | As I said before - options are almost limitless. Using JS we can i.e. 108 |
Now when we know how to transfer data between HTML and JS and apply CSS on the fly, it's high time to build some real app!
121 | 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /tutorial/4-todo-app.html: -------------------------------------------------------------------------------- 1 | 7 |In order to create our app we will need to execute following steps: 13 | 14 |
In order to create our app we will: 27 | 28 |
Update index.html code:
36 | 37 |
38 | <div class="app">
<form onsubmit="return false" action="#">
<input type="text" name="task" id="task" placeholder="Add new task...">
<input type="submit" id="add" value="Add">
</form>
<div id="todos">
<ul id="list">
</ul>
</div>
</div>
39 |
40 |
41 |
42 | Now let's do some small cleanup in JS, instead of concatenating our new list item inside the function:
43 | 44 |
45 | document.getElementById('list').insertAdjacentHTML('beforeend', "<li class='task'>" + task + "</li>")
46 |
47 |
48 | let's make it more readable and split it in 2 steps:
49 | 50 |
51 | const text = "<li class='task'>" + task + "</li>"
document.getElementById('list').insertAdjacentHTML('beforeend', text)
52 |
53 |
54 | We want to make sure that we won't add tasks with empty name:
55 | 56 | 57 |
58 | if (!task)
59 | return;
60 |
61 |
62 | This condition, checks whether task, isn't an empty value. In case it is, it will return 0, therefore we are adding ! sign in front which revert logic: 63 | 64 |
Finally, once we add new item to the list, we want to clear our input area:
73 | 74 |
75 | document.getElementById('task').value = '';
76 |
77 |
78 | The final scripts.js code after cleanup:
79 | 80 |
81 | function addTask() {
let task = document.getElementById('task').value;
if (!task)
return;
const text = "<li class='task'>" + task + "</li>"
document.getElementById('list').insertAdjacentHTML('beforeend', text)
document.getElementById('task').value = '';
}
document.getElementById('add').addEventListener('click', addTask);
82 |
83 |
84 |
85 |
88 | html{
89 | height: 100%;
90 | background-image: linear-gradient(#20a9d3,#0d5c9c);
91 | background-repeat: no-repeat;
92 | font-family: sans-serif;
93 | color: #0f222d;
94 | background-size: auto;
95 | }
96 |
97 | .app{
98 | width: 400px;
99 | display: flex;
100 | justify-content: center;
101 | flex-direction: column;
102 | margin: auto;
103 | }
104 | h1{
105 | text-align: center;
106 | color: #fff;
107 | }
108 | form{
109 | background-color: #fff;
110 | padding: 15px;
111 | }
112 | input[type="text"]{
113 | width: 310px;
114 | height: 30px;
115 | outline: 0;
116 | border: none;
117 | font-size: 1.5em;
118 | background: #fff;
119 | color: #2f4f4f;
120 | }
121 | input[type="submit"]{
122 | font-size: 1.5em;
123 | color: #53BDFF;
124 | background-color: #fff;
125 | outline: 0;
126 | border: none;
127 | width: 50px;
128 |
129 | }
130 | .todos{
131 | background-color: #fff;
132 | margin-top: 20px;
133 | padding-top: 10px;
134 | padding-bottom: 10px;
135 | padding-right: 40px;
136 |
137 | }
138 | ul{
139 | list-style: none;
140 | }
141 | li{
142 | border-bottom: 1px solid #53BDFF;
143 | padding-bottom: 15px;
144 | padding-top: 15px;
145 | font-size: 1.3em;
146 | color: #ffffff;
147 | cursor: pointer;
148 | }
149 |
150 | .done {
151 | text-decoration: line-through;
152 | color: #104123;
153 | cursor: pointer;
154 | }
155 |
156 |
157 |
158 | Now we have to mark our tasks as done. In order to do that we will add or remove class done to the item when someone clicks on it.
161 | 162 |Add new listener:
163 | 164 |
165 | document.getElementById('list').addEventListener('click', function(event){
166 | const element = event.target;
167 | console.log(element);
168 | });
169 |
170 |
171 | Now we can check console to verify if we are catching correct element.
172 | 173 | 174 |As you can notice - we are passing a click event to our function, and assigning it's target (so element which was clicked) to constant variable called element
175 |
176 |
177 | Since we have our element assign, the last thing we have to do is to toggle done class:
178 | 179 | 180 |
181 | document.getElementById('list').addEventListener('click', function(event){
182 | const element = event.target;
183 | element.classList.toggle("done");
184 | });
185 |
186 |
187 | Voila! Our code is ready.
188 | 189 | 190 |There are few more enhancements which we could provide to our app like: 191 | 192 |
Try to write this functionality yourself and if you want to see final solution, don't miss next tutorial!
199 | -------------------------------------------------------------------------------- /tutorial/2-js-input.html: -------------------------------------------------------------------------------- 1 | 7 |In order to build website we use HTML, CSS and JS. As you already know: 10 | 11 |
Let's learn how can we make communication between HTML and JS happen in both directions.
19 | 20 |JavaScript has multiple options to get values from HTML.
24 | 25 |Let's create a paragraph with id
26 | 27 |Paragraph 1
28 |
29 | and try to access this using GetElementById function in JS:
30 | 31 |
32 | let p = document.getElementById('p1');
33 | console.log(p);
34 |
35 |
36 | When you check in console, you will note that we received entire tag. But what if we are interested only in what inside the paragraph?
37 | 38 |Instead of printing out p, we will print it's innerText
39 | 40 |console.log(p.innerText);
41 |
42 | In case of nested structure:
43 | 44 |
45 | <div id="d1">
<p id="p1">Paragraph 1</p>
</div>
46 |
47 |
48 | we can get not only text but entire internal HTML:
49 | 50 |
51 | let d = document.getElementById('d1');
52 | console.log(d.innerText);
53 | console.log(d.innerHTML);
54 |
55 |
56 | We can also get values of it's atributes:
57 | 58 |<div id="d1" class="a b c "></div>
59 |
60 | console.log(d.className);
61 |
62 | and many more like: 63 | 64 |
Using ID is convenient when our element's have them. However we have to remember that id must be unique (2 elements can't have same id). This means that we can use them only for elements on the website which are unique.
77 | 78 |Sometimes we have elements which don't have id, what to do then?
79 | 80 |We can access them by tag
81 | 82 |
83 | const x = document. getElementsByTagName("p");
84 | for (let e of x) { e.style.color = "green"; }
85 |
86 |
87 |
88 | Note! When you use tag selector, you will get access to all paragraphs on the page!
89 | 90 |Above code will get access to all paragraphs on the page, and change its' color to green.
91 | 92 |You can also access elements by class name:
93 | 94 |
95 | const x = document. getElementsByClassName("js");
96 |
97 |
98 |
99 | Now you know how to literally access any element on the page. However, users browsing your website are not allowed to change elements like paragraphs.
102 | 103 |In order let your visitors interact with your page, we will use inputs. Inputs are used to build forms.
104 | 105 |Let's imagine that we want to build a simple TODO app. We will start with basic input in the index.html file:
106 | 107 | <input type="text">
108 |
109 |
110 | Since it ain't self explenatory, let's add some label to it:
111 | 112 |
113 | <label for="task">Task:</label>
<input type="text" name="task" id="task">
<input type="submit" id="add" value="Add">
114 |
115 |
116 | As you noticed we added few things:
117 |Keep in mind that HTML allows you to build very advanced and powerfull forms containing on or more following elements 124 |
Check more examples of inputs and forms
138 | 139 |Now when our minimalists form is ready, we have do last thing. Read data from our input when user click submit button/
140 | 141 | 142 |As always in programming, there are multiple way to achieve same result.
145 | 146 |On of the easiest option is to use onClick event to our submit input:
149 | 150 |
151 | <input type="submit" id="add" value="Add" onclick="addTask()">
152 |
153 |
154 | which will addTask() function:
155 | 156 |
157 | function addTask() {
158 | let task = document.getElementById('task').value;
159 | console.log(task)
160 | }
161 |
162 |
163 |
164 | Imagine that instead of simple input, we have entire form to create. I.e. tax form where we have provide 20 or 40 different answers - or - even better (worse?), that we are about to create multi step wizard with multiple subforms. I.e. regitration, order, invoice details.
167 |In order to organize our inputs, HTML offers a tag which works like a wrapper to all our inputs and allows us to submit them all at once.<form></form>
Wrap our input with form:
170 | 171 |
172 | <form onsubmit="addTask();return false" action="#">
<label for="task">Task:</label>
<input type="text" name="task" id="task">
<input type="submit" id="add" value="Add">
</form>
173 |
174 |
175 | Note: We added return false to onsubmit="" in order to prevent website from reload. We will cover that in future lesson about forms.
176 | 177 |Note:Although you can use inputs outside form tag - code will be still valid, if your intention is to submit data in any way, you should be using a form.
178 | 179 |Why do we put
<input> elements inside of <form></form> elements? For the same reason we put <li> tags inside of <ul> and <ol> elements - it's where they belong. It's semantically correct, and helps to define the markup. Parsers, screen readers, and various software can better understand your markup when it is semantically correct - when the markup has meaning, not just structure.
180 |
181 |
182 | Instead of explicitly specify which function to call in on HTML side, JavaScript allows us to define listeners. Event listeners can react on different events i.e.: 185 | 186 |
Example
197 | 198 | 199 |
200 | document.getElementById('add').addEventListener('click', addTask);
201 |
202 |
203 | Remember to remove call to addTask() function from onsubmit, but keep in mind to leave return false
204 | 205 |
206 | <form onsubmit="return false" action="#">
207 |
208 |
209 |
210 |
211 | As you already noticed, addEventListener accepts 2 arguments (actually - 3, but we will skip third for the moment since it's optional) 212 |
Since we know how to pass data from HTML to JS, let's move to the next lesson and learn how to we can do it in opposite direction.
219 | 220 | 221 | 222 | 223 | --------------------------------------------------------------------------------