### Part 1
:::warning
**Parts 1-4: Breaking it Apart**
It might help to start by forking the codepen into four separate pens. And for each pen, reducing/removing all unused code, i.e. both HTML and JS for that part, so that all that remains are the functional ones for that part to work. (There is a reason why I don't do this for you...)
Reducing what is visually in front of you can greatly help you to focus on the bits that are relevant to the sub-problem at hand.
Note that `printLog()` is utilized across multiple parts.
:::
- Click on the link at the top to view the `index-simple.html` version. Compare the HTML between this version and the Bootstrap version. Compare the JS between this version and the Bootstrap version.
- How do these two versions compare with regard to helping you understand Javascript?
:::info
The Javascript in both versions are exactly the same with the same functions, allowing the user to submit information and the buttons to react the same way even though the structure (via HTML) is different.
:::
- Play with the interface (each of the buttons) and observe how the program reacts. When tinkering, try changing the order in which you play with the interface. Take note of the printed _history_.
:::info
• History:
setName called():
firstName assigned to Estelle
lastName assigned to Tcha
greetUser called(): Estelle Tcha
printName called(): Estelle Tcha
:::
- Explain how this program works with regard to STATE, SEQUENCE, and CAUSALITY of each line, and/or specific parts of a line as appropriate. Use specific vocabulary, as demonstrated in the notes section.
- Be sure to articulate both aspects of the HTML and JS.
:::info
The <b>STATE</b> of the user is set at "anonymous undefined", making the first name and last name default to "anonymous" and "undefined" respectfully, until we input and set specific values for the first name (instead of "anonymous") and the last name (instead of "undefined"). Only after the user inputs new values will the variable printName be set at the first name and last name.
* *Refer to bullet point below under SEQUENCE to see STATE after a certain SEQUENCE is followed where the "RESET" button is utilized after the initial input of value.
The <b>STATE</b> of the JS for both versions are set the same.
The <b>STATE</b> for the HTML in the bootstrap version provides design structure utilizing panel-default, heading, title, body and also for the buttons. The simplified version does not have this
The <b>SEQUENCE</b> -- the order of the set of instructions -- is the order of the buttons here. This is important as the functions for the buttons "Greet User" and "Print Name" will automatically greet us as "anonymous undefined" if we do not input our own value for "Set Name". If the user clicks the button for "Set Name" first and inputs value for first name and last name before clicking the other buttons -- "Greet User" and "Print Name" -- then the functions utilize the values input by the user instead of the default "anonymous undefined".
* *However, once the "RESET" button is pressed, then the STATE of the default input value changes from "anonymous undefined" to "wonderful walrus", addressing the user as first name "wonderful" and last name "walrus" when the user clicks on "Greet User" and "Print Name" after the initial input value is "RESET".
The <b>CAUSALITY</b> in this program is to greet the user and print their name based on the user's input. By inputting a first and last name, the state of the program is changing. By clicking different buttons in different sequences, the sequence of the program is changing.
:::
- What does the `prompt` function return?
:::info
The prompt function enters the input value -- the first name & last name in this case -- and returns it to the function printLog() if the user clicks "OK" in the pop-up window.
:::
- Explain what you think the `document.querySelector()` does. Talk about this in terms of the functions vocabulary presented in the Notes.
:::info
The Document method querySelector() returns the first element within the document that matches the specified selector or group of selectors. So the first element from here is the first name of the full name. We set a [var firstName] from [function printName()] that combines the value for firstName and for lastName. After that, by using [document.querySelector(#full name)], we can return the first element of the full name.
:::
- If I told you that `document.querySelector` RETURNS something, what do you think that something is?
:::info
To return is to retrieve the element that is input into the function.
In this case, the full name.
:::
- How could you alter the `printName` function in order to print the users first and last name in the browser window tab?
:::info
```javascript
function printName() {
var fullName
document.querySelector('#fullName').textContent = fullName;
document.write('#prePartOne', `printName called(): ${fullName}`);
}
```
:::
- How would you use the `makeFullName` function to shorten the `greetUser` and `printName` code?
:::info
you could run the makeFullName function inside the `greetUser` and `printName` functions so that they wouldn't need to define the full name from scratch
:::
### Part 2
- Play with the interface (each of the buttons) and observe how the program reacts. When tinkering, try changing the order in which you play with the interface. Take note of the printed _history_.
- Explain how this program works with regard to STATE, SEQUENCE, and CAUSALITY of each line, and/or specific parts of a line as appropriate. Use specific vocabulary, as demonstrated in the notes section.
```javascript
function printLog(selector, message){
document.querySelector(selector).innerHTML += message + "<br>";
}
//variables introduced and username initialized
var username = "no username";
var email;
//function for changing the username according to text input in "username" category of form
function updateUsername(){
//calls the printLog function, which gets the innerHTML of the element with id="prePartTwo" and updates the innerHTML by adding "updateUsername called():" as the message
printLog("#prePartTwo", "updateUsername called():");
//this updates the username variable to be the value of the form input
username = document.querySelector('#username').value;
//this prints the update to the username variable by calling the printLog function and changing the message to clarify that the username variable has been updated.
printLog("#prePartTwo", ` username assigned to ${username}`);
}
//function for updating the email variable which uses one parameter (called "banana" here)
function updateEmail(banana) {
//calls the printLog function and updates the message parameter to be "updateEmail called():"
printLog("#prePartTwo", "updateEmail called():");
//updates the email variable according to the form input for the email category
email = banana.target.value;
//calls printLog again and this time updates message parameter to clarify that the email variable has been updated
printLog("#prePartTwo", ` email assigned to ${email}`);
}
//function for printing the form inputs
function printInfo() {
debugger;
//this updates the innerHTML of the element with id="userInfo" (so the banner above the form) to the values of the username variable and the email variable separated by a hyphen
document.querySelector('#userInfo').innerHTML = `<strong>${username} - <em>${email}</em></strong>`;
//this this prints the the update variables in the history
printLog("#prePartTwo", `printInfo called(): ${username} - ${email}`);
}
//this is the function for resetting the var username and var email values
function resetInfo() {
//this establishes the variable usernameElement and initializes it as the HTML element with id="username"
var usernameElement = document.querySelector('#username');
//this updates the value of usernameElement to be an empty string
usernameElement.value = "";
//this updates the value of the element with id="email" to be an empty string
document.querySelector('#email').value = "";
//this updates the banner text above the form to be "unknown person"
document.querySelector('#userInfo').textContent = "unknown person";
//this replaces the text in the history with two <br> elements
document.querySelector('#prePartTwo').innerHTML = "History:<br><br>";
//this puts a focus ring around usernameElement
usernameElement.focus();
}
```
-Be sure to articulate both aspects of the HTML and JS.
- What kind of events are happening in Part 2 and explain how this relates to when the handlers will run.
:::info
see annotated code above
:::
- What is `event.target`?
:::info
`eventTarget` tells you which element triggered the event (so which HTML calls the event)
:::
- What does the dot `.value, .textContent, .innerHTML` represent in this context?
:::info
`.value` represents the text input for form elements, which in this case are `username` and `email`
`.textContent` represents all the text stored within an element (including the computer readable-only text, like CSS and JS)
`.innerHTML` represents the human-readable text stored in the HTML element. In this scenario it was used to alter the text "History" in the element with `id="prePartTwo"` and the text greeting the user by name, stored in the element with `id="userInfo"`.
:::
- Why does `updateEmail` have a parameter for `event` data but the other functions do not?
:::info
The `updateEmail()` function uses a parameter to be able to update its value using `event.target`. So `banana.target` identifies the HTML element triggering the function, which in this case is the input element associated with `id="email"`, so `banana.target.value` gets the value of that element, or the text that gets input into the form, which in this case is the user's email.
:::
- `resetInfo` is actually a little broken. Why?
:::info
`resetInfo` doesn't actually update the values for `username` and `email` so if you press `printInfo` after clearing the history but before inputting new username and email values, `printInfo` will call the previous values for `username` and `email`
:::
### Part 3
- Play with the interface (each of the buttons) and observe how the program reacts. Take note of the printed _INFO_.
- Explain how this program works with regard to STATE, SEQUENCE, and CAUSALITY of each line, and/or specific parts of a line as appropriate. Use specific vocabulary, as demonstrated in the notes section.
- Be sure to articulate both aspects of the HTML and JS.
The button `Show Image Data (Partial)` calls the function `showImageData()`, which it then calls the `printElementPartialData()` function that look for `id=animalImage` in the document and print its data.
The `Show Image Data via Parent` called the function `showImageViaParent()` and it prints the first id element of `id=animalImageParent`'s children , which is`id=animalImage`.
The `Show Image Parent Data(Partial)` button calls the function `showParentData`, which it calls the function `printElementPartialData()` and print the data of its targeted id: `id=animalImageParent`.
The `Show Parent Data via Image` calls the function `showParentViaImage()`. This function will first look for the element with `id=animalImage`, then looks for the id of its parent which is `id=animalImageParent`.
The `Change Image` button calls the function `changeImage()`, which it select the image element with `id=animalImage`. It will then change the source of the image to the new source it defined.
The `Show This Button Data` button calls the function `showButtonData(event)`, which it prints the element that triggers this event.
The `Reset` button calls the function `resetPartThree()` which it assign the image cource back to its original image and blank all the date printed in `id=prePartThree`.
- Compare and contrast the `showParentData` and `showParentViaImage` functions.
- How do these two different functions achieve the same output?
`showParentData`immediately calls and print the element with the id `animalImageParent`, which it prints the data from the parent. `showParentViaImage` first look for the element with `id=animalImage`, then looks for the id of its parent which is `id=animalImageParent`, which result in identical result for `showParentData` and `showParentViaImage`.
- Play with the Change Image button.
- Can you modify the related code so that each time you pressed it, it would show 1 of 5 images, cycling through to the next image per click?
- There are several ways to solve this.
```javescript
var imgArray = new Array();
imgArray[0] = new Image();
imgArray[0].src = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/228274/wiggleCat.webp';
imgArray[1] = new Image();
imgArray[1].src = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/228274/wiggleDog.webp';
imgArray[2] = new Image();
imgArray[2].src = 'https://images.pexels.com/photos/45201/kitty-cat-kitten-pet-45201.jpeg?cs=srgb&dl=pexels-pixabay-45201.jpg&fm=jpg';
imgArray[3] = new Image();
imgArray[3].src = 'https://t3.ftcdn.net/jpg/02/95/94/94/360_F_295949484_8BrlWkTrPXTYzgMn3UebDl1O13PcVNMU.jpg';
imgArray[4] = new Image();
imgArray[4].src = 'https://cdn.pixabay.com/photo/2017/02/20/18/03/cat-2083492__340.jpg';
function changeImage(){
var img = document.querySelector("#animalImage");
for(var i = 0; i < imgArray.length; i++){
if(imgArray[i].src == img.src){
if(i === imgArray.length-1){
document.querySelector("#animalImage").src = imgArray[0].src;
break;
}
else{
document.querySelector("#animalImage").src = imgArray[i+1].src;
break;
}
}
}
}
```
- Play with the Show This Button button.
- What is the value of the property `onclick` of the button?
The `onclick`of the button called the javascript function `showButtonData (event)`, which it goes from its original state to printing text in the box .
### Part 4 - Challenge
- Play with the interface (each of the form inputs) and observe how the program reacts. Carefully take note of what actions cause what results, in what order. **ALSO**, open up your Chrome Devtools and watch your inspect elements tool pane as you interact with this form.
- Explain how this program works with regard to STATE, SEQUENCE, and CAUSALITY of each line, and/or specific parts of a line as appropriate. Use specific vocabulary, as demonstrated in the notes section.
::: info
The initial default <b>STATE</b> of this program is undefined. If no there is no input of value, the functions return an defined value, except for the radio function `Which do you prefer` which has a default input of the first value `Coffee`. For `What kind of coffee do you like`, once the user starts to input value, the user cannot return to "undefined".
The <b>SEQUENCE</b> of the form does not matter as none of the input value affects eachother as they are `static elements`.
In regards to <B>CAUSALITY</B>, there are call `events` that cause `effects` that run and return either a variable, string or function: `onclick`, `onkeypress`,`onkeyup`, `onblue`.
:::
- Be sure to articulate both aspects of the HTML and JS.
- Explain the differences between `select`, `checkbox`, `radio`, `textarea` with regard to how we get the input `values`.
:::info
`select`:
```javascript
function getSelectValue(event) {
///this variable first select element ith the id coffee
var selectEl = document.querySelector('#coffee');
///this returns the value of what is selected in #coffee
return selectEl.value;
}
}
```
`checkbox`
``` javascript
function getCheckboxValues() {
//This variable gets the input for the checkbox based on which boxes the user checks
var checkboxEls = document.querySelectorAll('#coffeeTime input[type="checkbox"]:checked');
//this variable creates an empty array that will contain the times of day when people drink coffee
var times = [];
//this pushes the selected checkbox labels to the var times array
for (var checkboxElement of checkboxEls) {
times.push(checkboxElement.value);
```
`radio`
```javascript
function getRadioValue(event) {
//this variable gets the value of the checked radio button ("coffee" or "tea")
var radioEl = document.querySelector('[name="whichDrink"]:checked');
//this returns the radio button value ("coffee" or "tea")
return radioEl.value;
```
`textarea`
```javascript
JS //this variable gets the value for the textare (Which the user will have filled in with their own text) and updates it to an empty string
var textareaEl = document.querySelector('textarea');
textareaEl.value = "";
HTML
<div class="form-group">
<label for="why">Why do you like coffee?</label>
<textarea id="why" class="form-control" placeholder="Enter reasons here" onkeypress="saveCoffee(event)" onkeyup="characterTyped(event)" onblur="editingOff()"></textarea>
</div>
<div class="form-group">
<button type="button" class="btn btn-primary" onclick="saveCoffee(event)">Save</button>
<button type="button" class="btn btn-danger" onclick="resetCoffee(event)">Reset</button>
</div>
</form>
</div>
</div>
</div>
```
:::
- What is the importance of the `name` attribute, especially for radio buttons?
:::info
The name property is an HTML attribute that defines a radio input group. We can only select one of the options as they are a part of the same input group.
In JS, the name attribute references data that passes value to the document.querySelector() function.
:::
- Explain the significance of `e`, `banana`, `bananaEvent`, and `event`.
- How are they the same and how are they different?
:::info
All of the above are events. However they are used differently in the actual code.
`e` is used to capture the event.target, which tells you which HTML element triggered the event
`banana` is a parameter given to the function `saveCoffee` so that the function can get information about what happens when it runs via `banana.key` and `banana.type`. Then the function runs one way or another depending on what information it gets from banana.
`bananaEvent` is a parameter given to the function `editingOff`, but it is not passed into the function when it is called in the HTML (`onClick` inside the `textArea` element). So it is establishing the potential to get event data, but it is not currently gathering event data the way that it is running now.
`event` is the parameter passed into `saveCoffee` and `resetCoffee` and `characterTyped` functions when they are called in the HTML. This suggests that the parameter used when calling the function doesn't have to match the parameter used when defining the function in order to act as an event.
:::
- Try tinkering with some of these functions to produce some diffent looking, behaving results in the results pane.
- Explain what you tinkered with and what the results were.
:::info
Change 1:
```javascript
var checkboxEls = document.querySelectorAll('#coffeeTime input[type="checkbox"]:checked');
for (var checkbox of checkboxEls) {
//changed "false" to "true" and this meant that the checkboxes stayed checked even after I'd hit the reset button
checkbox.checked = true;
}
```
Change 2:
```javascript
function characterTyped(e) {
var pEl = document.getElementById('realTimeStory');
//changed pEl.innerHTML from "e.target.value" so that instead of getting the input value of the text area (aka what users are typing in), the realTimeStory just prints "hello there is no content here"
pEl.innerHTML = "hello there is no content here";
pEl.nextElementSibling.classList.add('hidden');
}
```
Change 3:
```javascript
function resetCoffee(event) {
var selectEl = document.querySelector('#coffee');
selectEl.value = "";
/// We changed the radio[0] to radio[1], which when reset, it will set be set to tea instead of coffee.
var radioEl = document.querySelectorAll('[name="whichDrink"]');
radioEl[1].checked = true;
var checkboxEls = document.querySelectorAll('#coffeeTime input[type="checkbox"]:checked');
for (var checkbox of checkboxEls) {
checkbox.checked = false;
}
var textareaEl = document.querySelector('textarea');
textareaEl.value = "";
/// We changed realTimeStoryEl.innerHTML = "" to realTimeStoryEl.innerHTML = "Let's try again", which when reset, "no content" will become "Let's try again"
var realTimeStoryEl = document.getElementById('realTimeStory');
realTimeStoryEl.innerHTML = "Let's try again";
realTimeStoryEl.nextElementSibling.textContent = "";
document.querySelector('.tags').innerHTML = "";
}
```
:::