# Tinker Week 5 - Javascript Part II ### Group: Jordan, Alex, Anisa ###### tags: `mstu5003` `Tinker` ### 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 -Completing a todo -Removing a todo(s) Be specific but imagine you are talking to a non-programmer. Think about this in terms of observable actions and reactions. READ, WRITE, IF, ELSE, REPEAT, UNTIL, AND, OR # Adding a TO DO When thinking about the observerable actions and reactions of adding a todo we can refer to the following format: READ empty string READ value added after the onclick of "submit" computer will WRITE value entered by user into a collection of strings ADDs a new todo to the list on the users end READ new todo REPEAT for all new todos # Completing a todo When thinking about the observerable actions and reactions of completing a todo we can refer to the following format: Click the circle of the "todo" READ as "completed" in the console computer will cross off selected input VALUE READ value as completed with a "strikethrough" READ completed todo and remains on the list until it is removed REPEAT for all completed todos # Removing a todo When thinking about the observerable actions and reactions of removing a todo we can refer to the following format: CLICK the radio button of the "completed" todo "remove" button illuminates REMOVE button is true if radio button is clicked (eventLister) The eventListener READS function ADD element in a collection for "completed todos". REMOVE todo from the list READ reset function REPEAT for all removing todos ### Part 1: Variables, Functions, Arrays, and Events Explain the data variable. *Q1: What does this data (and the data inside) represent conceptually? The data represents the properties and values of the todo element. The data inside represents if the task is completed or not, and the timestamp which serves as the unique id of the object. *If I wanted to access the second object, how would I do that in code? To access the second object, first be sure to enter debug mode and then right click and go to inspet. From there we can easily see the dynamic of the objects, their classes, values, ids, and eventListeners. You would look within the body element of the code to start. Within the body element is the collection of elements in a <ul></ul>. By selecting the second element with your curser, you can focus specifically on the second object. *If I wanted to access the done property of the first object, how would I do that? You can access the done property of the first object by toggling the radio button which prompts class="complete" from the onclick. When the "done" property is either clicked on/off, the class="completed" will change !true, !false. <li id="task-1497141891479" class="complete" onclick="toggleComplete(event)"><i class="fa fa-check-circle-o"></i>Wake up</li> *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? You are manipulating the data and updating the visual display to reflect these changes. *Is this what you would have thought of? Not necessarily. At first I thought it must be the user causing the changes in the data, but based upon the pattern in the code we noticed that the data state must be changing the visual display. *What might be the significance of this program design decision? One possibility of this program decision is to have forsight for how the user will be interacting with the program. Because of the nature of the code and its modelled elements, the code anticipates user interaction which causes it to react accordingly. *What do these lines in my code do? - var todosEl = document.querySelector('#todos'); This element is important and "cached as a variable". This line of code tells the program that all elements on the todo list will be categorized with the id #todos. - var inputEl = document.querySelector('input'); This element is important and "cached as a variable". This line of code tells the program that all elements that validate the input value will be categorized as an array with the property of 'input'. - var completedEl = document.querySelector('#counter'); This element is important and "cached as a variable". This line of code tells the program that when an element is completed, it should get the id #counter and will be considered "completed" in the data. *Why declare these (see above) variables at the Global scope instead of in the functions? Or not at all… (E.g. document.querySelector('#todos');) 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? While going through the program out group was discussing the reasoning for declaring the above variables and believe it is important to be able to categorize the data sets as to keep them organized in preparation for next steps which include databases. Thinking from a large scale perspective, it will be very useful and helpful to be able to read the data from the backend, understanding the lineage between specific class and ids. "The target property of the Event interface is a reference to the object onto which the event was dispatched. It is different from Event.currentTarget when the event handler is called during the bubbling or capturing phase of the event" (https://developer.mozilla.org/en-US/docs/Web/API/Event/target). 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. 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. To our understanding, the id property in the todo object seemingly stayed the same. However, there was the class change. *What does !something mean? (The exclamation mark) and how is it used in this code when we toggleComplete? !something means the opposite of the value. For example, if a program uses the code !false, this means that the computer will read that as true. The toggleComplete event is prepared for the user interaction with the boolean set to false until the user interacts with it, and then changes it to true or validates it and proceeds with the following code to complete the function: ``` function addTodoItem() { if (!validateTask(inputEl.value)) { return; } var newTodo = { id: getTimeStamp() }; newTodo.task = inputEl.value; newTodo.done = false; data.push(newTodo); updateTodoItems(); resetInput(); } ``` *Try calling some of the functions directly from the console. Some will work. Some won’t. Explain what you find. Look at the function declarations in the todos.js file. *Where is each function being called? It seems that each function is being called after the model data set is established. *When is each function, actually called? Each function is actually called after the user interacts with the interface of the program. *What parameter(s) does that function have? The function is created to updateTodo list. The function can serve to add a new todo, update an existing todo (completed), and remove todos from the list. The function has the ability to add a timestamp to the new element. The element is also created with the pattern of an onclick eventListener *What is the argument that is passed into the function when it is called? The argument that is passed into the function when it is called depends on what function specifically is being called. ``` function initializeTodos() { updateTodoItems(); } function updateTodoItems() { var todosHTML = ""; for (todo of data) { if (todo.done) { todosHTML += `<li id="task-${ todo.id }" class="complete" onclick="toggleComplete(event)">`; todosHTML += `<i class="fa fa-check-circle-o"></i>`; // Font-awesome } else { todosHTML += `<li id="task-${ todo.id }" onclick="toggleComplete(event)">`; todosHTML += `<i class="fa fa-circle-o"></i>`; // Font-awesome } todosHTML += `${ todo.task }`; todosHTML += `</li>`; } if (todosHTML === "") { todosHTML = "<li>Nothing todo...</li>"; } todosEl.innerHTML = todosHTML; updateRemoveBtn(); } function updateRemoveBtn() { var completedTodos = data.filter(function(todo){ return todo.done === true; }); completedEl.textContent = completedTodos.length; if (completedTodos.length) { completedEl.parentElement.disabled = false; } else { completedEl.parentElement.disabled = true; } } function onEnterKey(event) { if (event.code === "Enter") { addTodoItem(); } } function validateTask(task) { if (task !== "") { return true; } else { return false; } } function addTodoItem() { if (!validateTask(inputEl.value)) { return; } var newTodo = { id: getTimeStamp() }; newTodo.task = inputEl.value; newTodo.done = false; data.push(newTodo); updateTodoItems(); resetInput(); } function toggleComplete(event) { var todoID = parseInt(event.currentTarget.id.replace('task-','')); var todoData = getTodoData(todoID); todoData.done = !todoData.done; updateTodoItems(); } function removeTodoItem(event) { var incompleteTodos = data.filter(function(todo){ return todo.done === false; }); data = incompleteTodos; updateTodoItems(); } function resetInput() { inputEl.value = ""; } function getTodoData(id) { var todoFound; for (var i=0; i < data.length; i++) { if (data[i].id === id) { todoFound = data[i]; // var indexAt = i; break; } } if (todoFound) { return todoFound; } else { return null; } } ``` *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? ``` console.log(data); console.log(todosEl); ``` The console.log(data); shows the array of objects and the values of each in a sequential format using numbers. The console.log(todosEL) is the same in that it displays the values of the elements, but it uses a <ul>...</ul> format to display the data. Additionally, when using the console.log(todosEl) in the debugger mode we can see the direct association between the console.log(todosEl) and the user interface experience. console.dir(data); console.dir(todosEl); The console.dir(data) displays the array of elements from the data as written in JS form. It is organized in familar collections with easy readability. The console.dir(todosEL) contains all of the potential properties housed within the element. console.dir(todosEl); has all properties on display; it contains properties with input and without input. <end>section 1</end> ### 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`.** > see image below for observations from the console > > ![](https://i.imgur.com/dMy5mTN.png) > **Change some of the task values. Run your code and explain how this changes what you see and why.** > See below for updated task values in the javascript code and resulting output on the HTML page. When the task values for the first two objects in the `data` array in the javascript code were changed, the resulting text for the first two todo items displaying on the initial todo list on the HTML page updated accordingly as the function `intializeTodos` calls the function `updateToDoItems`, which uses the `task` value from object items in the `data` array (see line 40 in javascript code below): > > > ![](https://i.imgur.com/fyvueuR.png) > > **Before (JS code):** > > ![](https://i.imgur.com/ZB6R63j.png) > **Before (HTML output) :** > ![](https://i.imgur.com/JaXINC2.png) > > **After (JS code):** > ![](https://i.imgur.com/LzQKI12.png) > > **After (HTML output):** > ![](https://i.imgur.com/oyL0C28.png) **`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.** > See below for observations from the console after typing: `console.dir(data)`. The console is printing the data inside the` data` array, organized by index number(0, 1 or 2). Nested within each index number are the properties and values associated with the object at that index number in the array. > > ![](https://i.imgur.com/NX2c046.png) **What is the difference between `data` before and after adding a new todo?** > > The difference would be the number of items in the `data `array. Adding a new todo adds a new object as an item to the array, so the array length would increase by 1. **Run the following code:** ```javascript= data.push({ done: true, task: "Goto Aikido Lessons", id: getTimeStamp() }); console.dir(data); ``` **What did the code above do? Does our page reflect the changes made? Why or why not? Prove it.** > See below for observations of changes in HTML output as well as console display after the above code is added to the javascript document and run. The above code added a todo list object item to the `data` array resulting in a new todo list item displaying in the HTML output. In addition, when the `console.dir(data)` line of code was executed, an array was printed to the console (see image below) showing an array with 4 object items, confirming that 1 item was added. > **Before: HTML Output:** > ![](https://i.imgur.com/OtYgTkB.png) > > **After: HTML Output:** > ![](https://i.imgur.com/ydGWEJg.png) > > **After: Console:** > ![](https://i.imgur.com/XiXdLgt.png) **Does order matter in Objects? What is the difference between Object keys (E.g. done, task, id) and Array indices (E.g. 0, 1, 2)? 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); ``` > In terms of the order of key/value pairs within objects, based on the last activity of running the code that added an object to an array, from which data was used to display a new todo task, the order of the key/value pair does not appear to matter in terms of accessing a given value associated with a key within the object. In contrast array indices appear to follow a set sequence, starting at 0 and incrementing up by 1 for subsequent items in the array. They are similar in that they both can be used to reference data, either within an array in the case of indices or within an object in the case of keys. Bracket notation can be used with either arrays or objects to access values, while dot notaiton appears to only work with objects. **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(el); ``` **What is an `element` really? How does our `element` relate in terms of similarities and differences to `example`? If I wanted to call the function in the `example` object, how would I do that? Prove it.** > >` element `in the code above refers to the element object associated with the selector "`ul`". Both the `element` variable and the `example` variable have assigned values which are objects that contain key/value pairs. To call the function in the `example` object, the following code should be executed: > > > ![](https://i.imgur.com/H4IJBlj.png) > > Observed output when the above code is executed (expected since there is a call to the `alert` function with arguement "Hello" within the `sayHello` function): > > ![](https://i.imgur.com/49OJFsb.png) > > > > See observations from the console for comparing the `element` and `example` objects below. > > ![](https://i.imgur.com/gn1OnCu.png) > > **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); ``` > Based on observations when running the above code, dot notation appears to work only when referencing the key name in an object directly, not when referencing the name indirectly when it is stored as a string in a variable (`x` in the above example; in this case it appears bracket notation must be used) > > See below for observations from the console when the above code is run. > > ![](https://i.imgur.com/cIbSOI3.png) > **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.** > A) The variable inputEl is set to the value of `document.querySelector('input')` > > Here document refers to an object called `document` (which I understand to be the whole webpage) and `querySelector` refers to a method which functions by finding an element in the document with the selector specified in the function's argument, in this case `input`. > ![](https://i.imgur.com/Y2P7Acp.png) > > B) newTodo.task = inputEl.value > > a variable `newTodo` is currently assigned an object, and a property for that object called `task` is being created and assigned a value `inputEl.value`, which refers to the `value `property of the `inputEl` object (See above) > > Similarly another property for the object assigned to `newTodo` called `done` is being created and assigned a value `false` > > ![](https://i.imgur.com/1ggut7k.png) > > > C) inputEl.value = ""; > > Here the `value` property of the object assigned to the `inputEl` variable is being set to an empty string. > ![](https://i.imgur.com/WwG7gKM.png) **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? What is the significance of the function argument that is passed INTO the filter parameters? 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? 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? Does filtering an array change the original array?** The filter function works by applying the argument function to an array, and returning a new array that contains all of the elements from the original array that passed the "Test" provided by the argument function. The argument function must return a boolean because the true/false determination is what determines what items from the original array get included in the new array. ### Part 3 Control Structures **I use the `if` statement in several places in this code. Explain why a conditional is necessary in:** ``` updateTodoItems updateRemoveButton onEnterKey validateTask addTodoItem getTodoData ``` **HINT: You might want to console.log the boolean condition where you see the `if` statements to understand what condition we are evaluating.** ``` if (booleanCondition) { ... } console.log(booleanCondition); ``` **Comment on how the boolean condition works as there are many different examples.** `updateTodoItems` this function uses a conditional to check if the value of the `todo` property is `done`. In this case rather than explictly stating that the value needs to be true, the `todo.done` is written in the `if` statement since it either has a value of true or false. If the value is true, a `complete` class is added to the HTML code for the list element for that to do item, and if the value is false, HTML code is created without the addition of the `complete` class. `updateRemoveButton` This function uses a conditional to check if a new array generated by filtering the data array for completed todos has a nonzero length. If this condition is true, that means one or more tasks has been completed and the user can be given the ability to remove them from the list, meaning the Remove button (which is the parent element of the element stored in the variable `completedEl`) would be enabled. If this condition is false, then no tasks have been completed and the Remove button will be set to disabled. ```javascript= function updateRemoveBtn() { var completedTodos = data.filter(function(todo){ return todo.done === true; }); completedEl.textContent = completedTodos.length; if (completedTodos.length) { completedEl.parentElement.disabled = false; } else { completedEl.parentElement.disabled = true; } } ``` `onEnterKey` this function uses a conditional to check if the event passed in as an argument to the event handler function has a property code with a value of `"Enter"`. if this condition is true only then will the addTodoItem function be called. In this case the strict equality operator is used in the if statement ```javascript= if (event.code === "Enter") ``` `validateTask` This function uses a conditional statement to check if the value of a task passed in as an argument is not equal to an empty string. This is explicitly written out in the `if` statement. ```javascript= function validateTask(task) { if (task !== "") { return true; } else { return false; } } ``` the function returns `true` if the value of task is not an empty string, indicating that the task is validated. `getTodoData` Two conditional statements are used in this function, one inside a for loop, and another outside of the for loop. For the conditional statement inside the for loop, the condition checked is if the `id `property of an element within the `data` array equals the id argument passed into the function. This is explicitly written out in the `if` statement: ```javascript= function getTodoData(id) { var todoFound; for (var i=0; i < data.length; i++) { if (data[i].id === id) { todoFound = data[i]; indexAt = i; break; } } ``` outside of the `for` loop, another conditional statement is used to check if todoFound is true, meaning the variable has a value (a value which would have been assigned inside of the `for` loop if the `if` condition within the for loop was met). If this condition is true, then the value of the variable`todoFound` is returned, else `null` is returned. In this case the `if` statement simply consists of the variable `todoFound`, which will evaluate to true if it has a value ```javascript= if (todoFound) { return todoFound; } else { return null; } } ``` **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? What does the `item` represent? (It can be named anything: x, item, thing etc.)** **Why are `for of` loops convenient compared to the traditional for? For what purpose(s) do I employ a `for` or `for of` loop in this program? On Facebook or Pinterest, or Twitter, how does a loop through data relate to the display of content?** > A `for of` loop iterates through every item in an array and executes a specified clock of code. The `item `represents a given item in the array. > > In this program a `for of` loop is used within the `updateToDoItems` function to iterate through each object in the `data `array and generate HTML code to display it in a todo list. > > In this program a `for`loop is used within the `getTodoData` function to check if a given id passed into the function matches the `id` property value for any object item within the `data` array, and if so, to assign that object to a variable called `todoFound`. > > At Facebook, Twitter, or Pinterest, a loop through data might update a display of content based on user inputs between the current code execution and the last code execution. ## 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?** > _How the alternate function works:_ > 1. First, the HTML content for the variable "todosEl" is assigned to be an empty string. `todosEl.innerHTML = "";` > 2. Next, an "if" statement performs several actions based on whether the length of the array "data" is false (i.e., equal to zero). `if (!data.length)` >3. If the data length of the array is zero, then an _li_ element with the text "Nothing todo..." is created and appended to the _ul_ element with id "todos". In other words, a list item is created that reads "Nothing todo..." when there are no items in the array _data_. ```javascript= var liElement = document.createElement('li'); liElement.innerText = "Nothing todo..."; todosEl.appendChild(liElement); ``` > 4. If the data length of the array is NOT zero, then a _for loop_ goes through each item in the array. An _li_ and _i_ element are created for each item in the array. The attributes _id_ and _onclick_ are assigned to each element; the values for the id attribute is retrieved from the item's id value in the array. ```javascript= for (todo of data) { var liElement = document.createElement('li'); var iElement = document.createElement('i'); liElement.id = todo.id; liElement.onclick = toggleComplete; ``` > 5. Next, an if statement checks whether the value for the property _done_ is true. If the value is true, the newly created list element is assigned the class of _complete_ and the _i_ element is assigned _check-circle-o_ (which gives the list item a checked circle). If the _done_ value is false, the newly created _i_ element is assigned a class of _circle-o_ (which gives the item an open circle). ```javascript= if (todo.done) { liElement.className = "complete"; iElement.className = "fa fa-check-circle-o"; } else { iElement.className = "fa fa-circle-o"; } ``` > 6. Finally, the appendChild method is used to add the ielement to the end of the list element and the innerText element assigns the "task" (i.e., the text of the todo) to be the text of the _li_ element. ```javascript= liElement.appendChild(iElement); liElement.innerText = todo.task; ``` <br /> > _How the two functions compare and contrast:_ > > Both functions start by assigning variables; both have a _for loop_ that performs different actions based on whether the value of the property _done_ for each item in the array was true or false; and both functions end by running the `updateRemoveBtn()` function. > However, the original function used template literals to assign attributes-value pairs to variables and the innerHTML property to return the content of those variables into the HTML for the list elements. <br /> **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?** > The timestamp is useful for arranging a list of completed and incomplete tasks by when they were first created; for prioritizing items on your todo list that were created the longest ago by placing them at the top of your todo list; and for giving deadlines to your todos by calculating when they were created and how much time remains to complete them. <br /> **Take a look at the incomplete functions markAllComplete and updateItemsLeft. Can you complete these and add the functionality to this app?** **function markAllComplete()** - **Add a button to your HTML that will be used to mark all todos as complete.** - **Modify this incomplete function so that it:** 1) **Changes all todo objects in data as done:true** 2) **Updates the visual display of the todo items in the todo app** 3) **Call this function in the appropriate place(s) (somwhere else in this code)** <!-- HTML --> > _HTML additions to code:_ a new button is created that runs the function markAllComplete onclick. ```html= <button onclick="markAllComplete()">Mark All Complete</button> ``` <!-- Javascript --> > _Javascript additions to code:_ a for loop is used to change every _done_ value in the _data_ array to true, and for applying template literals to create _list_ elements that insert values from the array and _i_ elements that insert checked circled into the HTML. ```javascript= var todosHTML = ""; for (todo of data) { todo.done = true; todosHTML += `<li id="task-${ todo.id }" class="complete" onclick="toggleComplete(event)">`; todosHTML += `<i class="fa fa-check-circle-o"></i>`; todosHTML += `${ todo.task }`; todosHTML += `</li>`; todosEl.innerHTML = todosHTML; } ``` **function updateItemsLeft()** - **Add an area where the app can give feedback to the user, how many items are left todo.** - **E.g. (3 items, all unchecked) "You have 3 tasks left"** - **E.g. (3 items, 1 checked) "You have 2 tasks left"** - **Modify this incomplete function so that it:** 1) **Calculates how many todo items are incomplete** 2) **Updates the visual display by printing the feedback** 3) **Call this function in the appropriate place(s) (somwhere else in this code)** >_Javascript additions to code:_ ```javascript= var tasksLeftNote = ""; var completedTDs = 0; for (item of data) { if (data.done) { completedTDs += 1; } else { console.log("1 TD is not done"); } } if (completedTDs = data.length) { tasksLeftNote = "No items are left todo"; } else { tasksLeftNote = "You have " + data.length-completedTDs + " left"; document.getElementByID("remainingCount").innerHTML = tasksLeftNote; } updateItemsLeft(); ``` ## Part 4 Debugging, Tools **What is the difference between Step over and Step into and how does this help you understand programs?** >Step over shows you step by step each line of code being invoked. Step into, however, explores into each line and the methods called within that line. In other words, step into provides a more detailed view of the sequence of events. **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?** > All of the properties associated with that variable are printed. Similarly to if we printed the console.dir() of that object, we see the entire DOM heirarchical tree of objects. **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?** >The blue line indicated code that has not yet been executed. We know because the variables are undefined until moving on to the next step. We would expect to see the entire DOM tree of objects representing this object and its relationship to other objects. For example, we would expect to see all the properties associated with completedEl, as well as all the properties associated with its parent and child elements, and their subsequent properties. **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?** >When entering a loop, the debugger runs through each line of code for each item in the loop. When the debugger encounters a filter function call, it appears to cycle through several elements to list them as comments and highlighted the return value of `todo.done === false`, presumably to check whether these items did have the property of false. For example, when the debugger encountered the filter to remove an item, it first printed: `todo = {id:1497141891479, task: "Wake up", done: false)` Next, it printed the other two items in the array for the todo list and appeared to check them against the _done_ value of false. ### Part X: Putting all together **Explain the program line by line with sufficient details, part by part. Be sure to copy blocks of code into this markdown using code formatting/fences as references to your explanations.For repetitive code, you can explain how a line works then summarize how it would work for the rest. Make it yours (group’s)** >Beginning with the todo list. The todo list contains a collection with the id "todos". Within the collection containing the id="todo", there is`<ul id="todos">`. Within `<ul id="todos">` we have a values with computer generated "id" properties which represent the user input. Within the unique elements, there are classes and event listeners. > For example: ```html= <li id="task-1497141891479" class="complete" onclick="toggleComplete(event)"><i class="fa fa-check- circle-o"></i>Wake up</li> ``` > The event listener is prompted when a user clicks or unclicks a specific todo item. The event listener inside the element signals to "completed" from an if/else function. ```javascript= function addTodoItem() { if (!validateTask(inputEl.value)) { return; } var newTodo = { id: getTimeStamp() }; newTodo.task = inputEl.value; newTodo.done = false; data.push(newTodo); updateTodoItems(); resetInput(); } function toggleComplete(event) { var todoID = parseInt(event.currentTarget.id.replace('task-','')); var todoData = getTodoData(todoID); todoData.done = !todoData.done; updateTodoItems(); } ``` >Next, we examine the controls. The `<div class="controls">` contains an input textbox, an addtodoItem button, and a remove item button. The text box contains the event listener `onkeypress="onEnterKey"`. The add todo and remove todo buttons both contain the event listener `onclick` to trigger the functions `addTodoItem()` and `removeTodoItem()`, respectively. > When clicking in the "text" box the eventListener onkeypress="" is triggered. This creates a new class of <"focus-visible" data focus visible added> > When clicking on the _Add_ button, the addTodoItem() function is triggered. The addTodoItem() functi on is defined first with an if statement that references the `validateTask `function. If the value of the _task_ property equals an empty string, then validate task will return false. The ! sign indicates the opposite of, and since the opposite of false is true, the condition will evaluate to true, and the function will return. This means there was no task to add to the todo list. > If the value of the _task_ property does not equal an empty string, then validate task will return true. The ! sign indicates the opposite of, and since the opposite of true is false, the condition will evaluate to false, and the function will continue onto the next line. A variable called newTodo is added to the collective of "todos" with the id="getTimeStamp()". A newTodo.task is created with the value of the element input.The pattern also contains a class for "newTodo.done" which is set to the boolean of "false". The data.push(newTodo) prints the new todo to the collection of "todos". Lastly, the model resets. > When clicking on the _Remove_ button, the removeTodoItem() function is triggered. See below for the function declaration. When called, the function will create a variable called `incompleteTodos`, which will store an array. This array will be the array that is returned when the `data` array is filtered using the function passed in as an argument that tests if the todo item is not done. The array `data` is then defined as the incomplete items. Lastly the `updateTodoItems` function is called again so that the HTML output reflects the new source data in the updated `data` array. > Finally, we detail the updateTodoItems function as follows: > First, the HTML content for the variable "todosEl" is assigned to be an empty string. `todosEl.innerHTML = "";` Next, an "if" statement performs several actions based on whether the length of the array "data" is false (i.e., equal to zero). `if (!data.length)` If the data length of the array is zero, then an _li_ element with the text "Nothing todo..." is created and appended to the _ul_ element with id "todos". In other words, a list item is created that reads "Nothing todo..." when there are no items in the array _data_. ```javascript= var liElement = document.createElement('li'); liElement.innerText = "Nothing todo..."; todosEl.appendChild(liElement); ``` >If the data length of the array is NOT zero, then a _for loop_ goes through each item in the array. An _li_ and _i_ element are created for each item in the array. The attributes _id_ and _onclick_ are assigned to each element; the values for the id attribute is retrieved from the item's id value in the array. ```javascript= for (todo of data) { var liElement = document.createElement('li'); var iElement = document.createElement('i'); liElement.id = todo.id; liElement.onclick = toggleComplete; ``` > Next, an if statement checks whether the value for the property _done_ is true. If the value is true, the newly created list element is assigned the class of _complete_ and the _i_ element is assigned _check-circle-o_ (which gives the list item a checked circle). If the _done_ value is false, the newly created _i_ element is assigned a class of _circle-o_ (which gives the item an open circle). ```javascript= if (todo.done) { liElement.className = "complete"; iElement.className = "fa fa-check-circle-o"; } else { iElement.className = "fa fa-circle-o"; } ``` > Finally, the appendChild method is used to add the ielement to the end of the list element and the innerText element assigns the "task" (i.e., the text of the todo) to be the text of the _li_ element. ```javascript= liElement.appendChild(iElement); liElement.innerText = todo.task; ``` See HTML code below relating to the controls section : ```html= <div class="controls"> <input type="text" onkeypress="onEnterKey(event)"> <button onclick="addTodoItem()">Add</button> <button onclick="removeTodoItem()"><span id="counter"></span> Remove</button> </div> ``` **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?** >Our group decided to attempt to add a dropdown option to our program to help users categorize the importance of their "todo" item. In the process, we added Bootstrap to the codepen. We also discussed color-coordinating the tasks, or having the option to assign the todo to someone in particular. We will need to reformat the todo pattern in order to accomodate adding a new class(es). We would tie the other choice of priority or user to the class in the newTodo.el. >We can create a new property in the data array with the value of low, medium, and high as radio buttons. We would also need to connect that function to a button. The eventListener would be triggered based on what the user selects. In the function, there would be functions for eventListeners for all 3 categories, but changed to true when the button is selected.