Session 09 - JavaScript, Part 2
Harvard Extension School
Fall 2020
Course Web Site: https://cscie12.dce.harvard.edu/
Topics
- JavaScript
- Data Formats - JSON
- Review: Building a List
- Separate JavaScript from HTML Markup wtih "addEventListener"
- Table striping with Javascript
- Things will go wrong...the Javascript Console is your friend
- Your work easier with jQuery
- jQuery Plugin - Tablesorter
- Separation from Markup
- JavaScript - Minifying and CDNs
- jQuery Examples
- Add Another
- Unobtrusive Javascript / Progressive Enhancement
- jQuery UI
- Slideshow
- Form Validation
- Javascript Helping with Navigation
Presentation contains 47 slides
JavaScript
Goals for the JavaScript Unit- Understand basics of JavaScript
- events
- console
- Understand basics of jQuery
- Understand how to use JavaScript
- Separate JS from Markup
- Be able to incorporate JavaScript functionality into a site
- Be able to "hack" JavaScript and jQuery to find solutions
- Ready for more!
Javascript
- Manipulate Styles
- Manipulate Content
- Communicate with Web Server (Ajax)
- Add functionality
Javascript
"JavaScript is now a language every developer should know."
– Mike Loukides, Vice President of Content Strategy for O'Reilly Media
JavaScript is everywhere: servers, rich web client libraries, HTML5, databases, even JavaScript-based languages.
If you've avoided JavaScript, this is the year to learn it.
And if you don't, you risk being left behind.
What is it?
- Programming language
- Runs within web browser
- Browser runs Javascript based upon events
- [Server-side language as well!]
What can it do?
Javascript provides programmatic access to virtually all aspects of a page.
- CSS properties
- Markup content
- Forms, communication to Server
- Add functionality
ECMAScript and JavaScript
The standard for JavaScript is called ECMAScript.
- ECMAScript v 5 (2009) and 5.1 (2011)
- ECMAScript v 6 (2015) -- you'll also see this as "ES6".
Javascript Resources
jQuery
jQuery is a JavaScript library that we will begin discussing next week!
Document Object Model (DOM)
<html>
<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>
Data Formats - JSON
A data format widely used in Ajax is JSON -- this format is used to pass data from the web server to the browser, and it is in a format that is easily worked with in JavaScript.
We first need to take a look at the JSON format and how we can work with it, and then we'll see how this works together in Ajax.
The introduction to JSON from json.org is a great place to start:
JSON (JavaScript Object Notation) is a lightweight data-interchange format. It is easy for humans to read and write. It is easy for machines to parse and generate. It is based on a subset of the JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999. JSON is a text format that is completely language independent but uses conventions that are familiar to programmers of the C-family of languages, including C, C++, C#, Java, JavaScript, Perl, Python, and many others. These properties make JSON an ideal data-interchange language.
JSON is built on two structures:
- A collection of name/value pairs. In various languages, this is realized as an object, record, struct, dictionary, hash table, keyed list, or associative array.
- An ordered list of values. In most languages, this is realized as an array, vector, list, or sequence.
These are universal data structures. Virtually all modern programming languages support them in one form or another. It makes sense that a data format that is interchangeable with programming languages also be based on these structures.
JSON array Example:
['Autumn', 'Winter', 'Spring', 'Summer']
JSON object Examples:
Simple "name/value" pairs:
{
"lastName" : "Bacow",
"firstName" : "Lawrence",
"email" : "president@harvard.edu"
}
"name/value" pairs, with values being an array (list) of things:
{
"apples" : ['Macoun','Empire','Honey Crisp','Albemarle Pippin'],
"oranges" : ['Naval Orange','Tangelo','Clementine','Valencia Orange']
}
Review: Building a List
Data:
{
"apples" : ['Macoun', 'Empire', 'Honey Crisp', 'Albemarle Pippin']
}
JavaScript:
function makeApplesList() {
ul_node = document.createElement("ul");
let mydata= {"apples" : ['Macoun','Empire','Honey Crisp','Albemarle Pippin']};
let itemlist = mydata.apples;
for (i in itemlist) {
let mytext = itemlist[i];
let text_node = document.createTextNode(mytext);
let li_node = document.createElement("li");
li_node.appendChild(text_node);
ul_node.appendChild(li_node);
};
let container = document.getElementById("itemlistcontainer");
container.appendChild(ul_node);
}
Invoking the script with a "click" event:
<button onclick="makeApplesList();">Build List of Apples</button>
Entire Example:
<div id="itemlistcontainer">
<button onclick="makeApplesList();" type="submit">Build List of Apples </button>
</div>
In
script
element within head
element (<script>
):
function makeApplesList() {
ul_node = document.createElement("ul");
let mydata= {"apples" : ['Macoun','Empire','Honey Crisp','Albemarle Pippin']};
let itemlist = mydata.apples;
for (i in itemlist) {
let mytext = itemlist[i];
let text_node = document.createTextNode(mytext);
let li_node = document.createElement("li");
li_node.appendChild(text_node);
ul_node.appendChild(li_node);
};
let container = document.getElementById("itemlistcontainer");
container.appendChild(ul_node);
}
Separate JavaScript from HTML Markup wtih "addEventListener"
let myButton = document.getElementById("makelistbutton");
myButton.addEventListener("click", makeApplesList);
Table striping with Javascript
- Use
onload
event attribute ofbody
element to call striping function. - Will use Document Object Model to access parts of the page
- Basic flow:
- Get the table to stripe (
getElementById
) - Get the table body (
getElementsByTagName
) - Get the rows within the table body (
getElementsByTagName
) - Go through each row, and assign an "evenRow" or "oddRow" class attribute
(for
loop andsetAttribute
DOM method)
- Get the table to stripe (
function stripeTable(tableid) {
let mytable = document.getElementById(tableid);
// get tbody (i.e. we do not want to stripe the thead)
let mytbody = mytable.getElementsByTagName('tbody');
/* getElementsByTagName gives us a Node List, so we need
to access it as a list (Array), arrayname[i].
Find all the tr within the tbody
*/
let myrows = mytbody[0].getElementsByTagName('tr');
/* Iterate over the node list of "tr" returned, setting
the class appropriately
*/
for(let i=0; i<myrows.length; i++) {
if ((i + 1) % 2 == 0) {
// even row -- the "%" operator is the "modulus" or remainder
myrows[i].setAttribute('class','evenRow');
} else {
// odd row
myrows[i].setAttribute('class','oddRow');
}
}
}
Things will go wrong...the Javascript Console is your friend
- United States Senate Table - Plain
- United States Senate Table - Striped with JS
- United States Senate Table - Striped with JS and Console Messages
function stripeTable(tableid) {
let mytable = document.getElementById(tableid);
console.log("mytable is:");
console.log(mytable);
// get tbody (i.e. we dont' want to stripe the thead)
let mytbody = mytable.getElementsByTagName('tbody');
console.log("mytbody is:");
console.log(mytbody);
/* getElementsByTagName gives us a Node List, so we need
to access it as a list (Array), arrayname[i].
Find all the tr within the tbody
*/
let myrows = mytbody[0].getElementsByTagName('tr');
console.log("myrows is:");
console.log(myrows);
console.log("myrows length is: " + myrows.length);
/* Iterate over the node list of "tr" returned, setting
the class appropriately
*/
for(let i=0; i<myrows.length; i++) {
let senatorname = myrows[i].getElementsByTagName('td')[0].firstChild.nodeValue;
console.log(senatorname);
if ((i + 1) % 2 == 0) {
// even rows
console.log("row with index of " + i + " is evenRow");
myrows[i].setAttribute('class','evenRow');
} else {
// odd rows
console.log("row with index of " + i + " is oddRow");
myrows[i].setAttribute('class','oddRow');
}
}
}
console.log()
allows you output messages to a console.
Example: Highlight By Age
function highlightbyage() {
let tableid = 'senatetable';
let older = 70;
let younger = 50;
let mytable = document.getElementById(tableid);
console.log("mytable is:");
console.log(mytable);
// get tbody (i.e. we dont' want to stripe the thead)
let mytbody = mytable.getElementsByTagName('tbody');
console.log("mytbody is:");
console.log(mytbody);
/* getElementsByTagName gives us a Node List, so we need
to access it as a list (Array), arrayname[i].
Find all the tr within the tbody
*/
let myrows = mytbody[0].getElementsByTagName('tr');
console.log("myrows is:");
console.log(myrows);
console.log("myrows length is: " + myrows.length);
/* Iterate over the node list of "tr" returned, setting
the class appropriately
*/
for(var i=0; i<myrows.length; i++) {
let bdaystr = myrows[i].getElementsByTagName('td')[3].firstChild.nodeValue;
console.log("bdaystr is " + bdaystr);
let [month, day, year] = bdaystr.split('/');
console.log(month + " " + day + " " + year);
let bday = new Date(year, month, day);
console.log("bday as Date object:");
console.log(bday)
let now = Date.now();
console.log("now is " + now);
let age = (now - bday)/(1000 * 365.25 * 24 * 60 * 60);
age = Math.round(age);
console.log(age);
if (age >= older) {
myrows[i].setAttribute('class','older');
} else if (age <= younger) {
myrows[i].setAttribute('class','younger');
}
}
}
Your work easier with 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.
- document traversal
- document manipulation
- event handling
- animation
- Ajax
- cross-browser
Learning jQuery
jQuery: Table Striping
Let's get started with jQuery by "striping" a table. The plain table comes from a list of United States Senators.
- Plain table: senate-plain.html
- Striped table: senate-striped.html
Include some Javascript libraries (jquery.js
) and write a function that selects the table rows and applies a class. Note that the jQuery selectors are like CSS selectors (and here we see custom jQuery selectors of:even
and:odd
).
<script src="https://code.jquery.com/jquery-3.5.1.min.js"
integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
crossorigin="anonymous"></script>
<script>
$(document).ready(function()
{
$("#senatetable tbody tr:even").addClass('evenRow');
$("#senatetable tbody tr:odd").addClass('oddRow');
}
);
</script>
Plain table:
Striped table:
jQuery and $(document).ready();
See: $(document).ready() for more explanation, including the shorthand of $()
.
jQuery Plugin - Tablesorter
jQuery Tablesorter Plugin makes dealing with tables even easier!
$(document).ready(function()
{
$("#senatetable").tablesorter(
{
theme: 'blue',
widgets: ['zebra']
}
);
}
);
- Plain table: senate-plain.html
- Sortable table: senate-tablesorter.html
- Javascript
- jQuery
- jQuery Tablesorter Plugin
- CSS
- Use the "blue" theme from the tablesorter plugin
- Assign tables with classes
- jQuery "ready" function
- Javascript
Data passed to the "tablesorter" plugin:
{
theme: 'blue',
widgets: ['zebra']
}
Tables are constructed with thead
and tbody
. Simply by giving them a class="sortable"
,
the jQuery Tablesorter Plugin makes them 'sortable' and 'striped':
Senate data used with permission from GovTrack.US.
Table sorting is
achieved through jQuery and the
jQuery Tablesorter Plugin
Tablesorter Example as a JSFiddle
Tablesorter Example as a JSFiddle
Separation from Markup
In an earlier example, we used the "onclick" attribute to specify a javascript function to call:
hide-show.html | Hide/Show as JSFiddle
In JavaScript, we saw the "addEventListener" method to add event listeners using JavaScript!
Separation from Markup
- Use Javascript to add the "onclick" listener
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
andfadeIn
) - Default Behavior Stopped. The default behavior for event propagation can be stopped.
- Unobtrusive. JS is used to hide additional form elements.
<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, 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.
</p>
</div>
<div style="width: 20%; 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();
}
);
});
JavaScript - Minifying and CDNs
Minified JS
Comments and unnecessary whitespace are removed.
- 288 kb for jquery-3.5.1.js
- 9 kb for jquery-3.5.1.min.js
70% reduction!
Load Your Core JS Library through a CDN
MaxCDN (jQuery CDN), Google, Microsoft, and cdnjs.com host several JS libraries through their CDNs.
Using jQuery with a CDN
Three reasons why you should let Google host jQuery for you (or any other CDN):
- Decreased latency
- Increased Parallelism
- Better Caching
CDNs to Use
But not just jQuery! Several JavaScript libraries are hosted through various CDNs:
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
andfadeIn
)
<form method="get" name="ice_cream" id="ice_cream" action="https://cscie12.dce.harvard.edu/echo">
<div>Would you like ice cream?
<br/>
<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>
</div>
<fieldset id="icecream_options">
<legend>Ice Cream Options </legend>
<p>How would you like it?
</p>
<label>
<input type="radio" id="container_cup" name="container" value="cup"/>
Cup </label>
<br/>
<label>
<input type="radio" id="container_cone" name="container" value="cone"/>
Cone </label>
<br/>
<p>Pick your toppings:
</p>
<label>
<input type="checkbox" name="toppings" id="toppings_wc" value="whipcream"/>
Whipped cream </label>
<br/>
<label>
<input type="checkbox" name="toppings" id="toppings_j" value="jimmies"/>
Jimmies </label>
<br/>
<label>
<input type="checkbox" name="toppings" id="toppings_nuts" value="nuts"/>
Nuts </label>
<br/>
<label>
<input type="checkbox" name="toppings" id="toppings_cherry" value="cherry"/>
Cherry </label> </fieldset>
<p>
<input type="submit"/>
</p>
</form>
In style
element
(<style>
) within head
element:
#icecream_options {
background-color: #eee;
margin-left: 2em;
}
label { display: block; }
In
script
element within head
element (<script>
):
$(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()
<form action="https://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>
):
$(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="https://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();
<form method="get" name="ice_cream" id="ice_cream" action="https://cscie12.dce.harvard.edu/echo">
<div>Would you like ice cream?
<br/>
<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>
</div>
<fieldset id="icecream_options">
<legend>Ice Cream Options </legend>
<p>How would you like it?
</p>
<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>
<p>Pick your toppings:
</p>
<label>
<input type="checkbox" name="toppings" id="toppings_wc" value="whipcream"/>
Whipped cream </label>
<label>
<input type="checkbox" name="toppings" id="toppings_j" value="jimmies"/>
Jimmies </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>
<p>
<input type="submit"/>
</p>
</form>
In style
element
(<style>
) within head
element:
#icecream_options {
background-color: #eee;
margin-left: 2em;
}
label { display: block; }
In
script
element within head
element (<script>
):
$(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');
}
}
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.
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"
media="all" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.12.2/jquery.min.js"
></script>
<script
src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"
></script>
<script >
$(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 GroupSummary: 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.
Markup:
<form action="https://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="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/themes/smoothness/jquery-ui.css"
media="all" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"
></script>
<script
src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js"
></script>
<script >
$(document).ready(function(){
$('input.date').datepicker();
})
</script>
jQuery UI Themes
Apply the "smoothness" theme | Apply the "hot-sneaks" theme |
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" href="form.css"/>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js">
</script>
<script >
$(document).ready(function(){
$("#myForm").validate();
});
</script>
</head>
<body>
<form id="myForm" method="post"
action="https://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" href="form.css"/>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.17.0/jquery.validate.min.js">
</script>
<script >
$(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="https://cscie12.dce.harvard.edu/echo">
<fieldset>
<legend>A Form to Illustrate Validation using the jQuery Validation Plugin</legend>
<p>
<label for="name">Name</label>
<input id="name" name="name" size="25"/>
</p>
<p>
<label for="email">Email Address</label>
<input id="email" name="email" size="25"/>
</p>
<p>
<label for="url">URL</label>
<input id="url" name="url" size="25" value="" />
</p>
<p>
<input class="submit" type="submit" value="Submit"/>
</p>
</fieldset>
</form>
</body>
</html>
Form Validation
$(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
- dynamically set classes/ids to achieve
Navigation
<html>
<head>
<title>The Great Binding Law, Gayanashagowa (Constitution of the Iroquois Nations)</title>
<link rel="stylesheet" href="style.css" />
</head>
<body id="part1">
<?php include("inc/header.php"); ?>
<?php include("inc/nav.php"); ?>
<main>
<?php include("inc/content1.php"); ?>
</main>
<?php include("inc/footer.php"); ?>
</body>
</html>
"You are here" with CSS
"You are Here" CSS Example in JSFiddle
<nav 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="iamhere"><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>
</nav>
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
- Each
body
is uniquely identified (id
) - Each navigation list item gets an
id
- CSS rule for
id="iamhere"
- 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" href="style.css" />
</head>
<body id="part3">
<?php include("inc/header.php"); ?>
<?php include("inc/nav.php"); ?>
<main>
<?php include("inc/content3.php"); ?>
<main>
<?php include("inc/footer.php"); ?>
</body>
</html>
Each navigation item has an id
:
<nav 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>
</nav>
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');
});
Clamshell Navigation
- Set "iamhere" id
- Close all nested lists
- Show parents of "iamhere"
- Show children of "iamhere"
<script >
$(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