# Session 11 - JavaScript, Part 4

Harvard Extension School
Spring 2022

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

### Topics

1. Gotchas - maps and templates
2. Client-side Form Validation
3. Form Validation with jQuery Validation Plugin
4. jQuery
5. "Click" examples
6. jQuery Plugins
7. Scope
8. Structure
9. Nature of America - David's Final Project

Session 11 - JavaScript, Part 4, slide1
Gotchas - maps and templates, slide2
Client-side Form Validation, slide3
JS: Form Validation - DIY (Do It Yourself), slide4
PristineJS - Form Validation, slide5
Form Validation with jQuery Validation Plugin, slide6
Form Validation - setting rules with 'class' attributes, slide7
Form Validation - setting rules as configuration, slide8
Form Validation - setting custom messages and error placement, slide9
Form Validation - defining a custom rule, slide10
jQuery, slide11
jQuery and $(document).ready();, slide12
"Click" examples, slide13
jQuery and Ice Cream, slide14
jQuery Plugins, slide15
Scope, slide16
Content, slide17
Think About the User, slide18
Structure, slide19
Structuring Content, slide20
Organize, slide21
Structural Models, slide22
Hierarchical, slide23
Biological, slide24
Too deep or too shallow?, slide25
Sequential, slide26
Organic, slide27
Site Architecture, slide28
Label, slide29
Labels - Are there conventions?, slide30
Nature of America - David's Final Project, slide31

Presentation contains 31 slides

- img
- img
- img
- img
- img

## Gotchas - maps and templates

### LeafletJS - bug in Safari

- Info windows on markers don't open in Safari (and possibly other browsers) with LeafletJS v 1.7.1
- Solution: leave it, or use LeafletJS 1.8.0-beta.3

Example Leaflet 1.7 and Example with Leaflet 1.8.0-beta.3

### Handlebars and Tables

Creating a Handlebars template with tables can be tricky, due to the way the browser parses the content of the "template".

Solutions

- Dont' use tables.
- Put your template in "script" tag. Codepen Example - using "script" element so browser doesn't parse template contents
- Generate only the "tr" elements in your template, and add them into to a partial table container. Codepen Example where only "tr" are created with template and then added into "table"

## Client-side Form Validation

Provide feedback to users prior to submitting form.

- Native browser functionality with HTML5 form controls (see MDN: Client-side form validation)
  - form0.html
- DIY (Do It Yourself) or RYO (Roll Your Own) with JS
- JS libraries — some are 'plain' JS based (e.g. Pristine), others with jQuery (e.g. jQuery Validation Plugin).

## JS: Form Validation - DIY (Do It Yourself)

- form-diy0.html
- form-diy1.html

Notes

- Pass in `ev` (event) into the submit listener
- Get value, test if two or more characters in length.
  If true, then let form continue; else stop the form from submitting (`ev.preventDefault()`)

    document.addEventListener("DOMContentLoaded", function(){
      let form = document.querySelector('#myForm');
      form.addEventListener("submit", function(ev){
        console.log("Submit event happened!");
        console.log(ev);

        let nameInput = document.querySelector('#name');
        let nameInputValue = nameInput.value;

        if (nameInputValue.length >= 2) {
          // consider valid
          return true;
        } else {
          // consider invalid
          console.log("Please fill out name field");
          alert("Please fill out name field");
          // would want to have better feedback to user!
          ev.preventDefault();
        }
      })
    })

## PristineJS - Form Validation

- PristinJS - Vanilla javascript form validation micro-library
- form1-pristine.html

    document.addEventListener("DOMContentLoaded",function(){
      let form = document.getElementById("myForm");
      let pristine = new Pristine(form);
      form.addEventListener('submit', function (e) {
         let valid = pristine.validate();
         if (valid) {
           return true;
         } else {
           e.preventDefault();
         }
      });
    })

## Form Validation with jQuery Validation Plugin

jQuery Validation Plugin makes validating forms easy and flexible.

You can use it "out of the box" quickly and create validation rules by simply using class names in your input elements. You can use this validation plugin in more sophisticated ways as well, including providing your own validation methods.

## Form Validation - setting rules with 'class' attributes

jQuery Validation Plugin makes validating forms easy and flexible.

- Form 1
- Use the `jquery.validation.js` plugin in a basic way.
- jQuery Validation ".validate()" documentation
- Validation rules are specified in "class" attributes

    <!DOCTYPE html>
    <html lang="en">
    <head>
      <title>A Form to Illustrate Validation using the jQuery Validation Plugin</title>
      <meta charset="utf-8" />
      <link rel="stylesheet"  href="form.css" />
      <script src="https://code.jquery.com/jquery-3.6.0.min.js" integrity="sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4=" crossorigin="anonymous"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.3/jquery.validate.min.js" integrity="sha512-37T7leoNS06R80c8Ulq7cdCDU5MNQBwlYoy1TX/WUsLFC2eYNqtKlV0QjH7r8JpG/S0GUMZwebnVFLPd6SU5yg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
      <script>
      $(document).ready(function(){
          $("#myForm").validate();
      });
      </script>
    </head>
    <body>
      <form  id="myForm" method="post"
        action="https://cs12.net/form/submit.php">
        <fieldset>
          <legend>Information</legend>

            <label for="name">Name
            <input id="name" name="name" size="25" type="text" required class="required"/> </label>

            <label for="email">Email Address
            <input id="email" name="email" size="25" type="email" class="required email"/> </label>

            <label for="url">URL
            <input id="url" name="url" size="25" class="required url"/> </label>

            <button type="submit">Submit Form</button>
        </fieldset>
      </form>
    </body>
    </html>

## Form Validation - setting rules as configuration

Rules are quite customizable and can be expressed in JavaScript sections and not in the code markup.

- form2.html
- Documentation: jQuery Validation "rules" configuration

      $(document).ready(function(){
        $("#myForm").validate(
          {
          rules: {
            name:  { required: true, minlength: 2 },
            email: { required: true, email: true },
            url:   { required: true, url: true }
          }
        });
      });

## Form Validation - setting custom messages and error placement

- form3.html

      $(document).ready(function(){
          var validation = $("#myForm").validate(
           {
             rules: {
               name: { required: true, minlength: 2 },
               email: { required: true, email: true },
               url: { required: true, url: true },
               favnum: { required: true, number: true },
               favnum10: { required: true, number: true, min: 1, max: 10},
               color: {required: true},
               season: {required: true, minlength: 2},
               yourdate: { required: true, date: true }
             },
             messages: {
                    season: { minlength: jQuery.validator.format("Pick a minimum of {0} choices") }
             },
             errorPlacement: function(error,element) {
                 if ( element.is("[name=color]") )
                    error.appendTo( $('p#color') );
                 else if ( element.is("[name=season]") )
                    error.appendTo( $('p#season') );
                 else if ( element.is("[name=comments]") )
                    error.insertAfter( $('label[for=comments]') );
                 else
                    error.insertAfter(element);
             }
           });
        });

## Form Validation - defining a custom rule

- form4.html

Here we define a new validation rule called "netid" (three characters and three numbers, e.g. 'abc123')

- jQuery.validator.addMethod(name, method [,message])
- Regular expression `var pattern = /^[a-zA-Z]{3}[0-9]{3,4}$/;`
  this is a regular expression pattern (regex) that matches three characters (e.g. abc) followed by three numbers (e.g. 123).
  - "^" matches the beginning of the string
  - "[a-zA-Z]" defines a character class of all lower and upper alphabetic characters
  - "{3}" indicates that the character class preceding occurs three times
  - "[0-9]" defines a character class of numbers - e.g. 0,1,2,3,4,5,6,7,8,9
  - "{3,4}" indicates that the character class preceding occurs at least three times and at most four times
  - "$" matches the end of the string
  - `pattern.test(value)` returns `true` or `false`, depending on whether the 'value' matches the pattern

    $(document).ready( function() {
        /* addMethod for netid validation */
        $.validator.addMethod(
          "netid",
           function(value, element) {
              var pattern = /^[a-zA-Z]{3}[0-9]{3,4}$/;
              return this.optional( element ) || pattern.test( value );
           },
           'Please enter a valid NetID (e.g. abc123).'
         );
        var validation = $("#myForm").validate(
             {
               rules: {
                 name: { required: true, minlength: 2 },
                 email: { required: true, email: true },
                 netid: { required: true, netid: true }
              }
        );
    });

## jQuery

What is jQuery?
jQuery is a fast, small, and feature-rich JavaScript library. It makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler with an easy-to-use API that works across a multitude of browsers. With a combination of versatility and extensibility, jQuery has changed the way that millions of people write JavaScript.

Easier:

- document traversal
- document manipulation
- event handling
- animation
- Ajax

### Learning jQuery

- jQuery Learning Center
- How jQuery Works

## jQuery and $(document).ready();

See: $(document).ready() for more explanation, including the shorthand of `$()`.

## "Click" examples

Let's see how we can do this with jQuery. Items to note:

- CSS selector
- Default behavior stopped
- jQuery effects of transition (yes, we could use CSS transitions instead)

Example 11.1 - jquery click events - Example 11.1<div id="cscie12-course2" style="font-family: calibri,verdana,tahoma,helvetica,sans-serif; float: left; width: 50%; padding: 10px; margin: 10px; border: medium solid black; background-color: #ffb;"><h3>CSCI E-12: Fundamentals of Website Development</h3><p> Harvard Extension School<br/> David Heitmeyer <br/> CSCI E-12 </p><p id="cscie12-description2"> This course provides a comprehensive overview of website development. Students explore the prevailing vocabulary, tools, and standards used in the field and learn how the various facets—including HTML5, CSS, JavaScript, Ajax, multimedia, scripting languages, HTTP, clients, servers, and databases—function together in today's web environment. The course provides a solid web development foundation, focusing on content and client-side (browser) components (HTML5, CSS, JavaScript, multimedia), with an overview of the server-side technologies. In addition, software and services that are easily incorporated into a website (for example, maps, checkout, blogs, content management) are surveyed and discussed. Students produce an interactive website on the topic of their choice for the final project and leave the course prepared for more advanced and focused web development studies. </p></div><div style="width: 30%; float: left; margin-left: 2em;"><p><strong>Hide/Show/Toggle Description</strong></p><ul><li><a href="#" id="hide">Hide</a></li><li><a href="#" id="show">Show</a></li><li><a href="#" id="toggle">Toggle</a></li></ul></div>$(document).ready(function() { $('#hide').click( function(event){ $('#cscie12-description2').fadeOut('slow'); event.preventDefault(); } ); $('#show').click( function(event){ $('#cscie12-description2').fadeIn('slow'); event.preventDefault(); } ); $('#toggle').click( function(event) { console.log('toggle!'); $('#cscie12-description2').toggle('slow'); event.preventDefault(); } ); });

- Markup
- Script
- Screenshot

     <div id="cscie12-course2" style="font-family: calibri,verdana,tahoma,helvetica,sans-serif; float: left; width: 50%; padding: 10px; margin: 10px; border: medium solid black; background-color: #ffb;">
       <h3>CSCI E-12: Fundamentals of Website Development   </h3>
       <p>Harvard Extension School
         <br/>
    David Heitmeyer
         <br/>
    CSCI E-12
       </p>
       <p id="cscie12-description2">This course provides a comprehensive overview of website development. Students explore the prevailing vocabulary, tools, and standards used in the field and learn how the various facets—including HTML5, CSS, JavaScript, Ajax, multimedia, scripting languages, HTTP, clients, servers, and databases—function together in today's web environment. The course provides a solid web development foundation, focusing on content and client-side (browser) components (HTML5, CSS, JavaScript, multimedia), with an overview of the server-side technologies. In addition, software and services that are easily incorporated into a website (for example, maps, checkout, blogs, content management) are surveyed and discussed. Students produce an interactive website on the topic of their choice for the final project and leave the course prepared for more advanced and focused web development studies.
       </p>
     </div>
     <div style="width: 30%; float: left; margin-left: 2em;">
       <p>
         <strong>Hide/Show/Toggle Description     </strong>
       </p>
       <ul>
         <li>
           <a href="#" id="hide">Hide       </a>
         </li>
         <li>
           <a href="#" id="show">Show       </a>
         </li>
         <li>
           <a href="#" id="toggle">Toggle       </a>
         </li>   </ul>
     </div>

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

    $(document).ready(function() {
                 $('#hide').click(
                  function(event){
                    $('#cscie12-description2').fadeOut('slow');
                    event.preventDefault();
                  }
                 );
                 $('#show').click(
                  function(event){
                    $('#cscie12-description2').fadeIn('slow');
                    event.preventDefault();
                  }
                 );
                 $('#toggle').click(
                  function(event) {
                    console.log('toggle!');
                    $('#cscie12-description2').toggle('slow');
                    event.preventDefault();
                  }
                 );
               });

## jQuery and Ice Cream

### JavaScript

Ice Cream and JavaScript

    document.addEventListener("DOMContentLoaded", function(){
    /* js to be executed when dom is loaded goes here */

      let iceCreamOptions = document.getElementById("icecream_options_v2");
      let wantRadioButtons = document.querySelectorAll("form input[name=want]");

      let icoClasses = iceCreamOptions.classList;
      icoClasses.add("collapsed");

      for (let radio of wantRadioButtons) {
        radio.addEventListener("click",function(){
          let yesRadio = document.getElementById("ic_yes");
          if (yesRadio.checked == true) {
            icoClasses.remove("collapsed");
          } else {
            icoClasses.add("collapsed");
          }
        })
      }

    });

### jQuery

Ice Cream and jQuery

- jQuery automatically sets up loops if there are multiple items
  e.g. `$("form input[name=want]")`

    $(document).ready(function(){
      console.log("jQuery ready!");
      let iceCreamOptions = $("#icecream_options_v2");
      let wantRadioButtons = $("#form input[name=want]");

      iceCreamOptions.addClass("collapsed");
      yesRadio = $('#ic_yes');
      $("form input[name=want]").click( function(){
        if (yesRadio.is(':checked') == true) {
          iceCreamOptions.removeClass("collapsed");
        } else {
          iceCreamOptions.addClass("collapsed");
        }
      })
    });

## jQuery Plugins

### Tablesorter

tablesorter is a jQuery plugin for turning a standard HTML table with THEAD and TBODY tags into a sortable table without page refreshes. tablesorter can successfully parse and sort many types of data including linked data in a cell.

- US Senate Table
- US Senate Table - Sortable

    $(document).ready(function(){
        $("#senatetable").tablesorter(
          {
            "theme"   : "blue",
            "widgets" : ["zebra"]
          }
        );
    });

## Scope

Define content or functionality requirements.

What's "in" and what's "out" -- or at least what's "later".

Start broad, then narrow and refine.

## Content

Questions to ask about content:

- Does it fit purpose of site?
- Does it suit the audience?
- Would your users find this useful?

### Approaching a Project

- What content already exists in web or other media types (brochures, pamphlets, statements, etc.).
  - Adapt (or re-adapt) it for the web
- What content would be good to develop for the site?
  - Create it for the web
- Define incremental goals to avoid "scope creep"
  - Initial Phase
  - Additional Phases

## Think About the User

## Structure

## Structuring Content

From Information Architecture for the World Wide Web (available through Harvard Libraries):

information architecture defined:

1. The structural design of shared information environments.
2. The combination of organization, labeling, search, and navigation systems within web sites and intranets.
3. The art and science of shaping information products and experiences to support usability and findability.
4. An emerging discipline and community of practice focused on bringing principles of design and architecture to the digital landscape.

### Organize, Label, (Navigate)

- Organize and Categorize
- Label
- Navigate

## Organize

- Strategy-driven: Top-down
- Content-driven: Bottom-up

### Plan for Growth

### How to?

- Sticky-notes or index cards
- whiteboard or wall

## Structural Models

- Hierarchical
- Sequential
- Organic

## Hierarchical

### Library of Congress Classification

"Q" - Science
"QC" - Physics

## Biological

- Kingdom
  - Phylum
    - Class
      - Order
        - Family
          - Genus
            - Species

Catalog of Life

## Too deep or too shallow?

Deep | Shallow

## Sequential

- Useful when "workflow" is important in web applications.

- When order is important or part of presentation.

## Organic

Wikipedia.com

## Site Architecture

- Topics
- Audience
- Task-Oriented
- Search
- Internal Organization

## Label

- Know your audience
- Test your labels (ask your audience)
  - Card Sort - physical or online, e.g. Optimal Sort
  - Ask questions
    - Where can I get a driver for my HP ENVY 5540?
    - What would expect to find in the category of Synergetic Integrated Scalable Enterprise Solutions?
    - What IT degree programs are available?

## Labels - Are there conventions?

### Categories and Labels from News Sites

CNN

ABC News

CBS

New York Times

NPR

Fox News

BBC

NBC

Al Jazerra

## Nature of America - David's Final Project

### Strategy

- Name of the site: “Nature of America”
- Purpose and goals of the site: The site will showcase the flora and fauna of different ecosystems in the United States, with the “Nature of America” stamp series as a framework. The main focus of the site will be the ecosystems and plants and animals features, but the art of the stamps will also be on display. The “Nature of America” stamp series contains twelve different stamp sets that were issued between 1999 and 2010. For each of the stamps, around twenty plants or animals are highlighted.
- Audiences
  - Primary audience: Lay-persons curious about different plants and animals in different ecosystems in the United States. The site is not intended for scientific or advanced information about the plants and animals. Though the site will use the “Nature of America” stamp series, it is not designed for the serious stamp collector.
  - Secondary audience: K-8 students interested in exploring the different plants and animals in different parts of the United States

### Scope

Ideas for content/function for site:

- Stamp sheets issued:
  Sonoran Desert, Pacific Coast Rain Forest, Great Plains Prairie, Longleaf Pine Forest, Arctic Tundra, Pacific Coral Reef, Northeast Deciduous Forest, Southern Florida Wetland, Alpine Tundra, Great Lakes Dunes, Kelp Forest, Hawaiian Rain Forest
- For each of the 12 stamp sheets issued:
  - Image of the pane, front and back
  - List of animals/plants
    - Scientific and common name
    - Photo of the animal/plant
    - Additional information or link to entry in eol.org (Encyclopedia of Life)
- About the stamp series; about the artist
- Interactive (JavaScript) ideas
  - Slideshows of the stamp pane images; animals/plants within each pane.
  - Map that shows the post office/place where each stamp sheet was first issued, as this maps to the area of the country where you can expect to find the ecosystem featured.
- Resources: USPS archives for when stamps were issued; eol.org (encyclopedia of life); Pixabay and other sites with images covered under creative commons.

For my project, I will focus on the home page, a page for the “Great Plains Prairie,” and one page that has a map showing where the first issue came from.

### Structure

This site will be pretty “flat” in structure, as the main content pages will be for each of the 12 different stamp sheets; plus a map and an ‘about’ page. So three “areas” of the site as shown in the structure, but I plan on having the home page show all the stamps as well as link to the about and map pages.