# Session 08 - Javascript, Part 1

Harvard Extension School
Fall 2024

Course Web Site: https://cscie12.dce.harvard.edu/

### Topics

1. JavaScript
2. Getting Started with JavaScript
3. JavaScript and HTML
4. Document Object Model (DOM)
5. JavaScript and Ice Cream

Session 08 - Javascript, Part 1, slide1
Client-side Web Parts: Markup, Style, Function, slide2
JavaScript, slide3
Goals in more detail, slide4
Javascript, slide5
Javascript, slide6
Javascript Resources, slide7
Javascript: Manipulate Styles, slide8
Javascript: Manipulate Content, slide9
Javascript: Communicate with Web Server, slide10
Javascript: Add functionality, slide11
Javascript: Add functionality, slide12
Getting Started with JavaScript, slide13
JavaScript and HTML, slide14
Script element in HTML5 should have separate end tag!, slide15
JavaScript in HTML, slide16
JavaScript Basics, slide17
JavaScript Functions, slide18
Events, slide19
addEventListener function lets us add Event Listeners via JavaScript!, slide20
Document Object Model (DOM), slide21
JavaScript and DOM, slide22
JavaScript and Ice Cream, slide23

Presentation contains 23 slides

- img
- img
- img
- img
- img

## Client-side Web Parts: Markup, Style, Function

- Markup (HTML)
  - Structure
  - Content
- Style (CSS)
  - Style
  - Presentation
  - Appearance
- Function (JavaScript)
  - Actions
  - Manipulations
  - Behavior

Structure + Style + Function
solarsystem.html

## JavaScript

Goals for the JavaScript Unit

- Understand where JavaScript fits into front-end web development
- Understand some basics in JavaScript
- Understand how to use JavaScript
- Be ready for more!

## Goals in more detail

- Understand where JavaScript fits into front-end web development
- Understand some basics in JavaScript
  - Do essential operations:
    - DOM manipulations
    - if...else
    - for..of loops
  - objects
  - events
  - DOM
  - JSON data structures
  - Troubleshoot with browser console
- Understand how to use JavaScript
  - Separate JS from Markup
  - Be able to incorporate JavaScript functionality into a site
  - Be able to use JavaScript for commonly needed functionality
- Be ready for more!

## Javascript

"JavaScript is now a language every developer should know."
– VP of tech company

JavaScript is everywhere:

- servers,
- rich web client libraries,
- HTML5,
- databases,
- and more!

## Javascript

### What is it?

- JavaScript is a programming language
- JavaScript runs within web browser
- Key concept in JavaScript is browser events

### What can it do?

Javascript provides programmatic access to virtually all aspects of a page.

- CSS classes and properties
- Markup content
- Forms, communication to Server
- Add functionality

### ECMAScript and JavaScript

The standard for JavaScript is called ECMAScript.

## Javascript Resources

- MDN JavaScript
- JS Reference (DevDocs)
- W3Schools JavaScript
- Marquis, M. (2016). JavaScript for Web Designers (1st edition). A Book Apart.
- Niederst Robbins, J. (2018). Learning Web design : a beginner's guide to HTML, CSS, Javascript, and web graphics (Fifth edition.). O'Reilly.

## Javascript: Manipulate Styles

- Manipulate Styles / Classes
- Manipulate Content
- Communicate with Web Server to Get and Post data
- Add functionality such as maps, galleries, etc.

## Javascript: Manipulate Content

- Manipulate Styles / Classes
- Manipulate Content
- Communicate with Web Server to Get and Post data
- Add functionality such as maps, galleries, etc.

## Javascript: Communicate with Web Server

- Manipulate Styles / Classes
- Manipulate Content
- Communicate with Web Server to Get and Post data
- Add functionality such as maps, galleries, etc.

## Javascript: Add functionality

- Manipulate Styles / Classes
- Manipulate Content
- Communicate with Web Server to Get and Post data
- Add functionality such as maps, galleries, etc.

## Javascript: Add functionality

- Manipulate Styles / Classes
- Manipulate Content
- Communicate with Web Server to Get and Post data
- Add functionality such as maps, galleries, etc.

### Code highlighting!

    <header>
      <h1>Our Solar System</h1>
      <nav>
        <ul>
          <li><a href="#">Planet</a></li>
          <li><a href="#">Solar System</a></li>
          <li><a href="#">Galaxy</a></li>
          <li><a href="#">Universe</a></li>
        </ul>
      </nav>
    </header>
    <main>
      <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Montes nascetur ridiculus mus mauris vitae ultricies leo integer malesuada.
      </p>
    </main>

    header {
      background-color: rgb(250, 250, 200);
      font-family: sans-serif;
      display: flex;
      padding: 1rem;
    }
    header > nav {
      flex-grow: 1;
      flex-shrink: 1;
    }
    header nav ul {
      list-style-type: none;
      padding: 0;
      display: flex;
      justify-content: flex-end;
    }
    header nav ul li {
      margin-left: 1rem;
    }
    header nav ul li a {
      display: block;
      padding: 0.5rem;
      text-align: right;
      font-weight: bold;
      font-size: 1.2rem;
    }
    header nav ul li a:link,
    header nav ul li a:visited {
      text-decoration: none;
    }
    header nav ul li a:hover,
    header nav ul li a:active {
      text-decoration: underline;
      color: white;
      background-color: blue;
    }
    main {
      line-height: 1.5;
    }
    h1,
    ul,
    li {
      margin: 0;
      padding: 0;
    }

## Getting Started with JavaScript

- MDN JavaScript
- JS Reference (DevDocs)
- W3Schools JavaScript
- Marquis, M. (2016). JavaScript for Web Designers (1st edition). A Book Apart.
- Niederst Robbins, J. (2018). Learning Web design : a beginner's guide to HTML, CSS, Javascript, and web graphics (Fifth edition.). O'Reilly.

### Some basics

- JS in HTML.
  Including JavaScript in HTML with `script` element, with either `src` attribute or JS code.
- Variables.
  Declare variables with `let` and sometimes `const`.
  Though you will see the older `var`, which works but is not preferred.
- Console is your friend.
  Your browser developer tools will be critical to use, and especially the "Console". Log to the console in JS with

      console.log('hello there!');

- When is the code executed?
  `script` in `head` or right before the body close tag - `</body>`
  But it is good practice to rely on specific events!
- Objects
- Conditional flow. `if...else`
- Iterations and Loops. `for...of`
- Functions - named and anonymous
- DOM (Document Object Model)
- Events, Listeners, and Handlers
  `load`, `click`, `focus`, `blur`, `submit`, `mouseover`, `mouseout`, `keypress`.
  HTML attributes are available, but don't use these.
  Add event listeners through JavaScript!

## JavaScript and HTML

- `<script>` element
  - Can reference an external JS file (`src` attribute)
  - JS code can be within `script` element
- `<script>` element can go in `head`, but is often placed just before the body close (i.e. `</body>`) elements.
- Note the `<noscript>` element for clients without JavaScript.

## Script element in HTML5 should have separate end tag!

To function in all browsers, `script` element should have an explicit end tag. Best:

    <script src="jquery.js"  > </script>

Do not use:

    <script src="jquery.js"  /><!-- DON'T DO THIS -->

## JavaScript in HTML

External Script

      <script src="path/to/javascript/file.js"  > </script>

Script within HTML document

      <script>
        /*
          JavaScript code as content of script element
        */
      </script>

## JavaScript Basics

- Variables.
  Declare variables with `let` and sometimes `const`.
  Though you will see the older `var`, which works but is not preferred.
- Console is your friend.
  Your browser developer tools will be critical to use, and especially the "Console". Log to the console in JS with

      console.log('hello there!');

- Strings and numbers
- Objects
- Conditional flow. `if...else`
- Iterations and Loops. `for...of` and `.forEach()`
- Functions - named and anonymous

## JavaScript Functions

### Named Functions

    function davidsFunction() {

    }

### Anonymous Functions

    function() {

    }

### Functions with arguments

    function calcContrast(color1, color2) {
      let contrast;
      /* contrast calculation..... */
      return(contrast);
    }

calling a function:

    let myContrast = calcContrast('a51c30','ffffff');

## Events

- Events - things that happen on page
- Event handler - code that is run when an event happens
- Registering an event listener and handler - linking the code you want to run to an event

### Working with Events

- `addEventListener()`
- `DOMContentLoaded`
- Events: `click`, `submit`, `change`, `focus`
  - And more events: `blur`, `mouseover`, `mouseout`, `keypress`, `mousedown`, and more

## addEventListener function lets us add Event Listeners via JavaScript!

- Example using addEventListener

      let myButton = document.getElementById("makelistbutton");
      myButton.addEventListener("click", makeSeasonsList);

## Document Object Model (DOM)

    <html lang="en">
      <head>
        <title>My Schools</title>
      </head>
      <body>
        <h1>My Schools</h1>
        <ul>
          <li>
            <a href="http://www.harvard.edu/">Harvard University</a><br/>
            <img src="images/veritas.gif" alt="Harvard Shield" height="84" width="72"/>
          </li>
          <li>
            <a href="http://www.ku.edu/">University of Kansas</a><br/>
            <img src="images/KUSeal.gif" alt="University of Kansas Seal" height="73" width="72"/>
          </li>
        </ul>
      </body>
    </html>

### DOM Visualizer

- DOM Visualizer

## JavaScript and DOM

- `querySelector` lets us use "CSS selector" syntax and grab the "first" occurence (so you always get a "single" item).
- `querySelectorAll` lets us use "CSS selector" syntax and grab the "all" occurences (so you get a "list" of things).
- Also you might see `getElementById` and `getElementsByTagName`
- `getAttribute` and `setAttribute`
- `classList` and `add`, `remove`, `toggle`
- Various DOM methods to create nodes and add to the node tree (not today!)

## JavaScript and Ice Cream

### Exposing Additional Form Elements

Additional relevant form elements are exposed based upon user input. Here, this is achieved by having the entire form in the markup, with a certain section hidden via CSS (`display: none;`). If "Yes" is chosen, the display property is changed to "block" through JS.

ice_cream.html

Example 7.1 - Exposing Additional Form Elements - Example 7.1
<form method="post" name="ice_cream" id="ice_cream" action="https://cs12.net/form/submit.php" enctype="application/x-www-form-urlencoded"><fieldset><legend>Would you like ice cream?</legend><label><input type="radio" name="want" id="ic_yes" value="yes"/>Yes</label><label><input type="radio" name="want" id="ic_no" value="no"/>No</label></fieldset><fieldset id="icecream_options"><legend>Ice Cream Options</legend><fieldset><legend>What flavor would you like?</legend><label><input type="radio" id="flavor_vanilla" name="flavor" value="vanilla"/>Vanilla</label><label><input type="radio" id="flavor_chocolate" name="flavor" value="choclate"/>Chocolate</label><label><input type="radio" id="flavor_chocolate_pb" name="flavor" value="chocolate_peanut_butter"/>Chocolate Peanut Butter</label><label><input type="radio" id="flavor_strawberry" name="flavor" value="strawberry"/>Strawberry</label></fieldset><fieldset><legend>Would you like a cup or a cone?</legend><label><input type="radio" id="container_cup" name="container" value="cup"/>Cup</label><label><input type="radio" id="container_cone" name="container" value="cone"/>Cone</label></fieldset><fieldset><legend>What topping do you want?</legend><label><input type="checkbox" name="toppings" id="toppings_wc" value="whipcream"/>Whipped cream</label><label><input type="checkbox" name="toppings" id="toppings_jimmies" value="jimmies"/>Jimmies</label><label><input type="checkbox" name="toppings" id="toppings_sprinkles" value="sprinkles"/>Sprinkles</label><label><input type="checkbox" name="toppings" id="toppings_nuts" value="nuts"/>Nuts</label><label><input type="checkbox" name="toppings" id="toppings_cherry" value="cherry"/>Cherry</label></fieldset></fieldset><button type="submit">Submit Order</button></form>label { display: block; } input[type=submit], button[type=submit] { display: block; } form fieldset { margin-bottom: 1rem; } #icecream_options { border-style: none; } button.clicked { border: 3px solid purple; } ul.resourcelist { border: 2px solid black; border-radius: 5px; } .hidden { display: none; } body { font-family: helvetica, sans-serif; margin: 1rem; line-height: 1.5; } document.addEventListener('DOMContentLoaded',function(){ console.log("dom is loaded!"); let iceCreamOptions = document.querySelector('#icecream_options'); iceCreamOptions.classList.add("hidden"); let wantRadioInputs = document.querySelectorAll("form input[name=want]"); wantRadioInputs.forEach(function(el){ console.log(el); el.addEventListener("click",function(){ console.log("radio button was just clicked!"); let yesRadio = document.querySelector('#ic_yes'); if (yesRadio.checked == true) { console.log("Yes is checked!"); iceCreamOptions.classList.remove("hidden"); } else { console.log("Yes is NOT checked"); iceCreamOptions.classList.add("hidden"); } }) }); });

- Markup
- Style
- Script
- Display

     <form method="post" name="ice_cream" id="ice_cream" action="https://cs12.net/form/submit.php">
       <fieldset>
         <legend>Would you like ice cream?     </legend>
         <label>
           <input type="radio" name="want" id="ic_yes" value="yes"/>
    Yes     </label>
         <label>
           <input type="radio" name="want" id="ic_no" value="no"/>
    No     </label>   </fieldset>
       <fieldset id="icecream_options">
         <legend>Ice Cream Options     </legend>
         <fieldset>
           <legend>What flavor would you like?       </legend>
           <label>
             <input type="radio" id="flavor_vanilla" name="flavor" value="vanilla"/>
    Vanilla       </label>
           <label>
             <input type="radio" id="flavor_chocolate" name="flavor" value="choclate"/>
    Chocolate       </label>
           <label>
             <input type="radio" id="flavor_chocolate_pb" name="flavor" value="chocolate_peanut_butter"/>
    Chocolate Peanut Butter       </label>
           <label>
             <input type="radio" id="flavor_strawberry" name="flavor" value="strawberry"/>
    Strawberry       </label>     </fieldset>
         <fieldset>
           <legend>Would you like a cup or a cone?       </legend>
           <label>
             <input type="radio" id="container_cup" name="container" value="cup"/>
    Cup       </label>
           <label>
             <input type="radio" id="container_cone" name="container" value="cone"/>
    Cone       </label>     </fieldset>
         <fieldset>
           <legend>What topping do you want?       </legend>
           <label>
             <input type="checkbox" name="toppings" id="toppings_wc" value="whipcream"/>
    Whipped cream       </label>
           <label>
             <input type="checkbox" name="toppings" id="toppings_jimmies" value="jimmies"/>
    Jimmies       </label>
           <label>
             <input type="checkbox" name="toppings" id="toppings_sprinkles" value="sprinkles"/>
    Sprinkles       </label>
           <label>
             <input type="checkbox" name="toppings" id="toppings_nuts" value="nuts"/>
    Nuts       </label>
           <label>
             <input type="checkbox" name="toppings" id="toppings_cherry" value="cherry"/>
    Cherry       </label>     </fieldset>   </fieldset>
       <button type="submit">Submit Order   </button>
     </form>

In `style` element (`<style>`) within `head` element:

    label {
      display: block;
    }

    input[type=submit],
    button[type=submit] {
      display: block;
    }
    form fieldset {
      margin-bottom: 1rem;
    }
    #icecream_options {
      border-style: none;
    }
    button.clicked {
      border: 3px solid purple;
    }
    ul.resourcelist {
      border: 2px solid black;
      border-radius: 5px;
    }
    .hidden {
      display: none;
    }
    body {
      font-family: helvetica, sans-serif;
      margin: 1rem;
      line-height: 1.5;
    }

In `script` element within `head` element (`<script>`):

    document.addEventListener('DOMContentLoaded',function(){
        console.log("dom is loaded!");
        let iceCreamOptions = document.querySelector('#icecream_options');

        iceCreamOptions.classList.add("hidden");
        let wantRadioInputs = document.querySelectorAll("form input[name=want]");

        wantRadioInputs.forEach(function(el){
            console.log(el);
            el.addEventListener("click",function(){
                console.log("radio button was just clicked!");
                let yesRadio = document.querySelector('#ic_yes');
                if (yesRadio.checked == true) {
                    console.log("Yes is checked!");
                    iceCreamOptions.classList.remove("hidden");
                } else {
                    console.log("Yes is NOT checked");
                    iceCreamOptions.classList.add("hidden");
                }
            })
        });

    });