Harvard Extension School, Fall 2018
CSCI E-12 Fundamentals of Web Site Development

# Session 09 - JavaScript, Part 2

Harvard Extension School
Fall 2018

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

Instructor email: david_heitmeyer@harvard.edu
Course staff email: cscie12@dce.harvard.edu

### Topics

1. JavaScript - Minifying and CDNs
2. jQuery Examples
3. Add Another
4. Unobtrusive Javascript / Progressive Enhancement
5. jQuery UI
6. Slideshow
7. Form Validation
8. Javascript Helping with Navigation

slide1 slide2 slide3 slide4 slide5 slide6 slide7 slide8 slide9 slide10 slide11 slide12 slide13 slide14 slide15 slide16 slide17 slide18 slide19 slide20 slide21 slide22 slide23 slide24 slide25 slide26 slide27 slide28 slide29 slide30

- img
- img
- img
- img
- img

## JavaScript - Minifying and CDNs

- Minifying
- CDNs - Content Delivery Networks

## Minified JS

Comments and unnecessary whitespace are removed.

- jquery-1.12.1: 287 kb
- jquery-1.12.1.min.js: 95 kb
  67% reduction!

### Minify Your JS (and CSS)

Some tools you can use to minify your JS:

- YUI Compressor. (JS and CSS)
- Minify JS
- and others (UglifyJS, JSMin, Closure Compiler)

## Load Your Core JS Library through a CDN

### CDN - What and Why

CDN = Content Delivery Network

See: 3 reasons why you should let Google host jQuery for you (or any other CDN)

- Decreased latency
- Increased Parallelism
- Better Caching

### CDNs to Use

See: Using jQuery with a CDN

But not just jQuery! MaxCDN, Google, Microsoft, and cdnjs.com host several JS libraries through their CDNs:

- Google Hosted Libraries
- MaxCDN is used for several Open Source projects
- Microsoft Ajax Content Delivery Network
- cdnjs.com
- For a fuller list see: Free Open Source CDNs (That You'll Actually Use)

## jQuery Examples

- Exposing additional form elements
- Check and Uncheck
- Add another

## Ice Cream

- Use JavaScript to add the "onclick" listener
- Use JavaScript to hide the `div` containing the additional options.

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

- Separation. The "click" handler is bound via JavaScript and not the onclick attribute.
- Fancier. jQuery provides many "effects" and "animations" (basic ones here are `fadeOut` and `fadeIn`)

Example 9.1 - Separation from Markup - Example 9.1 (Without Styles) | Example 9.1 JSFiddle

- Markup
- Style
- Script
- Screenshot

    <form method="get" name="ice_cream" id="ice_cream" action="http://cscie12.dce.harvard.edu/echo">
    <div>Would you like ice cream?<br/>
    <input type="radio" name="want" id="ic_yes" value="yes"/><label for="ic_yes">Yes</label><br/>
    <input type="radio" name="want" id="ic_no" value="no"/><label for="ic_no">No</label></div><fieldset id="icecream_options"><legend>Ice Cream Options</legend><p>How would you like it?</p>

    <input type="radio" id="container_cup" name="container" value="cup"/><label for="container_cup">Cup</label><br/>
    <input type="radio" id="container_cone" name="container" value="cone"/><label for="container_cone">Cone</label><br/><p>Pick your toppings:</p>

    <input type="checkbox" name="toppings" id="toppings_wc" value="whipcream"/><label for="toppings_wc">Whipped cream</label><br/>
    <input type="checkbox" name="toppings" id="toppings_j" value="jimmies"/><label for="toppings_j">Jimmies</label><br/>
    <input type="checkbox" name="toppings" id="toppings_nuts" value="nuts"/><label for="toppings_nuts">Nuts</label><br/>
    <input type="checkbox" name="toppings" id="toppings_cherry" value="cherry"/><label for="toppings_cherry">Cherry</label></fieldset><p>
    <input type="submit"/></p>

    </form>

In `style` element (`<style type="text/css">`) within `head` element:

    #icecream_options {
        background-color: #eee;
        margin-left: 2em;
    }

In `script` element within `head` element (`<script type="text/javascript">`):

    $(document).ready(function(){
        $("#icecream_options").hide();
        $("input[name='want']").click(function(){
          displayIceCreamOptions();
        });
    });
    function displayIceCreamOptions() {
        if ($("input[name='want']:checked").val() == 'yes') {
          $('#icecream_options').fadeIn('slow');
        } else {
          $('#icecream_options').fadeOut('slow');
        }
    }

## Check and Uncheck All

JavaScript:

Here we take advantage of an attribute value selector (`[name="how"]`) the ability to retrieve and set property values. Note too that we iterate through each of the checkboxes.

To read more about attributes vs properties in jQuery, see: .prop() and .attr()

Example 9.2 - Check/Uncheck all - Example 9.2 | Example 9.2 JSFiddle

- Markup
- Script
- Screenshot

    <form action="http://cscie12.dce.harvard.edu/echo" method="get">
    <h3>How did you hear about us?</h3><p>[<a href="#" id="checkall">check all</a>] [<a href="#" id="uncheckall">uncheck all</a>] [<a href="#" id="togglecheckboxes">toggle</a>]</p>
    <ul style="list-style: none;">
    <li>
    <input type="checkbox" name="how" value="radio"/>Radio</li>
    <li>
    <input type="checkbox" name="how" value="newspaper"/>Newspaper</li>
    <li>
    <input type="checkbox" name="how" value="magazine"/>Magazine</li>
    <li>
    <input type="checkbox" name="how" value="online"/>Online</li>
    <li>
    <input type="checkbox" name="how" value="friend"/>Friend</li>
    </ul>
    <input type="submit"/>
    </form>

In `script` element within `head` element (`<script type="text/javascript">`):

    $(document).ready(function() {
      console.log($('#input[name="how"]'));
      $('#checkall').click(function() {
        $('input[name="how"]').prop('checked',true);
        console.log('check all!');
      });
      $('#uncheckall').click(function() {
        $('input[name="how"]').prop('checked',false);
        console.log('uncheck all!');
      });
      $('#togglecheckboxes').click(function() {
        $('input[name=how]').each(function (i) {
          if ($(this).is(':checked')) {
            $(this).prop('checked',false);
          } else {
            $(this).prop('checked',true);
          }
        });
      });
     });

## Add Another

Example: add_another.html | Add Another in JSFiddle

JavaScript:

- select the "div" we want to duplicate
- clone the "div" to create a new one
- change the id (to maintain uniqueness) of the new div
- insert the new div into the document

    $(document).ready(function() {
        var numberofphones = 1;
        $('#addphone').click(function() {
          numberofphones++;
          newid = 'phone' + numberofphones;
          var phonediv = $('#phone1');
          var newphonediv = phonediv.clone();
          newphonediv.attr('id',newid);
          newphonediv.insertBefore('#addphone');
      });
     });

Markup:

    <form action="http://cscie12.dce.harvard.edu/echo" method="get">
      <fieldset>
        <legend>Contact Information</legend>
        <div>Name:
          <input type="text" name="name"/></div>
        <div id="phone1">Phone:
          <input type="text" name="phone"/> </div>
          <input type="button" id="addphone" value="Add another phone"/>
      </fieldset>
      <div><input type="submit"/></div>
    </form>

## Chaining jQuery

- calculate the new "id" string
- select the phone div to be duplicated
- duplicate (clone) the phone div
- change the id of the new phone div
- insert the new phone div into the document

jQuery methods return nodes, so we can easily chain these steps together.

Stepwise:

    $(document).ready(function() {
        var numberofphones = 1;
        $('#addphone').click(function() {
          numberofphones++;
          newid = 'phone' + numberofphones;
          var phonediv = $('#phone1');
          var newphonediv = phonediv.clone();
          newphonediv.attr('id',newid);
          newphonediv.insertBefore('#addphone');
      });
     });

Chained:

    $(document).ready(function() {
        var numberofphones = 1;
        $('#addphone').click(function() {
          numberofphones++;
          newid = 'phone' + numberofphones;
          $('#phone1').clone().attr('id',newid).insertBefore('#addphone');
      });
     });

## Unobtrusive Javascript / Progressive Enhancement

Principles of Unobtrusive JavaScript

- Separation
- Progressive Enhancement (Graceful Degradation)

## Progressive Enhancement for "add another"

- One strategy would be to hide the "Add Another" button and make it visible through JavaScript.
- Alternatively, we could create the "Add Another" node in JS and then adding it to the page via JS.

    $(document).ready(function() {
      $('#addphone').css('display','inline');
      var numberofphones = 1;
      $('#addphone').click(function() {
          numberofphones++;
          newid = 'phone' + numberofphones;
          $('#phone1').clone().attr('id',newid).insertBefore('#addphone');
      });
     });

A browser with JS disabled would display form with a single phone field.

Example: add_another_unobtrusive.html
With JavaScript disabled in browser:

## Ice Cream

Start with everything visible, then hide with JavaScript:
Key piece here is: `$("#icecream_options").hide();`

Example 9.3 - Separation from Markup - Example 9.3 (Without Styles) | <form method="get" name="ice_cream" id="ice_cream" action="http://cscie12.dce.harvard.edu/echo" enctype="application/x-www-form-urlencoded"><div> Would you like ice cream?<br/><input type="radio" name="want" id="ic_yes" value="yes"/><label for="ic_yes">Yes</label><br/><input type="radio" name="want" id="ic_no" value="no"/><label for="ic_no">No</label></div><fieldset id="icecream_options"><legend>Ice Cream Options</legend><p>How would you like it?</p><input type="radio" id="container_cup" name="container" value="cup"/><label for="container_cup">Cup</label><br/><input type="radio" id="container_cone" name="container" value="cone"/><label for="container_cone">Cone</label><br/><p>Pick your toppings:</p><input type="checkbox" name="toppings" id="toppings_wc" value="whipcream"/><label for="toppings_wc">Whipped cream</label><br/><input type="checkbox" name="toppings" id="toppings_j" value="jimmies"/><label for="toppings_j">Jimmies</label><br/><input type="checkbox" name="toppings" id="toppings_nuts" value="nuts"/><label for="toppings_nuts">Nuts</label><br/><input type="checkbox" name="toppings" id="toppings_cherry" value="cherry"/><label for="toppings_cherry">Cherry</label></fieldset><p><input type="submit"/></p></form>#icecream_options { background-color: #eee; margin-left: 2em; }$(document).ready(function(){ $("#icecream_options").hide(); $("input[name='want']").click(function(){ displayIceCreamOptions(); }); }); function displayIceCreamOptions() { if ($("input[name='want']:checked").val() == 'yes') { $('#icecream_options').fadeIn('slow'); } else { $('#icecream_options').fadeOut('slow'); } }

- Markup
- Style
- Script
- Screenshot

    <form method="get" name="ice_cream" id="ice_cream" action="http://cscie12.dce.harvard.edu/echo">
    <div>Would you like ice cream?<br/>
    <input type="radio" name="want" id="ic_yes" value="yes"/><label for="ic_yes">Yes</label><br/>
    <input type="radio" name="want" id="ic_no" value="no"/><label for="ic_no">No</label></div><fieldset id="icecream_options"><legend>Ice Cream Options</legend><p>How would you like it?</p>

    <input type="radio" id="container_cup" name="container" value="cup"/><label for="container_cup">Cup</label><br/>
    <input type="radio" id="container_cone" name="container" value="cone"/><label for="container_cone">Cone</label><br/><p>Pick your toppings:</p>

    <input type="checkbox" name="toppings" id="toppings_wc" value="whipcream"/><label for="toppings_wc">Whipped cream</label><br/>
    <input type="checkbox" name="toppings" id="toppings_j" value="jimmies"/><label for="toppings_j">Jimmies</label><br/>
    <input type="checkbox" name="toppings" id="toppings_nuts" value="nuts"/><label for="toppings_nuts">Nuts</label><br/>
    <input type="checkbox" name="toppings" id="toppings_cherry" value="cherry"/><label for="toppings_cherry">Cherry</label></fieldset><p>
    <input type="submit"/></p>

    </form>

In `style` element (`<style type="text/css">`) within `head` element:

    #icecream_options {
        background-color: #eee;
        margin-left: 2em;
    }

In `script` element within `head` element (`<script type="text/javascript">`):

    $(document).ready(function(){
        $("#icecream_options").hide();
        $("input[name='want']").click(function(){
          displayIceCreamOptions();
        });
    });
    function displayIceCreamOptions() {
        if ($("input[name='want']:checked").val() == 'yes') {
          $('#icecream_options').fadeIn('slow');
        } else {
          $('#icecream_options').fadeOut('slow');
        }
    }

What's the difference between sprinkles and jimmies?

## jQuery UI

jQuery UI is a curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library. Whether you're building highly interactive web applications or you just need to add a date picker to a form control, jQuery UI is the perfect choice.

## Tabs with jQuery

jQuery UI Tab Widget allows the easy creation of tabs from simple markup.

- Example: tabs-jquery.html

With JS and CSS:

Without JS and CSS:

Markup:

    <div id="tabs">
        <ul>
          <li><a href="#basic">Overview</a>
          </li>

          <li><a href="#description">Description</a>
          </li>
          <li><a href="#schedule">Schedule</a>
          </li>
        </ul>

        <div id="basic">
          <h2>Overview</h2>
          <h3>Fundamentals of Website Development
            <br/>CSCI E-12</h3>
          <p>Harvard Extension School</p>
          <p><a href="http://cscie12.dce.harvard.edu/">cscie12.dce.harvard.edu</a>
            </p>
        </div>

        <div id="description">
          <h2>Course Description</h2>
          <p>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, XHTML, 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, XHTML, 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.    </div>

        <div id="schedule">
          <h2>Schedule of Lectures</h2>

          <ol>
            <li>Introduction, Internet and Web Basics</li>
            <li>Markup: XHTML and HTML, Part 1</li>
            <li>Markup: XHTML and HTML, Part 2</li>
            <li>Style: Cascading Style Sheets (CSS), Part 1</li>
            <li>Style: Cascading Style Sheets (CSS), Part 2</li>
            <li>Style: CSS, Part 3</li>
            <li>Designing and Building a Site</li>
            <li>Function: Javascript, Part 1</li>
            <li>Function: JavaScript and Ajax, Part 2</li>
            <li>Function: External Functionality, Flash, Applets, and Web 2.0</li>
            <li>Video and Multimedia on the Web</li>
            <li>Server-side: Dynamic content</li>
            <li>Server-side: HTTP and Apache Web Server</li>
            <li>Grab Bag</li>
          </ol>
        </div>
      </div>

JS and CSS:

    <link rel="stylesheet"
      href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/sunny/jquery-ui.css"
      type="text/css" media="all" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"
        type="text/javascript"></script>
    <script
        src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"
        type="text/javascript"></script>
    <script type="text/javascript">
      $(function(){
        $('#tabs').tabs();
      });
    </script>

## jQuery UI Tabs: NOT for site navigation!

## jQuery UI Tabs: Featured Content Slider

Featured content slider using jQuery UI

Javascript: (just like any other jQuery UI Tabs:

    $(document).ready(function(){
         $("#featured").tabs({fx:{opacity: "toggle"}}).tabs("rotate", 5000, true);
    });

Markup:

    <div id="featured" >
      <div id="fragment-1"> <img src="images/featured1.jpg"  />
        <div class="info" >...</div>
      </div>
      <div id="fragment-2"> <img src="images/featured2.jpg"  />
        <div class="info" >...</div>
      </div>
      <div id="fragment-3"> <img src="images/featured3.jpg"  />
        <div class="info" >...</div>
      </div>
      <!-- ... -->
      <div id="fragment-7"> <img src="images/featured7.jpg"  />
        <div class="info" >...</div>
      </div>
      <ul class="ui-tabs-nav">
        <li id="nav-fragment-1"><a href="#fragment-1"><img src="thumbnail1.jpg"/></a></li>
        <li id="nav-fragment-2"><a href="#fragment-2"><img src="thumbnail2.jpg"/></a></li>
        <li id="nav-fragment-3"><a href="#fragment-3"><img src="thumbnail3.jpg"/></a></li>
        <!-- ... -->
        <li id="nav-fragment-7"><a href="#fragment-3"><img src="thumbnail7.jpg"/></a></li>
      </ul>
    </div>

## Rotating Carousels

- Designing Effective Carousels: Create a Fanciful Amusement, Not a House of Horrors
  by Kara Pernice from Nielsen Norman Group

  Summary: Carousels allow multiple pieces of content to occupy a single, coveted space. This may placate corporate infighting, but on large- or small-view ports, people often scroll past carousels. A static hero or integrating content in the UI may be better solutions. But if a carousel is your hero, good navigation and content can help make it effective.

### Harvard - Carousel to No Carousel

Carousel:

No Carousel:

## Other jQuery UI Widgets

jQuery UI is a curated set of user interface interactions, effects, widgets, and themes built on top of the jQuery JavaScript Library. Whether you're building highly interactive web applications or you just need to add a date picker to a form control, jQuery UI is the perfect choice.

jQuery UI provides abstractions for low-level interaction and animation, advanced effects and high-level, themeable widgets, built on top of the jQuery JavaScript Library, that you can use to build highly interactive web applications.

- Accordion
- Autocomplete
- Button
- Datepicker
- Dialog
- Menu
- Progressbar
- Selectmenu
- Slider
- Spinner
- Tabs
- Tooltip

## jQuery Datepicker Widget

jQuery has plugins that will provide an unobtrusive "calendar" widget for picking dates.

Example: date_picker.html

Markup:

    <form action="http://cscie12.dce.harvard.edu/echo">
      <p>
        Enter a start date: <input class="date" type="text" size="32" name="startdate" id="startdate" />
      </p>
      <p>
        Enter an end date: <input class="date" type="text" size="32" name="enddate" id="enddate" />
      </p>
      <input type="submit"/>
    </form>

CSS amd JS:

    <link rel="stylesheet"
      href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css"
      type="text/css" media="all" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"
        type="text/javascript"></script>
    <script
        src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"
        type="text/javascript"></script>
    <script type="text/javascript">
      $(document).ready(function(){
        $('input.date').datepicker();
      })
    </script>

## jQuery UI Themes

Apply the "smoothness" theme (`css/smoothness/jquery-ui-1.10.4.custom.css`): | Apply the "hot-sneaks" theme (`css/hot-sneaks/jquery-ui-1.10.4.custom.css`):

## Slideshow

Structure + Style + Function: solarsystem.html

Structure + Style: solarsystem-style.html

## Slideshow

A gallery with no JavaScript -- thumbnail images are linked to the full-sized image with a simple
`<a href="full/a.png" rel="gallery"><img src="thumb/a.png"/></a>`:

### Example Galleries

View example galleries implemented in various "lightbox" or "slideshow" programs.

Colorbox |  |
Fancybox |  |
Lightbox 2 |  |

## Form Validation

jQuery Validation Plugin makes validating forms easy and flexible.

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

    <html>
    <head>
      <title>A Form to Illustrate Validation using the jQuery Validation Plugin</title>
      <link rel="stylesheet" type="text/css" href="form.css"/>
    <script
      src="https://code.jquery.com/jquery-3.2.1.min.js"
      integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
      crossorigin="anonymous"></script>
    <script type="text/javascript"
        src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js">
    </script>
    <script type="text/javascript">
    $(document).ready(function(){
        $("#myForm").validate();
    });
    </script>
    </head>
    <body>
      <form  id="myForm" method="post"
        action="http://cscie12.dce.harvard.edu/echo">
        <fieldset>
          <legend>Information</legend>
          <p>
            <label for="name">Name</label> <em>(Required)</em>
            <br/>
            <input id="name" name="name" size="25" class="required"/> </p>
          <p>
            <label for="email">Email Address</label> <em>(Required)</em>
            <br/>
            <input id="email" name="email" size="25" class="required email"/> </p>
          <p>
            <label for="url">URL</label> <em>(Required)</em>
            <br/>
            <input id="url" name="url" size="25" class="required url"/> </p>
          <p>
            <input class="submit" type="submit" value="Submit Form"/> </p>
        </fieldset>
      </form>
    </body>
    </html>

## Form Validation

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

form2.html

    <html>
    <head>
      <title>A Form to Illustrate Validation using the jQuery Validation Plugin</title>
      <link rel="stylesheet" type="text/css" href="form.css"/>
    <script
      src="https://code.jquery.com/jquery-3.2.1.min.js"
      integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
      crossorigin="anonymous"></script>
    <script type="text/javascript"
        src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js">
    </script>
    <script type="text/javascript">
    $(document).ready(function(){
      var validation = $("#myForm").validate(
        {
        rules: {
          name:  { required: true, minlength: 2 },
          email: { required: true, email: true },
          url:   { required: true, url: true }
        }
      });
    });
    </script>
    </head>
    <body>
    <form id="myForm" method="post" action="http://cscie12.dce.harvard.edu/echo">
    <fieldset>
       <legend>A Form to Illustrate Validation using the jQuery Validation Plugin</legend>
       <p>
         <label for="name">Name</label><br/>
         <input id="name" name="name" size="25"/>
       </p>
       <p>
         <label for="email">Email Address</label><br/>
         <input id="email" name="email" size="25"/>
       </p>
       <p>
         <label for="url">URL</label><br/>
         <input id="url" name="url" size="25"  value="" />
       </p>
     <p>
         <input class="submit" type="submit" value="Submit"/>
       </p>
     </fieldset>
     </form>
    </body>
    </html>

## Form Validation

- 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);
           }
         });
      });

## Javascript Helping with Navigation

- Using Javascript to control navigation display
  - dynamically set classes/ids to achieve
    - You are Here
    - What is "close by"
    - Where you are in the broader context

## Navigation

    <html>
      <head>
        <title>The Great Binding Law, Gayanashagowa (Constitution of the Iroquois Nations)</title>
        <link rel="stylesheet" type="text/css" href="style.css" />
      </head>
      <body id="part1">
        <?php include("inc/header.php"); ?>
        <?php include("inc/nav.php"); ?>
        <div id="main">
          <?php include("inc/content1.php"); ?>
        </div>
        <?php include("inc/footer.php"); ?>
      </body>
    </html>

## "You are here" with CSS

"You are Here" CSS Example in JSFiddle

    <div id="navigation">
    <ul id="mainnav">
    <li id="navpart1"><a href="1.shtml">The Great Binding Law, Gayanashagowa</a></li>
    <li id="navpart2"><a href="2.shtml">Rights, Duties and Qualifications of Lords</a></li>
    <li id="navpart3"><a href="3.shtml">Election of Pine Tree Chiefs</a></li>
    <li id="navpart4"><a href="4.shtml">Names, Duties and Rights of War Chiefs</a></li>
    <li id="navpart5"><a href="5.shtml">Clans and Consanguinity</a></li>
    <li id="navpart6"><a href="6.shtml">Official Symbolism</a></li>
    <li id="navpart7"><a href="7.shtml">Laws of Adoption</a></li>
    <li id="navpart8"><a href="8.shtml">Laws of Emigration</a></li>
    <li id="navpart9"><a href="9.shtml">Rights of Foreign Nations</a></li>
    <li id="navpart10"><a href="10.shtml">Rights and Powers of War</a></li>
    <li id="navpart11"><a href="11.shtml">Treason or Secession of a Nation</a></li>
    <li id="navpart12"><a href="12.shtml">Rights of the People of the Five Nations</a></li>
    <li id="navpart13"><a href="13.shtml">Religious Ceremonies Protected</a></li>
    <li id="navpart14"><a href="14.shtml">The Installation Song</a></li>
    <li id="navpart15"><a href="15.shtml">Protection of the House</a></li>
    <li id="navpart16"><a href="16.shtml">Funeral Addresses</a></li>
    </ul>
    </div>

And the CSS:

    #navigation a {
      /* Rules for navigation items */
    }
    #navigation a:hover {
      /* Rules for navigation items */
    }

    /* Rules specific for "you are here" */
    #navigation #iamhere a,
    #navigation #iamhere a:hover {
      /* Rules for the "you are here" item */
    }

## "You are here" with JavaScript

View this technique in action.Example in JSFiddle

1. Each `body` is uniquely identified (`id`)
2. Each navigation list item gets an `id`
3. CSS rule for `id="iamhere"`
4. JavaScript to set the "iamhere" `id`

Note the `id` of the `body`:

    <html>
    <head>
        <title>Election of Pine Tree Chiefs (Constitution of the Iroquois Nations)</title>
        <link rel="stylesheet" type="text/css" href="style.css" />
      </head>
      <body id="part3">
        <?php include("inc/header.php"); ?>
        <?php include("inc/nav.php"); ?>
        <div id="main">
          <?php include("inc/content3.php"); ?>
        </div>
        <?php include("inc/footer.php"); ?>
      </body>
    </html>

Each navigation item has an `id`:

    <div id="navigation">
    <ul id="mainnav">
    <li id="navpart1"><a href="1.shtml">The Great Binding Law, Gayanashagowa</a></li>
    <li id="navpart2"><a href="2.shtml">Rights, Duties and Qualifications of Lords</a></li>
    <li id="navpart3"><a href="3.shtml">Election of Pine Tree Chiefs</a></li>
    <li id="navpart4"><a href="4.shtml">Names, Duties and Rights of War Chiefs</a></li>
    <li id="navpart5"><a href="5.shtml">Clans and Consanguinity</a></li>
    <li id="navpart6"><a href="6.shtml">Official Symbolism</a></li>
    <li id="navpart7"><a href="7.shtml">Laws of Adoption</a></li>
    <li id="navpart8"><a href="8.shtml">Laws of Emigration</a></li>
    <li id="navpart9"><a href="9.shtml">Rights of Foreign Nations</a></li>
    <li id="navpart10"><a href="10.shtml">Rights and Powers of War</a></li>
    <li id="navpart11"><a href="11.shtml">Treason or Secession of a Nation</a></li>
    <li id="navpart12"><a href="12.shtml">Rights of the People of the Five Nations</a></li>
    <li id="navpart13"><a href="13.shtml">Religious Ceremonies Protected</a></li>
    <li id="navpart14"><a href="14.shtml">The Installation Song</a></li>
    <li id="navpart15"><a href="15.shtml">Protection of the House</a></li>
    <li id="navpart16"><a href="16.shtml">Funeral Addresses</a></li>
    </ul>
    </div>

And the CSS:

    #navigation a {
      /* Rules for navigation items */
    }
    #navigation a:hover {
      /* Rules for navigation items */
    }

    /* Rules specific for "you are here" */
    #navigation #iamhere a,
    #navigation #iamhere a:hover {
      /* Rules for the "you are here" item */
    }

And the JavaScript (using jQuery) that finds the correct navigation item and sets the `id` attribute value to "iamhere":

    $(document).ready(function(){
      var mybodyid = $('body').attr('id');
      var mynavid = '#nav' + mybodyid;
      /* e.g. for 3.shtml:
          mybodyid is 'part3'
          mynavid  is '#navpart3'
       */
      $(mynavid).attr('id','iamhere');
    });

## Pages from Parts and Clamshell Navigation

- Set "iamhere" id
- Close all nested lists
- Show parents of "iamhere"
- Show children of "iamhere"

    <script type="text/javascript">
    $(document).ready(function(){
      console.log("Ready!");
      var mybodyid = $('body').attr('id');
      var mynavid = '#nav_' + mybodyid;
      console.log("mybodyid is " + mybodyid);
      console.log("mynavid is " + mynavid);
      // Set iamhere id
      $(mynavid).attr('id','iamhere');
      // hide all nested lists
      $('#navigation ul ul').hide();
        // show parents of "iamhere"
      $('#iamhere').parents().show();
      // show children of "iamhere"
      $('#iamhere').children().show();
    });
    </script>

### JSFiddle Example

Note for the JSFiddle example, we are using a 'div' to contain the 'id' instead of the 'body'.
Clamshell Navigation in JS Fiddle

### Files

- test.html
- style.css

Copyright © David Heitmeyer