├── README.md ├── book-list ├── app-es6-local-storage.js ├── app-es6.js ├── app.js └── index.html ├── section-10 ├── Symbols │ ├── app.js │ └── index.html ├── destruct │ ├── app.js │ └── index.html ├── iterators-generators │ ├── app.js │ └── index.html ├── maps │ ├── app.js │ └── index.html ├── profile-scroller │ ├── app.js │ └── index.html └── sets │ ├── app.js │ └── index.html ├── section-11 ├── factory │ ├── app.js │ └── index.html ├── mediator │ ├── app.js │ └── index.html ├── module-and-revealing-module │ ├── app.js │ └── index.html ├── observer │ ├── app-es6.js │ ├── app.js │ └── index.html ├── singleton │ ├── app.js │ └── index.html └── state │ ├── app.js │ └── index.html ├── section-12 └── tracalorie-project │ ├── app.js │ └── index.html ├── section-13 └── microposts │ ├── .gitignore │ ├── README.md │ ├── api │ └── db.json │ ├── assets │ └── css │ │ └── style.css │ ├── index.html │ ├── package-lock.json │ ├── package.json │ ├── src │ ├── app.js │ ├── http.js │ ├── modules-example │ │ ├── app.js │ │ ├── mymodule1.js │ │ └── mymodule2.js │ └── ui.js │ └── webpack.config.js ├── section-2 ├── arrays-methods.js ├── block-scope-with-let-and-const.js ├── calculations.js ├── console.js ├── date.js ├── functions.js ├── general-loops.js ├── if-else.js ├── index.html ├── objects.js ├── string-functions.js ├── switch.js ├── template-literals.js ├── var-let-const.js ├── variable-type-conversion.js ├── variables-types.js └── window-object.js ├── section-3 ├── creating-elements.js ├── document-object.js ├── dom-multiple-selectors.js ├── dom-single-selectors.js ├── event-bubling-and-delegation.js ├── event-listeners.js ├── index.html ├── keyboard-input-events.js ├── local-and-session-storage.js ├── mouse-events.js ├── remove-and-replace-attributes.js └── traversing-the-dom.js ├── section-4 ├── loan-calculator │ ├── app.js │ ├── img │ │ └── loading.gif │ └── index.html ├── number-guesser │ ├── app.js │ └── index.html └── task-list │ ├── app.js │ └── index.html ├── section-5 ├── built-in-constructors.js ├── constructor-and-this-keyword.js ├── es6-class-inheritance.js ├── es6-class.js ├── index.html ├── object-create.js ├── prototype-inheritance.js └── prototype.js ├── section-7 ├── exercise-1 │ ├── app.js │ ├── data.txt │ └── index.html ├── exercise-10 │ ├── app.js │ ├── easyhttp2.js │ └── index.html ├── exercise-11 │ ├── app.js │ └── index.html ├── exercise-12 │ ├── app.js │ ├── easyhttp3.js │ └── index.html ├── exercise-2 │ ├── app.js │ ├── customer.json │ ├── customers.json │ └── index.html ├── exercise-3 │ ├── app.js │ └── index.html ├── exercise-4 │ ├── app.js │ └── index.html ├── exercise-5 │ ├── app.js │ ├── easyhttp.js │ └── index.html ├── exercise-6 │ ├── es6-promise.js │ └── index.html ├── exercise-7 │ ├── app.js │ ├── index.html │ ├── posts.json │ └── test.txt ├── exercise-8 │ ├── app.js │ └── index.html └── exercise-9 │ ├── app.js │ ├── index.html │ ├── posts.json │ └── test.txt ├── section-8 ├── githubfinder │ ├── app.js │ ├── github.js │ ├── index.html │ └── ui.js └── weatherjs │ ├── app.js │ ├── index.html │ ├── storage.js │ ├── ui.js │ └── weather.js └── section-9 ├── error-handling ├── app.js └── index.html ├── regular-expression ├── exercise-1 │ ├── app.js │ └── index.html └── exercise-2 │ ├── app.js │ └── index.html └── user-form ├── app.js └── index.html /README.md: -------------------------------------------------------------------------------- 1 | # [Course - Modern Javascript from Beginning](https://www.udemy.com/modern-javascript-from-the-beginning) 2 | 3 | This repository is a place where i store all the files used in this course and can assist as consultation for commands and patterns. 4 | 5 | The course explains how to code in javascript from with new concepts from ES6+, where all the examples are great and explain straight to the point, i really recomend this course for people that have a minimal knowledge in javascript and want to understand old and new javascript code and patterns. 6 | 7 | [Youtube from teacher](https://www.youtube.com/traversymedia) 8 | -------------------------------------------------------------------------------- /book-list/app-es6-local-storage.js: -------------------------------------------------------------------------------- 1 | class Book { 2 | constructor(title, author, isbn) { 3 | this.title = title; 4 | this.author = author; 5 | this.isbn = isbn; 6 | } 7 | } 8 | 9 | class UI { 10 | addBookToList(book) { 11 | const list = document.getElementById('book-list'); 12 | // Create tr element 13 | const row = document.createElement('tr'); 14 | // Insert cols 15 | row.innerHTML = ` 16 | ${book.title} 17 | ${book.author} 18 | ${book.isbn} 19 | X 20 | `; 21 | 22 | list.appendChild(row); 23 | } 24 | 25 | showAlert(message, className) { 26 | // Create div 27 | const div = document.createElement('div'); 28 | // Add classes 29 | div.className = `alert ${className}`; 30 | // Add text 31 | div.appendChild(document.createTextNode(message)); 32 | // Get parent 33 | const container = document.querySelector('.container'); 34 | const form = document.getElementById('book-form'); 35 | // Insert alert 36 | container.insertBefore(div, form); 37 | 38 | // Timeout after 3 sec 39 | setTimeout(function() { 40 | document.querySelector('.alert').remove(); 41 | }, 3000); 42 | } 43 | 44 | deleteBook(target) { 45 | if(target.className === 'delete') { 46 | target.parentElement.parentElement.remove(); 47 | } 48 | } 49 | 50 | clearFields() { 51 | document.getElementById('title').value = ''; 52 | document.getElementById('author').value = ''; 53 | document.getElementById('isbn').value = ''; 54 | } 55 | } 56 | 57 | // Local Storage Classe 58 | class Store { 59 | static getBooks() { 60 | let books; 61 | if(localStorage.getItem('books') === null) { 62 | books = []; 63 | } else { 64 | books = JSON.parse(localStorage.getItem('books')); 65 | } 66 | 67 | return books; 68 | } 69 | 70 | static displayBooks() { 71 | const books = Store.getBooks(); 72 | 73 | books.forEach(function(book) { 74 | const ui = new UI(); 75 | 76 | // Add book to UI 77 | ui.addBookToList(book); 78 | }); 79 | } 80 | 81 | static addBook(book) { 82 | const books = Store.getBooks(); 83 | 84 | books.push(book); 85 | 86 | localStorage.setItem('books', JSON.stringify(books)); 87 | } 88 | 89 | static removeBook(isbn) { 90 | const books = Store.getBooks(); 91 | 92 | books.forEach(function(book, index) { 93 | if(book.isbn === isbn) { 94 | books.splice(index, 1); 95 | } 96 | }); 97 | 98 | localStorage.setItem('books', JSON.stringify(books)); 99 | } 100 | } 101 | 102 | // DOM Load Event 103 | document.addEventListener('DOMContentLoaded', Store.displayBooks); 104 | 105 | // Event Listeners for add book 106 | document.getElementById('book-form').addEventListener('submit', function(e) { 107 | e.preventDefault(); 108 | // Get form values 109 | const title = document.getElementById('title').value, 110 | author = document.getElementById('author').value, 111 | isbn = document.getElementById('isbn').value; 112 | 113 | // Instantiate book 114 | const book = new Book(title, author, isbn); 115 | 116 | // Instantiate UI 117 | const ui = new UI(); 118 | 119 | console.log(ui); 120 | 121 | // Validate 122 | console.log(title); 123 | if(title === '' || author === '' || isbn === '') { 124 | // Error alert 125 | ui.showAlert('Please fill in all fields', 'error'); 126 | } else { 127 | // Add book to list 128 | ui.addBookToList(book); 129 | 130 | // Add to LS 131 | Store.addBook(book); 132 | 133 | // Show sucess 134 | ui.showAlert('Book Added!', 'success'); 135 | 136 | // Clear Fields 137 | ui.clearFields(); 138 | } 139 | }); 140 | 141 | // Event Listener for delete 142 | document.getElementById('book-list').addEventListener('click', function (e) { 143 | e.preventDefault(); 144 | 145 | // Instantiate UI 146 | const ui = new UI(); 147 | 148 | // Delete book 149 | ui.deleteBook(e.target); 150 | 151 | // Remove from LS 152 | Store.removeBook(e.target.parentElement.previousElementSibling.textContent); 153 | 154 | // Show message 155 | ui.showAlert('Book Removed!', 'success'); 156 | }); -------------------------------------------------------------------------------- /book-list/app-es6.js: -------------------------------------------------------------------------------- 1 | class Book { 2 | constructor(title, author, isbn) { 3 | this.title = title; 4 | this.author = author; 5 | this.isbn = isbn; 6 | } 7 | } 8 | 9 | class UI { 10 | addBookToList(book) { 11 | const list = document.getElementById('book-list'); 12 | // Create tr element 13 | const row = document.createElement('tr'); 14 | // Insert cols 15 | row.innerHTML = ` 16 | ${book.title} 17 | ${book.author} 18 | ${book.isbn} 19 | X 20 | `; 21 | 22 | list.appendChild(row); 23 | } 24 | 25 | showAlert(message, className) { 26 | // Create div 27 | const div = document.createElement('div'); 28 | // Add classes 29 | div.className = `alert ${className}`; 30 | // Add text 31 | div.appendChild(document.createTextNode(message)); 32 | // Get parent 33 | const container = document.querySelector('.container'); 34 | const form = document.getElementById('book-form'); 35 | // Insert alert 36 | container.insertBefore(div, form); 37 | 38 | // Timeout after 3 sec 39 | setTimeout(function() { 40 | document.querySelector('.alert').remove(); 41 | }, 3000); 42 | } 43 | 44 | deleteBook(target) { 45 | if(target.className === 'delete') { 46 | target.parentElement.parentElement.remove(); 47 | } 48 | } 49 | 50 | clearFields() { 51 | document.getElementById('title').value = ''; 52 | document.getElementById('author').value = ''; 53 | document.getElementById('isbn').value = ''; 54 | } 55 | } 56 | 57 | // Event Listeners for add book 58 | document.getElementById('book-form').addEventListener('submit', function(e) { 59 | e.preventDefault(); 60 | // Get form values 61 | const title = document.getElementById('title').value, 62 | author = document.getElementById('author').value, 63 | isbn = document.getElementById('isbn').value; 64 | 65 | // Instantiate book 66 | const book = new Book(title, author, isbn); 67 | 68 | // Instantiate UI 69 | const ui = new UI(); 70 | 71 | console.log(ui); 72 | 73 | // Validate 74 | console.log(title); 75 | if(title === '' || author === '' || isbn === '') { 76 | // Error alert 77 | ui.showAlert('Please fill in all fields', 'error'); 78 | } else { 79 | // Add book to list 80 | ui.addBookToList(book); 81 | 82 | // Show sucess 83 | ui.showAlert('Book Added!', 'success'); 84 | 85 | // Clear Fields 86 | ui.clearFields(); 87 | } 88 | }); 89 | 90 | // Event Listener for delete 91 | document.getElementById('book-list').addEventListener('click', function (e) { 92 | e.preventDefault(); 93 | 94 | // Instantiate UI 95 | const ui = new UI(); 96 | 97 | // Delete book 98 | ui.deleteBook(e.target); 99 | 100 | // Show message 101 | ui.showAlert('Book Removed!', 'success'); 102 | }); -------------------------------------------------------------------------------- /book-list/app.js: -------------------------------------------------------------------------------- 1 | // Book Constructor 2 | function Book(title, author, isbn) { 3 | this.title = title; 4 | this.author = author; 5 | this.isbn = isbn; 6 | } 7 | 8 | // UI Constructor 9 | function UI() {} 10 | 11 | // Add Book to List 12 | UI.prototype.addBookToList = function (book) { 13 | const list = document.getElementById('book-list'); 14 | // Create tr element 15 | const row = document.createElement('tr'); 16 | // Insert cols 17 | row.innerHTML = ` 18 | ${book.title} 19 | ${book.author} 20 | ${book.isbn} 21 | X 22 | `; 23 | 24 | list.appendChild(row); 25 | } 26 | UI.prototype.showAlert = function (message, className) { 27 | // Create div 28 | const div = document.createElement('div'); 29 | // Add classes 30 | div.className = `alert ${className}`; 31 | // Add text 32 | div.appendChild(document.createTextNode(message)); 33 | // Get parent 34 | const container = document.querySelector('.container'); 35 | const form = document.getElementById('book-form'); 36 | // Insert alert 37 | container.insertBefore(div, form); 38 | 39 | // Timeout after 3 sec 40 | setTimeout(function() { 41 | document.querySelector('.alert').remove(); 42 | }, 3000); 43 | } 44 | 45 | // Delete Book 46 | UI.prototype.deleteBook = function (target) { 47 | if(target.className === 'delete') { 48 | target.parentElement.parentElement.remove(); 49 | } 50 | } 51 | 52 | UI.prototype.clearFields = function () { 53 | document.getElementById('title').value = ''; 54 | document.getElementById('author').value = ''; 55 | document.getElementById('isbn').value = ''; 56 | } 57 | 58 | // Event Listeners for add book 59 | document.getElementById('book-form').addEventListener('submit', function(e) { 60 | e.preventDefault(); 61 | // Get form values 62 | const title = document.getElementById('title').value, 63 | author = document.getElementById('author').value, 64 | isbn = document.getElementById('isbn').value; 65 | 66 | // Instantiate book 67 | const book = new Book(title, author, isbn); 68 | 69 | // Instantiate UI 70 | const ui = new UI(); 71 | 72 | // Validate 73 | console.log(title); 74 | if(title === '' || author === '' || isbn === '') { 75 | // Error alert 76 | ui.showAlert('Please fill in all fields', 'error'); 77 | } else { 78 | // Add book to list 79 | ui.addBookToList(book); 80 | 81 | // Show sucess 82 | ui.showAlert('Book Added!', 'success'); 83 | 84 | // Clear Fields 85 | ui.clearFields(); 86 | } 87 | }); 88 | 89 | // Event Listener for delete 90 | document.getElementById('book-list').addEventListener('click', function (e) { 91 | e.preventDefault(); 92 | 93 | // Instantiate UI 94 | const ui = new UI(); 95 | 96 | // Delete book 97 | ui.deleteBook(e.target); 98 | 99 | // Show message 100 | ui.showAlert('Book Removed!', 'success'); 101 | }); -------------------------------------------------------------------------------- /book-list/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 22 | Book List 23 | 24 | 25 |
26 |

Add Book

27 |
28 |
29 | 30 | 31 |
32 |
33 | 34 | 35 |
36 |
37 | 38 | 39 |
40 |
41 | 42 |
43 |
44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
TitleAuthorISBN#
55 |
56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /section-10/Symbols/app.js: -------------------------------------------------------------------------------- 1 | // Create a symbol 2 | const sym1 = Symbol(); 3 | const sym2 = Symbol('sym2'); 4 | 5 | console.log(sym1); // Symbol() 6 | console.log(sym2); // Symbol(sym2) 7 | console.log(typeof sym2); // symbol 8 | 9 | console.log(Symbol() === Symbol()); // false, never be the same 10 | console.log(Symbol('123') === Symbol('123')); // false, never be the same 11 | console.log(`Hello ${String(sym1)}`); // If needed to print 12 | console.log(`Hello ${sym1.toString()}`); // If needed to print 13 | 14 | // Unique Object Keys 15 | const KEY1 = Symbol() 16 | const KEY2 = Symbol('sym2'); 17 | 18 | const myObj = {}; 19 | 20 | myObj[KEY1] = 'Prop1'; 21 | myObj[KEY2] = 'Prop2'; 22 | myObj.key3 = 'Prop3'; 23 | myObj.key4 = 'Prop3'; 24 | 25 | console.log(myObj); 26 | console.log(myObj[KEY1]); 27 | console.log(myObj[KEY2]); 28 | 29 | // Symbols are not enumerable in for...in 30 | // Only myObj.key3 and myObj.key4 values in loop 31 | for(let i in myObj) { 32 | console.log(`${i}: ${myObj[i]}`); 33 | } 34 | 35 | // JSON.stringity ignores symbols 36 | console.log(JSON.stringify({key: 'prop'})); // {"key":"prop"} 37 | console.log(JSON.stringify({[Symbol('sym1')]: 'prop'})); //{} -------------------------------------------------------------------------------- /section-10/Symbols/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-10/destruct/app.js: -------------------------------------------------------------------------------- 1 | // Destructuring Assigment 2 | 3 | let a, b; 4 | [a, b] = [100, 200]; 5 | // Rest pattern 6 | [a, b, ...rest] = [100, 200, 300, 400, 500]; 7 | console.log(a, b, rest); 8 | 9 | ({a, b} = {a: 100, b:200, c:300, d:400, e:500}); 10 | ({a, b, ...rest} = {a: 100, b:200, c:300, d:400, e:500}); 11 | console.log(a, b, rest); 12 | 13 | // Array Destructuring 14 | const people = ['John', 'Beth', 'Mike']; 15 | const [person1, person2, person3] = people; 16 | console.log(person1, person2, person3); 17 | 18 | // Parse array returned from function 19 | function getPeople() { 20 | return ['John', 'Beth', 'Mike']; 21 | } 22 | let person11, person12, person13; 23 | [person11, person12, person13] = getPeople(); 24 | console.log(person11, person12, person13); 25 | 26 | // Object Destructuring 27 | const person = { 28 | name: 'John Doe', 29 | age: 32, 30 | city: 'Miami', 31 | gender: 'Male', 32 | sayHello: function() { 33 | console.log('Hello'); 34 | } 35 | } 36 | 37 | // Old ES5 38 | // const name = person.name, 39 | // age = person.age, 40 | // city = person.city; 41 | 42 | // New ES6 43 | const {name, age, city, sayHello} = person; 44 | console.log(name, age, city); 45 | sayHello(); -------------------------------------------------------------------------------- /section-10/destruct/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-10/iterators-generators/app.js: -------------------------------------------------------------------------------- 1 | // Iterator Example 2 | // function nameIterator(names) { 3 | // let nextIndex = 0; 4 | 5 | // return { 6 | // next: function() { 7 | // return nextIndex < names.length ? 8 | // {value: names[nextIndex++], done: false} : 9 | // {done: true} 10 | // } 11 | // } 12 | // } 13 | 14 | // // Create an array of names 15 | // const namesArray = ['Jack', 'Jill', 'John']; 16 | // // Init iterator and pass in the names array 17 | // const names = nameIterator(namesArray); 18 | 19 | // console.log(names.next().value); 20 | // console.log(names.next().value); 21 | // console.log(names.next().value); 22 | // console.log(names.next()); 23 | 24 | // Generator Example 25 | // function* sayNames() { 26 | // yield 'Jack'; 27 | // yield 'Jill'; 28 | // yield 'John'; 29 | // } 30 | 31 | // const name = sayNames(); 32 | 33 | // console.log(name.next().value); 34 | // console.log(name.next().value); 35 | // console.log(name.next().value); 36 | // console.log(name.next()); 37 | 38 | // ID Creator 39 | function* createIds() { 40 | let index = 0; 41 | while(true) { 42 | yield index++ 43 | } 44 | } 45 | 46 | const gen = createIds(); 47 | 48 | console.log(gen.next().value); 49 | console.log(gen.next().value); 50 | console.log(gen.next().value); 51 | console.log(gen.next().value); 52 | console.log(gen.next().value); 53 | console.log(gen.next().value); 54 | console.log(gen.next().value); -------------------------------------------------------------------------------- /section-10/iterators-generators/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-10/maps/app.js: -------------------------------------------------------------------------------- 1 | // MAPS = key-value pairs - can use ANY type as a key or value 2 | 3 | const map1 = new Map(); 4 | 5 | // Set Keys 6 | const key1 = 'some string', 7 | key2 = {}, 8 | key3 = function(){}; 9 | 10 | // Set map values by key 11 | map1.set(key1, 'Value of key1'); 12 | map1.set(key2, 'Value of key2'); 13 | map1.set(key3, 'Value of key3'); 14 | 15 | // Get values by key 16 | console.log(map1.get(key1), map1.get(key2), map1.get(key3)); 17 | 18 | // Count values 19 | console.log(map1.size); 20 | 21 | // Iterating maps 22 | // Loop using for...of to get keys and values 23 | console.log('-=-=-=-=-=-=-=-=-') 24 | for(let [key, value] of map1) { 25 | console.log(`${key} = ${value}`); 26 | } 27 | console.log('-=-=-=-=-=-=-=-=-') 28 | 29 | // Iterate keys only 30 | console.log('-=-=-=-=-=-=-=-=-') 31 | for(let key of map1.keys()) { 32 | console.log(key); 33 | } 34 | console.log('-=-=-=-=-=-=-=-=-') 35 | 36 | // Iterate values only 37 | console.log('-=-=-=-=-=-=-=-=-') 38 | for(let value of map1.values()) { 39 | console.log(value); 40 | } 41 | console.log('-=-=-=-=-=-=-=-=-') 42 | 43 | console.log('-=-=-=-=-=-=-=-=-') 44 | // Loop with forEach 45 | map1.forEach(function(value, key) { 46 | console.log(`${key} = ${value}`); 47 | }); 48 | console.log('-=-=-=-=-=-=-=-=-') 49 | 50 | // Convert to arrays 51 | // Create an array of the key value pairs 52 | const keyValArr = Array.from(map1); 53 | console.log(keyValArr); 54 | 55 | // Create an array of the values 56 | const valArr = Array.from(map1.values()); 57 | console.log(valArr); 58 | 59 | // Create an array of the keys 60 | const keyArr = Array.from(map1.keys()); 61 | console.log(keyArr); 62 | -------------------------------------------------------------------------------- /section-10/maps/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-10/profile-scroller/app.js: -------------------------------------------------------------------------------- 1 | const data = [ 2 | { 3 | name: 'John Doe', 4 | age: 32, 5 | gender: 'male', 6 | lookingfor: 'female', 7 | location: 'Boston MA', 8 | image: 'https://randomuser.me/api/portraits/men/82.jpg' 9 | }, 10 | { 11 | name: 'Jen Smith', 12 | age: 26, 13 | gender: 'female', 14 | lookingfor: 'male', 15 | location: 'Miami FL', 16 | image: 'https://randomuser.me/api/portraits/women/82.jpg' 17 | }, 18 | { 19 | name: 'William Johnson', 20 | age: 38, 21 | gender: 'male', 22 | lookingfor: 'female', 23 | location: 'Lynn MA', 24 | image: 'https://randomuser.me/api/portraits/men/83.jpg' 25 | }, 26 | ]; 27 | 28 | const profiles = profileIterator(data); 29 | 30 | // Call first profile 31 | nextProfile(); 32 | 33 | // Next Event 34 | document.getElementById('next').addEventListener('click', nextProfile); 35 | 36 | // Next profile Display 37 | function nextProfile() { 38 | const currentProfile = profiles.next().value; 39 | 40 | if(currentProfile !== undefined) { 41 | document.getElementById('profileDisplay').innerHTML = ` 42 | `; 48 | } else { 49 | // No more profiles 50 | window.location.reload(); 51 | } 52 | 53 | document.getElementById('imageDisplay').innerHTML = ``; 54 | } 55 | 56 | // Profile Iterator 57 | function profileIterator(profiles) { 58 | let nextIndex = 0; 59 | 60 | return { 61 | next: function() { 62 | return nextIndex < profiles.length ? 63 | {value: profiles[nextIndex++], done: false} : 64 | {done:true}; 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /section-10/profile-scroller/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Profile scroller 8 | 9 | 10 |
11 |
12 |
13 |

Profile Scroller

14 |
15 |
16 |
17 |
18 | 19 |
20 |
21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /section-10/sets/app.js: -------------------------------------------------------------------------------- 1 | // SETS - Store unique values of any type (only value, not key => value) 2 | 3 | const set1 = new Set(); 4 | 5 | // Add values to set 6 | set1.add(100); 7 | set1.add('A string'); 8 | set1.add({name: 'John'}); 9 | set1.add(true); 10 | set1.add(100); 11 | console.log(set1); 12 | 13 | const set2 = new Set([1, true, 'string']); 14 | console.log(set2); 15 | 16 | // Get count 17 | console.log(set1.size); 18 | 19 | // Check for values 20 | console.log(set1.has(100)); // true 21 | console.log(set1.has(50 + 50)); // true 22 | console.log(set1.has({name: 'John'})); // false 23 | 24 | // Delete from set 25 | set1.delete(100); 26 | console.log(set1); 27 | 28 | // Iterate through sets 29 | // For...of 30 | console.log('-=-=-=-=-=-=-=-=') 31 | for(let item of set1) { 32 | console.log(item); 33 | } 34 | console.log('-=-=-=-=-=-=-=-=') 35 | 36 | // forEach loop 37 | console.log("==================") 38 | set1.forEach((value) => { 39 | console.log(value); 40 | }); 41 | console.log("==================") 42 | 43 | // Convert set to array 44 | const setArr = Array.from(set1); 45 | console.log(setArr); 46 | 47 | -------------------------------------------------------------------------------- /section-10/sets/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-11/factory/app.js: -------------------------------------------------------------------------------- 1 | function MemberFactory() { 2 | this.createMember = function(name, type) { 3 | let member; 4 | 5 | if(type === 'simple') { 6 | member = new SimpleMembership(name); 7 | } else if(type === 'standard') { 8 | member = new StandardMembership(name); 9 | } else if(type === 'super') { 10 | member = new SuperMembership(name); 11 | } 12 | 13 | member.type = type; 14 | 15 | member.define = function() { 16 | console.log(`${this.name} (${this.type}): ${this.cost}`); 17 | } 18 | 19 | return member; 20 | } 21 | } 22 | 23 | const SimpleMembership = function(name) { 24 | this.name = name; 25 | this.cost = '$5'; 26 | } 27 | 28 | const StandardMembership = function(name) { 29 | this.name = name; 30 | this.cost = '$15'; 31 | } 32 | 33 | const SuperMembership = function(name) { 34 | this.name = name; 35 | this.cost = '$25'; 36 | } 37 | 38 | const members = []; 39 | const factory = new MemberFactory(); 40 | 41 | members.push(factory.createMember('John Doe', 'simple')); 42 | members.push(factory.createMember('Chris Jackson', 'super')); 43 | members.push(factory.createMember('Janice Williams', 'simple')); 44 | members.push(factory.createMember('Tom Smith', 'standard')); 45 | // console.log(members); 46 | 47 | members.forEach(function(member) { 48 | member.define(); 49 | }) -------------------------------------------------------------------------------- /section-11/factory/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox: Patterns 8 | 9 | 10 |

Javascript Sandbox: Patterns

11 | 12 | 13 | -------------------------------------------------------------------------------- /section-11/mediator/app.js: -------------------------------------------------------------------------------- 1 | const User = function(name) { 2 | this.name = name; 3 | this.chatroom = null; 4 | } 5 | 6 | User.prototype = { 7 | send: function(message, to) { 8 | this.chatroom.send(message, this, to); 9 | }, 10 | recieve: function(message, from) { 11 | console.log(`${from.name} to ${this.name}: ${message}`); 12 | } 13 | } 14 | 15 | const Chatroom = function() { 16 | let users = {}; // list of users 17 | 18 | return { 19 | register: function(user) { 20 | users[user.name] = user; 21 | user.chatroom = this; 22 | }, 23 | send: function(message, from, to) { 24 | if(to) { 25 | // Single user message 26 | to.recieve(message, from); 27 | } else { 28 | // Mass message 29 | for(key in users) { 30 | if(users[key] !== from) { 31 | users[key].recieve(message, from); 32 | } 33 | } 34 | } 35 | } 36 | } 37 | } 38 | 39 | const brad = new User('Brad'); 40 | const jeff = new User('Jeff'); 41 | const sara = new User('Sara'); 42 | 43 | const chatroom = new Chatroom(); 44 | 45 | chatroom.register(brad); 46 | chatroom.register(jeff); 47 | chatroom.register(sara); 48 | 49 | brad.send('Hello Jeff', jeff); 50 | sara.send('Hello Brad, you are the best dev ever!', brad); 51 | jeff.send('Hello Everyone!!!!') -------------------------------------------------------------------------------- /section-11/mediator/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox: Patterns 8 | 9 | 10 |

Javascript Sandbox: Patterns

11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /section-11/module-and-revealing-module/app.js: -------------------------------------------------------------------------------- 1 | // Separate the code in files to export functionalities 2 | 3 | // Basic structure 4 | // (function() { 5 | // // Declare private variables and functions 6 | // return { 7 | // // Declare public variables and functions 8 | // } 9 | // })(); 10 | 11 | // STANDARD MODULE PATTERN 12 | // const UICtrl = (function(){ 13 | // let text = 'Hello World'; 14 | 15 | // const changeText = function() { 16 | // const element = document.querySelector('h1'); 17 | // element.textContent = text; 18 | // } 19 | 20 | // return { 21 | // callChangeText: function() { 22 | // changeText(); 23 | // console.log(text); 24 | // } 25 | // } 26 | // })(); 27 | 28 | // UICtrl.callChangeText(); 29 | // console.log(UICtrl.text); // undefined 30 | // console.log(UICtrl.changeText()); // Error 31 | 32 | // REVEALING MODULE PATTERN 33 | const ItemCtrl = (function() { 34 | let data = []; 35 | 36 | function add(item) { 37 | data.push(item); 38 | console.log('Item Added....'); 39 | } 40 | 41 | function get(id) { 42 | return data.find(item => item.id === id) 43 | } 44 | 45 | return { 46 | add: add, // Revealing the private methods 47 | get: get // Revealing the private methods 48 | } 49 | })(); 50 | 51 | ItemCtrl.add({id: 1, name: 'John'}); 52 | ItemCtrl.add({id: 2, name: 'Mark'}); 53 | console.log(ItemCtrl.get(1)); 54 | console.log(ItemCtrl.get(2)); -------------------------------------------------------------------------------- /section-11/module-and-revealing-module/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox: Patterns 8 | 9 | 10 |

Javascript Sandbox: Patterns

11 | 12 | 13 | -------------------------------------------------------------------------------- /section-11/observer/app-es6.js: -------------------------------------------------------------------------------- 1 | class EventObserver { 2 | constructor() { 3 | this.observers = []; 4 | } 5 | 6 | subscribe(fn) { 7 | this.observers.push(fn); 8 | console.log(`You are now subscribed to ${fn.name}`); 9 | } 10 | 11 | unsubscribe(fn) { 12 | /* 13 | * Filter out from the list whatever mathces the callback 14 | * function. If there is no match, the callback gets to stay 15 | * on the list. The filte returns a new list and reassigns 16 | * the list of observers. 17 | * */ 18 | this.observers = this.observers.filter(function(item) { 19 | if(item !== fn) { 20 | return item; 21 | } 22 | }); 23 | console.log(`You are now unsubscribed from ${fn.name}`); 24 | } 25 | 26 | fire() { 27 | this.observers.forEach(function(item) { 28 | item.call(); 29 | }) 30 | } 31 | } 32 | 33 | const click = new EventObserver(); 34 | 35 | // Event Listeners 36 | document.querySelector('.sub-ms').addEventListener('click', function() { 37 | click.subscribe(getCurMilliseconds); 38 | }); 39 | document.querySelector('.unsub-ms').addEventListener('click', function() { 40 | click.unsubscribe(getCurMilliseconds); 41 | }); 42 | 43 | document.querySelector('.sub-s').addEventListener('click', function() { 44 | click.subscribe(getCurSeconds); 45 | }); 46 | document.querySelector('.unsub-s').addEventListener('click', function() { 47 | click.unsubscribe(getCurSeconds); 48 | }); 49 | 50 | document.querySelector('.fire').addEventListener('click', function() { 51 | click.fire(); 52 | }); 53 | 54 | 55 | // Click Handler 56 | const getCurMilliseconds = function() { 57 | console.log(`Current Milliseconds: ${new Date().getMilliseconds()}`); 58 | } 59 | const getCurSeconds = function() { 60 | console.log(`Current Seconds: ${new Date().getSeconds()}`); 61 | } -------------------------------------------------------------------------------- /section-11/observer/app.js: -------------------------------------------------------------------------------- 1 | function EventObserver() { 2 | this.observers = []; 3 | } 4 | 5 | EventObserver.prototype = { 6 | subscribe: function(fn) { 7 | this.observers.push(fn); 8 | console.log(`You are now subscribed to ${fn.name}`); 9 | }, 10 | unsubscribe: function(fn) { 11 | /* 12 | * Filter out from the list whatever mathces the callback 13 | * function. If there is no match, the callback gets to stay 14 | * on the list. The filte returns a new list and reassigns 15 | * the list of observers. 16 | * */ 17 | this.observers = this.observers.filter(function(item) { 18 | if(item !== fn) { 19 | return item; 20 | } 21 | }); 22 | console.log(`You are now unsubscribed from ${fn.name}`); 23 | }, 24 | fire: function() { 25 | this.observers.forEach(function(item) { 26 | item.call(); 27 | }) 28 | } 29 | } 30 | 31 | const click = new EventObserver(); 32 | 33 | // Event Listeners 34 | document.querySelector('.sub-ms').addEventListener('click', function() { 35 | click.subscribe(getCurMilliseconds); 36 | }); 37 | document.querySelector('.unsub-ms').addEventListener('click', function() { 38 | click.unsubscribe(getCurMilliseconds); 39 | }); 40 | 41 | document.querySelector('.sub-s').addEventListener('click', function() { 42 | click.subscribe(getCurSeconds); 43 | }); 44 | document.querySelector('.unsub-s').addEventListener('click', function() { 45 | click.unsubscribe(getCurSeconds); 46 | }); 47 | 48 | document.querySelector('.fire').addEventListener('click', function() { 49 | click.fire(); 50 | }); 51 | 52 | 53 | // Click Handler 54 | const getCurMilliseconds = function() { 55 | console.log(`Current Milliseconds: ${new Date().getMilliseconds()}`); 56 | } 57 | const getCurSeconds = function() { 58 | console.log(`Current Seconds: ${new Date().getSeconds()}`); 59 | } -------------------------------------------------------------------------------- /section-11/observer/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox: Patterns 8 | 9 | 10 |

Javascript Sandbox: Patterns

11 | 12 | 13 |

14 | 15 | 16 |

17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /section-11/singleton/app.js: -------------------------------------------------------------------------------- 1 | const Singleton = (function() { 2 | let instance; 3 | 4 | function createInstance() { 5 | const object = new Object('Object instance!!!'); 6 | return object; 7 | } 8 | 9 | return { 10 | getInstance: function() { 11 | if(!instance) { 12 | instance = createInstance(); 13 | } 14 | return instance; 15 | } 16 | } 17 | })(); 18 | 19 | const instanceA = Singleton.getInstance(); 20 | const instanceB = Singleton.getInstance(); 21 | 22 | if(instanceA === instanceB) { 23 | console.log('Same object'); 24 | } -------------------------------------------------------------------------------- /section-11/singleton/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox: Patterns 8 | 9 | 10 |

Javascript Sandbox: Patterns

11 | 12 | 13 | -------------------------------------------------------------------------------- /section-11/state/app.js: -------------------------------------------------------------------------------- 1 | const PageState = function() { 2 | let currentState = new homeState(this); 3 | 4 | this.init = function() { 5 | this.change(new homeState); 6 | } 7 | 8 | this.change = function(state) { 9 | currentState = state; 10 | } 11 | }; 12 | 13 | // Home State 14 | const homeState = function(page) { 15 | document.getElementById('heading').textContent = null; 16 | document.getElementById('content').innerHTML = ` 17 |
18 |

Hello, world!

19 |

This is a simple hero unit, a simple jumbotron-style component for calling extra attention to featured content or information.

20 |
21 |

It uses utility classes for typography and spacing to space content out within the larger container.

22 | Learn more 23 |
24 | `; 25 | } 26 | 27 | // About State 28 | const aboutState = function(page) { 29 | document.getElementById('heading').textContent = 'About Us'; 30 | document.getElementById('content').innerHTML = ` 31 |

This is the about page

32 | `; 33 | } 34 | 35 | // Contact State 36 | const contactState = function(page) { 37 | document.getElementById('heading').textContent = 'Contact Us'; 38 | document.getElementById('content').innerHTML = ` 39 |
40 |
41 | 42 | 43 |
44 |
45 | 46 | 47 |
48 | 49 |
50 | `; 51 | }; 52 | 53 | // Instantiate pageState 54 | const page = new PageState(); 55 | 56 | // Init the first state 57 | page.init(); 58 | 59 | // UI Vars 60 | const home = document.getElementById('home'), 61 | about = document.getElementById('about'), 62 | contact = document.getElementById('contact'); 63 | 64 | // Home 65 | home.addEventListener('click', (e) => { 66 | page.change(new homeState); 67 | 68 | e.preventDefault(); 69 | }); 70 | 71 | // About 72 | about.addEventListener('click', (e) => { 73 | page.change(new aboutState); 74 | 75 | e.preventDefault(); 76 | }); 77 | 78 | // Contact 79 | contact.addEventListener('click', (e) => { 80 | page.change(new contactState); 81 | 82 | e.preventDefault(); 83 | }); -------------------------------------------------------------------------------- /section-11/state/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | JavaScript Sandbox: Patterns 9 | 10 | 11 | 30 |
31 |

32 |
33 |
34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /section-12/tracalorie-project/app.js: -------------------------------------------------------------------------------- 1 | // Storage Controller 2 | const StorageCtrl = (function() { 3 | // Public Methods 4 | return { 5 | storeItem: function(item) { 6 | let items = []; 7 | // Check if any items in ls 8 | if(localStorage.getItem('items') !== null) { 9 | items = JSON.parse(localStorage.getItem('items')); 10 | } 11 | // Push new item 12 | items.push(item); 13 | // Set ls 14 | localStorage.setItem('items', JSON.stringify(items)); 15 | }, 16 | getItemsFromStorage: function() { 17 | let items; 18 | if(localStorage.getItem('items') === null) { 19 | items = []; 20 | } else { 21 | items = JSON.parse(localStorage.getItem('items')); 22 | } 23 | return items; 24 | }, 25 | updateItemStorage: function(updatedItem) { 26 | let items = JSON.parse(localStorage.getItem('items')); 27 | items.forEach(function(item, index) { 28 | if(updatedItem.id === item.id) { 29 | items.splice(index, 1, updatedItem); 30 | } 31 | }); 32 | localStorage.setItem('items', JSON.stringify(items)); 33 | }, 34 | deleteItemFromStorage: function(id) { 35 | let items = JSON.parse(localStorage.getItem('items')); 36 | items.forEach(function(item, index) { 37 | if(item.id === id) { 38 | items.splice(index, 1); 39 | } 40 | }); 41 | localStorage.setItem('items', JSON.stringify(items)); 42 | }, 43 | clearItemsFromStorage: function() { 44 | localStorage.removeItem('items'); 45 | } 46 | } 47 | })(); 48 | 49 | // Item Controller 50 | const ItemCtrl = (function() { 51 | // Item Contructor 52 | const Item = function(id, name, calories) { 53 | this.id = id; 54 | this.name = name; 55 | this.calories = calories; 56 | } 57 | 58 | // Data Structure / State 59 | const data = { 60 | // items: [ 61 | // // {id: 0, name: "Steak Dinner", calories: 1200}, 62 | // // {id: 1, name: "Cookie", calories: 400}, 63 | // // {id: 2, name: "Eggs", calories: 300}, 64 | // ], 65 | items: StorageCtrl.getItemsFromStorage(), 66 | currentItem: null, 67 | totalCalories: 0 68 | } 69 | 70 | // Public Methods 71 | return { 72 | getItems: function() { 73 | return data.items; 74 | }, 75 | addItem: function(name, calories) { 76 | let ID; 77 | // Create ID 78 | if(data.items.length > 0) { 79 | ID = data.items[data.items.length - 1].id + 1; 80 | } else { 81 | ID = 0; 82 | } 83 | 84 | // Calories to number 85 | calories = parseInt(calories); 86 | 87 | // Create new item 88 | newItem = new Item(ID, name, calories); 89 | 90 | // Add to items array 91 | data.items.push(newItem); 92 | 93 | return newItem; 94 | }, 95 | getItemById: function(id) { 96 | let found = null 97 | // Loop through items 98 | data.items.forEach(function(item) { 99 | if(item.id == id) { 100 | found = item; 101 | } 102 | }); 103 | return found; 104 | }, 105 | updateItem: function(name, calories) { 106 | // Calories to number 107 | calories = parseInt(calories); 108 | 109 | let found = null; 110 | data.items.forEach(function(item) { 111 | if(item.id === data.currentItem.id) { 112 | item.name = name; 113 | item.calories = calories; 114 | found = item; 115 | } 116 | }); 117 | 118 | return found; 119 | }, 120 | deleteItem: function(id) { 121 | // Get ids 122 | const ids = data.items.map(function(item) { 123 | return item.id; 124 | }); 125 | 126 | // Get index 127 | const index = ids.indexOf(id); 128 | 129 | // Remove item 130 | data.items.splice(id, 1); 131 | }, 132 | clearAllItems: function() { 133 | data.items = []; 134 | }, 135 | setCurrentItem: function(item) { 136 | data.currentItem = item; 137 | }, 138 | getCurrentItem: function() { 139 | return data.currentItem; 140 | }, 141 | getTotalCalories: function() { 142 | let total = 0; 143 | 144 | // Loop through items and add cals 145 | data.items.forEach(function(item) { 146 | total += item.calories; 147 | }); 148 | 149 | // Set total cal in data structure 150 | data.totalCalories = total; 151 | 152 | // Return total 153 | return data.totalCalories; 154 | }, 155 | logData: function() { 156 | return data; 157 | } 158 | } 159 | })(); 160 | 161 | // UI Controller 162 | const UICtrl = (function() { 163 | const UISelectors = { 164 | itemList: '#item-list', 165 | listItems: '#item-list li', 166 | addBtn: '.add-btn', 167 | updateBtn: '.update-btn', 168 | deleteBtn: '.delete-btn', 169 | backBtn: '.back-btn', 170 | clearBtn: '.clear-btn', 171 | itemNameInput: '#item-name', 172 | itemCaloriesInput: '#item-calories', 173 | totalCalories: '.total-calories' 174 | } 175 | 176 | // Public Methods 177 | return { 178 | populateItemList: function(items) { 179 | let html = ''; 180 | 181 | items.forEach(function(item) { 182 | html += `
  • 183 | ${item.name}: ${item.calories} Calories 184 | 185 |
  • `; 186 | }); 187 | 188 | // Insert list items 189 | document.querySelector(UISelectors.itemList).innerHTML = html; 190 | }, 191 | getItemInput: function() { 192 | return { 193 | name: document.querySelector(UISelectors.itemNameInput).value, 194 | calories: document.querySelector(UISelectors.itemCaloriesInput).value 195 | } 196 | }, 197 | addListItem: function(item) { 198 | // Show the list 199 | document.querySelector(UISelectors.itemList).style.display = 'block'; 200 | // Create li element 201 | const li = document.createElement('li'); 202 | // Add class 203 | li.className = 'collection-item'; 204 | // Add ID 205 | li.id = `item-${item.id}`; 206 | // Add HTML 207 | li.innerHTML = ` 208 | ${item.name}: ${item.calories} Calories 209 | 210 | `; 211 | // Insert item 212 | document.querySelector(UISelectors.itemList).insertAdjacentElement('beforeend', li); 213 | }, 214 | clearInput: function() { 215 | document.querySelector(UISelectors.itemNameInput).value = ''; 216 | document.querySelector(UISelectors.itemCaloriesInput).value = ''; 217 | }, 218 | updateListItem: function(item) { 219 | let listItems = document.querySelectorAll(UISelectors.listItems) 220 | 221 | // Turn Node list into array 222 | listItems = Array.from(listItems); 223 | 224 | listItems.forEach(function(listItem) { 225 | const itemID = listItem.getAttribute('id'); 226 | 227 | if(itemID !== `item-${item.id}`) { 228 | return; 229 | } 230 | 231 | document.querySelector(`#${itemID}`).innerHTML = ` 232 | ${item.name}: ${item.calories} Calories 233 | 234 | `; 235 | }); 236 | }, 237 | deleteListItem: function(id) { 238 | const itemID = `#item-${id}`; 239 | const item = document.querySelector(itemID); 240 | item.remove(); 241 | }, 242 | addItemToForm: function() { 243 | document.querySelector(UISelectors.itemNameInput).value = ItemCtrl.getCurrentItem().name; 244 | document.querySelector(UISelectors.itemCaloriesInput).value = ItemCtrl.getCurrentItem().calories; 245 | UICtrl.showEditState(); 246 | }, 247 | removeItems: function() { 248 | let listItems = document.querySelectorAll(UISelectors.listItems); 249 | 250 | // Turn Node list into array 251 | listItems = Array.from(listItems); 252 | 253 | listItems.forEach(function(item) { 254 | item.remove(); 255 | }) 256 | }, 257 | hideList: function() { 258 | document.querySelector(UISelectors.itemList).style.display = 'none'; 259 | }, 260 | showTotalCalories: function(totalCalories) { 261 | document.querySelector(UISelectors.totalCalories).textContent = totalCalories; 262 | }, 263 | clearEditState: function() { 264 | UICtrl.clearInput(); 265 | document.querySelector(UISelectors.updateBtn).style.display = 'none' 266 | document.querySelector(UISelectors.deleteBtn).style.display = 'none' 267 | document.querySelector(UISelectors.backBtn).style.display = 'none' 268 | document.querySelector(UISelectors.addBtn).style.display = 'inline' 269 | }, 270 | showEditState: function() { 271 | document.querySelector(UISelectors.updateBtn).style.display = 'inline' 272 | document.querySelector(UISelectors.deleteBtn).style.display = 'inline' 273 | document.querySelector(UISelectors.backBtn).style.display = 'inline' 274 | document.querySelector(UISelectors.addBtn).style.display = 'none' 275 | }, 276 | getSelectors: function() { 277 | return UISelectors; 278 | } 279 | } 280 | })(); 281 | 282 | // App Controller 283 | const App = (function(ItemCtrl, UICtrl, StorageCtrl) { 284 | // Load event listeners 285 | const loadEventListeners = function() { 286 | // Get UI Selectors 287 | const UISelectors = UICtrl.getSelectors(); 288 | 289 | // Add item event 290 | document.querySelector(UISelectors.addBtn).addEventListener('click', itemAddSubmit); 291 | 292 | // Disable submit on enter 293 | document.addEventListener('keypress', function(e) { 294 | if(e.keyCode === 13 || e.which === 13) { 295 | e.preventDefault(); 296 | return false; 297 | } 298 | }); 299 | 300 | // Edit icon click event 301 | document.querySelector(UISelectors.itemList).addEventListener('click', itemEditClick); 302 | 303 | // Update item event 304 | document.querySelector(UISelectors.updateBtn).addEventListener('click', itemUpdateSubmit); 305 | 306 | // Delete item event 307 | document.querySelector(UISelectors.deleteBtn).addEventListener('click', itemDeleteSubmit); 308 | 309 | // Clear items event 310 | document.querySelector(UISelectors.clearBtn).addEventListener('click', clearAllItemsClick); 311 | 312 | // Back button event 313 | document.querySelector(UISelectors.backBtn).addEventListener('click', UICtrl.clearEditState); 314 | } 315 | 316 | // Add item submit 317 | const itemAddSubmit = function(e) { 318 | e.preventDefault(); 319 | // Get form input from UI Controller 320 | const input = UICtrl.getItemInput(); 321 | 322 | // Check for name and calories input 323 | if(input.name === '' || input.calories === '') { 324 | return 325 | } 326 | // Add item 327 | const newItem = ItemCtrl.addItem(input.name, input.calories); 328 | // Add item to UI list 329 | UICtrl.addListItem(newItem); 330 | 331 | // Get total calories 332 | const totalCalories = ItemCtrl.getTotalCalories(); 333 | 334 | // Add total calories to UI 335 | UICtrl.showTotalCalories(totalCalories); 336 | 337 | // Store in localStorage 338 | StorageCtrl.storeItem(newItem); 339 | 340 | // Clear fields 341 | UICtrl.clearInput(); 342 | } 343 | 344 | // Update item submit 345 | const itemEditClick = function(e) { 346 | e.preventDefault(); 347 | if(!e.target.classList.contains('edit-item')) { 348 | return; 349 | } 350 | 351 | // Get list item id (item-0,item-1) 352 | const listId = e.target.parentNode.parentNode.id; 353 | 354 | // Break into an array 355 | const listIdArr = listId.split('-'); 356 | 357 | // Get the actual id 358 | const id = parseInt(listIdArr[1]); 359 | 360 | // Get item 361 | const itemToEdit = ItemCtrl.getItemById(id); 362 | 363 | // Set current item 364 | ItemCtrl.setCurrentItem(itemToEdit); 365 | 366 | // Add item to form 367 | UICtrl.addItemToForm(); 368 | } 369 | 370 | // Update item submit 371 | const itemUpdateSubmit = function(e) { 372 | e.preventDefault(); 373 | // Get item input 374 | const input = UICtrl.getItemInput(); 375 | 376 | // Update item 377 | const updatedItem = ItemCtrl.updateItem(input.name, input.calories); 378 | 379 | // Update UI 380 | UICtrl.updateListItem(updatedItem); 381 | 382 | // Get total calories 383 | const totalCalories = ItemCtrl.getTotalCalories(); 384 | 385 | // Add total calories to UI 386 | UICtrl.showTotalCalories(totalCalories); 387 | 388 | // Update local storage 389 | StorageCtrl.updateItemStorage(updatedItem); 390 | 391 | UICtrl.clearEditState(); 392 | } 393 | 394 | // Delete button event 395 | const itemDeleteSubmit = function(e) { 396 | e.preventDefault(); 397 | 398 | // Get current item 399 | const currentItem = ItemCtrl.getCurrentItem(); 400 | 401 | // Delete from data structure 402 | ItemCtrl.deleteItem(currentItem.id); 403 | 404 | // Delete from UI 405 | UICtrl.deleteListItem(currentItem.id); 406 | 407 | // Get total calories 408 | const totalCalories = ItemCtrl.getTotalCalories(); 409 | 410 | // Add total calories to UI 411 | UICtrl.showTotalCalories(totalCalories); 412 | 413 | // Delete from local storage 414 | StorageCtrl.deleteItemFromStorage(currentItem.id); 415 | 416 | UICtrl.clearEditState(); 417 | } 418 | 419 | // Clear items event 420 | const clearAllItemsClick = function(e) { 421 | // Delete all items form data structure 422 | ItemCtrl.clearAllItems(); 423 | 424 | // Get total calories 425 | const totalCalories = ItemCtrl.getTotalCalories(); 426 | 427 | // Add total calories to UI 428 | UICtrl.showTotalCalories(totalCalories); 429 | 430 | // Remove from UI 431 | UICtrl.removeItems(); 432 | 433 | // Remove from local storage 434 | StorageCtrl.clearItemsFromStorage(); 435 | 436 | // Hide UL 437 | UICtrl.hideList(); 438 | } 439 | 440 | // Public Methods 441 | return { 442 | init: function() { 443 | // Clear edit state / set initial state 444 | UICtrl.clearEditState(); 445 | 446 | // Fetch items from data structure 447 | const items = ItemCtrl.getItems(); 448 | 449 | // Check if any items 450 | if(items.length === 0) { 451 | UICtrl.hideList(); 452 | } else { 453 | // Populate list with items 454 | UICtrl.populateItemList(items); 455 | 456 | // Get total calories 457 | const totalCalories = ItemCtrl.getTotalCalories(); 458 | 459 | // Add total calories to UI 460 | UICtrl.showTotalCalories(totalCalories); 461 | } 462 | 463 | // Load event listeners 464 | loadEventListeners(); 465 | } 466 | } 467 | 468 | })(ItemCtrl, UICtrl, StorageCtrl); 469 | 470 | // Initialize App 471 | App.init(); -------------------------------------------------------------------------------- /section-12/tracalorie-project/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Tracalorie | Meal & Calorie Tracker 10 | 11 | 12 | 13 | 23 | 24 |
    25 | 26 |
    27 | 28 |
    29 |
    30 | Add Meal / Food Item 31 |
    32 |
    33 |
    34 | 35 | 36 |
    37 |
    38 | 39 | 40 |
    41 | 42 | 43 | 44 | 45 |
    46 |
    47 |
    48 |
    49 | 50 | 51 |

    Total Calories: 0

    52 | 53 | 54 | 55 |
    56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /section-13/microposts/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | build -------------------------------------------------------------------------------- /section-13/microposts/README.md: -------------------------------------------------------------------------------- 1 | # Babel Webpack Starter 2 | 3 | A starter pack to build JavaScript applications using standards from ES2015, ES2016 & ES2017. It uses webpack, Babel and webpack-dev-server to compile and serve. It is fully compatible with Async/Await as it uses the Babel polyfill. 4 | 5 | ### Version 6 | 1.1.0 7 | 8 | ## Usage 9 | 10 | ### Installation 11 | 12 | Install the dependencies 13 | 14 | ```sh 15 | $ npm install 16 | ``` 17 | 18 | ### Serve 19 | To serve in the browser - Runs webpack-dev-server 20 | 21 | ```sh 22 | $ npm start 23 | ``` 24 | 25 | ### Build 26 | Compile and build 27 | 28 | ```sh 29 | $ npm run build 30 | ``` 31 | 32 | ## More Info 33 | 34 | ### Author 35 | 36 | Brad Traversy 37 | [Traversy Media](http://www.traversymedia.com) 38 | 39 | ### License 40 | 41 | This project is licensed under the MIT License -------------------------------------------------------------------------------- /section-13/microposts/api/db.json: -------------------------------------------------------------------------------- 1 | { 2 | "posts": [ 3 | { 4 | "title": "Post 1", 5 | "body": "This is post 1", 6 | "id": 1 7 | }, 8 | { 9 | "id": 2, 10 | "title": "Post Two", 11 | "body": "This is post two" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /section-13/microposts/assets/css/style.css: -------------------------------------------------------------------------------- 1 | .delete { 2 | color: red; 3 | } -------------------------------------------------------------------------------- /section-13/microposts/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | My JavaScript App 11 | 12 | 13 | 18 | 19 |
    20 |
    21 |

    Say Something

    22 |

    What's on your mind

    23 |
    24 | 25 |
    26 |
    27 | 28 |
    29 | 30 | 31 | 32 |
    33 |
    34 |
    35 |
    36 | 37 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /section-13/microposts/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "babel_webpack_starter", 3 | "version": "1.0.0", 4 | "description": "Starter pack for compiling ES6+ apps to ES5", 5 | "main": "app.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "webpack", 9 | "start": "webpack-dev-server --output-public-path=/build/", 10 | "json:server": "json-server --watch api/db.json" 11 | }, 12 | "author": "Brad Traversy", 13 | "license": "MIT", 14 | "devDependencies": { 15 | "babel-core": "^6.26.0", 16 | "babel-loader": "^7.1.2", 17 | "babel-polyfill": "^6.26.0", 18 | "babel-preset-env": "^1.6.1", 19 | "babel-preset-stage-0": "^6.24.1", 20 | "webpack": "^3.8.1", 21 | "webpack-dev-server": "^2.9.4" 22 | }, 23 | "dependencies": { 24 | "json-server": "^0.12.2" 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /section-13/microposts/src/app.js: -------------------------------------------------------------------------------- 1 | import { http } from './http'; 2 | import { ui } from './ui.js'; 3 | import { SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION } from 'constants'; 4 | 5 | // Get posts on DOM load 6 | document.addEventListener('DOMContentLoaded', getPosts); 7 | 8 | // Listen for add post 9 | document.querySelector('.post-submit').addEventListener('click', submitPost); 10 | 11 | // Listen for delete 12 | document.querySelector('#posts').addEventListener('click', deletePost); 13 | 14 | // Listen for edit state 15 | document.querySelector('#posts').addEventListener('click', enableEdit); 16 | 17 | // Listen for cancel 18 | document.querySelector('.card-form').addEventListener('click', cancelEdit); 19 | 20 | // Get Posts 21 | function getPosts() { 22 | http.get('http://localhost:3000/posts') 23 | .then(data => ui.showPosts(data)) 24 | .catch(err => console.log(err)); 25 | } 26 | 27 | // Submit Post 28 | function submitPost() { 29 | const title = document.getElementById('title').value; 30 | const body = document.getElementById('body').value; 31 | const id = document.getElementById('id').value; 32 | 33 | const data = { 34 | title, 35 | body 36 | } 37 | 38 | // Validate input 39 | if(title === '' || body === '') { 40 | ui.showAlert('Please fill in all fields', 'alert alert-danger'); 41 | return; 42 | } 43 | 44 | // Check for ID 45 | if(id === '') { 46 | // Create Post 47 | http.post('http://localhost:3000/posts', data) 48 | .then(data => { 49 | ui.showAlert('Post added', 'alert alert-success'); 50 | ui.clearFields(); 51 | getPosts(); 52 | }) 53 | .catch(err => console.log(err)); 54 | } else { 55 | // Update Post 56 | http.put(`http://localhost:3000/posts/${id}`, data) 57 | .then(data => { 58 | ui.showAlert('Post updated', 'alert alert-success'); 59 | ui.changeFormState('add'); 60 | getPosts(); 61 | }) 62 | .catch(err => console.log(err)); 63 | } 64 | } 65 | 66 | // Delete Post 67 | function deletePost(e) { 68 | if(e.target.parentElement.classList.contains('delete')) { 69 | const id = e.target.parentElement.dataset.id; 70 | if(confirm('Are you sure?')) { 71 | http.delete(`http://localhost:3000/posts/${id}`) 72 | .then(data => { 73 | ui.showAlert('Post removed', 'alert alert-success'); 74 | getPosts(); 75 | }) 76 | .catch(err => console.log(err)); 77 | } 78 | } 79 | e.preventDefault(); 80 | } 81 | 82 | // Enable edit state 83 | function enableEdit(e) { 84 | e.preventDefault(); 85 | if(!e.target.parentElement.classList.contains('edit')) return; 86 | 87 | const id = e.target.parentElement.dataset.id; 88 | const body = e.target.parentElement.previousElementSibling.textContent; 89 | const title = e.target.parentElement.previousElementSibling.previousElementSibling.textContent; 90 | 91 | const data = { 92 | id, 93 | title, 94 | body 95 | } 96 | 97 | // Fill form with current post 98 | ui.fillForm(data); 99 | } 100 | 101 | function cancelEdit(e) { 102 | e.preventDefault(); 103 | if(e.target.classList.contains('post-cancel')) { 104 | ui.changeFormState('add'); 105 | } 106 | } -------------------------------------------------------------------------------- /section-13/microposts/src/http.js: -------------------------------------------------------------------------------- 1 | /** 2 | * EasyHTTP Library 3 | * Library for making HTTP requests 4 | * 5 | * @version 3.0.0 6 | * @author Lucas Floriani 7 | * @license MIT 8 | * 9 | */ 10 | 11 | class EasyHTTP { 12 | // Make an HTTP GET Request 13 | async get(url) { 14 | const response = await fetch(url); 15 | 16 | const resData = await response.json(); 17 | 18 | return resData; 19 | } 20 | 21 | // Make an HTTP POST Request 22 | async post(url, data) { 23 | const response = await fetch(url, { 24 | method: 'POST', 25 | headers: { 26 | 'Content-type': 'application/json' 27 | }, 28 | body: JSON.stringify(data) 29 | }) 30 | 31 | const resData = await response.json() 32 | 33 | return resData; 34 | } 35 | 36 | // Make an HTTP Put Request 37 | async put(url, data) { 38 | const response = await fetch(url, { 39 | method: 'PUT', 40 | headers: { 41 | 'Content-type': 'application/json' 42 | }, 43 | body: JSON.stringify(data) 44 | }) 45 | 46 | const resData = await response.json() 47 | 48 | return resData; 49 | } 50 | 51 | // Make an HTTP DELETE Request 52 | async delete(url) { 53 | const response = await fetch(url, { 54 | method: 'DELETE', 55 | headers: { 56 | 'Content-type': 'application/json' 57 | } 58 | }); 59 | 60 | const resData = await 'Resource Deleted...'; 61 | 62 | return resData; 63 | } 64 | } 65 | 66 | export const http = new EasyHTTP(); 67 | -------------------------------------------------------------------------------- /section-13/microposts/src/modules-example/app.js: -------------------------------------------------------------------------------- 1 | // CommonJS Module Syntax 2 | // const person = require('./mymodule1'); 3 | 4 | // ES2015 Module 5 | // IMPORT EACH VARIABLE 6 | // import {person, sayHello} from './mymodule2' 7 | // console.log(person.name); 8 | // console.log(sayHello()) 9 | // OR IMPORT ALL VARIABLES IN ONE 10 | // import * as mod from './mymodule2' 11 | // console.log(mod.person.name); 12 | // console.log(mod.sayHello()) 13 | // OR IMPORT A VARIABLE WITHOUT {} 14 | // import greeting from './mymodule2'; 15 | // console.log(greeting); -------------------------------------------------------------------------------- /section-13/microposts/src/modules-example/mymodule1.js: -------------------------------------------------------------------------------- 1 | // module.exports = { 2 | // name: 'Brad', 3 | // email: 'test@test.com' 4 | // } -------------------------------------------------------------------------------- /section-13/microposts/src/modules-example/mymodule2.js: -------------------------------------------------------------------------------- 1 | // export const person = { 2 | // name: 'John', 3 | // age: 30 4 | // } 5 | 6 | // // Can export all types of things 7 | // export function sayHello() { 8 | // return `Hello ${person.name}`; 9 | // } 10 | 11 | // // Without {} in import 12 | // const greeting = 'Hello World'; 13 | // export default greeting; -------------------------------------------------------------------------------- /section-13/microposts/src/ui.js: -------------------------------------------------------------------------------- 1 | class UI { 2 | constructor() { 3 | this.post = document.getElementById('posts'); 4 | this.titleInput = document.getElementById('title'); 5 | this.bodyInput = document.getElementById('body'); 6 | this.idInput = document.getElementById('id'); 7 | this.postSubmit = document.querySelector('.post-submit'); 8 | this.forState = 'add'; 9 | } 10 | 11 | // Show all posts 12 | showPosts(posts) { 13 | let output = ''; 14 | 15 | posts.forEach((post) => { 16 | output += ` 17 |
    18 |
    19 |

    ${post.title}

    20 |

    ${post.body}

    21 | 22 | 23 | 24 | 25 | 26 | 27 |
    28 |
    29 | `; 30 | }); 31 | 32 | this.post.innerHTML = output; 33 | } 34 | 35 | // Show alert message 36 | showAlert(message, className) { 37 | this.clearAlert(); 38 | 39 | // Create div 40 | const div = document.createElement('div'); 41 | // Add classes 42 | div.className = className; 43 | // Add text 44 | div.appendChild(document.createTextNode(message)); 45 | // Get parent 46 | const container = document.querySelector('.postsContainer'); 47 | // Get posts 48 | const posts = document.querySelector('#posts'); 49 | // Append message 50 | container.insertBefore(div, posts); 51 | 52 | // Timeout 53 | setTimeout(() => { 54 | this.clearAlert(); 55 | }, 3000); 56 | } 57 | 58 | // Clear alert message 59 | clearAlert() { 60 | const currentAlert = document.querySelector('.alert'); 61 | 62 | if(currentAlert) { 63 | currentAlert.remove(); 64 | } 65 | } 66 | 67 | // Clear all fields 68 | clearFields() { 69 | this.titleInput.value = ''; 70 | this.bodyInput.value = ''; 71 | } 72 | 73 | // Fill form to edit 74 | fillForm(data) { 75 | this.titleInput.value = data.title; 76 | this.bodyInput.value = data.body; 77 | this.idInput.value = data.id; 78 | 79 | this.changeFormState('edit'); 80 | } 81 | 82 | // Clear ID hidden value 83 | clearIdInput() { 84 | this.idInput.value = ''; 85 | } 86 | 87 | // Change the form state 88 | changeFormState(type) { 89 | if(type === 'edit') { 90 | this.postSubmit.textContent = 'Update Post'; 91 | this.postSubmit.className = 'post-submit btn btn-warning btn-block'; 92 | 93 | // Create cancel button 94 | const button = document.createElement('button'); 95 | button.className = 'post-cancel btn btn-light btn-block'; 96 | button.appendChild(document.createTextNode('Cancel Edit')); 97 | 98 | // Get parent 99 | const cardForm = document.querySelector('.card-form'); 100 | // Get element to insert before 101 | const formEnd = document.querySelector('.form-end'); 102 | // Insert cancel button 103 | cardForm.insertBefore(button, formEnd); 104 | 105 | return; 106 | } 107 | 108 | this.postSubmit.textContent = 'Post It'; 109 | this.postSubmit.className = 'post-submit btn btn-primary btn-block'; 110 | // Remove cancel button if it is there 111 | if(document.querySelector('.post-cancel')) { 112 | document.querySelector('.post-cancel').remove(); 113 | } 114 | // Clear ID from hidden field 115 | this.clearIdInput(); 116 | // Clear text 117 | this.clearFields(); 118 | } 119 | } 120 | 121 | export const ui = new UI(); -------------------------------------------------------------------------------- /section-13/microposts/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | module.exports = { 4 | entry: { 5 | app: [ 6 | 'babel-polyfill', 7 | './src/app.js', 8 | ], 9 | }, 10 | output: { 11 | path: path.resolve(__dirname, 'build'), 12 | filename: 'app.bundle.js', 13 | }, 14 | module: { 15 | loaders: [{ 16 | test: /\.js?$/, 17 | exclude: /node_modules/, 18 | loader: 'babel-loader', 19 | query: { 20 | presets: ['env', 'stage-0'] 21 | } 22 | }] 23 | } 24 | } -------------------------------------------------------------------------------- /section-2/arrays-methods.js: -------------------------------------------------------------------------------- 1 | // Create some arrays 2 | const numbers = [43,56,33,23,44,36,5]; 3 | const numbers2 = new Array(43,56,33,23,44,36,5); 4 | const fruit = ['Apple', 'Banana', 'Orange', 'Pear']; 5 | const mixed = [22, 'Hello', true, undefined, null, {a:1,b:1}, new Date()]; 6 | 7 | let val; 8 | 9 | // Get array length 10 | val = numbers.length; 11 | // Check if is array 12 | val = Array.isArray(numbers); 13 | // Get single value 14 | val = numbers[3]; 15 | val = numbers[0]; 16 | // Insert into array 17 | numbers[2] = 100; 18 | // Find index of value 19 | val = numbers.indexOf(36); 20 | 21 | // Mutating arrays 22 | // // Add on to end 23 | // numbers.push(250); 24 | // // Add on to front 25 | // numbers.unshift(120); 26 | // // Take off from end 27 | // numbers.pop(); 28 | // // Take off from front 29 | // numbers.shift(); 30 | // // Splice values 31 | // numbers.splice(1,3); 32 | // // Reverse 33 | // numbers.reverse(); 34 | 35 | // Concatenate array 36 | val = numbers.concat(numbers2); 37 | 38 | // Sorting arrays 39 | val = fruit.sort(); 40 | // val = numbers.sort(); 41 | 42 | // // Use the "compare function" 43 | // val = numbers.sort(function(x, y) { 44 | // return x - y; 45 | // }); 46 | 47 | // // Reverse sort 48 | // val = numbers.sort(function(x, y) { 49 | // return y - x; 50 | // }) 51 | 52 | // Find 53 | function over50(num) { 54 | return num > 50; 55 | } 56 | 57 | val = numbers.find(over50); 58 | 59 | console.log(numbers); 60 | console.log(val); -------------------------------------------------------------------------------- /section-2/block-scope-with-let-and-const.js: -------------------------------------------------------------------------------- 1 | // Global Scope 2 | var a = 1; 3 | let b = 2; 4 | const c = 3; 5 | 6 | // function test() { 7 | // var a = 4; 8 | // let b = 5; 9 | // const c = 6; 10 | // console.log('Function Scope:', a, b, c); 11 | // } 12 | 13 | // test(); 14 | 15 | // if(true) { 16 | // // Block Scope 17 | // var a = 4; // var muda a global 18 | // let b = 5; // let não muda a global 19 | // const c = 6; // const não muda a global 20 | // console.log('If Scope:', a, b, c); 21 | // } 22 | 23 | // for(let b = 0; b < 10; b++) { // Não muda a variável global 24 | // console.log(`Loop: ${b}`); 25 | // } 26 | 27 | // for(var a = 0; a < 10; a++) { // Muda a variável global 28 | // console.log(`Loop: ${a}`); 29 | // } 30 | 31 | console.log('Global Scope:', a, b, c); -------------------------------------------------------------------------------- /section-2/calculations.js: -------------------------------------------------------------------------------- 1 | const num1 = 100; 2 | const num2 = 50; 3 | let val; 4 | 5 | // Simple math with numbers 6 | val = num1 + num2; 7 | val = num1 - num2; 8 | val = num1 * num2; 9 | val = num1 / num2; 10 | val = num1 % num2; 11 | 12 | // Math Object 13 | val = Math.PI; 14 | val = Math.E; 15 | val = Math.round(2.4); // Arredonda valor para cima e para baixo 16 | val = Math.ceil(2.4); // Arredonda valor para cima 17 | val = Math.floor(2.8); // Arredonda valor para baixo 18 | val = Math.sqrt(64); // raiz quadrada 19 | val = Math.abs(-3); // valor absoluto (sempre positivo) 20 | val = Math.pow(8, 2); //numero elevado a tanto 21 | val = Math.min(2,33,5,6,22,34,-2); // menor numero 22 | val = Math.max(2,33,5,6,22,34,-2); // maior numero 23 | val = Math.random(); // número decimal aleatório 24 | 25 | val = Math.floor(Math.random() * 20 + 1); 26 | 27 | console.log(val); -------------------------------------------------------------------------------- /section-2/console.js: -------------------------------------------------------------------------------- 1 | // Log to console 2 | console.log('Hello World'); 3 | console.log(123); 4 | console.log(true); 5 | var greeting = "Hello"; 6 | console.log(greeting); 7 | console.log([1,2,3,4,5]); 8 | console.log({ 9 | a:1, 10 | b:2 11 | }); 12 | console.table({ 13 | a:1, 14 | b:2 15 | }); 16 | console.error('This is some error'); 17 | console.clear(); 18 | console.warn('This is a warning'); 19 | console.time('Hello'); 20 | console.log('Hello World'); 21 | console.log('Hello World'); 22 | console.log('Hello World'); 23 | console.log('Hello World'); 24 | console.log('Hello World'); 25 | console.log('Hello World'); 26 | console.log('Hello World'); 27 | console.timeEnd('Hello'); 28 | /* 29 | multi 30 | line 31 | comments 32 | */ -------------------------------------------------------------------------------- /section-2/date.js: -------------------------------------------------------------------------------- 1 | let val; 2 | 3 | const today = new Date(); 4 | let birthday = new Date('9-10-1981 11:25:00'); 5 | birthday = new Date('September 10 1981'); 6 | birthday = new Date('9/10/1981'); 7 | 8 | val = today.getMonth() + 1; 9 | val = today.getDate(); 10 | val = today.getDay(); // Dia da semana 11 | val = today.getFullYear(); 12 | val = today.getHours(); 13 | val = today.getMinutes(); 14 | val = today.getSeconds(); 15 | val = today.getMilliseconds(); 16 | val = today.getTime(); 17 | 18 | birthday.setMonth(2); 19 | birthday.setDate(12); 20 | birthday.setFullYear(1985); 21 | birthday.setHours(3); 22 | birthday.setMinutes(30); 23 | birthday.setSeconds(25); 24 | 25 | console.log(birthday); -------------------------------------------------------------------------------- /section-2/functions.js: -------------------------------------------------------------------------------- 1 | // FUNCTION DECLARATIONS 2 | 3 | function greet(firstName = 'John', lastName = 'Doe') { // ES6 4 | // if(typeof firstName === 'undefined'){firstName = 'John'} ES5 5 | // if(typeof lastName === 'undefined'){firstName = 'Doe'} ES5 6 | //console.log('Hello'); 7 | return `Hello ${firstName} ${lastName}`; 8 | } 9 | 10 | //console.log(greet()); 11 | 12 | // FUNCTION EXPRESSIONS 13 | 14 | const square = function(x = 3) { 15 | return x*x; 16 | }; 17 | 18 | console.log(square(8)); 19 | 20 | // IMMIDIATLEY INVOKABLE FUNCTION EXPRESSIONS - IIFEs 21 | 22 | // (function() { 23 | // console.log('IIFE Ran...'); 24 | // })(); 25 | 26 | // (function(name) { 27 | // console.log('Hello ' + name); 28 | // })('Brad'); 29 | 30 | // PROPERTY METHODS 31 | 32 | const todo = { 33 | add: function() { 34 | console.log('Add todo...'); 35 | }, 36 | edit: function(id) { 37 | console.log(`Edit todo ${id}`); 38 | } 39 | } 40 | todo.delete = function() { 41 | console.log('Delete todo...'); 42 | } 43 | 44 | todo.add(); 45 | todo.edit(22); 46 | todo.delete(); -------------------------------------------------------------------------------- /section-2/general-loops.js: -------------------------------------------------------------------------------- 1 | // FOR LOOP 2 | 3 | // for(let i = 0;i <= 10;i++) { 4 | // if(i === 2) { 5 | // console.log(`2 is my favorite number`); 6 | // continue; 7 | // } 8 | 9 | // if(i == 5) { 10 | // console.log('Stop the loop'); 11 | // break; 12 | // } 13 | 14 | // console.log(`Number ${i}`); 15 | // } 16 | 17 | // WHILE LOOP 18 | // let i = 0; 19 | // while(i < 10) { 20 | // console.log(`Number ${i}`); 21 | // i++; 22 | // } 23 | 24 | // DO WHILE 25 | // let i = 100; 26 | 27 | // do { 28 | // console.log(`Number ${i}`); 29 | // i++ 30 | // } while (i < 10); 31 | 32 | // LOOP THROUGH ARRAY 33 | const cars = ['Ford', 'Chevy', 'Honda', 'Toyota']; 34 | 35 | // for(let i = 0; i < cars.length; i++) { 36 | // console.log(cars[i]); 37 | // } 38 | 39 | // FOREACH 40 | // cars.forEach(function (car, index, cars) { 41 | // console.log(`${index} : ${car}`); 42 | // console.log(array); 43 | // }); 44 | 45 | // MAP 46 | // const users = [ 47 | // {id:1,name:'John'}, 48 | // {id:2,name:'Sara'}, 49 | // {id:3,name:'Karen'}, 50 | // {id:4,name:'Steve'}, 51 | // ] 52 | // const ids = users.map(function (user) { 53 | // return user.id; 54 | // }); 55 | // console.log(ids); 56 | 57 | 58 | //FOR IN LOOP 59 | const user = { 60 | firstName: 'John', 61 | lastName: 'Doe', 62 | age: 40 63 | } 64 | 65 | for(let x in user) { 66 | console.log(`${x}: ${user[x]}`); 67 | } -------------------------------------------------------------------------------- /section-2/if-else.js: -------------------------------------------------------------------------------- 1 | // if(sometring) { 2 | // do sometring; 3 | // } else { 4 | // do somenthing else; 5 | // } 6 | 7 | const id = 100; 8 | 9 | // // EQUAL TO 10 | // if(id == 100) { 11 | // console.log('CORRECT'); 12 | // } else { 13 | // console.log('INCORRECT'); 14 | // } 15 | 16 | // // NOT EQUAL TO 17 | // if(id != 101) { 18 | // console.log('CORRECT'); 19 | // } else { 20 | // console.log('INCORRECT'); 21 | // } 22 | 23 | // // EQUAL TO VALUE & TYPE 24 | // if(id === 100) { 25 | // console.log('CORRECT'); 26 | // } else { 27 | // console.log('INCORRECT'); 28 | // } 29 | 30 | // // NOT EQUAL TO VALUE & TYPE 31 | // if(id !== 100) { 32 | // console.log('CORRECT'); 33 | // } else { 34 | // console.log('INCORRECT'); 35 | // } 36 | 37 | // Test if undefined 38 | // if(typeof id !== 'undefined') { 39 | // console.log(`The ID is ${id}`); 40 | // } else { 41 | // console.log('NO ID'); 42 | // } 43 | 44 | // GREATER OR LESS THAN 45 | // if(id <= 100) { 46 | // console.log('CORRECT'); 47 | // } else { 48 | // console.log('INCORRECT'); 49 | // } 50 | 51 | // IF ELSE 52 | const color = 'yellow'; 53 | 54 | // if(color === 'red') { 55 | // console.log('Color is red'); 56 | // } else if (color === 'blue') { 57 | // console.log('Color is blue'); 58 | // } else { 59 | // console.log('Color is not red or blue'); 60 | // } 61 | 62 | // LOGICAL OPERATORS 63 | const name = 'Steve'; 64 | const age = 25; 65 | 66 | // AND && 67 | if(age > 0 && age < 12) { 68 | console.log(`${name} is a child`) 69 | } else if(age >= 13 && age <= 19) { 70 | console.log(`${name} is a teenager`); 71 | } else { 72 | console.log(`${name} is a adult`); 73 | } 74 | 75 | // OR || 76 | if(age < 16 || age > 65) { 77 | console.log(`${name} can not run in race`); 78 | } else { 79 | console.log(`${name} is registered for the race`); 80 | } 81 | 82 | // Ternary operator 83 | console.log(id == 100 ? 'Correct' : 'Incorrect'); 84 | 85 | // WITHOUT BRACES 86 | if(id == 100) 87 | console.log('CORRECT'); 88 | else 89 | console.log('INCORRECT'); 90 | 91 | -------------------------------------------------------------------------------- /section-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 |

    Javascript Sandbox: Section 2

    11 | 12 | 13 | -------------------------------------------------------------------------------- /section-2/objects.js: -------------------------------------------------------------------------------- 1 | const person = { 2 | firstName: 'Steve', 3 | lastName: 'Smith', 4 | age: 36, 5 | email: 'steve@aol.com', 6 | hobbies: ['music', 'sports'], 7 | address: { 8 | city: 'Miami', 9 | state: 'FL' 10 | }, 11 | getBirthYear: function() { 12 | return 2017 - this.age; 13 | } 14 | } 15 | 16 | let val; 17 | 18 | val = person; 19 | // Get specific value 20 | val = person.firstName; 21 | val = person['lastName']; 22 | val = person.age; 23 | val = person.hobbies[1]; 24 | val = person.address.state; 25 | val = person.address['city']; 26 | val = person.getBirthYear(); 27 | 28 | console.log(val); 29 | 30 | const people = [ 31 | {name: 'John', age: 30}, 32 | {name: 'Mike', age: 23}, 33 | {name: 'Nancy', age: 40}, 34 | ] 35 | 36 | for(let i = 0; i < people.length; i++) { 37 | console.log(people[i].name); 38 | } -------------------------------------------------------------------------------- /section-2/string-functions.js: -------------------------------------------------------------------------------- 1 | const firstName = 'William'; 2 | const lastName = 'Johnson'; 3 | const age = 36; 4 | const str = 'Hello there my name is Brad'; 5 | const tags = 'web design,web development,programming'; 6 | 7 | let val; 8 | 9 | val = firstName + lastName; 10 | 11 | // Concatenation 12 | val = firstName + ' ' + lastName; 13 | 14 | // Append 15 | val = 'Brad '; 16 | val += 'Traversy'; 17 | 18 | val = 'Hello, my name is ' + firstName + ' and I am ' + age; 19 | 20 | // Escaping 21 | val = 'That\'s awesome, I can\'t wait'; 22 | 23 | // Length 24 | val = firstName.length; 25 | 26 | // concat() 27 | val = firstName.concat(' ', lastName); 28 | 29 | // Change case 30 | val = firstName.toUpperCase(); 31 | val = firstName.toLowerCase(); 32 | 33 | val = firstName[0]; 34 | 35 | // indexOf() 36 | val = firstName.indexOf('l'); 37 | val = firstName.lastIndexOf('l'); 38 | 39 | // charAt() 40 | val = firstName.charAt(2); 41 | // Get last char 42 | val = firstName.charAt(firstName.length - 1); 43 | 44 | // substring() 45 | val = firstName.substring(0, 4); 46 | 47 | // slice() 48 | val = firstName.slice(0,4); 49 | val = firstName.slice(-3); 50 | 51 | // split() 52 | val = str.split(' '); 53 | val = tags.split(','); 54 | 55 | // replace() 56 | val = str.replace('Brad', 'Jack'); 57 | 58 | // includes() 59 | val = str.includes('Hello'); 60 | 61 | console.log(val); -------------------------------------------------------------------------------- /section-2/switch.js: -------------------------------------------------------------------------------- 1 | const color = 'red'; 2 | 3 | switch(color) { 4 | case 'red': 5 | console.log('Color is red'); 6 | break; 7 | case 'blue': 8 | console.log('Color is blue'); 9 | break; 10 | default: 11 | console.log('Color is not red or blue'); 12 | break; 13 | } 14 | 15 | let day; 16 | 17 | switch(new Date().getDay()) { 18 | case 0: 19 | day = 'Sunday'; 20 | break; 21 | case 1: 22 | day = 'Monday'; 23 | break; 24 | case 2: 25 | day = 'Tuesday'; 26 | break; 27 | case 3: 28 | day = 'Wednesday'; 29 | break; 30 | case 4: 31 | day = 'Thursday'; 32 | break; 33 | case 5: 34 | day = 'Friday'; 35 | break; 36 | case 6: 37 | day = 'Saturday'; 38 | break; 39 | } 40 | 41 | console.log(`Today is ${day}`); -------------------------------------------------------------------------------- /section-2/template-literals.js: -------------------------------------------------------------------------------- 1 | const name = 'John'; 2 | const age = 30; 3 | const job = 'Web Developer'; 4 | const city = 'Miami'; 5 | let html; 6 | 7 | // Without template strings (es5) 8 | html = ''; 14 | document.body.innerHTML = html; 15 | 16 | // With template strings (es6) 17 | function hello() { 18 | return 'Hello World'; 19 | } 20 | 21 | html = ` 22 | 31 | `; 32 | document.body.innerHTML = html; -------------------------------------------------------------------------------- /section-2/var-let-const.js: -------------------------------------------------------------------------------- 1 | // var, let, const 2 | 3 | // var name = "John Doe"; 4 | // console.log(name); 5 | // name = "Steve Smith"; 6 | // console.log(name); 7 | 8 | // // Init var 9 | // var greeting; 10 | // console.log(greeting); 11 | // greeting = "Hello"; 12 | // console.log(greeting); 13 | 14 | // // letters, numbers, _, $ 15 | // // Can not start with a number 16 | 17 | // // Multi word vars 18 | // var firstName = "John"; // Camel case 19 | // var first_name = 'Sara'; // Underscore 20 | // var FirstName = "Tom"; // Pascal case 21 | // var firstname; 22 | 23 | // LET 24 | // let name; 25 | // name = "John Doe"; 26 | // console.log(name); 27 | // name = "Steve Smith"; 28 | // console.log(name); 29 | 30 | // CONST 31 | // const name = "John"; 32 | // console.log(name); 33 | // Can not reassign 34 | // name = "Sara"; 35 | // Have to assign a value 36 | //const greeting; 37 | 38 | const person = { 39 | name: 'John', 40 | age: 30 41 | } 42 | 43 | person.name = "Sara"; 44 | person.age = 32; 45 | 46 | //console.log(person); 47 | 48 | const numbers = [1,2,3,4,5] 49 | numbers.push(6); 50 | 51 | console.log(numbers); -------------------------------------------------------------------------------- /section-2/variable-type-conversion.js: -------------------------------------------------------------------------------- 1 | let val; 2 | 3 | // Number to String 4 | val = String(555); 5 | val = String(4+4); 6 | // Boolean to String 7 | val = String(true); 8 | // Date to String 9 | val = String(new Date()); 10 | // Array to String 11 | val = String([1,2,3,4]); 12 | 13 | // toString() 14 | val = (5).toString(); 15 | val = (true).toString(); 16 | 17 | // String to number 18 | val = Number('5'); 19 | // Boolean to a Number 20 | val = Number(true); 21 | val = Number(false); 22 | // Null to a Number 23 | val = Number(null); 24 | val = Number('hello'); // NaN = Not a Number 25 | val = Number([1,2,3,4]); // NaN = Not a Number 26 | 27 | val = parseInt('100.30'); 28 | val = parseFloat('100.30'); 29 | 30 | // Output; 31 | console.log(val); 32 | console.log(typeof val); 33 | //console.log(val.length); // attribute from string type 34 | console.log(val.toFixed(2)); 35 | 36 | const val1 = String(5); 37 | const val2 = 6; 38 | const sum = Number(val1) + val2; 39 | console.log(sum); 40 | console.log(typeof sum); 41 | -------------------------------------------------------------------------------- /section-2/variables-types.js: -------------------------------------------------------------------------------- 1 | // Primitive 2 | 3 | // Strings 4 | const name = 'John Doe'; 5 | console.log(typeof name); 6 | // Number 7 | const age = 45; 8 | console.log(typeof age); 9 | //Boolean 10 | const hasKids = true; 11 | console.log(typeof hasKids); 12 | // Null 13 | const car = null; 14 | console.log(typeof car); 15 | // Undefined 16 | let test; 17 | console.log(typeof test); 18 | // Symbol 19 | const sym = Symbol(); 20 | console.log(typeof sym); 21 | 22 | // Reference Types - Objects 23 | 24 | //Array 25 | const hobbies = ['moveis', 'music']; 26 | console.log(typeof hobbies); 27 | //Object Literal 28 | const address = { 29 | city: 'Boston', 30 | state: 'MA' 31 | }; 32 | console.log(typeof address); 33 | // Date 34 | const today = new Date(); 35 | console.log(typeof today); -------------------------------------------------------------------------------- /section-2/window-object.js: -------------------------------------------------------------------------------- 1 | // WINDOW METHODS / OBJECTS / PROPERTIES 2 | //window.console.log(123); 3 | 4 | // Alert 5 | //window.alert('Hello World'); 6 | 7 | // Promt 8 | // const input = prompt(); 9 | // alert(input); 10 | 11 | // Confirm 12 | // if(confirm("Are you sure")){ 13 | // console.log("YES"); 14 | // } else { 15 | // console.log("NO"); 16 | // } 17 | 18 | let val; 19 | 20 | // Outter height and width with including toolbar/scroll 21 | // val = window.outerHeight; 22 | // val = window.outerWidth; 23 | 24 | 25 | // Inner height and width not including toolbar/scroll 26 | // val = window.innerHeight; 27 | // val = window.innerWidth; 28 | 29 | // Scroll Points 30 | // val = window.scrollY; 31 | // val = window.scrollX; 32 | 33 | // Location Object 34 | // val = window.location; 35 | // val = window.location.hostname; 36 | // val = window.location.port; 37 | // val = window.location.href; 38 | // val = window.location.search; // Variables in GET 39 | 40 | // Redirect 41 | // val = window.location.href = "http://google.com"; 42 | // Reload 43 | // window.location.reload(); 44 | 45 | // History object 46 | // val = window.history; 47 | // window.history.go(-1); // Return pages 48 | // val = window.history.length; // Pages before 49 | 50 | // Navigator Object 51 | // val = window.navigator; // Info about navigator (Chrome, Firefox, IE, etc) 52 | // val = window.navigator.appName; // Aways Nepscape 53 | // val = window.navigator.appVersion; // Versão do navegador 54 | // val = window.navigator.userAgent; // Versão do navegador 55 | // val = window.navigator.platform; // Versão do Sistema Operacional 56 | // val = window.navigator.vendor; 57 | // val = window.navigator.language; // Linguagem do navegador 58 | 59 | console.log(val); -------------------------------------------------------------------------------- /section-3/creating-elements.js: -------------------------------------------------------------------------------- 1 | // Create the element 2 | const li = document.createElement('li'); 3 | 4 | // Add class 5 | li.className = 'collection-item'; 6 | 7 | // Add id 8 | li.id = 'new-item'; 9 | 10 | // Add attribute 11 | li.setAttribute('title', 'New Item'); 12 | 13 | // Create text node and append 14 | li.appendChild(document.createTextNode('Hello World')); 15 | 16 | // Create new link element 17 | const link = document.createElement('a'); 18 | 19 | // Add href attribute 20 | link.setAttribute('href', '#'); 21 | 22 | // Add classes 23 | link.className = 'delete-item secondary-content'; 24 | 25 | // Add icon html 26 | link.innerHTML = ''; 27 | 28 | // append link into li 29 | li.appendChild(link); 30 | 31 | // Append li as child to ul 32 | document.querySelector('ul.collection').appendChild(li); 33 | 34 | console.log(li); 35 | console.log(link); -------------------------------------------------------------------------------- /section-3/document-object.js: -------------------------------------------------------------------------------- 1 | let val; 2 | 3 | val = document; 4 | val = document.all; //HTMLCollection // Pega todos os elementos presentes no html 5 | val = document.all[2]; // Seleciona um dos elementos presentes no html igual array 6 | val = document.all.length; // Quantos elementos tem no html 7 | val = document.head; 8 | val = document.body; 9 | val = document.doctype; 10 | val = document.domain; // Parte da url 11 | val = document.URL; // Toda URL 12 | val = document.characterSet; // UTF-8 13 | val = document.contentType; // Tipo do conteudo "text/html" 14 | 15 | // Seleção diretamente pelo objeto document 16 | val = document.forms; //HTMLCollection 17 | val = document.forms[0]; 18 | val = document.forms[0].id; 19 | val = document.forms[0].method; 20 | val = document.forms[0].action; 21 | 22 | val = document.links; //HTMLCollection 23 | val = document.links[0]; 24 | val = document.links[0].id; 25 | val = document.links[0].className; 26 | val = document.links[0].classList; //DOMTokenList 27 | val = document.links[0].classList[0]; //DOMTokenList 28 | 29 | val = document.images; //HTMLCollection 30 | 31 | val = document.scripts; //HTMLCollection 32 | val = document.scripts[2].getAttribute('src'); // Para pegar atributos especificos 33 | 34 | let scripts = document.scripts; 35 | // scripts.forEach( function (script) { // Erro pq é HTMLCollection 36 | // console.log(script) 37 | // }); 38 | 39 | let scriptArr = Array.from(scripts) 40 | scriptArr.forEach( function (script) { //funciona 41 | console.log(script.getAttribute('src')) 42 | }); 43 | 44 | console.log(val); -------------------------------------------------------------------------------- /section-3/dom-multiple-selectors.js: -------------------------------------------------------------------------------- 1 | // document.getElementsByClassName() 2 | 3 | // const items = document.getElementsByClassName('collection-item'); 4 | // console.log(items); 5 | // console.log(items[0]); 6 | // items[0].style.color = 'red'; 7 | // items[3].textContent = 'Hello'; 8 | 9 | // const listItems = document.querySelector('ul').getElementsByClassName('collections-item'); 10 | 11 | // console.log(listItems); 12 | 13 | // document.getElementByTagName 14 | // let lis = document.getElementsByTagName('li'); 15 | // console.log(lis); 16 | // console.log(lis[0]); 17 | // lis[0].style.color = 'red'; 18 | // lis[3].textContent = 'Hello'; 19 | 20 | // //Convert HTMLCollection into Array 21 | // lis = Array.from(lis); 22 | 23 | // lis.reverse(); 24 | 25 | // lis.forEach(function(li, index){ 26 | // console.log(li.className); 27 | // li.textContent = `Hello ${index}`; 28 | // }); 29 | 30 | // console.log(lis); 31 | 32 | // document.querySelectorAll(); 33 | 34 | const items = document.querySelectorAll('ul.collection li.collection-item'); //Nodelist 35 | console.log(items); 36 | 37 | items.forEach(function(item, index){ 38 | item.textContent = `Hello ${index}`; 39 | }) 40 | 41 | const liOdd = document.querySelectorAll('li:nth-child(odd)'); 42 | const liEven = document.querySelectorAll('li:nth-child(even)'); 43 | 44 | liOdd.forEach(function(li, index){ 45 | li.style.background = '#ccc'; 46 | }) 47 | 48 | for(let i = 0; i < liEven.length;i++){ 49 | liEven[i].style.background = '#f4f4f4'; 50 | } -------------------------------------------------------------------------------- /section-3/dom-single-selectors.js: -------------------------------------------------------------------------------- 1 | // // document.getElementById() 2 | 3 | // console.log(document.getElementById('task-title')); 4 | 5 | // // Get things from the element 6 | // console.log(document.getElementById('task-title').id); 7 | // console.log(document.getElementById('task-title').className); 8 | 9 | // const taskTitle = document.getElementById('task-title'); 10 | 11 | // // Change styling 12 | // taskTitle.style.background = '#333'; 13 | // taskTitle.style.color = '#fff'; 14 | // taskTitle.style.padding = '5px'; 15 | // // taskTitle.style.display = 'none'; 16 | 17 | // // Change content 18 | // taskTitle.textContent = 'Task List'; 19 | // taskTitle.innerText = 'My Tasks'; 20 | // taskTitle.innerHTML = 'Task List 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | Task List 12 | 13 | 14 | 15 |
    16 |
    17 |
    18 |
    19 |
    20 | Task List 21 |
    22 |
    23 |
    24 | 25 | 26 |
    27 | 32 |
    33 | 34 | 35 |
    36 |
    37 |
    Tasks
    38 | 70 | Clear Tasks 71 |
    72 |
    73 |
    74 |
    75 |
    76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /section-3/keyboard-input-events.js: -------------------------------------------------------------------------------- 1 | const form = document.querySelector('form'); 2 | const taskInput = document.getElementById('task'); 3 | const heading = document.querySelector('h5'); 4 | const select = document.querySelector('select'); 5 | 6 | // Clear input 7 | taskInput.value = ''; 8 | 9 | // form.addEventListener('submit', runEvent); 10 | 11 | // Keydown 12 | // taskInput.addEventListener('keydown', runEvent); 13 | 14 | // Keyup 15 | // taskInput.addEventListener('keyup', runEvent); 16 | 17 | // Keypress 18 | // taskInput.addEventListener('keypress', runEvent); 19 | 20 | // Focus 21 | // taskInput.addEventListener('focus', runEvent); 22 | 23 | // Blur 24 | // taskInput.addEventListener('blur', runEvent); 25 | 26 | // Cut 27 | // taskInput.addEventListener('cut', runEvent); 28 | 29 | // Paste 30 | // taskInput.addEventListener('paste', runEvent); 31 | 32 | // Input 33 | // taskInput.addEventListener('input', runEvent); 34 | 35 | // Change 36 | select.addEventListener('change', runEvent); // For selects 37 | 38 | 39 | 40 | 41 | 42 | 43 | function runEvent(e){ 44 | console.log(`EVENT TYPE: ${e.type}`); 45 | 46 | // console.log(e.target.value); 47 | 48 | // heading.innerText = e.target.value; 49 | 50 | // Get input value 51 | // console.log(taskInput.value); 52 | 53 | // e.preventDefault(); 54 | } -------------------------------------------------------------------------------- /section-3/local-and-session-storage.js: -------------------------------------------------------------------------------- 1 | // Set local storage item 2 | // localStorage.setItem('name', 'John'); 3 | // localStorage.setItem('age', '30'); 4 | 5 | // Set session storage item 6 | // sessionStorage.setItem('name', 'Beth'); 7 | 8 | // Remove from storage 9 | // localStorage.removeItem('name'); 10 | 11 | // Get from storage 12 | // const name = localStorage.getItem('name'); 13 | // const age = localStorage.getItem('age'); 14 | // console.log(name, age); 15 | 16 | // Clear localStorage 17 | // localStorage.clear(); 18 | 19 | document.querySelector('form').addEventListener('submit', function(e) { 20 | e.preventDefault(); 21 | const task = document.getElementById('task').value; 22 | 23 | let tasks; 24 | 25 | if(localStorage.getItem('tasks') === null) { 26 | tasks = []; 27 | } else { 28 | tasks = JSON.parse(localStorage.getItem('tasks')); 29 | } 30 | 31 | tasks.push(task); 32 | 33 | localStorage.setItem('tasks', JSON.stringify(tasks)); 34 | 35 | alert('Task saved'); 36 | }); 37 | 38 | // Print values in localStorage 39 | const tasks = JSON.parse(localStorage.getItem('tasks')); 40 | tasks.forEach(function(task){ 41 | console.log(task); 42 | }); -------------------------------------------------------------------------------- /section-3/mouse-events.js: -------------------------------------------------------------------------------- 1 | const clearBtn = document.querySelector('.clear-tasks'); 2 | const card = document.querySelector('.card'); 3 | const heading = document.querySelector('h5'); 4 | 5 | // Click 6 | // clearBtn.addEventListener('click', runEvent); 7 | 8 | // Doubleclick 9 | // clearBtn.addEventListener('dblclick', runEvent); 10 | 11 | // Mousedown 12 | // clearBtn.addEventListener('mousedown', runEvent); 13 | 14 | // Mouseup 15 | // clearBtn.addEventListener('mouseup', runEvent); 16 | 17 | // Mouseenter 18 | // card.addEventListener('mouseenter', runEvent); 19 | 20 | // Mouseleave 21 | // card.addEventListener('mouseleave', runEvent); 22 | 23 | // Mouseover 24 | // card.addEventListener('mouseover', runEvent); // Only in the element selected, not child 25 | 26 | // Mouseout 27 | // card.addEventListener('mouseout', runEvent); // Only in the element selected, not child 28 | 29 | // Mousemove 30 | card.addEventListener('mousemove', runEvent); 31 | 32 | 33 | // Event Handler 34 | function runEvent(e) { 35 | console.log(`EVENT TYPE ${e.type}`); 36 | 37 | heading.textContent = `MouseX: ${e.offsetX} MouseY: ${e.offsetY}`; 38 | 39 | document.body.style.backgroundColor = `rgb(${e.offsetX},${e.offsetY}, 40)`; 40 | } -------------------------------------------------------------------------------- /section-3/remove-and-replace-attributes.js: -------------------------------------------------------------------------------- 1 | // REPLACE ELEMENT 2 | 3 | // Create Element 4 | const newHeading = document.createElement('h2'); 5 | //Add id 6 | newHeading.id = 'task-title' 7 | // New text node 8 | newHeading.appendChild(document.createTextNode('Task List')); 9 | 10 | // Get the old heading 11 | const oldHeading = document.getElementById('task-title'); 12 | // Parent 13 | const cardAction = document.querySelector('.card-action'); 14 | 15 | // Replace 16 | cardAction.replaceChild(newHeading, oldHeading); 17 | 18 | // REMOVE ELEMENT 19 | const lis = document.querySelectorAll('li'); 20 | const list = document.querySelector('ul'); 21 | 22 | // Remove list item 23 | lis[0].remove(); 24 | 25 | // Remove child element 26 | list.removeChild(lis[3]); 27 | 28 | // CLASSES & ATTR 29 | const firstLi = document.querySelector('li:first-child'); 30 | const link = firstLi.children[0] 31 | 32 | let val; 33 | 34 | // Classes 35 | val = link.className; // String de classes 36 | val = link.classList; // DOMTokenList 37 | val = link.classList[0]; 38 | link.classList.add('test'); 39 | link.classList.remove('test'); 40 | val = link; 41 | 42 | // Attributes 43 | val = link.getAttribute('href'); 44 | val = link.setAttribute('href', 'http://google.com'); 45 | link.setAttribute('title', 'Google'); 46 | val = link.hasAttribute('title'); 47 | link.removeAttribute('title'); 48 | val = link; 49 | 50 | console.log(val); -------------------------------------------------------------------------------- /section-3/traversing-the-dom.js: -------------------------------------------------------------------------------- 1 | let val; 2 | 3 | const list = document.querySelector('ul.collection'); 4 | const listItem = document.querySelector('li.collection-item:first-child'); 5 | 6 | val = listItem; 7 | val = list; 8 | 9 | // Get child nodes 10 | val = list.childNodes; //NodeList (Get line breaks to) 11 | val = list.childNodes[0]; 12 | val = list.childNodes[0].nodeName; 13 | val = list.childNodes[1].nodeType; // Numbers below 14 | // 1 - Element 15 | // 2 - Attribute (deprecated) 16 | // 3 - Text node 17 | // 8 - Comment 18 | // 9 - Document itself 19 | // 10 - Doctype 20 | 21 | 22 | // Get children element nodes 23 | val = list.children; // HTMLCollection (Dont get line breaks) 24 | val = list.children[1]; 25 | list.children[1].textContent = 'Hello'; 26 | // Children of children 27 | list.children[3].children[0].id = 'test-link'; 28 | val = list.children[3].children; // HTMLCollection 29 | val = list.children[3].children[0]; 30 | 31 | // First child 32 | val = list.firstChild; // Like NodeList childNodes, but only the first 33 | val = list.firstElementChild; // Like HTMLCollection children, but only the first 34 | 35 | // Last child 36 | val = list.lastChild; // Like NodeList childNodes, but only the last 37 | val = list.lastElementChild; // Like HTMLCollection children, but only the last 38 | 39 | // Count child elements 40 | val = list.childElementCount; // Quantity elements 41 | 42 | // Get parent node 43 | val = listItem.parentNode; //Same thing 44 | val = listItem.parentElement; //Same thing 45 | // Parent of parent 46 | val = listItem.parentElement.parentElement; 47 | 48 | // Get next sibling 49 | val = listItem.nextSibling; // Like nodeList childNodes 50 | val = listItem.nextElementSibling; // Like HTMLCollection children 51 | val = listItem.nextElementSibling.nextElementSibling; // Like HTMLCollection children 52 | 53 | // Get prev sibling 54 | val = listItem.previousSibling; // Like nodeList childNodes 55 | val = listItem.previousElementSibling; // Like HTMLCollection children 56 | //val = listItem.previousElementSibling.previousElementSibling; // Like HTMLCollection children 57 | 58 | console.log(val); -------------------------------------------------------------------------------- /section-4/loan-calculator/app.js: -------------------------------------------------------------------------------- 1 | // Listen for submit 2 | document.getElementById('loan-form').addEventListener('submit', function(e){ 3 | e.preventDefault(); 4 | // Hide results 5 | document.getElementById('results').style.display = 'none'; 6 | 7 | // Show loader 8 | document.getElementById('loading').style.display = 'block'; 9 | 10 | setTimeout(calculateResults, 2000); 11 | }); 12 | 13 | // Calculate Results 14 | function calculateResults() { 15 | // UI Vars 16 | const amount = document.getElementById('amount'); 17 | const interest = document.getElementById('interest'); 18 | const years = document.getElementById('years'); 19 | const mounthlyPayment = document.getElementById('monthly-payment'); 20 | const totalPayment = document.getElementById('total-payment'); 21 | const totalInterest = document.getElementById('total-interest'); 22 | 23 | const principal = parseFloat(amount.value); 24 | const calculatedInterest = parseFloat(interest.value) / 100 / 12; 25 | const calculatedPayments = parseFloat(years.value) * 12; 26 | 27 | // Compute monthly payment 28 | const x = Math.pow(1 + calculatedInterest, calculatedPayments); 29 | const monthly = (principal * x * calculatedInterest) / (x - 1); 30 | 31 | if(isFinite(monthly)) { 32 | mounthlyPayment.value = monthly.toFixed(2); 33 | totalPayment.value = (monthly * calculatedPayments).toFixed(2); 34 | totalInterest.value = ((monthly * calculatedPayments) - principal).toFixed(2); 35 | 36 | // Hide results 37 | document.getElementById('results').style.display = 'block'; 38 | 39 | // Show loader 40 | document.getElementById('loading').style.display = 'none'; 41 | } else { 42 | showError('Please check your numbers'); 43 | } 44 | } 45 | 46 | // Show Error 47 | function showError(error) { 48 | // Hide results 49 | document.getElementById('results').style.display = 'none'; 50 | 51 | // Show loader 52 | document.getElementById('loading').style.display = 'none'; 53 | 54 | // Create a div 55 | const errorDiv = document.createElement('div'); 56 | 57 | // Get elements 58 | const card = document.querySelector('.card'); 59 | const heading = document.querySelector('.heading'); 60 | 61 | // Add class 62 | errorDiv.className = 'alert alert-danger'; 63 | 64 | // Create text node and append to div 65 | errorDiv.appendChild(document.createTextNode(error)); 66 | 67 | // Insert error above heading 68 | card.insertBefore(errorDiv, heading); 69 | 70 | // Clear error after 3 seconds 71 | setTimeout(clearError, 3000); 72 | } 73 | 74 | function clearError() { 75 | document.querySelector('.alert').remove(); 76 | } -------------------------------------------------------------------------------- /section-4/loan-calculator/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lucasfloriani/course-modern-javascript-from-the-beginning/fa061a5a04ae19c67573185144210a97f6689bbe/section-4/loan-calculator/img/loading.gif -------------------------------------------------------------------------------- /section-4/loan-calculator/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Hello, world! 8 | 13 | 14 | 15 |
    16 |
    17 |
    18 |
    19 |

    Loan Calculator

    20 |
    21 |
    22 |
    23 |
    24 | @ 25 |
    26 | 27 |
    28 |
    29 |
    30 |
    31 |
    32 | % 33 |
    34 | 35 |
    36 |
    37 |
    38 | 39 |
    40 |
    41 | 42 |
    43 |
    44 | 45 |
    46 | Loading 47 |
    48 | 49 |
    50 |
    Results
    51 |
    52 |
    53 |
    54 | Monthly Payment 55 |
    56 | 57 |
    58 |
    59 |
    60 |
    61 |
    62 | Total Payment 63 |
    64 | 65 |
    66 |
    67 |
    68 |
    69 |
    70 | Total Interest 71 |
    72 | 73 |
    74 |
    75 |
    76 |
    77 |
    78 |
    79 |
    80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /section-4/number-guesser/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | GAME FUNCTION: 3 | - Player must guess a number between a min and max 4 | - Player gets 2 certain amount of guesses 5 | - Notify player of guesses remaining 6 | - Notify the player of the correct answer if loose 7 | - Let player choose to play again 8 | */ 9 | 10 | // Game values 11 | let min = 1, 12 | max = 10, 13 | winningNum = getRandomNum(min, max), 14 | guessesLeft = 3; 15 | 16 | // UI Elements 17 | const game = document.getElementById('game'), 18 | minNum = document.querySelector('.min-num'), 19 | maxNum = document.querySelector('.max-num'), 20 | guessBtn = document.getElementById('guess-btn'), 21 | guessInput = document.getElementById('guess-input'), 22 | message = document.querySelector('.message'); 23 | 24 | // Assign UI min and max 25 | minNum.textContent = min; 26 | maxNum.textContent = max; 27 | 28 | // Play again event listener 29 | game.addEventListener('mousedown', function(e) { 30 | if(e.target.className === 'play-again') { 31 | window.location.reload(); 32 | } 33 | }); 34 | 35 | 36 | // Listen for guess 37 | guessBtn.addEventListener('click', function() { 38 | let guess = parseInt(guessInput.value); 39 | 40 | // Validate 41 | if(isNaN(guess) || guess < min || guess > max) { 42 | setMessage(`Please enter a number between ${min} and ${max}`, 'red'); 43 | } 44 | 45 | // Check if won 46 | if(guess === winningNum) { 47 | // Game over - won 48 | gameOver(true, `${winningNum} is correct. YOU WIN`); 49 | 50 | } else { 51 | // Wrong number 52 | guessesLeft--; 53 | 54 | if(guessesLeft === 0) { 55 | // Game over - lost 56 | gameOver(false, `Game Over, you lost. The correct number was ${winningNum}`); 57 | 58 | } else { 59 | // Game continues - answer wrong 60 | 61 | // Change border color 62 | guessInput.style.borderColor = 'red'; 63 | 64 | // Clear Input 65 | guessInput.value = ''; 66 | 67 | // Tell user its the wrong number 68 | setMessage(`${guess} is not correct, ${guessesLeft} guesses left`, 'red'); 69 | } 70 | } 71 | }); 72 | 73 | // Game over 74 | function gameOver(won, msg) { 75 | let color; 76 | color = won ? 'green' : 'red'; 77 | 78 | // Disable input 79 | guessInput.disabled = true; 80 | // Change border color 81 | guessInput.style.borderColor = color; 82 | // Set message 83 | setMessage(msg, color); 84 | 85 | // Play Again? 86 | guessBtn.value = 'Play Again'; 87 | guessBtn.className = 'play-again'; 88 | } 89 | 90 | // Get Winning Number 91 | function getRandomNum(min, max) { 92 | return Math.floor((Math.random(min, max) * (max - min + 1) + min)); 93 | } 94 | 95 | // Set message 96 | function setMessage(msg, color) { 97 | message.style.color = color; 98 | message.textContent = msg; 99 | } -------------------------------------------------------------------------------- /section-4/number-guesser/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Number Guesser 9 | 10 | 11 |
    12 |

    Number Guesser

    13 |
    14 |

    Guess a number between and

    15 | 16 | 17 |

    18 |
    19 |
    20 | 21 | 22 | -------------------------------------------------------------------------------- /section-4/task-list/app.js: -------------------------------------------------------------------------------- 1 | // Define UI Vars 2 | const form = document.getElementById('task-form'); 3 | const taskList = document.getElementsByClassName('collection')[0]; 4 | const clearBtn = document.getElementsByClassName('clear-tasks')[0]; 5 | const filter = document.getElementById('filter'); 6 | const taskInput = document.getElementById('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 22 | filter.addEventListener('keyup', filterTasks); 23 | } 24 | 25 | // Get Tasks from LS 26 | function getTasks() { 27 | let tasks; 28 | 29 | if(localStorage.getItem('tasks') === null){ 30 | tasks = []; 31 | } else { 32 | tasks = JSON.parse(localStorage.getItem('tasks')); 33 | } 34 | 35 | tasks.forEach(function(task){ 36 | // Create li element 37 | const li = document.createElement('li'); 38 | // Add class 39 | li.className = 'collection-item'; 40 | // Create text node and append to li 41 | li.appendChild(document.createTextNode(task)); 42 | //Create new link element 43 | const link = document.createElement('a'); 44 | // Add class 45 | link.className = 'delete-item secondary-content'; 46 | // Add icon html 47 | link.innerHTML = ''; 48 | // Append the link to li 49 | li.appendChild(link); 50 | 51 | // Append li to ul 52 | taskList.appendChild(li); 53 | }); 54 | } 55 | 56 | // Add Task 57 | function addTask(e) { 58 | e.preventDefault(); 59 | 60 | if(taskInput.value === '') { 61 | alert('Add a task'); 62 | } 63 | 64 | // Create li element 65 | const li = document.createElement('li'); 66 | // Add class 67 | li.className = 'collection-item'; 68 | // Create text node and append to li 69 | li.appendChild(document.createTextNode(taskInput.value)); 70 | //Create new link element 71 | const link = document.createElement('a'); 72 | // Add class 73 | link.className = 'delete-item secondary-content'; 74 | // Add icon html 75 | link.innerHTML = ''; 76 | // Append the link to li 77 | li.appendChild(link); 78 | 79 | // Append li to ul 80 | taskList.appendChild(li); 81 | 82 | // Store in LS 83 | storeTaskInLocalStorage(taskInput.value); 84 | 85 | // Clear input 86 | taskInput.value = ''; 87 | } 88 | 89 | // Store Task 90 | function storeTaskInLocalStorage(task) { 91 | let tasks; 92 | 93 | if(localStorage.getItem('tasks') === null){ 94 | tasks = []; 95 | } else { 96 | tasks = JSON.parse(localStorage.getItem('tasks')); 97 | } 98 | tasks.push(task); 99 | 100 | localStorage.setItem('tasks', JSON.stringify(tasks)); 101 | } 102 | 103 | // Remove task 104 | function removeTask(e) { 105 | if(e.target.parentElement.classList.contains('delete-item')) { 106 | if(confirm('Are You Sure?')) { 107 | e.target.parentElement.parentElement.remove(); 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 | 118 | if(localStorage.getItem('tasks') === null){ 119 | tasks = []; 120 | } else { 121 | tasks = JSON.parse(localStorage.getItem('tasks')); 122 | } 123 | 124 | tasks.forEach(function(task, index){ 125 | if(task === taskItem.textContent) { 126 | tasks.splice(index, 1); 127 | } 128 | }); 129 | 130 | localStorage.setItem('tasks', JSON.stringify(tasks)); 131 | } 132 | 133 | // Clear Tasks 134 | function clearTasks() { 135 | // Slower 136 | // taskList.innerHTML = ''; 137 | 138 | // Faster 139 | while(taskList.firstChild) { 140 | taskList.removeChild(taskList.firstChild); 141 | } 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 | 165 | } -------------------------------------------------------------------------------- /section-4/task-list/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Task List 10 | 11 | 12 |
    13 |
    14 |
    15 |
    16 |
    17 | Task List 18 |
    19 |
    20 |
    21 | 22 | 23 |
    24 | 25 |
    26 |
    27 |
    28 |
    29 |
    Tasks
    30 |
    31 | 32 | 33 |
    34 |
      35 | Clear Tasks 36 |
      37 |
      38 |
      39 |
      40 |
      41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /section-5/built-in-constructors.js: -------------------------------------------------------------------------------- 1 | // Strings 2 | 3 | const name1 = 'Jeff'; // String 4 | const name2 = new String('Jeff'); // Object 5 | 6 | // name2.foo = 'bar'; 7 | // console.log(name1,name2); 8 | 9 | console.log(typeof name1, typeof name2); 10 | 11 | if(name2 === 'Jeff') { 12 | console.log('YES'); 13 | } else { 14 | console.log('NO'); 15 | } 16 | 17 | // Number 18 | const num1 = 5; // Number 19 | const num2 = new Number(5); // Object 20 | 21 | console.log(num1, num2); 22 | 23 | //Boolean 24 | const bool1 = true; // Boolean 25 | const bool2 = new Boolean(true); // Object 26 | 27 | console.log(typeof bool1, typeof bool2); 28 | 29 | // Function 30 | const getSum1 = function(x, y) { 31 | return x + y; 32 | } 33 | 34 | const getSum2 = new Function('x','y', 'return 1 + 1'); 35 | 36 | console.log(getSum2(1,1)); 37 | 38 | // Object 39 | const john1 = {name: 'John'} 40 | const john2 = new Object({name: 'John'}); 41 | console.log(john1); 42 | 43 | // Arrays 44 | const arr1 = [1,2,3,4]; 45 | const arr2 = new Array(1,2,3,4); 46 | 47 | console.log(arr1, arr2); 48 | 49 | // Regular Expressions 50 | const re1 = /\w+/; 51 | const re2 = new RegExp('\\w+'); 52 | 53 | console.log(re1,re2); -------------------------------------------------------------------------------- /section-5/constructor-and-this-keyword.js: -------------------------------------------------------------------------------- 1 | // Person constructor 2 | function Person(name, dob) { 3 | this.name = name; 4 | // this.age = age; 5 | this.birthday = new Date(dob); 6 | this.getAge = function() { 7 | const diff = Date.now() - this.birthday.getTime(); 8 | const ageDate = new Date(diff); 9 | return Math.abs(ageDate.getUTCFullYear() - 1970); 10 | } 11 | } 12 | 13 | // const brad = new Person('Brad', 36); 14 | // const john = new Person('John', 30); 15 | 16 | // console.log(brad); 17 | // console.log(john); 18 | 19 | const brad = new Person('Brad', '9-10-1981'); 20 | console.log(brad.getAge()); -------------------------------------------------------------------------------- /section-5/es6-class-inheritance.js: -------------------------------------------------------------------------------- 1 | class Person { 2 | constructor(firstName, lastName) { 3 | this.firstName = firstName; 4 | this.lastName = lastName; 5 | } 6 | 7 | greeting() { 8 | return `Hello there ${this.firstName} ${this.lastName}`; 9 | } 10 | } 11 | 12 | 13 | class Customer extends Person { 14 | constructor(firstName, lastName, phone, membership) { 15 | super(firstName,lastName); 16 | 17 | this.phone = phone; 18 | this.membership = membership; 19 | } 20 | 21 | static getMembershipCost() { 22 | return 500; 23 | } 24 | } 25 | 26 | const john = new Customer('John', 'Doe', '555-555-5555', 'Standard'); 27 | console.log(john); 28 | console.log(john.greeting()); 29 | console.log(Customer.getMembershipCost()); -------------------------------------------------------------------------------- /section-5/es6-class.js: -------------------------------------------------------------------------------- 1 | class Person { 2 | constructor(firstName, lastName, dob) { 3 | this.firstName = firstName; 4 | this.lastName = lastName; 5 | this.birthday = new Date(dob); 6 | } 7 | 8 | greeting() { 9 | return `Hello there ${this.firstName} ${this.lastName}`; 10 | } 11 | 12 | calculateAge() { 13 | const diff = Date.now() - this.birthday.getTime(); 14 | const ageDate = new Date(diff); 15 | return Math.abs(ageDate.getUTCFullYear() - 1970); 16 | } 17 | 18 | getsMarried(newLastName) { 19 | this.lastName = newLastName; 20 | } 21 | 22 | static addNumbers(x, y) { 23 | return x + y; 24 | } 25 | } 26 | 27 | const mary = new Person('Mary', 'Williams', '11-13-1980'); 28 | console.log(mary); 29 | console.log(mary.greeting()); 30 | console.log(mary.calculateAge()); 31 | mary.getsMarried('Thompson'); 32 | console.log(mary); 33 | console.log(Person.addNumbers(1, 2)); -------------------------------------------------------------------------------- /section-5/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-5/object-create.js: -------------------------------------------------------------------------------- 1 | const personPrototypes = { 2 | greeting: function() { 3 | return `Hello there ${this.firstName} ${this.lastName}`; 4 | }, 5 | getsMarried: function(newLastName) { 6 | this.LastName = newLastName; 7 | } 8 | } 9 | 10 | const mary = Object.create(personPrototypes); 11 | mary.firstName = 'Mary'; 12 | mary.lastName = 'Williams'; 13 | mary.age = 30; 14 | mary.getsMarried('Thompson'); 15 | console.log(mary); 16 | console.log(mary.greeting()); 17 | 18 | const brad = Object.create(personPrototypes, { 19 | firstName: {value: 'Brad'}, 20 | lastName: {value: 'Traversy'}, 21 | age: {value: 36} 22 | }); 23 | console.log(brad); 24 | console.log(brad.greeting()); -------------------------------------------------------------------------------- /section-5/prototype-inheritance.js: -------------------------------------------------------------------------------- 1 | // Person constructor 2 | function Person(firstName, lastName) { 3 | this.firstName = firstName; 4 | this.lastName = lastName; 5 | } 6 | // Greeting 7 | Person.prototype.greeting = function() { 8 | return `Hello there ${this.firstName} ${this.lastName}`; 9 | } 10 | // Create Person 11 | const person1 = new Person('John', 'Doe'); 12 | console.log(person1.greeting()); 13 | 14 | 15 | // Customer constructor 16 | function Customer(firstName, lastName, phone, membership) { 17 | Person.call(this, firstName, lastName); 18 | 19 | this.phone = phone; 20 | this.membership = membership; 21 | } 22 | // Customer greeting 23 | Customer.prototype.greeting = function () { 24 | return `Hello there ${this.firstName} ${this.lastName} welcome to our company`; 25 | } 26 | // Inherit the Person prototype methods 27 | Customer.prototype = Object.create(Person.prototype); 28 | // Make Customer.prototype return Customer() 29 | Customer.prototype.constructor = Customer; 30 | // Create customer 31 | const customer1 = new Customer('Tom', 'Smith', '555-555-55555', 'Standard'); 32 | console.log(customer1); 33 | console.log(customer1.greeting()); 34 | -------------------------------------------------------------------------------- /section-5/prototype.js: -------------------------------------------------------------------------------- 1 | // Object.prototype 2 | // Person.prototype 3 | 4 | // Person constructor 5 | function Person(firstName, lastName, dob) { 6 | this.firstName = firstName; 7 | this.lastName = lastName; 8 | this.birthday = new Date(dob); 9 | // this.calculateAge = function() { 10 | // const diff = Date.now() - this.birthday.getTime(); 11 | // const ageDate = new Date(diff); 12 | // return Math.abs(ageDate.getUTCFullYear() - 1970); 13 | // } 14 | } 15 | 16 | // Calculate age 17 | Person.prototype.calculateAge = function() { 18 | const diff = Date.now() - this.birthday.getTime(); 19 | const ageDate = new Date(diff); 20 | return Math.abs(ageDate.getUTCFullYear() - 1970); 21 | } 22 | 23 | // Get full name 24 | Person.prototype.getFullName = function() { 25 | return `${this.firstName} ${this.lastName}`; 26 | } 27 | 28 | // Gets Married 29 | Person.prototype.getsMarried = function(newLastName) { 30 | this.lastName = newLastName; 31 | } 32 | 33 | const john = new Person('John', 'Doe', '8-12-90'); 34 | const mary = new Person('Mary', 'Johnson', 'March 20 1978'); 35 | 36 | console.log(mary); 37 | console.log(john.calculateAge()); 38 | console.log(mary.getFullName()); 39 | console.log(mary.getsMarried('Smith')); 40 | console.log(mary.getFullName()); 41 | console.log(mary.hasOwnProperty('firstName')); 42 | console.log(mary.hasOwnProperty('getFullName')); -------------------------------------------------------------------------------- /section-7/exercise-1/app.js: -------------------------------------------------------------------------------- 1 | document.getElementById('button').addEventListener('click', loadData); 2 | 3 | function loadData() { 4 | // Create an XHR Object 5 | const xhr = new XMLHttpRequest(); 6 | 7 | // OPEN 8 | xhr.open('GET', 'data.txt', true); 9 | 10 | console.log('READYSTATE', xhr.readyState); 11 | 12 | // Optional - Used for spinners/loaders (readyState in stage 3) 13 | xhr.onprogress = function() { 14 | console.log('READYSTATE', xhr.readyState); 15 | }; 16 | 17 | // HTTP Statuses 18 | // 200: 'OK' 19 | // 403: 'Forbidden' 20 | // 404: 'Not Found' 21 | // ------------------ 22 | // readyState Values 23 | // 0: request not initialized 24 | // 1: server connection established 25 | // 2: request received 26 | // 3: processing request 27 | // 4: request finished and response is ready 28 | // Newest version, not needed to check readyState, aways in readyState 4 29 | xhr.onload = function() { 30 | console.log('READYSTATE', xhr.readyState); 31 | if(this.status === 200) { 32 | // console.log(this.responseText); 33 | document.getElementById('output').innerHTML = `

      ${this.responseText}

      `; 34 | } 35 | } 36 | 37 | // Older version 38 | /* 39 | xhr.onreadystatechange = function() { 40 | console.log('READYSTATE', xhr.readyState); 41 | if(this.status === 200 && this.readyState === 4) { 42 | console.log(this.responseText); 43 | } 44 | } 45 | */ 46 | 47 | // Check for errors 48 | xhr.onerror = function() { 49 | console.log('Request error...'); 50 | } 51 | 52 | // Send the request 53 | xhr.send(); 54 | } -------------------------------------------------------------------------------- /section-7/exercise-1/data.txt: -------------------------------------------------------------------------------- 1 | Um arquivo de texto padrão -------------------------------------------------------------------------------- /section-7/exercise-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Ajax Sandbox 9 | 10 | 11 |
      12 | 13 |
      14 |
      15 |
      16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /section-7/exercise-10/app.js: -------------------------------------------------------------------------------- 1 | const http = new EasyHTTP(); 2 | 3 | // Get Users 4 | // http.get('https://jsonplaceholder.typicode.com/users') 5 | // .then(data => console.log(data)) 6 | // .catch(err => console.error(err)); 7 | 8 | // User Data 9 | // const data = { 10 | // name: 'John Doe', 11 | // username: 'johndoe', 12 | // email: 'jdoe@gmail.com' 13 | // }; 14 | 15 | // Create Post 16 | // http.post('https://jsonplaceholder.typicode.com/users', data) 17 | // .then(data => console.log(data)) 18 | // .catch(err => console.error(err)); 19 | 20 | // Update Post 21 | // http.put('https://jsonplaceholder.typicode.com/users/2', data) 22 | // .then(data => console.log(data)) 23 | 24 | // Delete User 25 | // http.delete('https://jsonplaceholder.typicode.com/users/2') 26 | // .then(data => console.log(data)) 27 | // .catch(err => console.error(err)); -------------------------------------------------------------------------------- /section-7/exercise-10/easyhttp2.js: -------------------------------------------------------------------------------- 1 | /** 2 | * EasyHTTP Library 3 | * Library for making HTTP requests 4 | * 5 | * @version 2.0.0 6 | * @author Lucas Floriani 7 | * @license MIT 8 | * 9 | */ 10 | 11 | class EasyHTTP { 12 | // Make an HTTP GET Request 13 | get(url) { 14 | return new Promise((resolve, reject) => { 15 | fetch(url) 16 | .then(res => res.json()) 17 | .then(data => resolve(data)) 18 | .catch(err => reject(err)) 19 | }); 20 | } 21 | 22 | // Make an HTTP POST Request 23 | post(url, data) { 24 | return new Promise((resolve, reject) => { 25 | fetch(url, { 26 | method: 'POST', 27 | headers: { 28 | 'Content-type': 'application/json' 29 | }, 30 | body: JSON.stringify(data) 31 | }) 32 | .then(res => res.json()) 33 | .then(data => resolve(data)) 34 | .catch(err => reject(err)) 35 | }); 36 | } 37 | 38 | // Make an HTTP Put Request 39 | put(url, data) { 40 | return new Promise((resolve, reject) => { 41 | fetch(url, { 42 | method: 'PUT', 43 | headers: { 44 | 'Content-type': 'application/json' 45 | }, 46 | body: JSON.stringify(data) 47 | }) 48 | .then(res => res.json()) 49 | .then(data => resolve(data)) 50 | .catch(err => reject(err)) 51 | }); 52 | } 53 | 54 | // Make an HTTP DELETE Request 55 | delete(url) { 56 | return new Promise((resolve, reject) => { 57 | fetch(url, { 58 | method: 'DELETE', 59 | headers: { 60 | 'Content-type': 'application/json' 61 | } 62 | }) 63 | .then(res => res.json()) 64 | .then(() => resolve('Resource Deleted...')) 65 | .catch(err => reject(err)) 66 | }); 67 | } 68 | } -------------------------------------------------------------------------------- /section-7/exercise-10/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | EasyHTTP2 Example 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /section-7/exercise-11/app.js: -------------------------------------------------------------------------------- 1 | // async function myFunc() { 2 | // const promise = new Promise((resolve, reject) => { 3 | // setTimeout(() => resolve('Hello'), 1000); 4 | // }); 5 | 6 | // const error = false; 7 | 8 | // if(!error) { 9 | // // Wait until promise is resolved 10 | // const res = await promise; 11 | // return res; 12 | // } else { 13 | // await Promise.reject(new Error('Something went wrong')); 14 | // } 15 | // } 16 | 17 | // myFunc() 18 | // .then(res => console.log(res)) 19 | // .catch(err => console.error(err)); 20 | 21 | async function getUsers() { 22 | // await response of the fetch call 23 | const response = await fetch('https://jsonplaceholder.typicode.com/users'); 24 | 25 | // Only proceed once its resolved 26 | const data = await response.json(); 27 | 28 | // Only proceed once the second promise is resolved 29 | return data; 30 | } 31 | 32 | 33 | getUsers() 34 | .then(users => console.log(users)); -------------------------------------------------------------------------------- /section-7/exercise-11/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-7/exercise-12/app.js: -------------------------------------------------------------------------------- 1 | const http = new EasyHTTP(); 2 | 3 | // Get Users 4 | // http.get('https://jsonplaceholder.typicode.com/users') 5 | // .then(data => console.log(data)) 6 | // .catch(err => console.error(err)); 7 | 8 | // User Data 9 | // const data = { 10 | // name: 'John Doe', 11 | // username: 'johndoe', 12 | // email: 'jdoe@gmail.com' 13 | // }; 14 | 15 | // Create Post 16 | // http.post('https://jsonplaceholder.typicode.com/users', data) 17 | // .then(data => console.log(data)) 18 | // .catch(err => console.error(err)); 19 | 20 | // Update Post 21 | // http.put('https://jsonplaceholder.typicode.com/users/2', data) 22 | // .then(data => console.log(data)) 23 | 24 | // Delete User 25 | // http.delete('https://jsonplaceholder.typicode.com/users/2') 26 | // .then(data => console.log(data)) 27 | // .catch(err => console.error(err)); -------------------------------------------------------------------------------- /section-7/exercise-12/easyhttp3.js: -------------------------------------------------------------------------------- 1 | /** 2 | * EasyHTTP Library 3 | * Library for making HTTP requests 4 | * 5 | * @version 3.0.0 6 | * @author Lucas Floriani 7 | * @license MIT 8 | * 9 | */ 10 | 11 | class EasyHTTP { 12 | // Make an HTTP GET Request 13 | async get(url) { 14 | const response = await fetch(url); 15 | 16 | const resData = await response.json(); 17 | 18 | return resData; 19 | } 20 | 21 | // Make an HTTP POST Request 22 | async post(url, data) { 23 | const response = await fetch(url, { 24 | method: 'POST', 25 | headers: { 26 | 'Content-type': 'application/json' 27 | }, 28 | body: JSON.stringify(data) 29 | }) 30 | 31 | const resData = await response.json() 32 | 33 | return resData; 34 | } 35 | 36 | // Make an HTTP Put Request 37 | async put(url, data) { 38 | const response = await fetch(url, { 39 | method: 'PUT', 40 | headers: { 41 | 'Content-type': 'application/json' 42 | }, 43 | body: JSON.stringify(data) 44 | }) 45 | 46 | const resData = await response.json() 47 | 48 | return resData; 49 | } 50 | 51 | // Make an HTTP DELETE Request 52 | async delete(url) { 53 | const response = await fetch(url, { 54 | method: 'DELETE', 55 | headers: { 56 | 'Content-type': 'application/json' 57 | } 58 | }); 59 | 60 | const resData = await 'Resource Deleted...'; 61 | 62 | return resData; 63 | } 64 | } -------------------------------------------------------------------------------- /section-7/exercise-12/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | EasyHTTP3 Example 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /section-7/exercise-2/app.js: -------------------------------------------------------------------------------- 1 | document.getElementById('button1').addEventListener('click', loadCustomer); 2 | document.getElementById('button2').addEventListener('click', loadCustomers); 3 | 4 | // Load Customer 5 | function loadCustomer(e) { 6 | const xhr = new XMLHttpRequest(); 7 | 8 | xhr.open('GET', 'customer.json', true); 9 | 10 | xhr.onload = function() { 11 | if(this.status === 200) { 12 | // console.log(this.responseText); 13 | 14 | const customer = JSON.parse(this.responseText); 15 | 16 | const output = ` 17 | 23 | `; 24 | 25 | document.getElementById('customer').innerHTML = output; 26 | } 27 | } 28 | 29 | xhr.send(); 30 | } 31 | 32 | 33 | // Load Customers 34 | function loadCustomers(e) { 35 | const xhr = new XMLHttpRequest(); 36 | 37 | xhr.open('GET', 'customers.json', true); 38 | 39 | xhr.onload = function() { 40 | if(this.status === 200) { 41 | // console.log(this.responseText); 42 | 43 | const customers = JSON.parse(this.responseText); 44 | 45 | let output = ''; 46 | 47 | customers.forEach(function(customer) { 48 | output += ` 49 | 55 | `; 56 | }); 57 | 58 | document.getElementById('customers').innerHTML = output; 59 | } 60 | } 61 | 62 | xhr.send(); 63 | } -------------------------------------------------------------------------------- /section-7/exercise-2/customer.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": 1, 3 | "name": "John Doe", 4 | "company": "123 Designs", 5 | "phone": "444-555-6666" 6 | } -------------------------------------------------------------------------------- /section-7/exercise-2/customers.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": 1, 4 | "name": "John Doe", 5 | "company": "123 Designs", 6 | "phone": "444-555-6666" 7 | }, 8 | { 9 | "id": 2, 10 | "name": "Steve Smith", 11 | "company": "Hello Productions", 12 | "phone": "333-222-2222" 13 | }, 14 | { 15 | "id": 3, 16 | "name": "Tara Williams", 17 | "company": "Traversy Media", 18 | "phone": "111-222-3333" 19 | } 20 | ] -------------------------------------------------------------------------------- /section-7/exercise-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Ajax Sandbox 9 | 10 | 11 |
      12 | 13 | 14 |

      15 |

      Customer

      16 |
      17 |

      Customers

      18 |
      19 |
      20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /section-7/exercise-3/app.js: -------------------------------------------------------------------------------- 1 | document.querySelector('.get-jokes').addEventListener('click', getJokes); 2 | 3 | function getJokes(e) { 4 | const number = document.querySelector('input[type="number"]').value; 5 | const numberValue = number === '' ? 1 : number; 6 | 7 | const xhr = new XMLHttpRequest(); 8 | 9 | xhr.open('GET', `http://api.icndb.com/jokes/random/${numberValue}`, true); 10 | 11 | xhr.onload = function() { 12 | if(this.status === 200) { 13 | const response = JSON.parse(this.responseText); 14 | 15 | let output = ''; 16 | 17 | if(response.type === 'success') { 18 | response.value.forEach(function(joke) { 19 | output += `
    • ${joke.joke}
    • `; 20 | }); 21 | } else { 22 | output += '
    • Something went wrong
    • '; 23 | } 24 | 25 | document.querySelector('.jokes').innerHTML = output; 26 | } 27 | } 28 | 29 | xhr.send(); 30 | 31 | e.preventDefault(); 32 | } -------------------------------------------------------------------------------- /section-7/exercise-3/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Chuck Norris Joke Generator 9 | 10 | 11 |
      12 |

      Chuck Norris Joke Generator

      13 |
      14 |
      15 | 16 | 17 |
      18 |
      19 | 20 |
      21 |
      22 | 23 |
      24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /section-7/exercise-4/app.js: -------------------------------------------------------------------------------- 1 | const posts = [ 2 | { 3 | title: 'Post One', 4 | body: 'This is post one' 5 | }, 6 | { 7 | title: 'Post Two', 8 | body: 'This is post two' 9 | } 10 | ]; 11 | 12 | // function createPost(post) { 13 | // setTimeout(function() { 14 | // posts.push(post) 15 | // }, 2000); 16 | // } 17 | 18 | // function getPosts() { 19 | // setTimeout(function() { 20 | // let output = ''; 21 | // posts.forEach(function(post) { 22 | // output += `
    • ${post.title}
    • `; 23 | // }); 24 | // document.body.innerHTML = output; 25 | // }, 1000); 26 | // } 27 | 28 | // createPost({title: 'Post Three', body: 'This is post three'}); 29 | 30 | // getPosts(); 31 | 32 | 33 | function createPost(post, callback) { 34 | setTimeout(function() { 35 | posts.push(post) 36 | callback(); 37 | }, 2000); 38 | } 39 | 40 | function getPosts() { 41 | setTimeout(function() { 42 | let output = ''; 43 | posts.forEach(function(post) { 44 | output += `
    • ${post.title}
    • `; 45 | }); 46 | document.body.innerHTML = output; 47 | }, 1000); 48 | } 49 | 50 | createPost({title: 'Post Three', body: 'This is post three'}, getPosts); -------------------------------------------------------------------------------- /section-7/exercise-4/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Ajax Sandbox 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-7/exercise-5/app.js: -------------------------------------------------------------------------------- 1 | const http = new easyHTTP; 2 | 3 | // Get Posts 4 | // http.get('https://jsonplaceholder.typicode.com/posts', function (err, posts) { 5 | // if(err) { 6 | // console.log(err); 7 | // } else { 8 | // console.log(posts); 9 | // } 10 | // }); 11 | 12 | // Get Single Post 13 | // http.get('https://jsonplaceholder.typicode.com/posts/1', function (err, post) { 14 | // if(err) { 15 | // console.log(err); 16 | // } else { 17 | // console.log(post); 18 | // } 19 | // }); 20 | 21 | // Create Data 22 | const data = { 23 | title: 'Custom Post', 24 | body: 'This is a custom post' 25 | }; 26 | 27 | // Create Post 28 | // http.post('https://jsonplaceholder.typicode.com/posts', data, function(err, post) { 29 | // if(err) { 30 | // console.log(err); 31 | // } else { 32 | // console.log(post); 33 | // } 34 | // }) 35 | 36 | // Update Post 37 | // http.put('https://jsonplaceholder.typicode.com/posts/1', data, function(err, post) { 38 | // if(err) { 39 | // console.log(err); 40 | // } else { 41 | // console.log(post); 42 | // } 43 | // }) 44 | 45 | // Delete Post 46 | http.delete('https://jsonplaceholder.typicode.com/posts/1', function(err, response) { 47 | if(err) { 48 | console.log(err); 49 | } else { 50 | console.log(response); 51 | } 52 | }) 53 | -------------------------------------------------------------------------------- /section-7/exercise-5/easyhttp.js: -------------------------------------------------------------------------------- 1 | function easyHTTP() { 2 | this.http = new XMLHttpRequest(); 3 | } 4 | 5 | // Make an HTTP GET Request 6 | easyHTTP.prototype.get = function (url, callback) { 7 | this.http.open('GET', url, true); 8 | 9 | this.http.onload = function() { 10 | if(this.status === 200) { 11 | callback(null, this.responseText); 12 | } else { 13 | callback(`Error: ${this.status}`); 14 | } 15 | } 16 | 17 | this.http.send(); 18 | } 19 | 20 | // Make an HTTP POST Request 21 | easyHTTP.prototype.post = function (url, data, callback) { 22 | this.http.open('POST', url, true); 23 | this.http.setRequestHeader('Content-type', 'application/json'); 24 | 25 | this.http.onload = function() { 26 | callback(null, this.responseText); 27 | } 28 | 29 | this.http.send(JSON.stringify(data)); 30 | } 31 | 32 | // Make an HTTP PUT Request 33 | easyHTTP.prototype.put = function (url, data, callback) { 34 | this.http.open('PUT', url, true); 35 | this.http.setRequestHeader('Content-type', 'application/json'); 36 | 37 | this.http.onload = function() { 38 | callback(null, this.responseText); 39 | } 40 | 41 | this.http.send(JSON.stringify(data)); 42 | } 43 | 44 | // Make an HTTP DELETE Request 45 | easyHTTP.prototype.delete = function (url, callback) { 46 | this.http.open('DELETE', url, true); 47 | 48 | this.http.onload = function() { 49 | if(this.status === 200) { 50 | callback(null,'Post deleted'); 51 | } else { 52 | callback(`Error: ${this.status}`); 53 | } 54 | } 55 | 56 | this.http.send(); 57 | } -------------------------------------------------------------------------------- /section-7/exercise-5/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | EasyHTTP Example 8 | 9 | 10 |

      EasyHTTP Example

      11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /section-7/exercise-6/es6-promise.js: -------------------------------------------------------------------------------- 1 | const posts = [ 2 | { 3 | title: 'Post One', 4 | body: 'This is post one' 5 | }, 6 | { 7 | title: 'Post Two', 8 | body: 'This is post two' 9 | } 10 | ]; 11 | 12 | function createPost(post) { 13 | return new Promise(function(resolve, reject) { 14 | setTimeout(function() { 15 | posts.push(post); 16 | 17 | const error = true; 18 | 19 | if(!error) { 20 | resolve(); 21 | } else { 22 | reject('Error: Something went wrong'); 23 | } 24 | }, 2000); 25 | }); 26 | } 27 | 28 | function getPosts() { 29 | setTimeout(function() { 30 | let output = ''; 31 | posts.forEach(function(post) { 32 | output += `
    • ${post.title}
    • `; 33 | }); 34 | document.body.innerHTML = output; 35 | }, 1000); 36 | } 37 | 38 | createPost({title: 'Post Three', body: 'This is post three'}) 39 | .then(getPosts) 40 | .catch(function(err) { 41 | console.log(err); 42 | }).finally(function() { 43 | console.log('Get posts finished'); 44 | }); -------------------------------------------------------------------------------- /section-7/exercise-6/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-7/exercise-7/app.js: -------------------------------------------------------------------------------- 1 | document.getElementById('button1').addEventListener('click', getText); 2 | // Get local text file data 3 | function getText() { 4 | fetch('test.txt') 5 | .then(function(res) { 6 | return res.text(); 7 | }) 8 | .then(function(data) { 9 | console.log(data); 10 | document.getElementById('output').innerHTML = data; 11 | }) 12 | .catch(function(err) { 13 | console.error(err); 14 | }); 15 | } 16 | 17 | document.getElementById('button2').addEventListener('click', getJson); 18 | // Get local json data 19 | function getJson() { 20 | fetch('posts.json') 21 | .then(function(res) { 22 | return res.json(); 23 | }) 24 | .then(function(data) { 25 | console.log(data); 26 | let output = ''; 27 | data.forEach(function(post) { 28 | output += `
    • ${post.title}
    • `; 29 | }); 30 | document.getElementById('output').innerHTML = output; 31 | }) 32 | .catch(function(err) { 33 | console.error(err); 34 | }); 35 | } 36 | 37 | document.getElementById('button3').addEventListener('click', getExternal); 38 | // Get from external API 39 | function getExternal() { 40 | fetch('https://api.github.com/users') 41 | .then(function(res) { 42 | return res.json(); 43 | }) 44 | .then(function(data) { 45 | console.log(data); 46 | let output = ''; 47 | data.forEach(function(user) { 48 | output += `
    • ${user.login}
    • `; 49 | }); 50 | document.getElementById('output').innerHTML = output; 51 | }) 52 | .catch(function(err) { 53 | console.error(err); 54 | }); 55 | } -------------------------------------------------------------------------------- /section-7/exercise-7/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Ajax Sandbox 9 | 10 | 11 |
      12 |

      Fetch API Sandbox

      13 | 14 | 15 | 16 |

      17 |
      18 |
      19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /section-7/exercise-7/posts.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "Post one", 4 | "body": "This is post one" 5 | }, 6 | { 7 | "title": "Post two", 8 | "body": "This is post two" 9 | }, 10 | { 11 | "title": "Post three", 12 | "body": "This is post three" 13 | } 14 | ] -------------------------------------------------------------------------------- /section-7/exercise-7/test.txt: -------------------------------------------------------------------------------- 1 | This is a sample text file -------------------------------------------------------------------------------- /section-7/exercise-8/app.js: -------------------------------------------------------------------------------- 1 | // const sayHello = function() { 2 | // console.log('hello'); 3 | // } 4 | 5 | // const sayHello = () => { 6 | // console.log('hello'); 7 | // } 8 | 9 | // One line function does not need braces 10 | // const sayHello = () => console.log('hello'); 11 | 12 | // One line returns 13 | // const sayHello = () => 'Hello'; 14 | 15 | // Same as above 16 | // const sayHello = function() { 17 | // return 'Hello'; 18 | // } 19 | // console.log(sayHello()); 20 | 21 | // Return object 22 | //const sayHello = () => ({ msg: 'Hello'}); 23 | 24 | // Single param does not need paranthesis 25 | // const sayHello = name => console.log(`Hello ${name}`); 26 | // const sayHello = (name) => console.log(`Hello ${name}`); 27 | 28 | // Multi param needs paranthesis 29 | // const sayHello = (firstName, lastName) => console.log(`Hello ${firstName} ${lastName}`); 30 | 31 | // sayHello('Brad'); 32 | 33 | const users = ['Nathan', 'John', 'William']; 34 | 35 | // Without arrow functions 36 | // const nameLengths = users.map(function(name) { 37 | // return name.length; 38 | // }); 39 | 40 | // Shorter with arrow functions 41 | // const nameLengths = users.map(function(name) { 42 | // return name.length; 43 | // }); 44 | 45 | // Shortest version with arrow functions 46 | const nameLengths = users.map(name => name.length); 47 | 48 | console.log(nameLengths); 49 | 50 | -------------------------------------------------------------------------------- /section-7/exercise-8/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox 8 | 9 | 10 |

      Arrow Functions

      11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /section-7/exercise-9/app.js: -------------------------------------------------------------------------------- 1 | document.getElementById('button1').addEventListener('click', getText); 2 | // Get local text file data 3 | function getText() { 4 | fetch('test.txt') 5 | .then(res => res.text()) 6 | .then(data => { 7 | console.log(data); 8 | document.getElementById('output').innerHTML = data; 9 | }) 10 | .catch(err => console.error(err)); 11 | } 12 | 13 | document.getElementById('button2').addEventListener('click', getJson); 14 | // Get local json data 15 | function getJson() { 16 | fetch('posts.json') 17 | .then(res => res.json()) 18 | .then(data => { 19 | console.log(data); 20 | let output = ''; 21 | data.forEach(post => { 22 | output += `
    • ${post.title}
    • `; 23 | }); 24 | document.getElementById('output').innerHTML = output; 25 | }) 26 | .catch(err =>console.error(err)); 27 | } 28 | 29 | document.getElementById('button3').addEventListener('click', getExternal); 30 | // Get from external API 31 | function getExternal() { 32 | fetch('https://api.github.com/users') 33 | .then(res => res.json()) 34 | .then(data => { 35 | console.log(data); 36 | let output = ''; 37 | data.forEach(user => { 38 | output += `
    • ${user.login}
    • `; 39 | }); 40 | document.getElementById('output').innerHTML = output; 41 | }) 42 | .catch(err => console.error(err)); 43 | } -------------------------------------------------------------------------------- /section-7/exercise-9/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | Ajax Sandbox 9 | 10 | 11 |
      12 |

      Fetch API Sandbox

      13 | 14 | 15 | 16 |

      17 |
      18 |
      19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /section-7/exercise-9/posts.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "title": "Post one", 4 | "body": "This is post one" 5 | }, 6 | { 7 | "title": "Post two", 8 | "body": "This is post two" 9 | }, 10 | { 11 | "title": "Post three", 12 | "body": "This is post three" 13 | } 14 | ] -------------------------------------------------------------------------------- /section-7/exercise-9/test.txt: -------------------------------------------------------------------------------- 1 | This is a sample text file -------------------------------------------------------------------------------- /section-8/githubfinder/app.js: -------------------------------------------------------------------------------- 1 | // Init GitHub 2 | const github = new GitHub(); 3 | // Init Ui 4 | const ui = new UI(); 5 | 6 | // Search input 7 | const searchUser = document.getElementById('searchUser'); 8 | 9 | // Search input event listener 10 | searchUser.addEventListener('keyup', (e) => { 11 | // Get input text 12 | const userText = e.target.value; 13 | 14 | if(userText !== '') { 15 | // Make http call 16 | github.getUser(userText) 17 | .then(data => { 18 | if(data.profile.message === 'Not Found') { 19 | // Show alert 20 | ui.showAlert('User not found', 'alert alert-danger'); 21 | } else { 22 | // Show profile 23 | ui.showProfile(data.profile); 24 | ui.showRepos(data.repos); 25 | } 26 | }); 27 | } else { 28 | // Clear profile 29 | ui.clearProfile(); 30 | } 31 | }); -------------------------------------------------------------------------------- /section-8/githubfinder/github.js: -------------------------------------------------------------------------------- 1 | class GitHub { 2 | constructor() { 3 | this.client_id = 'add64605a67c0116a861'; 4 | this.client_secret = 'f546e9575c515e6f0b97cea744cfd42f4a0e2003'; 5 | this.repos_count = 5; 6 | this.repos_sort = 'created: asc'; 7 | } 8 | 9 | async getUser(user) { 10 | const profileUrl = `https://api.github.com/users/${user}?client_id=${this.client_id}&client_secret=${this.client_secret}`; 11 | const profileResponse = await fetch(profileUrl); 12 | 13 | const repoUrl = `https://api.github.com/users/${user}/repos?per_page=${this.repos_count}&sort=${this.repos_sort}&client_id=${this.client_id}&client_secret=${this.client_secret}`; 14 | const repoResponse = await fetch(repoUrl); 15 | 16 | const profile = await profileResponse.json(); 17 | const repos = await repoResponse.json(); 18 | 19 | return { 20 | profile, 21 | repos 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /section-8/githubfinder/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | GitHub Finder 8 | 9 | 10 | 11 | 16 |
      17 | 22 |
      23 |
      24 |
      25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /section-8/githubfinder/ui.js: -------------------------------------------------------------------------------- 1 | class UI { 2 | constructor() { 3 | this.profile = document.getElementById('profile'); 4 | } 5 | 6 | // Display profile in UI 7 | showProfile(user) { 8 | this.profile.innerHTML = ` 9 |
      10 |
      11 |
      12 | 13 | View Profile 14 |
      15 |
      16 | Public Repos: ${user.public_repos} 17 | Public Gists: ${user.public_gists} 18 | Followers: ${user.followers} 19 | Following: ${user.following} 20 |
      21 |
      22 |
        23 |
      • Company: ${user.company}
      • 24 |
      • Website/Blog: ${user.blog}
      • 25 |
      • Location: ${user.location}
      • 26 |
      • Member Since: ${user.created_at}
      • 27 |
      28 |
      29 |
      30 |
      31 |

      Latest Repos

      32 |
      33 | `; 34 | } 35 | 36 | showRepos(repos) { 37 | let output = ''; 38 | 39 | repos.forEach(repo => { 40 | output += ` 41 |
      42 |
      43 |
      44 | ${repo.name} 45 |
      46 |
      47 | Stars: ${repo.stargazers_count} 48 | Watchers: ${repo.watchers} 49 | Forks: ${repo.forks_count} 50 |
      51 |
      52 |
      53 | `; 54 | }); 55 | 56 | // Output repos 57 | document.getElementById('repos').innerHTML = output; 58 | } 59 | 60 | // Show alert message 61 | showAlert(message, className) { 62 | // Clear any remaining alerts 63 | this.clearAlert(); 64 | // Create div 65 | const div = document.createElement('div'); 66 | // Add classes 67 | div.className = className; 68 | // Add text 69 | div.appendChild(document.createTextNode(message)); 70 | // Get parent 71 | const container = document.querySelector('.searchContainer'); 72 | // Get search box 73 | const search = document.querySelector('.search'); 74 | // Insert alert 75 | container.insertBefore(div, search); 76 | 77 | // Timeout after 3 sec 78 | setTimeout(() => { 79 | this.clearAlert(); 80 | }, 3000) 81 | } 82 | 83 | // Clear alert message 84 | clearAlert() { 85 | const currentAlert = document.querySelector('.alert'); 86 | 87 | if(currentAlert) { 88 | currentAlert.remove(); 89 | } 90 | } 91 | 92 | 93 | // Clear profile 94 | clearProfile() { 95 | this.profile.innerHTML = ''; 96 | } 97 | } -------------------------------------------------------------------------------- /section-8/weatherjs/app.js: -------------------------------------------------------------------------------- 1 | // Init storage 2 | const storage = new Storage(); 3 | // Get stored location data 4 | const weatherLocation = storage.getLocationData(); 5 | 6 | // Init weather object 7 | const weather = new Weather(weatherLocation.city, weatherLocation.state); 8 | 9 | // Init UI object 10 | const ui = new UI(); 11 | 12 | // Get weather on DOM load 13 | document.addEventListener('DOMContentLoaded', getWeather); 14 | 15 | // Change location event 16 | document.getElementById('w-change-btn').addEventListener('click', (e) => { 17 | const city = document.getElementById('city').value; 18 | const state = document.getElementById('state').value; 19 | 20 | // Change location 21 | weather.changeLocation(city, state); 22 | 23 | // Set location in LS 24 | storage.setLocationData(city, state); 25 | 26 | // Get and display weather 27 | getWeather(); 28 | 29 | // Clode modal 30 | $('#locModal').modal('hide'); 31 | }) 32 | 33 | function getWeather() { 34 | weather.getWeather() 35 | .then(results => { 36 | ui.paint(results); 37 | }) 38 | .catch(err => console.error(err)); 39 | } -------------------------------------------------------------------------------- /section-8/weatherjs/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | WeatherJS 8 | 9 | 10 | 11 |
      12 |
      13 |
      14 |

      15 |

      16 |

      17 | 18 |
        19 |
      • 20 |
      • 21 |
      • 22 |
      • 23 |
      24 |
      25 | 28 |
      29 |
      30 |
      31 | 32 | 33 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /section-8/weatherjs/storage.js: -------------------------------------------------------------------------------- 1 | class Storage { 2 | constructor() { 3 | this.city; 4 | this.state; 5 | this.defaultCity = 'Miami'; 6 | this.defaultState = 'FL'; 7 | } 8 | 9 | getLocationData() { 10 | if(localStorage.getItem('city') === null) { 11 | this.city = this.defaultCity; 12 | } else { 13 | this.city = localStorage.getItem('city'); 14 | } 15 | 16 | if(localStorage.getItem('state') === null) { 17 | this.state = this.defaultState; 18 | } else { 19 | this.state = localStorage.getItem('state'); 20 | } 21 | 22 | return { 23 | city: this.city, 24 | state: this.state 25 | } 26 | } 27 | 28 | setLocationData(city, state) { 29 | localStorage.setItem('city', city); 30 | localStorage.setItem('state', state); 31 | } 32 | } -------------------------------------------------------------------------------- /section-8/weatherjs/ui.js: -------------------------------------------------------------------------------- 1 | class UI { 2 | constructor() { 3 | this.location = document.getElementById('w-location'); 4 | this.desc = document.getElementById('w-desc'); 5 | this.string = document.getElementById('w-string'); 6 | this.details = document.getElementById('w-details'); 7 | this.icon = document.getElementById('w-icon'); 8 | this.humidity = document.getElementById('w-humidity'); 9 | this.feelsLike = document.getElementById('w-feels-like'); 10 | this.dewpoint = document.getElementById('w-dewpoint'); 11 | this.wind = document.getElementById('w-wind'); 12 | } 13 | 14 | paint(weather) { 15 | this.location.textContent = weather.display_location.full; 16 | this.desc.textContent = weather.weather; 17 | this.string.textContent = weather.temperature_string; 18 | this.icon.setAttribute('src', weather.icon_url); 19 | this.humidity.textContent = `Relative Humidity: ${weather.relative_humidity}`; 20 | this.feelsLike.textContent = `Feels Like: ${weather.feelslike_string}`; 21 | this.dewpoint.textContent = `DewPoint: ${weather.dewpoint_string}`; 22 | this.wind.textContent = `Wind: ${weather.wind_string}`; 23 | } 24 | } -------------------------------------------------------------------------------- /section-8/weatherjs/weather.js: -------------------------------------------------------------------------------- 1 | class Weather { 2 | constructor(city, state) { 3 | this.apiKey = '6eee9a6a5ddd5721'; 4 | this.city = city; 5 | this.state = state; 6 | } 7 | 8 | // Fetch weather from API 9 | async getWeather() { 10 | const url = `http://api.wunderground.com/api/${this.apiKey}/conditions/q/${this.state}/${this.city}.json` 11 | const response = await fetch(url); 12 | 13 | const responseData = await response.json(); 14 | 15 | return responseData.current_observation; 16 | } 17 | 18 | // Change weather location 19 | changeLocation(city, state) { 20 | this.city = city; 21 | this.state = state; 22 | } 23 | } -------------------------------------------------------------------------------- /section-9/error-handling/app.js: -------------------------------------------------------------------------------- 1 | const user = {email: 'jdoe@gmail.com'}; 2 | 3 | try { 4 | // Produce a ReferenceError 5 | // myFunction(); 6 | 7 | // Produce a TypeError 8 | // null.myFunction(); 9 | 10 | // Will product SyntaxError 11 | // console.log(eval('Hello World')); 12 | 13 | // Will product a URIError 14 | // decodeURIComponent('%'); 15 | 16 | if(!user.name) { 17 | // throw 'User has no name'; 18 | throw new SyntaxError('User has no name'); 19 | } 20 | } catch(e) { 21 | console.log(`User Error: ${e.message}`); 22 | // console.log(e); 23 | // console.log(e.message); 24 | // console.log(e.name); 25 | // console.log(`${e.name}: ITS NULL STUPID!!!`); 26 | // console.log(e instanceof ReferenceError); 27 | // console.log(e instanceof TypeError); 28 | } finally { 29 | console.log('Finally runs reguardless of result...'); 30 | } 31 | 32 | console.log('Program continues...'); -------------------------------------------------------------------------------- /section-9/error-handling/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-9/regular-expression/exercise-1/app.js: -------------------------------------------------------------------------------- 1 | let re; 2 | re = /hello/; 3 | re = /hello/i; // i = case insensitive 4 | // re = /hello/g; // Global search 5 | 6 | 7 | // console.log(re); 8 | // console.log(re.source); 9 | 10 | // exec() - Return result in an array or null 11 | // const result = re.exec('brad hello world'); 12 | // console.log(result); 13 | // console.log(result[0]); 14 | // console.log(result.index); 15 | // console.log(result.input); 16 | 17 | // test() - Returns true or false 18 | // const result = re.test('Hello'); 19 | // console.log(result); 20 | 21 | // match() - Return result array or null 22 | // const str = 'Hello There'; 23 | // const result = str.match(re); 24 | // console.log(result); 25 | 26 | // search() - Returns index of the first match if not found returns -1 27 | // const str = 'Brad Hello There'; 28 | // const result = str.search(re); 29 | // console.log(result); 30 | 31 | // replace() - Return new string with some or all matches of a pattern 32 | // const str = 'Hello There'; 33 | // const newStr = str.replace(re, 'Hi'); 34 | // console.log(newStr); -------------------------------------------------------------------------------- /section-9/regular-expression/exercise-1/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-9/regular-expression/exercise-2/app.js: -------------------------------------------------------------------------------- 1 | let re; 2 | // Literal Characters 3 | // i = case insensitive 4 | re = /hello/; // Does not matches 'Hello World' 5 | re = /hello/i; // Matches 'Hello World' 6 | 7 | // Metacharacter Symbols 8 | // ^ = Must start with 9 | re = /^h/; // Does not match 'Hello World' 10 | re = /^h/i; // Matches 'Hello World' 11 | 12 | // $ = Must end with 13 | re = /i$/; // Does not match 'Hello World' 14 | re = /d$/; // Matches 'Hello World' 15 | re = /World$/; // Matches 'Hello World' 16 | 17 | // Combined $ and ^ to be the same regex in text 18 | re = /^hello$/; // Does not match 'Hello World' 19 | re = /^hello world$/i; // Matches 'Hello World' 20 | 21 | // . = Matches any ONE character 22 | re = /^h.llo world$/i; // Matches 'Hello World' but dont matches 'Heello World' because is only one character 23 | 24 | // * = Matches any character 0 or more times 25 | re = /h*llo world/i; // Matches 'Hello World', 'Heello World' or 'Hllo World' 26 | 27 | // ? = Optional character (grey) 28 | re = /gre?a?y/; // Matches string with grey, gray or gry 29 | 30 | // \ = Escape character (grey?) 31 | re = /gre?a?y\?/; // Matches gray?, grey? or gry? 32 | 33 | // [] = Character Sets, needs to be one of the characters in brackets (gray) 34 | re = /gr[ae]y/i; // Matches gray or grey 35 | re = /[GF]ray/; // Matches Gray or Fray 36 | re = /[^GF]ray/; // Matches anything except G or F 37 | re = /^[GF]ray/; // Matches only if starts with G or F 38 | re = /[A-Z]ray/; // Matches any uppercase Letter 39 | re = /[a-z]ray/; // Matches any lowercase Letter 40 | re = /[A-Za-z]ray/; // Matches any Letter 41 | re = /[0-9]ray/; // Matches any Digit 42 | re = /[0-3]ray/; // Matches 0,1,2,3 43 | 44 | // {} - Quantifies the character before 45 | re = /Hel{2}o/i; // Must occur exactly {m} amount of times 46 | re = /Hel{2,4}o/i; // Must occur exactly {2 to 4} amount of times 47 | re = /Hel{2,}o/i; // Must occur at least {m} times 48 | 49 | // () - Grouping 50 | re = /^([0-9]x){3}$/; // Group to matches 3 digits with 3 digits = 3x3x3x 51 | 52 | // Shorthand Character Classes 53 | re = /\w/; // \w = Word Character like alphanumeric or _ 54 | re = /\w+/; // + = one or more 55 | re = /\W/; // \w = Non-Word Character anything but alphanumeric or _ like ! 56 | re = /\d/; // Match any digit 57 | re = /\d+/; // Match any digit one or more times 58 | re = /\D/; // Match any Non-Digit character 59 | re = /\s/; // Match whitespace character like space or tab 60 | re = /\S/; // Match Non-whitespace character diferent than space or tab 61 | re = /Hell\b/i; // Word boundary, not word that has the word (Hello, welcome to Hell) 62 | 63 | // Assertions 64 | re = /x(?=y)/; // Match x only if followed by y (aosdxyhsoahsaodh) 65 | re = /x(?!y)/; // Match x only if not followed by y (aosdxhsoahsaodh) 66 | 67 | // String to match 68 | const str = 'aosdxhsoahsaodh'; 69 | 70 | 71 | // Log Results 72 | const result = re.exec(str); 73 | console.log(result); 74 | 75 | function reTest(re, str) { 76 | if(re.test(str)) { 77 | console.log(`${str} matches ${re.source}`); 78 | } else { 79 | console.log(`${str} does NOT match ${re.source}`); 80 | } 81 | } 82 | 83 | reTest(re, str); -------------------------------------------------------------------------------- /section-9/regular-expression/exercise-2/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Javascript Sandbox 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /section-9/user-form/app.js: -------------------------------------------------------------------------------- 1 | // Form Blur Event Listeners 2 | document.getElementById('name').addEventListener('blur', validateName); 3 | document.getElementById('zip').addEventListener('blur', validateZip); 4 | document.getElementById('email').addEventListener('blur', validateEmail); 5 | document.getElementById('phone').addEventListener('blur', validatePhone); 6 | 7 | function validateName() { 8 | const name = document.getElementById('name'); 9 | const re = /^[a-zA-Z]{2,10}$/; 10 | 11 | if(!re.test(name.value)) { 12 | name.classList.add('is-invalid'); 13 | } else { 14 | name.classList.remove('is-invalid'); 15 | } 16 | } 17 | 18 | function validateZip() { 19 | const zip = document.getElementById('zip'); 20 | const re = /^[0-9]{5}(-[0-9]{4})?$/; 21 | 22 | if(!re.test(zip.value)) { 23 | zip.classList.add('is-invalid'); 24 | } else { 25 | zip.classList.remove('is-invalid'); 26 | } 27 | } 28 | 29 | function validateEmail() { 30 | const email = document.getElementById('email'); 31 | const re = /^([a-zA-Z0-9_\-\.]+)@([a-zA-Z0-9_\-\.]+)\.([a-zA-Z]{2,5})$/; 32 | 33 | if(!re.test(email.value)) { 34 | email.classList.add('is-invalid'); 35 | } else { 36 | email.classList.remove('is-invalid'); 37 | } 38 | } 39 | 40 | function validatePhone() { 41 | const phone = document.getElementById('phone'); 42 | const re = /^\(?\d{3}\)?[-. ]?\d{3}[-. ]?\d{4}$/; 43 | 44 | if(!re.test(phone.value)) { 45 | phone.classList.add('is-invalid'); 46 | } else { 47 | phone.classList.remove('is-invalid'); 48 | } 49 | } -------------------------------------------------------------------------------- /section-9/user-form/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
      10 |
      11 |
      12 |

      User Form

      13 |
      14 |
      15 | 16 | 17 |
      18 | Name must be between 2 and 10 characters 19 |
      20 |
      21 |
      22 | 23 | 24 |
      25 | Enter a valid zipcode 26 |
      27 |
      28 |
      29 | 30 | 31 |
      32 | Enter a valid email 33 |
      34 |
      35 |
      36 | 37 | 38 |
      39 | Enter a valid phone 40 |
      41 |
      42 | 43 |
      44 |
      45 |
      46 |
      47 | 48 | 49 | 50 | 51 | 52 | 53 | --------------------------------------------------------------------------------