--- 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 >- Users input the texts of a new "to do" in the input field, click on the "Add" button, then the new "to do" will show up in the last line of the list. >- _Pseudocode_: >```markdown= > WRITE the texts of a new todo item in the input field > READ the new todo item added in the input field > WRITE the new todo item to the list > CLEAR the input field - Completing a todo >- Users click on anywhere within the line of the completed task, the line will have a strikethrough, the texts will turn grey and italic, the small circle will be checked. >- _Pseudocode_: >```markdown= >IF an item is clicked on > WRITE the item in grey color > WRITE the item in italic > WRITE the item with stikrthrough > WRITE the circle of the item with a check mark > WRITE the number in the Remove button to the number of items checked >ELSE write nothing - Removing a todo(s) >- Users click on the red "x Remove" button (x is the number of completed items), the completed items will disappear from the list. >- _Pseudocode_: >```markdown= > IF there are items completed > WRITE the number of completed items in front of Remove > WRITE the Remove button in red color > WRITE the text in the button in black color > ENABLE the Remove button > REMOVE completed items when clicked on > WRITE the text "0 Remove" in grey color > WRITE the button in grey color > DISABLE the remove button >ELSE > KEEP in the diabled state with grey button and the grey text "o Remove" 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= # Making toast for a big family READ loaf of bread READ slice of loaf Put slice in toaster WRITE time to toast Start the toaster Cook the toast READ time WRITE time by one second less REPEAT UNTIL time is zero Remove toast REPEAT for all slices in loaf # Serving toast WRITE number of slices total READ number of family members READ toastiness IF toast is burnt AND (total slices >= number of family members) throw away toast decrement slices total ELSE serve toast to family member ``` - 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. - Explain what similarities and differences you noticed about the instructions / steps / processes in the code vs. your psuedocode. >The pseudocode is somewhere between the descriptive actions and the real codes. It's a process to help sort out the logic and sequence to better find the final logic of the codes. But it's not the best choice for human reading or machine. Human read it with difficulties, while computers cannot read it at all. Therefore, we can use it as a tool to smooth the process. - 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.) > We tried switching between the normal quotes and template literals using backticks. It turned out that a template literal is so much better cause it's clear and concise. `<`won't be misunderstood as "less than", and there won't be `""`flying around. We also changed the CSS of the task inside `<li class = "">${task}</li>`,like duplicating the task or changing the color of the text to red, to make the to do list more decorated. ### Part 1: Variables, Functions, Arrays, and Events - Explain the `data` variable. - What does this data (and the data inside) represent conceptually? >It represent the tasks that the user input into the todo list which also contain the specific timestamp and the status of whether the task is completed. - If I wanted to access the second object, how would I do that in code? >`data[1]` - If I wanted to access the `done` property of the first object, how would I do that? >`data[0].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? >When the uset input new tasks, the data is manipulated and the visual display is updated to reflect those changes. - Is this what you would have thought of? >Yes. Visual display always update after the data is updated. - What might be the significance of this program design decision? >It makes a logical sense to have the visual display reflect those changes made in data. - What do these lines in my code do? ```javascript= var todosEl = document.querySelector('#todos'); var inputEl = document.querySelector('input'); var completedEl =document.querySelector('#counter'); ``` >To declare variables that associate with id and element from the HTLM. - Why declare these (see above) variables at the Global scope instead of in the functions? - Or not at all... (E.g. `document.querySelector('#todos');`) >Because they will be used often. Declaring these variables could allow them to be selected more conviniently later. - 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? - 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); ``` >![](https://i.imgur.com/haunG1I.png) When I use event.target in console, the console will display the second part of the picture. It contains no is and the onclick compare to when i use event.currentTarget. - 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? >No. The `id` property in the `data` array is the a unique identifier for all the items and the timestamp when the user input new tasks. The `id` in `toggleComplete` function is the identifier of the tasks that are currently unfinished. - What does `!something` mean? (The exclamation mark) and how is it used in this code when we `toggleComplete`? >`!` is a logic reversal operator, if something was true it will return false, if something is false, it will return true. >In the case of `toggleComplete`, it means that the completion status will change from complete to incomplete when the user click on the task. - Try calling some of the functions directly from the console. Some will work. Some won't. - Explain what you find. >Some cannot be observed. - Look at the function declarations in the JS panel. - _Where_ is each function being called? >The functions `initializeTodos` are called at the end of the JS panel. - _When_ is each function, actually called? >The function `initializeTodos` is actually called when the user open the page. And the nested functions are called afterward. - What parameter(s) does that function have? >`initializeTodos` does not have its own parameters. - What is the argument that is passed into the function when it is called? >There is no argument that is passed into the function. - 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); ``` ![](https://i.imgur.com/v4nO6Uy.png) >Because the `console.dir` could display the output in hierarchical listing that allow you see the contents of child objects. We could see all the properties of a specified JavaScript object. ### 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. > ![](https://i.imgur.com/PsbElXp.png) > ![](https://i.imgur.com/lvoVTpm.png) > All the listed items were crossed out when `done` was changed into `true`. When the value of `task` was manipulated in the array of data in Javascript, the page was updated by the `function initializeTodos()` and `function updateTodoItems()` , which changed the HTML content by getting the id of the objects in the array and updated the new objects. - `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? > ![](https://i.imgur.com/srvbOBP.png) > ![](https://i.imgur.com/uFQrpDe.png) > The number of items is `3` in the original array. The objects are listed in a sequence of index number`0`, `1`, `2` in the array. After adding one new todo, the number adds 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. - Does order matter in `Objects`? > ![](https://i.imgur.com/EbCX9En.png) > The above code adds a new todo object into the data array. The page reflects the changes by showing a crossed-over item in the list. The order matters in `objects` since it decides the sequence the objects were got by id in the HTML content in `function initializeTodos()` and `function updateTodoItems()`. Their orders in the array will help decide their ranks in the list. - 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); ``` >`Object` keys contain different properties and values of one specific object. `Array` is a collection of objects and can contain more than one objects. `Object` keys and `Array` indices are similar in that they can both reference data. While indices must be used along with `[]`, keys can be used with either `[""]` or `.`. - 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? - 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` here is a variable and refers to the selector of `ul`. `element` and `example` are both variables that have assigned values of an object. The difference is that the attributes and values of`element` is related to the specific item `ul` relevant to the selector. And they are not visible in the variable itself. However, the keys and value pairs of `example` are visible in the `{}` and the same keys and value pairs show up after `console.dir(example)`. The function can be called through `example.sayHello()`. > ![](https://i.imgur.com/CkoJfGA.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); ``` >![](https://i.imgur.com/ub134Fc.png) > Based on our observation, it seems that `console.log(user.x)` didn't return a username as we expected. This because the variable of `x` is not directly stored to the array `user` but is a reference. Therefore, we must use bracket notation here. - 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. > ![](https://i.imgur.com/uSGsJtU.png) > The document object represents the whole webpage. The right side of `.` is the querySelector() method, which is used to return the first element that matches a specified CSS selector in the document. - 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 filte function applies the argument function and creates a new array filled with elements that pass the test provided by a function. The function argument that is taken in the filter function must returen a boolean. The purpose is to use the `true` or `false` as the parameters to decide whether or not the items in the original array should be included in the new array created in the filter function. Filtering an array does not change the original array. ### Part 3 Control Structures - I use the `if` statement in several places in this code. Explain why a conditional is necessary in: - `updateTodoItems` - >`if` statement is necessary for checking `done` of several task objects `todo` in the array `data` is true. - >If `done` is true, `todosHTML will change this task's HTML to have the class of `complete`, and have a check on the circle. - >If `done` is false, todosHTML will not change this task's HTML to have the class of `complete`, and not have a check on the circle. - >If the 'todosHTML' is an empty string, it will have a `<li>` of `Nothing todo..`. - `updateRemoveButton - >`completedTodos` will have all the task objects if their `todo.done === true` in the form of array. - >if `completedTodos.length` is 0, the `parentElement` of `completedEl` will become `disabled`. if `completedTodos.length` is not 0, the parent `completedEl.parentElement.disabled` will be true. - >This `if` statement make the button which is the `parentElement` of `completedEl` enable or disable according to the number of compeleted todos. - `onEnterKey` - > if the user press `Enter` key on the keyboard, function `addTodoItem()` will be called. - `validateTask` - > check and return if the `task` is not an empty string. - `addTodoItem` - >use the function `validateTask` to make sure the user input value is not an empty string, otherwise the function will not run. - `getTodoData` - >With `for` loop, this `if` statement will find the task object according to the `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. - >it is usually used to check the statement in `()` is true, and make code after `{` run if the statement is true or make code after `else{` run if the statement is false. - 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? - > the loop will travel through every items of a list. - What does the `item` represent? (It can be named anything: `x`, `item`, `thing` etc.) - > it means a item of list, and the order of `item` in the loop is also according to the order in the `list` instead of a random order. - >In list `[1,2,3,4,5]`, the loop will start with item `1` and end with item `5`. - Why are `for of` loops convenient compared to the traditional `for`? - > We do not need to decide the begining number of `i`, the looping condition of `i`, and the change of `i` in every turn. - > We only need to decide the which list we want to loop. - For what purpose(s) do I employ a `for` or `for of` loop in this program? - > more specific use - > For example, If I want to loop in the reverse order of the list, I can use `i--` instead of `i++`, set the initial value of `i` to the value of `list.length-1`, and set the condition `i >= 0`. - On Facebook or Pinterest, or Twitter, how does a loop through data relate to the display of content? - > Firstly, generate the list of content according to the update time,user preference, or popularity. - >use a `for` or `for of` loop to display in the user-selected order. ### 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) { for (var i=0; i < data.length; i++) var liElement = document.createElement('li'); var iElement = document.createElement('i'); //liElement.id = todo.id; liElement.id = data[i].id; liElement.onclick = toggleComplete; //if (todo.done) { if (data[i].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; liElement.innerText = data[i].task; todosEl.appendChild(liElement); } } updateRemoveBtn(); } ``` > When we replece `for of` loop with traditional `for` loop using `i`, we also need to change `todo` to `data[i]` because `todo` is not exist anymore but `data[i]` has the same function. - 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`? - > We need a unique `id` for each task item in order to make sure that there are no same `id`s for different tasks. - > the function `getTimeStamp` returns a number, in milliseconds, the current time stamp since January 1, 1970, which is a unique number and can be used for the `id` of each task item. - Take a look at the incomplete functions `markAllComplete` and `updateItemsLeft`. - Can you complete these and add the functionality to this app? ```javscript= function markAllComplete() { for (todo of data) { todo.done = true; } updateTodoItems(); } ``` ```javscript= function updateItemsLeft() { let incompeted = 0; for (todo of data) { if(!todo.done){ incompeted++; } } feedbackEl.innerHTML = `You have ${incompeted} tasks left`; } ``` ### 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? `Step over` and `Step into` go line by line, `Step over` only show the code in one fuction but `Step into` will go into anothor function everytime the line of code contains a function. - 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? ![](https://i.imgur.com/ZctiRft.png) - Highlight the variable `inputEl` on this highlighted blue line. - Why does the console say `inputEl` is undefined? This line of code is about to be executed. - 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? Blue lines represent code that is about to be executed. Because the variables is not defined. And after step into, the variable is defined. - 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? Undefined. - 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? It show line by line from the condition of the loop to the end of loop. And goes back to the condition again and again untill the loop condition is no longer satisfied. - How does the debugger behave when you reach the a `filter` function call? It execute the return several times. The time is due to the number of list items in data. - What does filter do and how does it work? Filter's function parameter is a function. Here use an anonymous function that returns the Every data in the list will go through the function and test. If the return is true, it will reserve and the false one will abandon. ### Part X: Putting all together **Explain the program line by line with sufficient details, part by part.** :::success - Line by line - 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. ::: ```javscript= var data = [ { id: 1497141891479, task: "Wake up", done: false }, ``` > This data part is an array of three objects (The rest two are repetitive so not placed here). The id is numeric, the task is string, and the completion field is Boolean. > ```javscript= function initializeTodos() { updateTodoItems(); } ``` > This function is the start of the program. ```javscript= 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(); } ``` > This funciton modifies the output of todo text based on the events and attributes set in the HTML,and then displays the output. After the todo is completed, a strikethrough will appear on the text. If all tasks are finished, it will display `"Nothing to do..."`. ```javscript= function onEnterKey(event) { if (event.code === "Enter") { addTodoItem(); } } ``` >This function transfers the text input in the text box to the todo list. ```javscript= function removeTodoItem(event) { var incompleteTodos = data.filter(function(todo){ return todo.done === false; }); data = incompleteTodos; updateTodoItems(); } ``` >This function filters the incomplete tasks from the completed tasks. And the todo list will be updated. ```javscript= 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; } } ``` > This function uses a `for` loop and `if` `else` statement to identify the `id` and pick out data. If `todoFound` finds the data, it will return the data. Else, it will return `null`. **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? ::: > The current Todo list helps users to list down and organize their "projects" for a period of time. Based on this, we generated the idea of combining the Todo list with a calendar to assign each "project" with certain time blocks. Users will be more efficient if they are clear about what to do at a certain time.