mem2408
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- tags: mstu5003, tinker, js --- # TINKER - Javascript Part II <!-- - See repository: https://github.com/jmk2142/TodoMSTU5003 --> - See demonstration: https://codepen.io/jmk2142/pen/oGxwPQ - Tinker Markdown: https://hackmd.io/zJmA8GKJR5-Oe2Zy4r1wqw?both <!-- For this week, the actual Markdown file is not available via Github Gists. I have included it within this week's Tinker repository along with the rest of the code. It is called `README.md`. You might want to `IMPORT` the markdown into hackmd.io to use that tool (recommended.) To get access to this code, and the actual Markdown to play with, you can use Github to CLONE the repository using the Github GUI Client. You can get the idea of what repositories are in my Youtube Video: ## Github: How to clone my repository You'll want to start with the video overview: https://youtu.be/QOXhN90d9Mk?list=PLn93-yl6k7zUkSFNI8MQqmIVn017z8vKO Since you want to copy MY repository, once you have the Github GUI Client installed - you can do so with one click of a button. Just click on the Clone or download option, then **Open in Desktop** and that will automatically open it up in the Git GUI. (See Below) ![Clone thorugh Github](https://i.imgur.com/onzsWMy.png) Keep in mind that since you are cloning my repository, you will only be able to commit changes to your local computer. You will not be able to _sync_ or _push_ changes to my Github repository - for obvious security reasons. (You wouldn't want just anyone to change YOUR code.) If you would like to use Github for your work in progress, what you can do is **_FORK_** my repository first. (See _FORK_ button under account picture.) This will create a copy of this repository under your account name in Github. You can clone YOUR version of this to your local computer, then commit and push to your account to your heart's content. :smiley_cat: --- --> ## Devtools You will also want to watch this video on the `console` as we will be using it extensively to Tinker this week. General Video on Console: https://youtu.be/GAqOggzH_GE?list=PLn93-yl6k7zUkSFNI8MQqmIVn017z8vKO One of the most important tools we'll use is the `DEBUGGER`. :::success **Debugger Demonstration and Youtube Video** <!-- REPO: https://github.com/jmk2142/Debugger DEMO: https://jmk2142.github.io/Debugger --> CODE: https://codepen.io/jmk2142/pen/RwZErre DEMO: https://cdpn.io/jmk2142/debug/RwZErre YOUTUBE: https://youtu.be/RdF7j4no0Ts ::: I recommend that at some point, you watch these demonstrations and use these tools to explore the Tinker. :::info In order to use `console.dir(object)` and see the object property/values, make sure your console setting is set to DEFAULT. ![](https://i.imgur.com/cmR16Mg.png) ::: ## Tinker GIST: TODOS > Good bye, "Hello World!" `Hello World` is probably the most common introductory program around as it's so simple. ```javascript= alert("Hello World!"); // Or alternatively... console.log("Hello World!"); ``` Unfortunately, it's not very useful. It doesn't really show the range of different programming concepts and to be quite frank, it's boring. Many beginners like us are interested in creating interactive applications and this requires a range of programming concepts. 1. HTML Elements 2. CSS 3. Variables 4. Operators 5. Functions 6. Control Statements 7. Events 8. Data Structures + Data (e.g. Arrays, Objects, Booleans, Numbers, Strings) And you really cant get a sense of how these things work together with a 1 line program like `Hello World!`. ### Enter TODOS Some clever programmer realized this and probably thought: > What's the simplest, _real_ program I can build that will incorporate all the important aspects of a basic interactive program? And the **TODOS** or **TODO LIST** program was born. The beauty of TODOS is that it has everything in a pretty simple package. It can be solved using a variety of different strategies and can be created to be _simpler_ or _more sophsiticated_ depending on ones needs. It tends to now be the defacto standard for demonstrating a full interactive application. Beginners AND advanced students alike build TODO apps as they learn new things. For example, our TODOS Tinker is designed to demonstrate the base JS concepts with a few _stretch_ challenges embedded in it. In my regular practice, when I have to learn a new library or framework, I will probably start by viewing an existing TODO app built with that specific library to see how that library works. Sort of like how you might compare a basic HTML page with a Bootstrap page (of the same content) to be able to compare and contrast the two. If you're interested, you can briefly look at [this page](http://todomvc.com/) which is an archive of the TODO application built in various different frameworks. And this is where I am hoping to take this class, the culmination of all the things we've been working towards - to understanding this first, real, interactive program and hopefully - you can apply some of these concepts in your own works. ## Tinker Tasks In this tinker, were going to: 1. Review prior concepts in this new context: - Variables, functions, events, and arrays 2. Observe, analyze, and study new concepts: - Control statements (E.g. `if`, `for`) - Logical operators (E.g. `===`,`&&`, `||`,`<`,`<=`,`>`,`>=`, etc.) - Objects (and `array` of `objects`) 3. Learn how to use more developer tools to study JS code - Source (i.e. debugger) - Console (i.e. `console.log`, `console.dir`) We will continue to observe, analyze and think about this program in terms of: > What is the STATE? > What is the SEQUENCE? > What is the CAUSALITY? ### Part 0: Conceptual Program Overview Play with the program and observe how it reacts to user interactions. - _Without_ talking about it in _programming terms_ explain the user observable steps/process of the following three interactions and how the program responds. - Adding a todo :::info 1) write something in the input box and click "Add" 2) The computer accepts the input and adds it the list and changes the styling so that the new item is styled the same way ::: - Completing a todo :::info 1) if circle box gets checked, the todo gets crossed out and changed to gray italic font ::: - Removing a todo(s) :::info 1) The remove button updates according to how many completed todos are on the list 2) If you click the remove button, the completed todos disappear ::: Be specific but imagine you are talking to a _non-programmer_. Think about this in terms of observable actions and reactions. > User puts toast in the toaster. Sets the length of the timer. Pushes the lever to start the toaster. The toast pops out the toaster after the time is completed and goes "DING". - For each of the interactions above write in _pseudocode_ the steps of how the program for that interaction unfold and results. Pseudocode is semi-formal structure to write out the gist of how your program would work. It uses some keywords but is largely language agnostic. There isn't a single correct way to do it but the following are some rules that can help. - RULES: - One statement per line - CAPITALIZE initial _keywords_ - READ, WRITE, IF, ELSE, REPEAT, UNTIL, AND, OR - Indent to show hierarchy and groups of operation - Keep statements language independent ```markdown= # Adding todos READ text written in the input box READ text input if the input is present, make ADD button clickable ADD input text to todolist # Completing a todo CHECK to see if todo is completed (if circle box is checked) IF todo is completed: CHANGE styling to gray italics, crossed off # Removing a todo UPDATE Remove button to include the number of completed tasks IF remove button is clicked ERASE tasks ``` - Using your pseudocode, identify the function(s) in the actual JS code that relate to your pseudocode. - Compare and contrast your pseudocode with the actual code. :::info ### Adding a todo ```javascript= //function that adds a todo item once the input from the box is submitted function onEnterKey(event) { if (event.code === "Enter") { addTodoItem(); } } //if the task is NOT nothing, then return true function validateTask(task) { if (task !== "") { return true; } else { return false; } } //if there IS input in the box, validate task will return false, but w/ the ! it will return true, and will return the text that has been added to the todo item function addTodoItem() { if (!validateTask(inputEl.value)) { return; } //newTodo var is turned into an obj and an id is added via the timestamp of the input var newTodo = { id: getTimeStamp() }; //adding task and done to the obj array newTodo.task = inputEl.value; newTodo.done = false; //newTodo is pushed to the end of the data array data.push(newTodo); //updateTodoItems is called and input clear upon adding new todo to the list updateTodoItems(); resetInput(); } ``` ### Completing a todo ```javascript= function updateTodoItems() { var todosHTML = ""; //naming each element in object-array a todo for (todo of data) { //if the task is marked as done --> change its appearance if (todo.done) { //changing the class to complete, so triggering styling changes we imagine, and ADDING an onclick event to the HTML to trigger the function toggleComplete todosHTML += `<li id="task-${ todo.id }" class="complete" onclick="toggleComplete(event)">`; //changing styling to crossthrough italic todosHTML += `<i class="fa fa-check-circle-o"></i>`; // Font-awesome //if event is not complete } else { //adds the HTML for the togglecomplete event but does not mark event as complete todosHTML += `<li id="task-${ todo.id }" onclick="toggleComplete(event)">`; //adds the check circle next to text todosHTML += `<i class="fa fa-circle-o"></i>`; // Font-awesome } //this is outside of the else. So refers to todo of data. It adds the task associated with the todo in var data todosHTML += `${ todo.task }`; //it closes the list item todosHTML += `</li>`; } //this is outside todo of data. If there is nothing in the HTML for the todo item, add the text "nothing to do..." if (todosHTML === "") { todosHTML = "<li>Nothing todo...</li>"; } //this is every time. Update todosEl.innerHTML, which is actually grabbing from the document, with the var todosHTML, which is just established here todosEl.innerHTML = todosHTML; //calls the function to update the count on the remove button updateRemoveBtn(); } ``` ### Removing a todo ```javascript= function updateRemoveBtn() { //establishes a var completedTodos and has it return all the todo items within the obj data that are completed var completedTodos = data.filter(function(todo){ return todo.done === true; }); //updates the text content of completedEl to be the length of the array completedTodos completedEl.textContent = completedTodos.length; //if there ARE completed todos... if (completedTodos.length) { //undisable the remove button completedEl.parentElement.disabled = false; } else { //disable the remove button completedEl.parentElement.disabled = true; } } function removeTodoItem(event) { //establishes var incompleteTodos and intiializes it as an array containing all the todos that are NOT complete var incompleteTodos = data.filter(function(todo){ return todo.done === false; }); //data is updated to equal the incomplete todos data = incompleteTodos; //updatetodoitems is called updateTodoItems(); } ``` ::: - Explain what similarities and differences you noticed about the instructions / steps / processes in the code vs. your psuedocode. :::info one thing that always surprises me is how precise code must be in order to run correctly. Everything must be broken down in to the smallest possible component. For example, in order to add items to the todo list, you need not one but three functions: `onEnterKey` `validateTask` and `addTodoItem` ::: - Manipulate different parts of the code as you see fit. Why did you decide to manipulate that part? What happened? (More structured tinkering to follow.) :::info one thing I did was to manipulate the following HTML code to see how it affected the styling of items on the todo list: ```javascript todosHTML += `<li id="task-${ todo.id }" class="complete" onclick="toggleComplete(event)">`; ``` ::: ### Part 1: Variables, Functions, Arrays, and Events - Explain the `data` variable. - What does this data (and the data inside) represent conceptually? :::info It represents the various todo items. Each of the objects within the array is a `todo` and each contains information about its `ID`, its status (is it `done`?) and the `task` that it represents. ::: - If I wanted to access the second object, how would I do that in code? :::info data[1] ::: - If I wanted to access the `done` property of the first object, how would I do that? :::info data[1].done ::: - Look through the rest of the code where this `data` array is used. When the user does things, am I manipulating the visual display and updating the data to reflect those changes? Or am I manipulating the data and updating the visual display to reflect those changes? :::info you're manipulating the data and then updating the visual display to reflect those changes ::: - Is this what you would have thought of? :::info I think so--even though viewers think only of the visual display changing and they don't think about the data, it makes sense that it should always be a change in the data that initiates any change in design ::: - What might be the significance of this program design decision? :::info This places the data at the heart of the design--it means that to change anything about the appearance one must always change the data set and this is important because it avoids a situation where the cosmetics of the page change but the data doesn't update to reflect that ::: - What do these lines in my code do? ```javascript= var todosEl = document.querySelector('#todos'); var inputEl = document.querySelector('input'); var completedEl = document.querySelector('#counter'); ``` :::info these establish and initialize global variables that will be used throughout various functions (and they link each variable to their respective HTML ids and elements) ::: - Why declare these (see above) variables at the Global scope instead of in the functions? :::info because they are used across various functions. In essence we'll use additional variables within functions in order to manipulate these global variables which store the three big pieces of data that we need to make the program run ::: - Or not at all... (E.g. `document.querySelector('#todos');`) :::info Right, `todosEl` is used only once throughout the script, but it is useful for readability and it makes it easier to parse what is happening when the variable is being updated ::: - The `toggleComplete` function has an event parameter. Inside the function I access `event.currentTarget`. What is the difference between `event.currentTarget` and `event.target` which we used previously? :::info `event.currentTarget` gets the html element to which the event handler has been attached, rather than the element that triggers the event (which is what `event.Target` does). ::: - Hint 1: You can add a `console.log(event)` etc. inside that function to test the value of `event.target` and `event.currentTarget`. - Hint 2: When testing, click on a todo to "complete" it. Click on two areas: the `li` as well as the `i` (font icon) element to see the differences. - Hint 3: You can pass multiple arguments to `console.log()`. I often pass two: first a string label, second the thing I want to log. This will basically make the logs easier to identify if you use `console.log()` a lot. ```javascript= console.log("SOME LABEL: ", dataToLog); ``` - In the `toggleComplete` function, there is a `event.currentTarget.id`. Is that `id` the same thing as the id property in my todo objects in the `data` array? - Explain. :::info Yes. It is the same as the `id` in the data array. Up in the `updateTodoItems` function, and HTML `li` element is generated for each new item added to the list and each `li` element is given the `id`: `todo.id`. So when a user tries to toggle the todos from incomplete to complete, they click on that HTML element, and trigger that `id` put in place earlier in the `updateTodoItems` function ::: - What does `!something` mean? (The exclamation mark) and how is it used in this code when we `toggleComplete`? :::info the `!` means that an output of `false` is returned as `true` and vice versa. It is commonly used in toggle functions. In `toggleComplete` it changes the current `done` state (true/false) to its opposite, every time the button is pressed ::: - Try calling some of the functions directly from the console. Some will work. Some won't. - Explain what you find. :::info functions that use variables which are defined within the function will not work when called directly to the console. Neither will functions which use an event to grab data, as the event is essentially a parameter that changes depending on a user's interaction with the script. ::: - Look at the function declarations in the JS panel. - _Where_ is each function being called? - _When_ is each function, actually called? - What parameter(s) does that function have? - What is the argument that is passed into the function when it is called? :::info There are three main functions that are called on buttons embedded in the HTML: `onEnterKey`, `addTodoItem`, `removeTodoItem`. All other functions are called within these functions, typically dependent on an `if/else` statement. The only functions with parameters are `onKeyEvent(event)` (argument passed in is the event), `validateTask(task)`(argument passed in is `inputEl.value`), `removeTodoItem(event)` (argument passed in is the event), `getTodoData(id)`(argument passed in is `todoID`). ::: - Use the console (in Chrome devtools) to `console.log()` and `console.dir()` the following. What is the difference between `console.log` and `console.dir` and why is `console.dir` kind of more useful for looking at some kinds of data? ```javascript= console.log(data); console.log(todosEl); console.dir(data); console.dir(todosEl); ``` :::info `console.log` prints anything in its string representation, including objects. `console.dir` prints an object as a set of properties so it's only useful for looking at objects. ::: ### Part 2: Objects and Arrays of Objects - Manipulate the different _properties_ of the _objects_ inside the `data` array. - Change all todo objects' `done` property to `true`. - Change some of the task values. - Run your code and explain how this changes what you see and why. :::info When all the done property is changed to true, there is a strikethough through all the todo items in the list. When the task value was changed, the contents of the todo list changed. Because the data (variables and elements) of the original array are changed, what is shown visually changes as well. ::: - `console.dir()` the `data` array. Goto the console and _OPEN_ the `> Array(3)` text by clicking on it. Go deeper by opening up the nested objects. Analyze what you see. Then add a new todo through the user interface. `console.dir()` the `data` array again and investigate the insides. - What is the difference between `data` before and after adding a new todo? :::info A new task of a new todo is added to the orginal array, with A new id and a new task value and done property are added as well to the data array. ::: - Run the following code: ```javascript= data.push({ done: true, task: "Goto Aikido Lessons", id: getTimeStamp() }); console.dir(data); ``` - What did the code above do? :::info The code added a new task to the very end of the todo data array. ::: - Does our page reflect the changes made? Why or why not? Prove it. :::info The page initially does not reflect the change and only exists in the code. The changes show only once the items are clicked. This is because the clicking of the items triggers the function and only updates it then. ::: - Does order matter in `Objects`? :::info Yes. The order of the code reflects how it is visually shown on the page. ::: - What is the difference between `Object` keys (E.g. `done`, `task`, `id`) and `Array` indices (E.g. `0`, `1`, `2`)? :::info Object keys: identifiers that refer to the value stored in objects. Array indices: references to call on objects ::: - How are they similar? ```javascript= var myAry = [123, "Code", true]; var myObj = { id: 123, task: "Code", done: true } console.log(myAry[1]); console.log(myObj["task"]); console.log(myObj.task); ``` :::info Both are used to call certain data in objects. For instance, console.log(myObj["task"]); console.log(myObj.task); from the code above both call for the data in `task`. ::: - Compare the following in the console: ```javascript= var element = document.querySelector('ul'); var author = { first: "Mark", last: "Twain" } var example = { theAnswer: 42, student: true, hobby: "Fishing", sayHello: function(){ alert("Hello"); }, favNums: [1,2,3], favAuthor: author }; console.dir(example); console.dir(element); ``` - What is an `element` really? :::info An `element` is the HTML code that the JS code is referring to. Here, it is the `ul`. ::: - How does our `element` relate in terms of similarities and differences to `example`? :::info `element` and `example` are both elements from innerHTML. However, the `element` are tags that retrieve detailed information about the object, and the `example` are the values of the object. ::: - If I wanted to call the function in the `example` object, how would I do that? Prove it. :::info The function in the example objects has an id of "sayHello" and returns the value of "Hello". Thus, it would be: console.dir(example.Hello); ::: - Try the following code in the console. How does dot notation and bracket notation differ and why would you want to use one or the other? ```javascript= var x = "username"; var user = { username: "happyCat" } console.log(user.username); console.log(user["username"]); console.log(user[x]); console.log(user.x); ``` :::info Both access properties of an object. The bracket notation can access values in an object, without knowing the name of the object. The dot notation needs to know the name of the object. ::: - Identify various areas where the `.` object notation is used and explain the thing on the left side of the `.` and the thing on the right side of the `.` - E.g. `document.querySelector()` `document` is... `querySelector` is... - HINT: There are MANY choices here. :::info In the case of `document.querySelector()` , the `document` is the defined variable where the function is happening and the `querySelector` is the action of the function. ::: - In two areas of my code, I use what is called a `filter` function. It's a function that arrays can use like `list.pop()`, `list.push()`. - How does a filter function work? :::info The filter function creates a new array that pass the function's text (here, "pop", to take off, and "push", to add). ::: - What is the significance of the function argument that is passed INTO the filter parameters? :::info The function here references the function behind the `filter` feature, in the same way that `document.querySelector` is also a function (just one that is preset). `Filter` is not acutally evaluating the function, it's evaluating the `item` inside of the function. ::: - With regard to the function that is passed into the filter as an argument, that function must `return` a boolean or evaluate to a boolean. What is the purpose of this? :::info This is because the fiter function only creates the new array based on whether they are determined to be "true". ::: - What does the _filter function_ return? E.g. `var x = list.filter(...); // What was returned to x?` - CAUTION: NOT the function argument that goes into the filter. - HINT: If you don't know, can you use console to "test" an idea out? :::info As mentioned above, the filter function returns a newly created array of elements only determined to be true. ::: - Does filtering an array _change_ the original array? :::info Filtering an array does not change the original array, although it creates a new one. ::: ### Part 3 Control Structures - I use the `if` statement in several places in this code. Explain why a conditional is necessary in: - `updateTodoItems` :::info It's used here to change the appearance of the todo tasks `if` they are done. ::: - `updateRemoveButton` :::info It's used here to say `if` there ARE completed todos (this is a boolean, and will return true or false), then something should happen. ::: - `onEnterKey` :::info It's used here to say `if` the enter key is pressed, trigger the `addTodoItem` function. ::: - `validateTask` :::info It's used here to say `if` the text input for the task is NOT nothing, then return `true`. ::: - `addTodoItem` :::info It's used here along with the `!` that is typically used for toggling. Without the `!`, if there WERE input in the box, validate task would return false. With the `!` however, it will return true, and will return the text that has been added to the todo item. ::: - getTodoData :::info Here `todoFound` is initialized so that it loops through all the items in the data array. An `if` statement is embedded in this loop so that the function will return all items in the array that have the same id as the variable `id`. ::: - HINT: You might want to `console.log` the boolean condition where you see the `if` statements to understand what condition we are evaluating. ```javascript= if (booleanCondition) { ... } console.log(booleanCondition); ``` - Comment on how the boolean condition works as there are many different examples. :::info The boolean works such if booleanCondition (as seen below) exists, the `if` statement will return `true` and the contingent script will run. ```javascript if (booleanCondition) { ... } ``` ::: - In this code, there are two kinds of `for` loops. The more traditional that looks like: ```javascript= for (var i=0; i < list.length; i++) { // CODE } ``` and a `for of` loop that looks like: ```javascript= for (item of list) { // CODE } ``` - How does a `for of` loop work? :::info A `for...of` loop gives a name to the items in an array and allows you to loop through an array or other changeable piece of data and manipulate it. ::: What does the `item` represent? (It can be named anything: `x`, `item`, `thing` etc.) :::info the item represents a subcomponent of the array (but it doesn't have to always be an object, it could be a string, etc) ::: - Why are `for of` loops convenient compared to the traditional `for`? :::info They offer a more efficient way to loop through and manipulate data (since both can be accomplished with a `for of` loop) ::: - For what purpose(s) do I employ a `for` or `for of` loop in this program? :::info A `for of` loop is used when you specifically want to manipulate data while looping through it. That's why it's specifically used in the `updateTodoItems` function and not used in the function `getTodoData` ::: - On Facebook or Pinterest, or Twitter, how does a loop through data relate to the display of content? :::info The display of content in the feed of these social media platforms, for instance, in the case of gifs, audio and videos, auto-replays while the scroll is set on that specific part of the screen. ::: ### Part 3 Specific Routines - Take a look at the `updateTodoItems`. Comment it out and replace it with this alternate, but functionally identical version. How does this function work and how do they relate / differ? ```javscript= function updateTodoItems() { todosEl.innerHTML = ""; if (!data.length) { var liElement = document.createElement('li'); liElement.innerText = "Nothing todo..."; todosEl.appendChild(liElement); } else { for (todo of data) { var liElement = document.createElement('li'); var iElement = document.createElement('i'); liElement.id = todo.id; liElement.onclick = toggleComplete; if (todo.done) { liElement.className = "complete"; iElement.className = "fa fa-check-circle-o"; } else { iElement.className = "fa fa-circle-o"; } liElement.appendChild(iElement); liElement.innerText = todo.task; todosEl.appendChild(liElement); } } updateRemoveBtn(); } ``` :::info What you've done here is removed all of the variables that helped with the readability of this function. It works exactly the same as before, but now it's much more cumbersome and difficult to interpret how it manipulating the DOM. ::: - Take a look at the helper function `getTimeStamp`. This function will return a number, in milliseconds, the current time stamp since January 1, 1970. - I call this when I create new todo items, what are some ideas as to why I might be using a timestamp for todo `ids`? :::info this ensures that every addition to the todo list is given a unique id, as no two items will be added at the same time ::: - Take a look at the incomplete functions `markAllComplete` and `updateItemsLeft`. - Can you complete these and add the functionality to this app? :::info ```javascript function markAllComplete() { data.forEach(todo => { if(todo.done !== true) todo.done = true; }); updateTodoItems(); } ``` ```javascript function updateItemsLeft() { var completeCount = 0; data.forEach(todo => { if(todo.done == false) completeCount++; }); itemLeftEl.innerHTML = `<p>You have ${completeCount} task(s) Left</p>`; } ``` ::: ### Part 4 Debugging, Tools Using the Chrome debugger (source) tool create breakpoints and watch the program execute line by line, part by part. Experience how this tool can give you insight into your program's _STATE_, _SEQUENCE_, _CAUSALITY_. #### Chrome Debugger - Set breakpoints at the following locations of your program - `function initializeTodos` - `function onEnterKey` - `function addTodoItem` - `function toggleComplete` - Use the `Step over the next function call` feature to watch how the program pauses during the _SEQUENCE_ of its routines. - Use the `Step into the next function call` feature to watch how the program pauses during the _SEQUENCE_ of its routines. - What is the difference between `Step over` and `Step into` and how does this help you understand programs? :::info `Step over` allows you to continue on to the next place where you have set a breakpoint. When you step over a function, that function runs completely, and the debugger brings you to the next breakpoint. `Step into` allows you to look inside a function and evaluate what is being triggered line by line. ::: - Use `Step into` until you've reached the line `var inputEl = document.querySelector('input');`. Should be highlighted in blue. - Highlight the variable `todosEl` on the line before it and `right click` on it. Select _Evaluate in console_. - What does the console print? :::info The console prints the HTML element associated with todosEl. When the site is paused, it also gives the scope. ::: - Highlight the variable `inputEl` on this highlighted blue line. - Why does the console say `inputEl` is undefined? - When you step through your code, does the blue line represent code that is about to be executed or code that has already executed? How do you know? - What do you predict would be the console value of the variable `completedEl` on the next line if you _Evaluate to console_ at this point? :::info The console says that inputEl is undefined because the blue arrow indicates the line that it's about to execute, so `inputEl` wouldn't have been executed yet. The blue line represents code that's about to be executed. It always jumps to the next line when you try to add a breakpoint at the function level. `completedEl` would be undefined because it wouldn't have run yet. ::: - Watch how debugger annotates your source code with the updated _state_ of different variables as your program progresses. - How does the debugger behave when you enter a loop in your program? - How does the debugger behave when you reach the a `filter` function call? - What does filter do and how does it work? :::info We're not totally sure what to look for, but it looks like you can use the debugger to track where exactly you are in a loop. Similarly, with `filter`, it should let you see where the `filter` is inside an array. `Filter` finds all the objects that meet certain criteria within the array and returns those objects. ::: ### Part X: Putting all together **Explain the program line by line with sufficient details, part by part.** :::success ```javascript= // The core TRUTH of this program var data = [ { id: 1497141891479, task: "Wake up", done: false }, { id: 1497141913701, task: "Eat breakfast", done: false }, { id: 1497141937545, task: "Learn code", done: true } ]; // Important Elements - Cached as variables var todosEl = document.querySelector('#todos'); var inputEl = document.querySelector('input'); var completedEl = document.querySelector('#counter'); function initializeTodos() { updateTodoItems(); } function updateTodoItems() { var todosHTML = ""; //naming each element in object-array a todo for (todo of data) { //if the task is marked as done --> change its appearance if (todo.done) { //changing the class to complete, so triggering styling changes we imagine, and ADDING an onclick event to the HTML to trigger the function toggleComplete todosHTML += `<li id="task-${ todo.id }" class="complete" onclick="toggleComplete(event)">`; //changing styling to crossthrough italic todosHTML += `<i class="fa fa-check-circle-o"></i>`; // Font-awesome //if event is not complete } else { //adds the HTML for the togglecomplete event but does not mark event as complete todosHTML += `<li id="task-${ todo.id }" onclick="toggleComplete(event)">`; //adds the check circle next to text todosHTML += `<i class="fa fa-circle-o"></i>`; // Font-awesome } //this is outside of the else. So refers to todo of data. It adds the task associated with the todo in var data todosHTML += `${ todo.task }`; //it closes the list item todosHTML += `</li>`; } //this is outside todo of data. If there is nothing in the HTML for the todo item, add the text "nothing to do..." if (todosHTML === "") { todosHTML = "<li>Nothing todo...</li>"; } //this is every time. Update todosEl.innerHTML, which is actually grabbing from the document, with the var todosHTML, which is just established here todosEl.innerHTML = todosHTML; //calls the function to update the count on the remove button updateRemoveBtn(); } function updateRemoveBtn() { //establishes a var completedTodos and has it return all the todo items within the obj data that are completed var completedTodos = data.filter(function(todo){ return todo.done === true; }); //updates the text content of completedEl to be the length of the array completedTodos completedEl.textContent = completedTodos.length; //if there ARE completed todos... if (completedTodos.length) { //undisable the remove button completedEl.parentElement.disabled = false; } else { //disable the remove button completedEl.parentElement.disabled = true; } } //function that adds a todo item once the input from the box is submitted function onEnterKey(event) { if (event.code === "Enter") { addTodoItem(); } } //if the task is NOT nothing, then return true function validateTask(task) { if (task !== "") { return true; } else { return false; } } //if there IS input in the box, validate task will return false, but w/ the ! it will return true, and will return the text that has been added to the todo item function addTodoItem() { if (!validateTask(inputEl.value)) { return; } //newTodo var is turned into an obj and an id is added via the timestamp of the input var newTodo = { id: getTimeStamp() }; //adding task and done to the obj array newTodo.task = inputEl.value; newTodo.done = false; //newTodo is pushed to the end of the data array data.push(newTodo); //updateTodoItems is called and input clear upon adding new todo to the list updateTodoItems(); resetInput(); } function toggleComplete(event) { //replaces the ID of the original event w/ todoID, which is the timestamp of the input var todoID = parseInt(event.currentTarget.id.replace('task-','')); //todoData is updated to equal the output of thefunction getTodoData with todoID passed in var todoData = getTodoData(todoID); //if todoData.done is true, switch to false todoData.done = !todoData.done; //calls updateTodoItems function updateTodoItems(); } function removeTodoItem(event) { //establishes var incompleteTodos and intiializes it as an array containing all the todos that are NOT complete var incompleteTodos = data.filter(function(todo){ return todo.done === false; }); //data is updated to equal the incomplete todos data = incompleteTodos; //updatetodoitems is called updateTodoItems(); } function resetInput() { //resets the textbox to empty string inputEl.value = ""; } function getTodoData(id) { //establishes var todoFound var todoFound; // initializes todoFound to loop through all the items in the data array, and to be equal to the item in the array that has the same id as the "var id" for (var i=0; i < data.length; i++) { if (data[i].id === id) { todoFound = data[i]; // var indexAt = i; break; } } //if the matching todo is found, return it if (todoFound) { return todoFound; //if none is found, return null } else { return null; } } initializeTodos(); ``` ::: **Make it yours (group's)** :::success - Try to extend this program to do something cool, as a group, your own original idea(s). - What is something that a Todo list or todo list user might benefit from? ::: :::info It might be useful to be able to set a due date for todo items. We talked about various ways to do this, but unfortunately we're not totally sure how to execute! :::

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully