rd2705
    • 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
    # Week 5 - Tinker Javascript Part II #### Rainy Duan, Steven Azeka, & Patrick Sunwoo #### MSTU 5003, Summer 2021 --- ### Part 0 --- * We played with the program and observed how it reacted to user interactions. In terms of the three observable steps or processes of three interactions - adding a `todo`, completing a `todo`, and removing a `todo` - we would explain the steps and processes of the interactions and how the program responded as follows: * The user lists a series of activites he/she/they have to accomplish that day. Once that activity is completed, he/she/they will cross out that activity from the list. Then, the crossed-out activity will be removed as soon as the page of listed activites is refreshed. * For each of the interactions above, we wrote in pseudocode the steps for how programs for different interactions unfolded and resulted, whilst considering the following rules: (1) One statement per line; (2) CAPITALIZE initial keywords; (3) READ, WRITE, IF, ELSE, REPEAT, UNTIL, AND, OR; (4) Indent to show hierarchy and groups of operation; (5) Keep statements language independent... * Making a To-Do List ``` READ list of todo activities READ todo activity Put todo activity on list WRITE completion progress Start the todo activity Do the activity READ completion progress WRITE stage of completion progress REPEAT UNTIL activity is completed Remove todo activity REPEAT for all todo activities ``` * Removing a To-Do Activity ``` WRITE number of todo activities total READ number of bulletpoints available READ completion progress IF todo avtivity is completed AND (total bulletpoints >= number of todo activities) delete todo activity decrement todo activities total ELSE add todo activity to list of todos ``` * Using our pseudocode, we identified the function(s) in the actual JS code that related to our pseudocode: ``` 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; } } ``` * Next, we compared and contrasted our pseudocode with the actual code. Through this process, we wanted to explain the similarities and differences we noticed about the instructions, steps, and processes in the code vs. our pseudocode: * We noticed that the computational thinking and the progression of events are similar in both codes. The pseudocode is not as specific as the actual code nor is does it refer to any buttons being used. There's also no reference to previous pseudocode like how the regular code references IDs. * Next, we manipulated different parts of the code as we saw fit. The following explains why we decided to manipulate these parts and what happened: * We decided to take out the `todosHTML` code and, as a result, the to-do list lost all the words/the list of activities from HTML. We wanted to manipulate this part, because this was the section that was not included in the pseudocode. --- ### Part 1: Variables, Functions, Arrays, and Events --- * First, we wanted to explain the `data` variable: * Firstly, this data (and the data inside) represented the following: * Conceptually, this data and the data within represent the information that we see and would like to complete as part of the todo list. For example, an instance of the object would represent the ID, the task and if the task was complete. * Next, to access the second object, we would accomplish this in the code by doing the following: * The quickest way would be to use the indexed array notation `data[1]`. We could also go to `var data` and just look at the second object. We could also either reference the id or the task. Below, we show the code that we could use: * ``todosHTML += <li id="task-${ todo.id }">; todosHTML +=`${ todo.task }`;`` * If we wanted to access the `done` property of the first object, we would do the following: * We could use the dot notation with the array `data[0].done`. We could look at the first set of data under var data.The done property here is false. The following shows this: `var data = [{id: 1497141891479, task: "Wake up", done: false};` * Next, we look through the rest of the code where this data array was used. * When the user does things, they are more likely manipulating the data and updating the visual display to reflect those changes: ``` 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 }; ``` * Overall, this is what we would have thought of as well, and we predicted something similar. We presumed that the visual display being updated followed manipulating data within the JS code. * The significance of this program design decision might be that it would be easier to visually display using code since data is already compiled. Using a function like the one above would be able to represent todo activities instead of writing each other out and then coding to represent. * Next, we examined these following lines of code: ``` var todosEl = document.querySelector('#todos'); var inputEl = document.querySelector('input'); var completedEl = document.querySelector('#counter'); ``` * We surmise that these lines work to attain the appropriate elements from HTML to use as references in later functions. For example, the `todosEl` variable was used later in the following later in the script: `todosEl.innerHTML = todosHTML;`. Also, the `addtoDoItem()` function utilized `if (!validateTask(inputEl.value))`, with the `inputEl` variable being set first and used in this specific line of code. * Next, we declared variables at the Global scope, instead of in the functions, such as ``document.querySelector(`#todos`):);``, because these codes could be used later for the remainder of our Javascript code. If they were declared in functions, it would only work for that specific function. However, if they weren't defined, then we couldn't use them in later functions. * Next, we examined the `toggleComplete()` function, which had an event parameter. Inside the function, we accessed `event.currentTarget`. The difference between `event.currentTarget` and `event.target` was that `event.currentTarget` let us know which element had the `event listener` that is associated with a specific event, while the `event.target` told us which element specifically triggered the event of interest, but doesn't seem to directly correlate to the current event listener. * In the `toggleComplete` function, there was a event.currentTarget.id. That `id` was *not* same as was the `id` property in the `todo` objects in the data array. This was because the `id` that `event.currentTarget.id` was referring to was not in the HTML code. * Next, in the code, `!something` means that whatever followed the exclamation would be negated. When we `toggleComplete`, the `!` mark was used as follows: `todoData.done = !todoData.done;`. This code suggests that `todoData` is not in the `done` state, as specified by the exclamation point preceding `todoData.done`. * Next, we tried calling some of the functions directly from the console, where some worked. The following explains what we found: ![](https://i.imgur.com/PvYyoLh.jpg) **<center>Figure 1: Result of calling functions directly from the console</center>** * Specifically, we found that we had to input the name of the function into `()` of `console.log()` or `console.dir()`. Otherwise, we wouldn't get anything out, as shown in Figure 1 above. * Next, we looked at the function declarations in the todos.js file. * Here, we found that each function was called in Javascript in the order and in the locations where the `todo` list activity occurred, in terms of a sequence. Each function was actually called (i.e., *when*) at the very end, when the entire program was initiated. That function usually had no parameters, shown by `()`, though some had parameters like `(events)` and `(id)`. The argument passed into the function when it was called was the result of the previous function, unless otherwise stated in the function. * Next, we used the console (in Chrome devtools) to console.log() and console.dir() the code below. ``` console.log(data); console.log(todosEl); console.dir(data); console.dir(todosEl); ``` * We found that there was a distinct difference between `console.log()` and `console.dir()`, in that `console.log` only returns what was written in the code, while `console.dir` gives us all the dtails associated with what we were calling. `console.dir()` may be more useful for examining some kinds of data because it reveals more data along the likes of `ariaAtomic` and `ariaAutoComplete`, showing values of `null`, in association with a certain id (see Figure 2). However, `console.log()` may show less detailed information, such as the value of a `class` property (see Figure 3). ![](https://i.imgur.com/OYueKaq.jpg) **<center>Figure 2: Result of using `console.dir()`</center>** ![](https://i.imgur.com/iBTYHUl.jpg) **<center>Figure 3: Result of using `console.log()`</center>** --- ### Part 2: Objects and Arrays of Objects --- * When we manipulated the different properties of the objects inside the `data` array, we found the following: * Changing the todo objects' `done` property to `true` inside the `data` array caused these items to be struck through and the text in the string to be italicized, along with a checkmark appearing in a circular checkbox, seemingly to denote that these tasks were finished visually through the strikethrough of text. This was, of course, undone when the item was clicked, which would cause the strikethrough and italicization to vanish. * Changing the task values as part of string caused the items inside the data array to display differently, based on what we changed it to. * All of this is shown in the figure below: ![](https://i.imgur.com/tOIHmNU.png) **<center>Figure 4: Changing the `done` property to `true` and changing task values inside the string </center>** * The code changes as displayed above when run because toggling the value of `done` to `true` seems to mark them with a strikethrough and an italicization of text. The `Boolean` property values of `true` and `false` are involved in this. Next, the `task` value seems to correspond to a string encased in quotation marks, where changing the content inside of the quotation marks changes the `task` value in the string that is displayed to the screen on the `todo` list. Additionally, when the value of `done` is changed to `false`, in a manner of speaking, the checkbox in the circle next to the list item tends to disappear. * Next, we worked to `console.dir()` the `data` array. We first went to the console and worked to OPEN the `> Array(3)` text by clicking on it. We then went deeper by opening up the nested objects. The following shows the results of our analysis of our findings, along with details about what was inside of the data array upon using `console.dir()` after adding a new `todo` through the user interface and investigating: * Before adding a new `todo`, the length of the array was considered "3", as shown by `length: 3` in the console, whilst the length of the array was considered "4", when a new `todo` was added. The indices ranged from `0` to `2` before adding a `todo`, whilst the indices ranged from `0` to `3` after adding a `todo` (please see below). It's also interesting to note the presence of the `id` values, where the adding of a `todo` required using one of the pre-existing `id` values. This would be worth exploring further in depth, though it seems that certain `id` values are required in order to produce items for the `data` array in the form of a `todo` list that can cross out items. Upon further research, this seems to represent the number of seconds from January 1, 1970 (source: https://flaviocopes.com/how-to-get-timestamp-javascript/). ![](https://i.imgur.com/cvJHTF5.jpg) **<center>Figure 5: Before adding a new `todo` to the `data` array </center>** ![](https://i.imgur.com/keYTdvg.jpg) **<center>Figure 6: After adding a new `todo` to the `data` array </center>** * Next, we ran the following code: ```javascript= data.push({ done: true, task: "Goto Aikido Lessons", id: getTimeStamp() }); console.dir(data); ``` * The above code, when run, led to the addition of another `todo` object using the `.push()` function that added an element to the end of the `data` array, as we learned in the FCC *and* set the `done` property to true, to indicate that the `todo` object was complete, with the `id` property being set to the current timestamp which, upon further research, seems to represent the number of seconds from January 1, 1970 (source: https://flaviocopes.com/how-to-get-timestamp-javascript/). * Our page ***does*** seem to reflect the changes made. This is likely because the properties are formatted and set to values in a manner that is consistent with the other elements in the `data` array. Specifically, setting the `done` property to `true` strikes through the text to indicate that it has been completed with a checkmark, whilst changing the value of the string representing the value of the `task` property manifests that value as a string on the list. This is proven by the output shown below: ![](https://i.imgur.com/8azToQX.png) **<center>Figure 7: After adding a new `todo` to the `data` array using the `.push()` method </center>** * Order ***does*** matter in Objects, as using the `.push()` function seems to only function properly at the end. Specifically, when the above code containing the `.push()` is **not** placed at the end of the `data` array, it seems that the entire visual output of a checklist disappears. This is further underscored by the use of `data.pop()` in the code, which, as mentioned in the FCC, removed the last value in the `data` array, but which seems to mainly function when it is placed at the end. however, which `data.pop()` is used in the middle of the array, the entire array seems to disappear. The same applies to the use of even `data.shift()` in the middle of the `data` array, as this removes the entire visual output of a list; however, placing `data.shift()` at the end of the array does do the job of removing the first object in the list. A similar issue appears when attempting to place `data.push()`, `data.pop()`, and `data.shift()` methods (and other similar methods) before the `data` variable is even declared, which seems to make sense, given that the data must be declared before a method of any kind is performed. * **`Object` keys** (e.g., `done`, `task`, `id`) seem to denote specific properties of objects that can manifest in various formats (e.g., Boolean, string) with specific values, whilst the **`Array` indices** seem to be used to access the actual properties through referencing, in the form of zero-based indexing. On a **fundamental level**, `Object` keys seem to refer to special types of data, whilst `Array` indices seem to reference specific variables (source: https://dev.to/zac_heisey/objects-vs-arrays-2g0e). Looking at the code below, the difference is further underscored not only in how the `Object` key and `Array` indices are referenced, but also how the specific `arrays` are set up. Specifically, for `Array` indices, the use of bracket notations with `Array` indices allows for specific `properties` to be accessed through zero-based indexing, which seems to be most appropriate for an array that is not necessarily represented by a set of objects, but rather an array represented by bracket notation that is inline, without the necessary need for `object` to be declared explicitly (e.g., `123`, instead of `id: 123`). On the other hand, the `Object` keys seem to be listed differently, with `Object` keys represented by explicit **properties** comprised of a specific **key** and its associated value (e.g., `id: 123`). * Using the `Object` keys and `Array` indices, however, are similar, in that each of them can be changed (albeit by different means), and each of which can be used to store a specific list of values (source: https://dev.to/zac_heisey/objects-vs-arrays-2g0e). As shown below, both the `myAry` `Array` indices and `myObj` `Object` keys are used to represent "123", "Code", and "true" as values (even if `myObj` more explicitly represents the property with its value). Each can have individual values accessed and changed (i.e., `myAry` through the use of zero-based indexing, bracket notation, and associated methods vs. `myObj` through the use of dot notation, naming of properties, and associated methods). ```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); ``` * Next, we compared the following in the console, in terms of an `element` and an `example` object: ```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); ``` * An `element` is a part of HTML language that of a starting tag, content that can defined in a variety of ways, and an ending tag. This element can consist of many methods and properties associated with it, such as `id`. This `element` seems to form the basis of objects in a `Document`. In the instance of the code shown, the `Document` method `querySelector` seems to return the first `Element` corresponding to a selector that is specified through such a method (source: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector). * Our `element` relates to `example`, in that it is declared as a variable and that is seems to be focused on a specific element, namely `ul`. Though not explicitly shown, it is also implicit (in most cases, at least) that there are at least a few properties associated with the `ul` that the `Document` method `querySelector()` is being run on. Our `example` seems to have these properties of `objects` specified by keys and values, such as `theAnswer: 42`. One key difference here, however, is that `element` here seems to focus on finding the first element using a selector using the `querySelector()` method of `Document`, whilst our `example` seems to involve some kind of array with `object` keys and values associated with them that `element` doesn’t specifically name. Moreover, `element` focuses more on one selector via the specification of `ul`, whereas `element` seems to consist of various foci, at least in terms of the `object` keys that are specificaied in the code. Moreover, one of the `object` key properties, `favNums`, has a value associated with it in the form of an array, which is not explicitly stated for `element` here. On a more fundamental level, element forms the basis of objects, whilst the `example` represents an object. The `example` object could be derived from an element, whereas the element itself forms the basis for objects like `example`. * To call the function in the `example` object, this could be done by using dot notation together with the `console.log()` method. Proof of this is shown in the figure below: ![](https://i.imgur.com/i1TuSyR.png) **<center>Figure 8: Calling the `function` in the `example object` </center>** * As seen in the figure, using `console.log(example.sayHello())` returns the alert, "Hello", in a dialog box. The use of the `dot` notation allows us to access the `sayHello()` function as a property of the `example` object, so as to call that function and to display the message inside the string of "Hello" as an alert in a dialog box. * Dot notation follows a format the names the object, followed by a `.` and the property of the object, so that the property of the object can be read. For example, `user.username` on Line 5 accesses the `username` property of the `user` object that is declared as a variable, returning the value of the `username` property, which is the string "happyCat". Bracket notation, on the other hand, names the object, followed by `[]`, where the property is placed in double quotes. For example, `user["username"]` on Line 6 accesses the `username` property of the `user` object that is declared as a variable, return the value of the `username` property, which is the string "happyCat". According to our FCC, the bracket notation is most useful when the property itself has spaces, which does not seem to be accessible using dot notation. Another instance where bracket notation would be useful would be with an array, especially given that there are already brackets being used as part of zero-based indexing, so, ¿por qué no? ```javascript= var x = "username"; var user = { username: "happyCat" } console.log(user.username); console.log(user["username"]); console.log(user[x]); console.log(user.x); ``` * There are many different cases in which the `.` object notation is used in the above code and in this week's Tinker, which will be covered below: * `console.log()`: The `console` object is the object that allows for debugging via the debugging console, as learned in the FCC. The `log()` is the `console` method that outputs the content in the parentheses to the web console for the purposes of debugging. * `console.dir()`: Again, the `console` object allows for debugging via the debugging console. The `dir()` is the `console` method that outputs the properties of the specific object in question that can be viewed and expanded in the console. Placing a parameter inside of the parentheses allows for a variable's list of properties to be displayed; the lists of properties can show child objects. * `user.username`: The `user` object is the declared variable `user`, which has specific object keys denoted by properties and associated values. The `username` is a property, or an `object` key, with the value of "happyCat" associated with it. Using these together allows for the value of the `username` property to be returned in the form of the string, "happyCat". * `Date.now()`: The `Date` is an object representing one moment in time (🎶 "Give me one moment in time..." 🎶 -Whitney Houston) that has properties associated with it in reference to how much time has passed since January 1, 1970 UTC, as mentioned previously. The `now()` property represents a method that refers to the current number of milliseconds that have passed since January 1, 1970 UTC (source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now). * `user.x`: Again, the `user` object is the declared variable `user`, which has specific object keys denoted by properties and associated values. The `x` represents a property of the `user` object that refers to value of the variable `x`, which is `username`. Put together, this dot notation should return the same output as `user.username`. * `document.querySelector()`: The `document` object is the entirety of the specified webpage, which can be used to get other elements and objects on the page (source: https://www.w3schools.com/js/js_htmldom_document.asp). The `querySelector()` property is a method is used to obtain the first element that corresponds to a specific slector (source: https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector). For example, `var inputEl=document.querySelector('input')` would return the first element with the tag `<input>... </input>` that is shown on Line 16 of the HTML code. * `todo.done`: The `todo` object is in reference to constants or values in a set of data with specific to-do items that are to be completed. On the other hand, the `done` property of the `todo` object is a property that has the Boolean values marked by `true` or `false`, with a value of `true` being denoted by the italicization and strikethrough of text, along with the ticking of a circular checkbox. * `todo.id`: The `todo` object is in reference to constants or values in a set of data with specific to-do items that are to be completed. In the context of this week's Tinker, each `todo` object seems to refer to the task that must be finished, such as a task like, "Get out of bed", as shown above in Figure AA. The `id` refers to a property of the `todo` object that seems to be represented by a number, perhaps in reference to the number of milliseconds passed since January 1, 1970 UTC. These `id` properties' values are associated with specific `todo` objects within represented by the `data` variable. * `todo.task`: The `todo` object is in reference to constants or values in a set of data with specific to-do items that are to be completed. In the context of this week's Tinker, each `todo` object seems to refer to the task that must be finished, such as a task like, "Get out of bed", as shown above in Figure AA. The `task` refers to the property of the `todo` object specified by a string in double quotes representing what the user must do, like "Get out of bed", as shown in Figure AA above. * `completedEl.textContent`: The `completedEl` object refers to the variable `completedEl` declared in Javascript, which is obtained by running the `document` method `querySelector` to return the first element associated with the `id` attribute of `counter` that is part of the `<span>...</span>` element in HTML associated with removing `todo` objects from the `todo` list. The `textContent` property is the property that returns the text content of all elements associated with the `completedEl` object. However, contextually, this set `object.property` finds the length of a string associated with a set of finished to-do's, so long as there are `todo` objects still existing, as implied by the following Javascript code: ```javascript= var completedTodos = data.filter(function(todo){ return todo.done === true; }); ``` * Here, the `completedEl` object seems to be associated with removing items from a list, as implied by `function updateRemoveBtn()` that precedes the code above (source: https://www.w3schools.com/jsref/prop_node_textcontent.asp). * `completedEl.parentElement.disabled`: Again, the `completedEl` object refers to the variable `completedEl` declared in Javascript, which is obtained by running the `document` method `querySelector` to return the first element associated with the `id` attribute of `counter` that is part of the `<span>...</span>` element in HTML associated with removing `todo` objects from the `todo` list. Again, the `completedEl` object seems to be associated with removing items from a list, as implied by `function updateRemoveBtn()`. The `parentElement` property, as the name suggests, is the parent element of the current object of interest. The `disabled` property is the state of the `parentElement` of the `completedEl` object being disabled, where disabling `parentElement` seems to occur only when `completedEl.textContent` = `completedToDos.length`. This seems to, in a sense, not disable the `Remove` button, so long as there are `todo` objects still in existence, as implied by the following code: ```javascript= if (completedTodos.length) { completedEl.parentElement.disabled = false; } else { completedEl.parentElement.disabled = true; } } ``` * `event.code`: The `event` object is an event that occurs that occurs as a result of some action by the user, where `event` refers to a parameter in the context of this code passed into `function onEnterKey()`. This event can have a event handler associated with it that names the event, where `onEnterKey()` implies that, upon entering a key, the user triggers an event associated with the `event` object. The `code` property seems to represent an actual physical key on the keyboard that the user inputs, which has an associated value with it. For example, for the `event` object with property `code` having a value of "Enter", the `addTodoItem()` function occurs in response, which adds an event to the to-do list. * `data[i].id`: The `data[i]` object refers to an index that is referenced by `[i]` in brackets from the `data` array at the top of the Javascript code. The `id` property of the `data[i]` object refers to the `id` values associated with each of the objects found in the `data` array. In the context of this week's Tinker, `data[i].id` is used to iterate through a `for` loop, where, if the property of `id` for the `data[i]` object in the `data` array matches the `id` value, the `todoFound` variable becomes equivalent to the variable indexed at "i" in the `data` array. * `inputEl.value`: The `inputEl` object refers to the variable `inputEl` found from the first element returned by the `Document` method `querySelector()` for the `<input>...</input>` element, corresponding to the user's input of type `text`, as shown in the HTML code. The `value` property refers to either a default value, a script-assigned value, or the value that the user entered as an input (source: https://www.bitdegree.org/learn/javascript-input#:~:text=The%20JavaScript%20input%20text%20property,value%20assigned%20by%20the%20script). In this specific context, `inputEl.value` is set to the value of `newToDo.task`; that is, the `task` property of the `newToDo` object that is delared as a variable is added to the list, corresponding to an item being added to the to-do list shown as a visual output on the screen. * `event.currentTarget.id.replace()`: The `event` object is an event that occurs that occurs as a result of some action by the user, where `event` refers to a parameter in the context of this code passed into `function onEnterKey()`. This event can have a event handler associated with it that names the event, where `onEnterKey()` implies that, upon entering a key, the user triggers an event associated with the `event` object. The `currentTarget` property is the specified element with an event listener to initiate some given event, as noted previously. The `id` property refers to the value of the `id` associated with the element specified by the `currentTarget` property in association with a specific event listened to initiate a given event. Finally, the `replace()` property refers to a function in which some string seems to be replaced. This property is implied in the Javascript code by the code that follows it: `var todoID = parseInt(event.currentTarget.id.replace('task-',''));`. * In two areas of the specified code, we see a `filter` function, which can be used by arrays. The following details the means through which this function works, its importance, the purpose of certain Booleans returned, whether the *filter* function changes an original array, and what the *filter* function actually returns: * A filter function works by seemingly returning all values within the array that match with a specific argument that are specified by `return`. Specifically, with both variables `completedTodos` and `incompleteTodos`, there is the following argument: `return todo.done === true`, where the `done` property of the `todo` objects within a given array must have a Boolean value of `true`, as shown by the strict equality operator, which implies that these are returned in an array, perhaps to be filtered as an array, either for inclusion or exclusion. This is consistent with what was found upon deeper, independent research (sources: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter, https://www.javascripttutorial.net/javascript-array-filter/). * The `function(todo)` argument passed INTO the filter parameters has a particular significance, in that it specifies `todo` as the parameter for consideration as an object, where its particular property of `done` being set to true allows for the determination of what is in the array that is returned. That is, the `todo` parameter allows for the `todo` object to be the only object under consideration for making a new array with all elements that match the given argument of `todo.done === True`. The function argument serves to specify which object is under consideration, so as to return a set of elements pertinent to the function of interest. In the instances shown, the function argument of `todo` passed into the filter parameters allows for a new array to be created with the specific tasks that have been completed as part of the `completedTodos` and `incompleteTodos` variables. * The purpose of the function needing to `return` a boolean or evaluating to a boolean allows for the `done` property to be tested to either be a boolean value of `true` or `false` that corresponds to whether a task was complete or not, respectively. In essence, the purpose of this function is to evaluate very simply in a binary way whether or not a task was complete, represented by the two aforementioned boolean states. * As mentioned, the *filter function* returns an array with values that are consistent with the `done` property of the `todo` object being set to a boolean value of `true`, meaning an array with values matching up with tasks that have been complete as part of the `todo` object. * In spite of the array returned by the *filter function*, filtering an array **does not** seem to change the original array itself. Instead, filtering an array seems to merely return an array that matches up to a given function argument that is passed into the filter parameters. In a sense, we can think of the *filter function* as giving us additional information about what meets a given function argument, rather than altering what we originally had. --- ### Part 3: Control Structures --- ``` javascript= 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(); } ``` * In reference to the above code, when the `updateTodoItems()` function is called, it will go through the for loop, `for (todo of data)`. The `for` loop will go through the entire list of `data` objects, with each instance given the value of `todo`. We could have used a more traditional approach of `for`, if we wanted to go through part of the instances. However, the conditional is necessary because of how it evaluates and represent an object on the to-do list being finished, shown by the property of `done` for the `todo` object. Specifically, the `if (todo.done)` statement as part of the property of `todo` is set to `true`, it will assign that item to the CSS rule of `.complete`, which corresponds to italicizing and striking through the text in the to-do list, proven by the fact that such formatting disappears when `"class=complete"` is removed. On the other hand, the `else` part of the conditional is necessary to indicate that `class` is *not* set to `"complete"`, even if the `id` property of the `todo` object is added to the list by using the addition assignment operator (`+=`) to concatenate the list item with an id that involves a task inserted through a template literal in the form of `$ { todo.id }`. The distinction here from the `if` statement of the conditional is further distinguished by the fact that the `fa-circle-o` class is a class for the icon (`<i>...</i>`) element, denoting a circular checkbox that is not checked. The function will add to the list the value of each `todo.task` to `todosHTML`. It also returns the value of `Nothing todo...`, if todosHTML is empty. ``` css = .complete { text-decoration: line-through; font-style: italic; color: grey; } ``` ``` 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; } } ``` * In reference to the above code, the `updateRemoveBtn` begins by creating a new array using the `filter` function with each instance of the `true` data object copied. The total number is then passed through `completedEl` and displayed on the button using the `textContent()` function. The `completedEl.parentElement.disabled` either enables or disables the ability to use the button, based on if there are items complete (i.e., no items complete = `false` --> items complete = `true`). Here, the conditional is necessary, as the `if... else` statement evaluates whether items on the to-do list have been completed, which results in either disabling or not disabling the `parentElement` property of the `completedEl` object using the `disabled` property for `parentElement`. Specifically, as part of the `if` statement, if the `completedTodos` object has a `length` property that seemingly exists, representing no items being complete, the `disabled` property of the `parentElement` property of the `completedEl` object is set to false, indicating that no items have been compelete. On the other hand, as part of the `else` statement, if the `completedTodos` object doesn't have a `length` property, then the `disabled` property of the `parentElement` property of the `completedEl` object is set to `true`, indicating that items have been completed. ``` javascript= function onEnterKey(event) { if (event.code === "Enter") { addTodoItem(); } } ``` * In reference to the above code, when entering the text in the text area, the `onEnterKey` function will call the addTodoItem function when the user returns the value of `return`. The `if` statement of this conditional is necessary, because, this represents what is inside the curly braces represents what will happen when the "enter" key is hit; specifically, if `event.code` is strictly equal to `"Enter"`, representing a case in which the `event` object is an event that occurs by the user hitting "Enter" after entering input into the text box, this triggers the `addTodoItem()` function, which means the user input will be added as a `todo` object into the array. ``` javascript= 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(); } ``` * In reference to the above code, in the `validateTask()` function, the parameter of `task` is passed into this function. The `if... else` statement is necessary here, because the `if` statement represents the instance in which the parameter, `task`, is *not* equal to an empty string (or empty value), which means the task has some content in it, and this will return a boolean value of `true`, which seems to represent a valid task; on the other hand, the `else` statement represents the instance in which the parameter, `task`, *is* equal to an empty string, which means the task has no content in it; this will return a boolean value of `false`, which seems to represent an invalid task. * Next, the `addTodoItem` function above calls the value of `inputEl`, a global variable set to the input element. Using the `validateTask` function, if the value of `inputEl` is blank, it returns `false`. Here, the `if` statement as part of the conditional is necessary, because not running the `validateTask()` function on `inputEl.value` seems to return no value, given only the presence of `return` in the code. The `addTodoItem` function then flips and returns this value. The function then creates a new object `newTodo` with the time stamp value for the id and fills the task property with the user entered text. This instance of the `newTodo` object is automatically set to `false`. The function then pushes the `newTodo` object into the original data object and updates the list, while resetting the button by calling there respective functions. ``` javascript= 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; } } ``` * Next, in reference to the above code, the `getTodoData` function takes in an `id` value and compares it to the existing id’s in the `data` object with an iteration through index values. Within the `for` loop, the variable `i` is initialized as an index value of 0 that continues until the end of the `data` array, with the value of `i` being incremented for each iteration. Here, the `if` statement as a conditional in the `for` loop is necessary because it allows the `id` property of `data` object at index `i` (using zero-based indexing) to be compared against the value of `id`. If there is strict equivalence, this sets `todoFound` with a value of `data` at index value `i`, then it breaks the code. In essence, the `if` statement evaluates whether the past value is found; if the passed value is found, it passes the `todoFound` variable the instance of `i` of the `data` object and breaks, then returns the value. Then, outside of the `for` loop, the next conditional `if... then` statement is necessary, because it evaluates whether a passed value is found in the `data` object called `todoFound`, based on whether `todoFound` or `null` is returned. Firstly, for the `if` part of the statement, if the passed value is found, shown by `if (todoFound)`, it passes the `todoFound` variable the instance `i` of the `data` object, then it returns this value. If not, it returns a `null` value. This would be interesting if you had multiple instances with the same `id` – this wouldn’t happen. * In general, the boolean condition seems to operate by evaluating whether the boolean condition is true; in the instance that it *is* true, it seems that the variable may be returned. This is exemplified above by the `return todoFound` for the Boolean `if(todoFound)` condition in the `getTodoData(id)` function. The boolean condition also tests out strict equivalence operators (`===`), `not` operators (`!==`), properties (e.g., `todo.done`), and functions (e.g., `!validateTask(inputEl.value)`) to decide how to proceed and to see if what's inside the `if...` statement will actually be executed. * The `for of` loop seems to work by taking items, like `todo`, from `list` (e.g., `for`(`todo` of `data`)), then evaluating each item in the list through an iteration, of some kind, then generating outputs. For example, with `for (todo of data)`, the boolean conditional of `if (todo.done)` seemed to concatenate not only the `todo.id` property through a template literal, but also a `class="complete"` that is visualized by italicizing and striking through text, and another class of "fa-check-circle-o" for the `<i>...</i>` element, all of which corresponds to task being completed. On the other hand, the `else` was missing this "complete" class and "fa-check-circle-o" for the `<i>...</i>` element, with the iteration occurring for every single item in the list that come in the form of tasks on the list. The `item` in `item of list` seems to represent a specific object that is being evaluated by being passed as an argument into the `for (list of items)` loop to decide whether the `if` or `else` statement executes. * The `for of` loop is more convenient that a conventional `for` loop, it seems, because the `for` loop may require initialization of the variable, conditions on the variable, and incrementing the variable. The `for of` loop, however, seems to provide a shorthand way of denoting this to allow for faster, more efficient evaluation. This is most properly exemplified by the use of the `updatetoDoItems()` function, where `for of` is used in lieu of iterating `for` multiple times to iterate through all of the objects in the `data` array. * The `for` loop is used the `getTodoData(id)` function when finding and passing in the `id` values using zero-based indexing to determine whether `id` property matches the `id` value in general to return either `null` or `todoFound`. The `for of` loop, on the other hand, was used to evaluate a list of items, where the `todo` item of the list `data` is evaluated for whether or not the property `done` is set to true to include or not include the `"complete"` class that corresponds to striking through and italicizing text and the `fa-check-circle-o` class associated with the `<i>...</i>` element that corresponds to checking off a circular checkbox; the `if` component does include the above two classes, while the `else` component does *not* include the above two classes. * On Facebook, Pinterest, and Twitter, the loop through data seems to refer to the repetitive nature of formatting of boxes, such as dialog boxes for posts on Facebook or posts on Twitter (I don't know - we're trying here!). We could see a similar formatting for `container` classes being executed for both `if` and `else`, though, if we're getting creative, maybe the privacy status of different posts on Twitter and Facebook might depend on whether the `if` or `else` part of the conditional is met? Who knows. Also, given recent, shall we say, Twitter wars with the alt-right, we could also imagine Twitter somehow finagling its ingenious algorithm to identify certain key words or text using `for` loops, so as to auto-generate messages about "fake news" using special formatting via CSS classes. For Pinterest, we could see looping through data being used data being changed upon hovering or upon clicks, in, perhaps, an analogous manner to the "complete" class being executed upon clicking upon an element in this Tinker in the to-do list; specifically, we could see an image on Pinterest turning grey upon a click, perhaps using a `for` loop that continues, where an `else` statement that doesn't match a non-clicking condition or event may lead to an image being greyed out. --- ### Part 3 (Continued): Specific Routines --- ```javascript= 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(); } ``` * The updated version doesn’t use the radio buttons; instead, it changes state based on the click of the item text. This version also uses the `innerHTML` property of the `todosEL` element and sets it to empty string, whereas the original just directly set `Todos` to empty string. This version also uses the parent child relationship to embed the properties: `liElement.appendChild(iElement);`. In addition to all of this, the updated version creates elements like `li` and `i`. Nonetheless, both versions are similar, in that meeting the boolean condition specified by passing in the parameter (`todo.done`) into the `for (todo of data)` as part of an `if` statement allows for the class of an object to include "complete" (presumably to indicate a strikethrough and italicization of text) and `else` statement allows for an object to have the class of `fa-circle-check-o` to be executed, corresponding to the checking of a circular tick box. In essence, while there are different class names used and different means through which `if...else` conditional statements are incorporated, it seems entirely possible that both accomplish the same thing. * Regarding **why** the `getTimestamp` helper function would be called when creating new `todo` items, the helper function `getTimestamp` can be used to create a unique ID. If you had similar id values, you would run into issues adding the item and call it. For example, `getTodoData` would only return the first instance because of the `break`. It could have been resolved with multiple copies if the `break` is removed, however, with larger datasets, you would have to run through the entire set each time. The timestamp represents the number of milliseconds since January 1, 1970. On a more practical level, perhaps the timestamp would be used for time-sensitive tasks that need to be completed by a certain deadline, represented temporally by a certain number of seconds from January 1, 1970. The timestamps may also be utilized to represent temporal limits or time elapsed from January 1, 1970 that could be used through application to prioritize the to-do list using different objects chronologically organized. ![](https://i.imgur.com/eJDV8It.png) ![](https://i.imgur.com/wHwdaXm.png) ```htmlembedded= <button onclick="markAllComplete()">mark all</button> ``` ```javascript= function markAllComplete() { for (todo of data) { todo.done = true; } updateTodoItems(); } ``` ![](https://i.imgur.com/KYezBhP.png) ```javascript= HTML: <p id="numberComLeft"></p> JS: updateItemsLeft(); ... function updateItemsLeft() { var completedTodos = data.filter(function (todo) { return todo.done === true; }); document.querySelector("#numberComLeft").innerHTML = "Completed tasks: " + completedTodos.length + " Tasks left: " + (data.length - completedTodos.length); } ``` * We tried to complete the incomplete functions `markAllComplete` and `updateItemsLeft`, though we were unsuccessful. The explanations of each function and the steps we tried to use are detailed below: * The `markAllComplete` function cycles through all the instances of the object, then calls the `done` property shown by the dot notation, and sets it to `true`. To update the list of items, we would need to call the `updateTodoItems` function. The JS code we tried to use is below: ```javascript= function markAllComplete(){ initializeTodos(); todosHTML = ""; for (todo of data) { todosHTML += `<li id="task-${ todo.id }" class="complete" onclick="toggleComplete(event)">`; todosHTML += `<i class="fa fa-check-circle-o"></i>` } } ``` * The thinking here was that the use of `todo of data` could be used in lieu of a `for (todo)` or other similar kind of loop to iterate through the indices. Since this was not successful, as noted before, we hypothesize that a potential solution would be to call the `updateTodoItems` function. * The `updateItemsLeft` function filters out all the existing data items via `data.filter(function (todo)` and returns those that are true via `return todo.done === true`. It then prints out the result. The JS code we tried to use is below: ```javascript= function updateItemsLeft() { data.filter(function (todo)); return todo.done === true; return "there are" + ${( #counter } tasks left to do; console.log("there are" + ${( #counter } tasks left to do); } ``` * Though we weren't successful, we tried to use `data.filter(function (todo))` to get an array out that consisted of todo data items and returned those that were true by setting the `done` property of the `todo` object equal to true. Th use of the template literals in both the `return` and `console.log` were in an attempt to try to insert the number of tasks remaining, taking into account both the number of tasks checked off, compared to not checked off. --- ### Part 4: Debugging, Tools --- Using the Chrome debugger (source) tool, we created breakpoints and watched the program execute line by line, part by part. Through this, we were able to experience how the debugger tool could provide us with insight into our program's STATE, SEQUENCE, and CAUSALITY. **Chrome Debugger** * First, we set breakpoints at the following locations of our program: * `function initializeTodos` * `function onEnterKey` * `function addTodoItem` * `function toggleComplete` * Upon refreshing the page and hitting the "Resume Script Execution" button under "Sources", our first pause was at `var data=` (Line 117 of JS code). This then skipped to `var todosEl=` (Line 136 of JS code), followed by `var inputEl=` (Line 137), then `var completedEl=` (Line 138), then `initializeToDos()` (Line 272). This is followed by jumping to `function initializeTodos()` (Line 140), which is then followed by `updateTodoItems()` (Line 141), then the end of `}` (Line 142). Nothing happens up to Line 141. Then, all of a sudden, a to-do list populates with tasks, with the final task, `Learn code` being struck through, with the round checkbox being checked off. The sequence seems to execute somewhat out of order via pausing as part of routines, which incorporates variables, followed by a function declaration at the bottom, followed by further up in the program. Overall, using the `step over next function call` will carry out code without exploring specific aspects of a function call, with the next function call after pausing being skipped, if it is not pertinent to the debugging problem of interest (source: https://developer.chrome.com/docs/devtools/javascript/reference/). That is, each time the program pauses, this focuses on function calls being skipped that do not pertain to the problem being debugged, hence the skipping. * The `step into next function call` starts with highlighting `[` as part of `var data = [` (Line 117), then `document` as part of `var inputEl = document.querySelector('input')` and`var inputEl = document.querySelector('input')` and `var completedEl = document.querySelector('#counter')` (Line 136-138). Then, the `initializeTodos()` was highlighted. Next, the `updateTodoItems()` function as part of `function InitializeTodos()` (Lines 140-141). After this, the empty string `""` as part of `var todosHTML = ""` (Line 145) was highlighted. Next was `data`, then `todo`, on Line 146 as part of `for (todo of data) {`. Next, `if` as part of `if (todo.done)` on Line 147, then `todosHTML +=` (line 151), then `todosHTML +=` (line 152), then `todo` as part of `todosHTML += `{ todo.task } (line 155). Next, `todosHTML` as part of `todosHTML += </li>;` (line 156). Next, `todo` on line 146 as part of `for (todo of data)`, then `if (todo.done) {` (line 147), then `todo` on lines 151-152 again, then `todo` on line 155, then `todo` on line 156, then `todo` on line 146, then `if` on line 147, then `todos` on lines 148-149 again, then `todo` on line 155, then `todosHTML` on line 156, then `todo` on line 146, then `if` on line 158 as part of `if (todosHTML === "") {`, then `todosEl` as part of `todosEl.innerHTML = todosHTML` (line 161), then `updateRemoveBtn()` (line 162), then `data` as part of `var completedTodos = data.filter(function(todo){` (line 166), then `done` as part of `return todo.done === true;` (line 167), then line 141 or 166 (not sure), then `done` (line 167) twice, then line 141, then `completedEl` on line 170 as part of `completedEl.textContent = completedTodos.length`, then `length` as part of `if (completedTodos.length) {` (line 172), then `completedEl` as part of `completedEl.parentElement.disabled = false` (Line 173), then the closing curly brace on line 177, followed by the curly brace on line 163, then the closing curly brace on line 142. This was followed by highlighting `</script>` on Line 273. * **Key differences:** The `Step over next function call` feature seems to move past a function call on the line where the debugger may currently be located, if that specific function is not pertinent to the problem that we are not trying to debug, without moving into specific function calls, whilst `step into next function call` seems to literally move into function calls on the nearmost lines (source: https://developer.chrome.com/docs/devtools/javascript/reference/). For example, the `step into next function call` seems to go into the `if... else` components of the `for (todo of data)` loop, whilst the `step over next function call` skips over this `for (todo of data)` loop entirely. These help me to understand programs in terms of the specific functions via the `step into next function call`, as executed in the code. However, the `step over next function call` helps me to understand which aspects of the line for the problem that is being debugged are pertinent. * Next, we used `Step into` until we reached the line `var inputEl = document.querySelector('input');`, which was highlighted in blue. We then highlighted the variable `todosEl` on the line before it, right-clicked it, and chose *Evaluate in console* (or, in the case of the console, *Evaluate selected text in console*). * As a result of this, the console printed `undefined` when the entire line was highlighted and selected. However, when the variable `todosEl`, only, was selected and evaluated in the console, the following was printed: `<ul id="todos">`. Upon expansion, this revealed the following: ```javascript <ul id="todos"> <!--ITEMS HERE--> </ul> ``` * Upon highlighting the variable `inputEl` on the highlighted blue line, the console says that `inputEl` is undefined. * In this instance, `inputEl` is likely undefined because the user has not actually entered any input, given that the code is written as follows: `var inputEl = document.querySelector('input');`, where the `document` method `querySelector` method is used to return the first element from the `<input>...</input>` tag in the HTML code. * As we step through our code, the blue line seems to represent code that is *about* to be excuted. We surmised this due to the fact that the code was only executed after stepping into the next function call. For instance, when `var todosHTML = ""` was highlighted, nothing appeared. However, when we stepped into the next function call, tbhe following appeared in the console: ![](https://i.imgur.com/6wNbtox.png) **<center>Figure 9: Result of stepping into next code and the output that results </center>** * Specifically, as shown in the output above, the value of the variable `todosHTML` is only set to an empty string, `""` after we step into the next function call. * Another specific instance of proof for the fact that the blue line represents code that's about to executed was as follows: ![](https://i.imgur.com/piw1THK.png) **<center>Figure 10: Result of stepping into next code and the output that results regarding populating a list</center>** * Specifically, when moving to `updateRemoveBtn()` on Line 162, this is when TODO List X populates, with the last object or task, `Learn code`, being crossed out and the circular font-awesome button being checked off. * At this point, we predict that the console value of the variable `completedEl` on the next line would be `undefined`, if we were to `Evaluate to console` at this point, given that there are not necessarily any objects to remove, prior to a list of to-do items actually populating, hence rendering the `Remove` button moot, at this point. * Finally, we watched how the debugger annotated our source code with the updated state of different variables as our program progressed. * When entering a `for` loop in our program, any variables or function calls were executed and entered as part of the annotation. For example, with `function updateTodoItems()`, when the `for` loop was entered, the preceding `var todosHTML = ""` was annotated for this variable as `todosHTML = ""` to start. Then, as the program progresses through `if... else` conditional statements, once the end of the `else` statement is reached, the preceding lines seem to be utilized to update `todosHTML=`. For example, when Line 152 is reached, we get the following annotation in peach for `todosHTML`: `todosHTML = "<li id="\task-149714189147 onclick=\"toggleComplete(event)"`, which *does* not take into account the code on Line 152, which is as follows: ```javascript todosHTML += `<i class="fa fa-circle-o"></i>`; ``` * The above code only updates the state of the `todosHTML` variable after Line 152 is already passed. * In short, the `for` loop seems to update the state of different variables with preceding code that has already been passed. * When a `filter` function call is reached, no updated state associated with the variable is actually demonstrated. However, when the `filter` function call is passed to the nexdt line, the state of associated variables may be updated. For example, let's say we have the following code in the console: ```javascript=165 function updateRemoveBtn() { var completedTodos = data.filter(function(todo){ return todo.done === true; }); ``` * Here, going to Line 167 updates the state of `todo`, as shown by the following annotation in peach and in line with Line 166: `todo = {id: 1497141891479, task: "Wake up", done: false}`. * When this `for` loop is iterated through, the following other updates of the state of `todo` will show up: `todo = {id: 1497141913701, task: "Eat breakfast", done: false}.` `todo = {id: 1497141937545, task: "Learn code", done: true}` * It is also worth noting that, when the bottom of the `for` loop is reached, in the `Scope` window, where `Local` variables (we believe, at least) are defined and elaborated upon, there is a statement returns a `boolean` value of `true` or `false`. For the first two tasks, "Wake up" and "eat breakfast", we get the following statement: `return value: false`. However, for the final task, "Learn code", we get the following statement: `return value: true`. Moreover, the `Scope` window shows that, upon reaching the first line containing the filter function, the variable associated with it is undefined. * As shown above, `filter()` creates an array of values that match the values posited by a test, such as fulfilling a boolean condition of `true` or `false` for `done` (source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter). The `filter()` function works by running a function with a parameter passed into it, like `todo`. Where possible, the `filter()` function seems to engage in iteration over each and every element found in array, like the `data` variable, and pass each element from an array into the function of interest, with the `filter()` function serving to return values as part of an array if they meet the conditions specified by the `filter()` function (source: https://www.javascripttutorial.net/javascript-array-filter/). Let's take, for example, the following code: ```javascript=50 function updateRemoveBtn() { var completedTodos = data.filter(function(todo){ return todo.done === true; }); ``` * Here, the `updateRemoveBtn()` function utilizes the `filter()` function by passing `todo` as an argument to generate an array of filtered values that meet the criteria specified by the strict equality operator shown as follows: `return todo.done === true`. That is, this iterates through the `data` variable array, with only the last task, "Learn code", supposedly being returned, since that's the only `done` property of the `todo` object that has a boolean value of `true`. --- ### Part X: Putting all together --- // 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 }, { id: 1233048902189, task: "Buy bitcoin", done: true } ]; // var data = []; // 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 = ""; 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) { debugger; 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]; break; } } if (todoFound) { return todoFound; } else { return null; } } // HELPER FUNCTION function getTimeStamp() { return Date.now(); // this returns a timestamp in milliseconds since 1970. } // PARTIAL FUNCTIONS 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) } 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) } // START THE APPLICATION initializeTodos(); console.log('a'); console.log('b'); :::success * **Lines 1-18:** The object/variable `data` is declared and set equal to an array. Each of the three objects in the array has an id, task, and done property associated with it. The id property consists of a number representing the number of milliseconds from January 1, 1970 UTC. The task property refers to a string that represents a task for the user to do. The done property refers to a property with a boolean value of true or false, corresponding to whether that task was completed or not. * **Lines 21-23:** The objects/variables todosEl, inputEl, and completedEl are cached from elements considered to be important. Each variable is set using the document method querySelector, in reference to either an id (e.g., todos, counter) or a tag (i.e., input), all coming from either HTML or CSS. * **Lines 25-27:** The function initializeTodos() is declared, with updateTodoItems being a nested function that's declared. This happens at the start of the program. * **Lines 29-48:** When the `updateTodoItems` function is called, the var todosHTML is initialized to an empty string, shown by "" on Line 30. Then, the function updateTodoItems() will go through the for loop `for (todo of data)`, which will go through the entire list of data objects, with each instance given the value of todo. You could have used a more traditional approach of for if you wanted to go through part of the instances. When the `if (todo.done)` or the property of todo is set to true, it will assign that item to the css rule of `.complete`. The function will add to the list the value of each `todo.task` to `todosHTML`. It also returns the value of `Nothing todo...` if todosHTML is empty. For lines 33-34, With`<li id="task-${ todo.id }" class="complete" onclick="toggleComplete(event)">`, which involves using a string and template literal, it adds a list item with the todo id and gives it the css class .complete value to cross out the item and italicize it, while triggering the toggleComplete function passing the event value in as a parameter upon clicking on the item. The CSS for this is shown below: ```javascript= .complete { text-decoration: line-through; font-style: italic; color: grey; } ``` * As part of the list item id, "task-" is concatenated with the insertion of the template literal, where the value of todo.id can be inserted as part of the string. As part of this, there will also be todosHTML concatenated with the icon (`<i>`) element, where its class is set to font-awesome and font-awesome-check-circle-o, corresponding to a circle checkbox. On the other hand, when the todo.done property is not set to true, as denoted by "else", the todosHTML is concatenated with the list item id being set to "task-" being concatenated with the template literal, which is used to insert the value of todo.id using a template literal, where the list item with the todo item is added and will trigger the toggleComplete function passing the event value in as a parameter upon clicking on the item. The absence of the CSS class "complete" means that the item is not crossed out and that the circular tickbox is not checked. In addition, todosHTML, as part of this else condition is concatenated using "+=" with the icon classes (`<i>`) of font awesome and font-awesome-circle-o, corresponding to a circular tick box that is not checked off. * **Lines 50-62:** The `updateRemoveBtn()` function begins by creating a new array using the filter function with each instance of the true data object copied. The total number is then passed through `completedEl` and displayed on the button using the `textContent()` function. The`completedEl.parentElement.disabled` either enables or disables the ability to use the button based on if there’s items complete (`no items complete = false --> items complete = true`). * **Lines 64-68:** When entering the text in the text area, the `onEnterKey` function will call the addTodoItem function when the user returns the value of `return`. * **Lines 70-94:** In the `addTodoItem` function it calls the value of `inputEl`, a global variable set to the input element. Using the `validateTask` function, if the value of `inputEL` is blank it returns false. The `addTodoItem` function then flips and returns this value. The function then creates a new object `newTodo` with the time stamp value for the id and fills the task property with the user entered text. This instance of the `newTodo` object is automaticly set to false. The function then pushes the `newTodo` object into the original data object and updates the list while resetting the button by calling there respective functions. * **Lines 96-101:** The toggleComplete function takes in an event. A new variable is created, 'todoID' that takes in the existing id and compares it to the existing list in Data. and then changes the done state. Finally, it updates the list. * **Lines 103-109:** The removeTodoItem function takes in an event. A new variable 'incompleteTodos' filters the current data of todos and returns the todos that have already been completed. The new data set only contains todos that are done and the list is then updated. * **Lines 111-113:** The resetInput sets the input element back to "" blank in the text box. * **Lines 115-131:** The `getTodoData` function takes in an id value and compares it to the existing id’s in the `data` object. If passed value is found, it passes the `todoFound` variable the instance `i` of the `data` object and breaks. It then returns this value. If not it returns a `null` value. This would be interesting if you had multiple instances with the same id – wouldn’t happen. * **Lines: 134-136:** The function getTimeStamp is called with the demand of returning the current date, resulting in a timestamp of milliseconds since 1970. * **Lines 157:** Starts the sequence of the program eventually calling updateTodoItems(); ::: **Make it yours (group's)** :::success * In terms of extending this program, we chose to extend ideas from this Tinker to our Doodles for this week. For example, the computational thinking behind clearing completed lists has really been helpful in getting us oriented to clear text when a button is pressed. We think this is the essence/crux of a to-do list, where things and events are organized in a logical way to provide order for the user. Due to this logical nature, it makes our work as programmers easier to think about the processes behind the code and to more effectively provide users with the experience that they need. Like you mentioned Jin, there's something so fulfilling about eliminating a completed task from a list of activities. We're still thinking of ways to apply this week's learning, so please look forward to our doodles and final projects! * Another thing that we tried to do using CSS to make this ours was to format the items in the list using different formatting using stars and colors. As shown below, the addition to the `.starcute` and `.red` classes allowed for the colors to change to red for completed tasks and blue for non-completed tasks. These classes were then added to the `updateTodoItems()` function. Additionally, `fa-circle` was changed to `fa-star` for the unchanged items. ![](https://i.imgur.com/ibsA5Ys.jpg) **<center>Figure 11: Reformatting font-awesome elements</center>** * In terms of JS and HTML, we also added a video component to the screen when any object was crossed out. We did this by first adding the following code to HTML: ```htmlembedded= <iframe id="ytVideo" width="560" height="315" src="" frameborder="0" allow="autoplay; encrypted-media" class="hidden" allowfullscreen></iframe> ``` * Next, we declared the following in JS: ```javascript= let el = document.querySelector('iframe'); ``` * Finally, as part of `function updateTodoItems()`, we added the following code as part of the `if...` conditional: ```javascript= el.src="https://www.youtube.com/watch? v=92cwKCU8Z5c"` ``` * This seemed to populate the video of interest the first time that an object was clicked and therefore crossed out; however, this didn't seem to work in subsequent iterations. We'll try more iterations. Patrick wanted to try out using some of what he used in a previous Doodle with remotes, but, oh, well... perhaps that can be remixed and reworked in the final project more extensively and he can get this to work! * Something that a Todo list or todo list that a user might benefit from is the ability to use the "complete" class, as it truly allows for practical applications when running the good ol' fashioned grocery store shopping list. It allows users the ability to add and remove items via this program. The todo list also could be reformatted using CSS, as noted above, to allow for more versatility when it comes to formatting different buttons in terms of prioritization.

    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