Labguide html5 css4 Jquery
Labguide html5 css4 Jquery
Student Labs
1
Table of Contents
Lab 1 - Create a Basic HTML5 Layout ...............................................................................3
Lab 2 - Improve Your Forms Using HTML5 .....................................................................10
Lab 3 - Drawing Using the Canvas Element .....................................................................29
Lab 4 - Intro to CSS3 .........................................................................................................36
Lab 5 - Applying Basic Styles ...........................................................................................40
Lab 6 - Modify Text Styles ................................................................................................50
Lab 7 - Control Element Spacing with Box Properties......................................................61
Lab 8 - Intro to JavaScript .................................................................................................73
Lab 9 - Basic JavaScript Syntax ........................................................................................77
Lab 10 - JavaScript Functions............................................................................................88
Lab 11 - Arrays in JavaScript .............................................................................................95
Lab 12 - Getting Started with jQuery ..............................................................................106
Lab 13 - More on Selectors .............................................................................................. 111
Lab 14 - Dynamic Style Class Assignment ..................................................................... 118
Lab 15 - DOM Manipulation ...........................................................................................121
Lab 16 - Form Event Handling ........................................................................................125
Lab 17 - Basic Ajax..........................................................................................................127
Lab 18 - Submitting Form Using Ajax ............................................................................133
Lab 19 - Build a Drag and Drop Application ...................................................................139
Lab 20 - Build a Slide Show Viewer ...................................................................................... 144
Lab 21 - Develop a Simple Plugin ...................................................................................154
Lab 22 - Media Queries and Responsive Design .............................................................159
Lab 23 - Responsive Layout ............................................................................................172
Lab 24 - Orientation Responsiveness ..............................................................................179
Lab 25 - Responsive Images with Media Queries ...........................................................188
Lab 26 - Responsive Images with Picturefill ...................................................................192
Lab 27 - Getting Started With Bootstrap .........................................................................198
Lab 28 - Simple Components ..........................................................................................202
Lab 29 - Integrating jQuery with Bootstrap Components ...............................................206
Lab 30 - Mobile Web Testing With Chrome ...................................................................212
2
Lab 1 - Create a Basic HTML5 Layout
In this lab, you will create an HTML5 template which will serve as the starting point for
creating new HTML files in upcoming labs.
This lab will help you understand what a very simple HTML5 document looks like.
Specifically, you will learn to declare the DOCTYPE and character encoding.
When creating HTML5 files, you will use Notepad as a text editor. Of course, you're free
to use another text editor if you'd prefer.
Also, we'll be using Google Chrome as a web browser, since it provides the best support
for HTML5 in a Windows environment.
Note: On the Mac, Safari provides the best support for HTML5. Feel free to
experiment with other web browsers, such as Firefox 4 and Internet Explorer 9.
However, we can't guarantee that all the HTML5 pages you create will render properly
in those other browsers. If you want to see how well your browser supports HTML5,
navigate to http://www.html5test.com from within the associated browser.
Note: These labs were written using Chrome 23.0.x. If you're using another version of
Chrome, you may see slight differences in the GUI.
3
3. Under Settings expand Show advanced settings...
4
Wait for the clearing process to complete.
8. Click the Content settings button, which is located to the left of the Clear
browsing data button.
9. Scroll down in the browser and click the Manage exceptions button under the
Location section.
10. If any exceptions appear in the panel, select the exception and click the X to the
right of it to delete the exception.
5
11. Click the X in the upper right corner of the Geolocation Exceptions panel to close
the panel.
12. Click the X in the upper right corner of the Content Settings panel to close the
panel.
13. Close the browser.
C:\Software\NotepadPlus\notepad++.exe
<!DOCTYPE html>
<html>
The DOCTYPE declaration must be the very first element in your HTML5 document. It
even must appear before the html element.
6
Note: For those of you who are familiar with XML and XHTML (an XML compliant
version of HTML), the DOCTYPE element is used to indicate the document type
definition (DTD) that an XML document adheres to. A DTD is used to specify the
grammar of an XML document.
However, an HTML5 document is not XML, so the DOCTYPE element is not required
for this purpose. Instead, it's used to trigger "no-quirks mode" (a.k.a. "standards mode").
"No-quirks mode" implies the browser renders the page according to the HTML5 and
CSS standards. "Quirks mode" implies it doesn't and instead tries to maintain backward
compatibility with legacy pages created for older browser versions.
Also, notice that in HTML5 the DOCTYPE element is kept very minimal and simply
includes the root element name. Normally, when entering a DOCTYPE element in an
XHTML/XML document, you would need to specify several other pieces of
information, including a URL pointing to the DTD (see example below). However,
since the DOCTYPE element is not being used to reference a DTD, we can omit this
additional information.
e.g.,
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
Note: The DOCTYPE element is case insensitive. You could have written the
following instead:
<!DOCTYPE HTML>
<!doctype html>
5. Define the document's character encoding inside the head element as shown below.
<head>
<meta charset="utf-8"/>
<title>HTML 5 Template</title>
</head>
Note: The character encoding declaration is shorter than the one you're accustomed to
writing in HTML4:
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
7
Note: HTML5 is not XML. Hence, element names are not case sensitive, elements
don't require both a start and end tag, and attribute names don't need to be enclosed in
quotes. Hence, you could have expressed the meta element in any of the ways listed
below:
<META CHARSET="utf-8"/>
<META CHARSET=utf-8/>
<meta charset="utf-8">
<meta charset=utf-8/>
<Meta CharSet=Utf-8>
<body>
Contents goes here...
</body>
</html>
Next, you will save the HTML file to the Apache Web Server document root.
7. Open Windows Explorer.
8. Create a folder called layout under the following directory (the Apache folder may
be installed in another location, check with your instructor):
C:\Apache2.2\htdocs
8
Part 3 - Test
In order to test the HTML5 document, we'll use Google Chrome, since it provides the
best support for HTML5.
1. Open the Chrome browser.
2. Enter the following URL into the address bar:
http://localhost/layout/html5Template.html
Part 4 - Review
In this lab, you created a template for your HTML5 files. In the process, you learned
how to declare DOCTYPE and meta elements.
9
Lab 2 - Improve Your Forms Using HTML5
An HTML form is used for gathering information from a user and submitting it to a
server to be processed. This information normally needs to be validated. This is
typically done both on the client side and the server side, since client validation may be
turned off in the browser.
Prior to HTML5, the form fields didn't have any built-in validation logic. That meant
you were stuck writing JavaScript code to perform client side validation, which was both
tedious and error prone. Now in HTML5, new input types were introduced containing
built-in validation logic, which eliminates the need for JavaScript code (see note below).
In this lab, you will learn to use several of the new input types: e-mail, date, number,
and range.
In addition to these new input types, HTML5 also supports three major new features for
form fields: the placeholder, autofocus, and pattern attributes. Implementing the
features provided by these attributes used to require JavaScript code.
The placeholder attribute allows the developer to define the text that will appear in a text
box-based control when its contents are empty. When the field gains focus, the text is
removed. If the user doesn't type a value into the field and the field loses focus, the text
is restored. You may want to use the placeholder attribute when implementing a search
field to indicate to the user they should input a value. This way, you don't need to define
a label for the search field that's displayed adjacent to it.
The autofocus attribute tells a browser to automatically give focus to a particular form
field when the page is loaded.
The pattern attribute is used to specify a regular expression that a field's value must
match.
Note: You'll still want to have JavaScript code inside your pages for older browsers that
don't support HTML5 or for newer browsers that don't fully support HTML5. You can
navigate to http://www.html5test.com to see how well your browser supports HTML5.
Below are the results for Google Chrome v10.0.x., which provides fairly good support
for the new HTML5 form features:
10
Part 1 - Create an Input Form Using the New HTML5 Input Types
In this part, you will create a new HTML file, based on the template, which will contain
an input form for registering a new employee. You will make use of several of the new
input types which provide built-in validation.
1. Open C:\Apache2.2\htdocs\layout\html5Template.html. Save it as
registerEmployee.html in the same folder.
2. Change the title content to:
11
Next we will create the registration form.
5. Add the following form element:
<form action="thankYou.html">
</form>
6. Add a label and a corresponding text field for the employee's name inside the form
element:
<label for="email">E-mail:</label><br/>
<input type="email" name="email" id="email" placeholder="Enter a valid
e-mail" required />*<br/>
12
Notice the following:
• To create an e-mail field, we used the input element and specified the new HTML
input type email.
• To specify that the e-mail is mandatory, we used the new HTML5 attribute
required. That means the required attribute is not specific to text fields (input
type="text"), but can be used with many of the new input types too.
8. Add a label and a date field for the employee's date of birth.
<label for="age">Age:</label><br/>
<input type="number" name="age" id="age" size="6" min="18" max="120"
step="1" value="21" /><br/>
13
Notice the following:
• To create a range field, we used the input element and specified the new HTML
input type range.
• We used the min and max attributes to specify the minimum number of years of
experience (0) and maximum number of years of experience (100), respectively.
• We used the step attribute to specify the interval (1) between valid values (e.g., 1,
2, 3).
• We used the value attribute to specify the default number of years of experience
(0).
11. Add a label and a text field for the employee's phone number:
<label for="phone">Phone:</label><br/>
<input type="text" name="phone" id="phone" pattern="[0-9]{3}-[0-9]{3}-
[0-9]{4}" placeholder="XXX-XXX-XXXX" required />*<br/>
14
Part 2 - Test
1. Open Google Chrome.
2. Navigate to the following URL:
http://localhost/layout/registerEmployee.html
15
• Chrome rendered the Date of Birth field (input type="date") as a spin box (i.e., a
text field with up and down arrows that you click on to change the value) that
allows you to increment/decrement the date by a day. Ideally, it would have been
preferable if it rendered a date picker. Once again, HTML5 does not specify a
default rendering for this input type.
• Chrome also rendered the Age field (input type="number") as a spin box.
However, when you click the up and down arrows, the age is incremented by the
value of the step attribute (1).
• Chrome rendered the Years of Experience field (input type="range") as a slider
bar. However, we can't tell what the value selected is. We'll address this
limitation in the next part of the lab.
Note: If you loaded this page in Opera 11.01, this is how it would look:
Notice the date field is rendered as a drop-down. If you click on the drop-down, a date
picker will be displayed:
16
Note: If you load a page in an older browser that doesn't support/fully support HTML5,
the new input types will be ignored. The input types will gracefully degrade to text
fields (type="text").
e.g., Internet Explorer 7
17
Now let's test how the form works. We'll test the "happy day" scenario first.
5. Input the following values:
Full Name: Mike Harris
E-mail: [email protected]
Date of Birth: 01-23-1980
Age: 21 (default value)
Years of Experience: 0 (default value)
Phone: 215-314-2300
Now let's try some error scenarios. First, we'll see what happens if you omit a required
field.
18
8. Click the Back button (left arrow).
9. Delete the text in the full name field.
10. Try submitting the form.
11. You should see the following error message:
Pretty cool!
Let's try another error scenario. Let's see what happens if the user types in an invalid e-
mail address.
12. Enter Mike Harris back into the full name field.
13. Change the e-mail address from [email protected] to mharris.
14. Try submitting the form.
15. You should see the following error message:
Note: Opera will also display a visual cue (callout box) indicating a validation rule has
failed when you try submitting the form, as shown below. The error messages though
are a little bit different. This is because the HTML5 specification doesn't dictate what
error messages should be displayed.
19
Part 3 - Display the Value of the Range Field
In this part, you will add some JavaScript and HTML code to display the value for the
number of years of experience that the user input, since Chrome doesn't automatically
display values for range fields.
1. Open registerEmployee.html.
2. First off, add a span element to the right of the range field. The span element will
display the value the user selected for the number of years of experience:
3. Next, add an onchange event handler to the range field that gets called after the user
drags the slider to a new position:
Note: The parameter this that's passed to the displayRating function is a reference to
the current element (i.e., the input element).
4. Add a script element before </head>.
<script>
</script>
Note: In HTML5, you no longer need to specify the type attribute to indicate the
category of scripting language you're using. It now defaults to "text/javascript".
20
5. Add the event handler function, displayRating, inside the script element:
function displayRating(slider) {
document.getElementById("ratingValue").innerHTML = slider.value;
}
This function retrieves a reference to the span element and updates the HTML inside with
the slider value.
Note: Remember, JavaScript is a case sensitive language so pay attention to case.
6. Save your changes.
7. Close all open browsers.
Now let's test the changes.
8. Navigate to the following URL:
http://localhost/layout/registerEmployee.html
You should now see 0 for the number of years of experience listed to the right of the
slider.
9. Drag the slider all the way to the right. Make sure the value increments in steps of 1
and reaches a maximum value of 100.
10. Now drag the slider all the way to left. Make sure the value decrements in steps of
1 and reaches a minimum value of 0.
Troubleshooting: If the value doesn't get updated when you drag the slider, refer to the
next section for troubleshooting instructions.
21
Part 4 - Troubleshooting JavaScript Problems in Chrome
In this part, you will learn a little bit about how to troubleshoot JavaScript related
problems that crop up when using Chrome.
For example, if you load a web page that has JavaScript syntax errors and do something
that invokes that code, Chrome won't display any errors unless you open the Developer
Tools. Aside from viewing syntax errors, you can use the Developer Tools for debugging
semantic errors.
In our case, we will pretend you made a typo.
1. Change the code as shown in bold below:
function displayRating(slider) {
document.getelementById("ratingValue").innerHTML = slider.value;
}
Notice the red X in the lower right corner of the screen. This indicates there are errors in
your page.
22
Note: You will probably see a different number of errors than above. The number 9
does not indicate how many errors there are in the HTML file. In our case, there is only
1 error. It just indicates how many times that line of code was executed in error (in this
case, 9 times). Since I kept dragging the slider to the right, it kept trying to execute the
same line of code to update the value.
7. Click the Console tab.
It should show you the error message that occurred when executing the code, along with
the offending file and line number.
The error message is very clear. The HTMLDocument object doesn't have a method
named getelementById.
8. Click the registerEmployee.html:9 link.
9. Chrome will show you the offending line of code in the Scripts tab.
23
15. Verify a breakpoint symbol (blue arrow) appears.
Note: When a breakpoint is hit, it means that the line of code (in our case,
document.getElementById()) is about to be executed.
18. In the right panel, look inside the Scope Variables panel and you'll see the slider
variable listed.
19. Expand it and you can see the value of its properties.
Ordinarily, being able to see the value of a variable or its properties can be useful in
troubleshooting semantic errors. In our case, it doesn't help us, since we don't have any
semantic errors.
24
20. To execute the line of code, click the Step over next function call button in the
toolbar at the top of the panel.
Note: There is also a Step into next function call that allows you to step through the
code inside of a function that's called by the current function. This can be useful in terms
of troubleshooting functions you've written which call other functions.
22. Click the Resume script execution button (to the left of the Step over next
function call button) to resume running the script.
23. Remove the breakpoint by clicking on the blue arrow in the margin. The arrow
should disappear.
24. Close the Developer Tools by selecting Tools->Developer tools from the menu bar.
Note: You can also press Ctrl-Shift-I to open and close the Developer Tools.
Part 5 - Display the Value of the Range Field Using the Output
Element
In this part, you will replace the existing span element and JavaScript function that you
used to display the slider value with the new output element. The output element was
introduced in HTML5 to display the result of a calculation.
25
1. Replace the span element:
<span id="ratingValue">0</span><br/>
<output name=output>0</output><br/>
2. Add the 'oninput' attribute below to the 'rating' input element, so that it looks like so:
Like the output element, the oninput attribute was also introduced in HTML5. It's used
to specify what happens when the oninput event is triggered . This event is triggered
when the user interacts with an input control. In this case, we're setting the value of the
output element to the value of the rating element.
3. Delete the script element, containing the displayRating function, since it's no longer
needed.
4. Save your changes.
5. Refresh the browser. You should now see 0 for the number of years of experience
listed to the right of the slider.
6. Drag the slider all the way to the right. Make sure the value increments in steps of 1
and reaches a maximum value of 100.
7. Now drag the slider all the way to left. Make sure the value decrements in steps of 1
and reaches a minimum value of 0.
26
1. Add the following style element before </head>:
<style type="text/css">
:required, :invalid { background-color: pink; }
:valid { background-color: white; }
</style>
HTML5 introduced new pseudo-classes that can be used to style validation errors. In this
case, you specified that any required elements or invalid elements should have a
background color of pink, whereas any valid elements should have a background color of
white.
2. Save and close the file.
3. Refresh the page.
You should see the following screen:
Notice that all the required fields (Full Name, E-mail, Date of Birth, and Phone) are
displayed in pink. This makes sense, given that they're not filled in. It also indicates that
Chrome validates the field data even before you submit the form.
4. Input Mike Harris for the full name.
Notice the Full Name field turns white. This means the field is valid. Remember that
you set the background color for the :valid pseudo-class to white.
27
5. Now input [email protected] for the e-mail.
Now the E-mail field should turn white.
6. Repeat this process for the remaining fields.
7. Submit the form. You should see the thank you page.
8. Close the browser.
Part 7 - Review
In this lab, you learned how to:
• Use some of the new input types: e-mail, date, number, and range
• Use the autofocus, placeholder, and pattern attributes
• Use the output element and oninput attribute.
• Style the fields that are in error
28
Lab 3 - Drawing Using the Canvas Element
In this lab, you will learn how to draw 2D graphics using the canvas element introduced
in HTML5. The canvas element allows you to draw rectangles, ovals, lines, arcs, text,
images, etc. We won't be drawing anything too fancy in this lab. Instead, we'll simply
draw a green rectangle containing two red diagonal lines.
<title>Draw Something</title>
29
A canvas doesn't display anything by default. It's just used to define a rectangular region
within the page that you can draw on. To draw on it, we'll need to use JavaScript. A
canvas element has a corresponding DOM element (called HTMLCanvasElement) that
we can use to draw graphics.
Note: Technically, you can have many canvas elements inside your page, each of which
contains it own drawing.
6. Add an onload event handler to the body element:
<body onload="drawOnCanvas();">
When the page loads, the drawOnCanvas function, which we'll be writing next, gets
called.
7. Add the following script element before </head>:
<script>
</script>
function drawOnCanvas() {
var c = document.getElementById("c");
var ctx = c.getContext("2d");
30
10. Add the following code to draw a green rectangle to the drawOnCanvas function:
(0,0)
x
31
Note: When specifying the fillStyle color, you can specify a CSS color in hexadecimal
format (e.g., "#00FF00"), in RGB format (e.g., "rgb(0, 255, 0)"), or using one of the
predefined color names (e.g., "red").
Note: If you don't want to create a filled rectangle, you can use the strokeRect method
instead. It has the same method signature as the fillRect method.
11. Add the following code to draw the first diagonal to the drawOnCanvas function:
moveTo(x, y) allow you to specify where to start drawing a line. In this case, the starting
point for your line is the upper left corner of the rectangle.
lineTo(x, y) indicates where to draw the line to. In this case, the end point for your line is
the lower right corner of the rectangle.
12. In a similar manner, add the following code to draw the second diagonal:
13. Add the following code to render the two lines you drew in red ink to the
drawOnCanvas function:
Technically, when you draw lines in HTML5, they're not displayed by default. You need
to tell the context object to render them using its stroke method. One analogy that can be
made is that you're drawing with a pen which is out of ink. When you call the stroke
method, you refill the pen with ink and retrace the lines (in this case, red ink, since the
strokeStyle property was set to red).
Note: Technically, the above rule applies to all paths (complex objects). A path is a set
of subpaths. A subpath is a set of one or more points connected by a straight line or a
curved line. When you drew the two diagonal lines, you created a path consisting of two
subpaths.
14. Save the file.
32
Part 2 - Test
1. Open Google Chrome.
2. Navigate to the following URL:
http://localhost/canvas/drawOnCanvas.html
As expected, the canvas contains the drawing you created in the previous part. However,
notice that you can't see the border of the canvas.
4. Open drawOnCanvas.html.
5. To see the border of the canvas, add the following style attribute to the canvas
element:
33
7. Refresh the page in the browser.
You should now see the edges of the canvas.
Make sure that when you draw inside the canvas, you take into account the size of the
canvas. Let's see what happens if you don't.
8. Try changing the size of the rectangle to a value that exceeds the width of the
canvas:
34
11. Change the rectangle width back to its original size and save your changes.
12. Test again.
13. Close the browser and the editor.
Part 3 - Review
In this lab, you learned how to use the canvas element to draw a filled rectangle and lines.
35
Lab 4 - Intro to CSS3
In this lab you will copy some files used in the labs and see some basics about how CSS
is used to define styles of web pages.
http://localhost/css3/intro/intro.html
36
2. Observe the appearance of the page. Take note of the colors, style and size of the
text, etc. These will change somewhat when you alter the styles in the page.
3. Leave the browser open to the page as you will refresh it later.
4. Run the following program to run a specialized editor. You do not need to use
anything but a regular text editor for the labs but this program has some tools that can
make it easier to work with the web pages you will be editing.
C:\Software\NotepadPlus\notepad++.exe
C:\Apache2.2\htdocs\css3\intro\intro.html
7. Observe how currently there are some <style> definitions near the top of the page
that are modifying how the browser displays the page.
37
8. Modify the 'color' properties of the two existing styles as shown in bold below.
http://localhost/css3/intro/intro.html
11. Observe how the color of the text at the top of the page changes colors with the
change to the style.
Note: If for some reason you do not see a change, it could be because the browser is
caching the page. Use the tools of the browser to clear the cache, close all open browser
windows, open a new window and try the URL again. You should try this first anytime
you don't see a change you expect to see if the browser cache is not letting you see
changes you have made to the pages.
38
12. Return to the editor that was editing the page and modify the 'font-weight' property
as shown in bold below.
Part 3 - Review
In this lab you just saw some basics about how CSS3 styles modify the display of web
pages. You also copied some files and used tools that will be used in other labs to explore
CSS3 styles in more depth.
39
Lab 5 - Applying Basic Styles
In this lab you will see some of the various ways to define styles and link style definitions
to elements of a web page. This will include inline styles, style classes, and external
stylesheets.
C:\Apache2.2\htdocs\css3\intro
Note: If you do not see this folder, you can copy this from the 'C:\LabFiles\css3' folder
or extract the appropriate lab solution for the previous lab from the
'C:\LabFiles\Solutions' folder. Be careful which files you copy and where you place
them to make sure the web server can locate them with the URLs provided in the labs.
http://localhost/css3/intro/intro.html
40
2. Observe the appearance of the page. Take note of the colors, style and size of the
text, etc. These will change somewhat when you alter the styles in the page.
3. Leave the browser open to the page as you will refresh it later.
4. Run the Notepad++ program or a regular text editor.
C:\Software\NotepadPlus\notepad++.exe
Note: A file may appear since Notepad++ opens the last used file. To avoid this in
future, close the file first and then close Notepad++.
5. Once you have the Notepad++ program running (or another text editor if you
prefer), open the following file:
C:\Apache2.2\htdocs\css3\intro\intro.html
6. Find the first '<h1>' tag and add the 'style' property as shown in bold below. Make
sure you have proper syntax including the quotes and the colon and semi-colon in the
style rule.
<body>
<h1 style="color:orange;">Alice’s Adventures In Wonderland</h1>
<h1 id="ch01">Chapter 1 Down the Rabbit-Hole</h1>
http://localhost/css3/intro/intro.html
41
9. Observe how the color of the text at the top of the page changes colors with the
change to the style.
Note: If for some reason you do not see a change, it could be because the browser is
caching the page. Use the tools of the browser to clear the cache, close all open browser
windows, open a new window and try the URL again. You should try this first anytime
you don't see a change you expect to see if the browser cache is not letting you see
changes you have made to the pages.
42
3. Return to the browser showing the page and refresh the page again. Notice that now
the paragraph text is a different color, has a little more space between lines and is
indented.
p {
color: rgb(153,153,153);
font-family: perpetua, georgia, serif;
line-height: 1.5;
text-indent: 3em; }
.chaptertitle {
font-family: perpetua, georgia, serif;
font-variant: small-caps;
letter-spacing: .1em; }
</style>
</head>
2. Scroll down to the second <h1> element and notice that part of it already has a
<span> tag that applies the 'chaptertitle' style. This was so another lab could show two
different colors by using the style class. You do not have to modify anything here.
43
3. Find the link anchor tag (<a>) near the bottom of the page and add the 'class'
property with the name of the new class as shown in bold below.
</article>
<footer><nav> Next:
<a class="chaptertitle" href="AAIWL-ch02.html">The Pool of Tears</a>
</nav></footer>
6. Return to the editor that was editing the page. Modify the existing '<style>' tag by
adding a new 'a.chaptertitle' style class definition as shown in bold below. This is a
“dependent” class that can only be applied to the anchor (<a>) element.
.chaptertitle {
font-family: perpetua, georgia, serif;
font-variant: small-caps;
letter-spacing: .1em; }
a.chaptertitle {
font-size: 2em;
font-style: italic; }
</style>
</head>
44
8. Return to the browser showing the page and refresh the page again. Notice that
nothing else on the page changes but the size and style of the link text changes. The
dependent class only applied to this element.
45
3. Return to the browser showing the page and refresh the page again. Now the text
should have quite a bit of padding on the top and left of the page.
4. Return to the editor editing the page. Within the existing <style> tag add the
following '@import' rule in bold. Make sure it is at the top of the content of the <style>
tag.
46
6. Return to the browser showing the page and refresh the page again. Now you
should have an image that fills in some of the empty space that was created.
7. If you want you can open the following files and look at some of the style rules that
have made the changes you saw.
C:\Apache2.2\htdocs\css3\intro\global.css
C:\Apache2.2\htdocs\css3\intro\ch01.css
47
Part 6 - Pseudo-Classes
One new feature of CSS3 is the use of “pseudo-classes”. These are special states of
certain HTML elements that can be styled independently of the other states of the
element. One of the best examples of this are the various states of a link.
1. Return to the editor editing the page. Within the existing <style> tag add the
following pseudo-class definitions in bold. Notice that they contain a colon (':') and not a
period because the link state the style applies to comes after the colon.
a.chaptertitle {
font-size: 2em;
font-style: italic; }
a:link {
color: darkred;
border-bottom: 1px solid red; }
a:visited {
color: darkred;
border-bottom: 1px dashed red;}
a:hover {
color: red;
border-bottom: 1px solid pink;}
a:active {
color: pink;
border-bottom: 1px solid pink;}
</style>
</head>
48
Part 7 - Review
In this lab you saw many different ways to define styles that apply to HTML elements.
You could define them inline directly in the element, embedded within the <style> tag on
the page, or link to external stylesheets. You also saw some aspects of “pseudo-classes”
that are styles for various states of HTML elements.
49
Lab 6 - Modify Text Styles
In this lab you will modify various text properties with font styles. Since text can be a
large part of the content of a page, these styles can have a big impact on the overall style
of a page.
C:\Apache2.2\htdocs\css3\text
Note: If you do not see this folder, you can copy this from the 'C:\LabFiles\css3' folder
or extract the appropriate lab solution for the previous lab from the
'C:\LabFiles\Solutions' folder. Be careful which files you copy and where you place
them to make sure the web server can locate them with the URLs provided in the labs.
http://localhost/css3/text/index.html
50
2. Observe that right now the text does not really have much style applied to it but this
will change as various style properties are added.
3. Leave the browser open to the page as you will refresh it later.
4. Run the Notepad++ program or a regular text editor.
C:\Software\NotepadPlus\notepad++.exe
Note: A file may appear since Notepad++ opens the last used file. To avoid this in
future, close the file first and then close Notepad++.
5. Once you have the Notepad++ program running (or another text editor if you
prefer), open the following file:
C:\Apache2.2\htdocs\css3\text\index.html
6. Notice that the page already has a link to a stylesheet of the name
'font-properties.css'. Rather than defining styles directly in the page we will edit this file.
C:\Apache2.2\htdocs\css3\text\font-properties.css
51
9. Add the 'font-family' property to the 'body' style as shown in bold below. Make sure
the entire name of the 'Times New Roman' font is in quotes.
body {
font-family: Constantia, Georgia, "Times New Roman", serif;
}
http://localhost/css3/text/index.html
12. You may not see a big change but there should be some subtle differences in the
font. This may be because your browser is now using one of the fonts in the 'font family'
list instead of the default font for the browser.
Note: Often 'Times New Roman' is a default font of the browser so unless our
'font-family' property had a different font available to the browser before this you might
not see any change.
13. Return to the editor that was editing the 'font-properties.css' file. Modify the other
style rules that are currently empty to add the 'font-family' property shown in bold below.
52
14. Save the file but leave it open.
15. Return to the browser that was showing the page and refresh the page.
16. Observe that the font styles used by the various headers at the top of the page
change as they are now using some type of “sans-serif” font.
C:\Apache2.2\htdocs\css3\text\index.html
2. Modify the name of the file linked to as the stylesheet as shown in bold below.
Since web fonts require quite long style rules we will provide much of it for you to avoid
typos.
C:\Apache2.2\htdocs\css3\text\font-properties-webfont.css
53
5. Observe the various '@font-face' rules, one example of which is shown below. The
most important property is the 'font-family' property which can be a name of your
choosing. We will see this show up later. Also notice that there are various 'url(...)'
functions linking to files that were copied to the web server. There are several different
URLs because different browsers (and versions) may use different file formats for web
fonts.
@font-face {
font-family: 'BodyCopy';
src: url('fonts/DVS/DejaVuSerif.eot');
src: url('fonts/DVS/DejaVuSerif.eot?#iefix')
format('embedded-opentype'),
url('fonts/DVS/DejaVuSerif.woff') format('woff'),
url('fonts/DVS/DejaVuSerif.ttf') format('truetype');
font-weight: normal;
font-style: normal; }
Note: The “Font Squirrel” web site, has useful tools for downloading free web fonts and
provides sample stylesheet code for the '@font-face' rules that can be used to link to
those fonts. That sample code would be similar to that shown above with the only
difference being the relative URL to access the font files where you decide to place them
on the server.
http://www.fontsquirrel.com/
6. Scroll to the bottom of the 'font-properties-webfont.css' file and find the various
styles that had previously been defined in the other stylesheet file. Currently they are the
same as they were in that file.
7. To use the web fonts we must reference the name given to it in the '@font-face' rules
so add the following bold entries to the values of the various 'font-family' style properties.
Make sure to also add the comma between the new font name and the fonts that were
already present. Also double check that the font name you add matches exactly the
'font-family' property defined with the various '@font-face' rules.
body {
font-family: 'BodyCopy', Constantia, Georgia,
'Times New Roman', serif;
}
h1, h2, .author {
font-family: 'TitleCopy', Corbel, Helvetica, Arial,
sans-serif;
}
h2 .chaptertitle {
font-family: 'TitleCopy', Corbel, Helvetica, Arial,
sans-serif;
}
54
Note: When using web fonts it is common to list the name given to the web font by the
'@font-face' rules as the first font referenced in a 'font-family' property. If other fonts
are listed first, the browser may end up using a local font instead of the web font which
might defeat the purpose of the uniformity across browsers which is part of the appeal of
web fonts.
8. Save the file but leave it open.
9. Return to the browser that was showing the page and refresh the page. Open a new
one to the following URL if you closed it:
http://localhost/css3/text/index.html
10. You should see that the fonts of the body and the headers change quite drastically
as the web font is picked up instead of the “standard” fonts used before.
55
2. Save the file but leave it open.
3. Return to the browser that was showing the page and refresh the page. Open a new
one to the following URL if you closed it:
http://localhost/css3/text/index.html
4. You should see the first line of text, the only thing to use the <h1> element, is now
italic.
Note: It is important that because this is a web font that the definition of the related
'@font-face' rule did NOT indicate that the web font only applied for “normal” text.
Notice that the 'TitleCopy' @font-face does not have the 'font-style' property while the
'BodyCopy' @font-face does. Depending on the web font you might need different files
to download for different font styles so this depends somewhat on the exact web font
being used.
In this example the 'LTG' font used for the 'TitleCopy' font family has one set of files for
all styles (bold, italic, bold-italic) of the font. So for this web font we do not need to
define the 'font-weight' or 'font-style' properties in the rule because it can be used for all.
In the example of the 'DVS' font used for 'BodyCopy', there are different files for each
style of font. So for these 4 'font-face' rules, the 'font-weight' and 'font-style' properties
are used so that depending on the style used within the page the appropriate rule will be
matched. In this case the value of the 'font-family' property for all 4 is set to
'BodyCopy'. This just makes it so that you do not need to change the name of the font to
switch to a different style. We could have also used different names like
'BodyCopyBold', 'BodyCopyItalic', etc but this would have required you to switch to the
different name of the font when you wanted to change the style. Either way would be
valid and it is a preference which approach to take.
56
5. Return to the editor for the 'font-properties-webfont.css' file. Add the following new
style rule in bold to display the 'author' style elements in all uppercase.
Note: The 'author' style is already applied in the page but hadn't yet had any unique style
properties defined.
6. Save the file but leave it open.
7. Return to the browser that was showing the page and refresh the page.
8. You should see a change to the style of the authors name.
Note: It seems like the web font being used for the title text does not really have support
for bold. If we were using a “standard” font for the header elements we could add
properties like 'font-weight: bold;' to use bold text.
57
Part 5 - Modify Text Alignment
Controlling how the text is aligned can be another important style property.
1. Return to the editor for the 'font-properties-webfont.css' file. Modify the existing
'body' style rule to include the properties in bold below to justify text.
body {
font-family: 'BodyCopy', Constantia, Georgia,
'Times New Roman', serif;
text-align: justify;
text-justify: distribute;
}
Note: The most important property is the 'text-align' property as the manner in which the
justification is done (controlled by the 'text-justify' property) may be difficult to notice
differences.
2. Save the file but leave it open.
3. Return to the browser that was showing the page and refresh the page.
4. You should see body text in the main content of the page is now justified instead of
left-aligned.
5. Return to the editor for the 'font-properties-webfont.css' file. Add the following new
style rule in bold to center <h2> elements.
58
6. Save the file but leave it open.
7. Return to the browser that was showing the page and refresh the page.
8. You should see the <h2> header text centered on the page.
9. Return to the editor for the 'font-properties-webfont.css' file. Modify the existing
'h2.chaptertitle' style rule to include the properties in bold below to adjust the size and
vertical alignment.
h2 .chaptertitle {
font-family: 'TitleCopy', Corbel, Helvetica, Arial,
sans-serif;
vertical-align: middle;
font-size: 200%;
}
59
Part 6 - Review
There are many different style properties that can affect display of text. This starts with
what font is used but also includes other properties like style, weight, size, and alignment.
Web Fonts are also new with CSS3 and can allow you to more closely control the style
across browsers and platforms by allowing the browser to download font format files
instead of relying on linking to fonts already local to the browser and machine.
60
Lab 7 - Control Element Spacing with Box Properties
The “Box” around an element controls how elements are spaced or grouped with other
elements on the page. In this lab you will control some of the common box style
properties.
C:\Apache2.2\htdocs\css3\box
Note: If you do not see this folder, you can copy this from the 'C:\LabFiles\css3' folder
or extract the appropriate lab solution for the previous lab from the
'C:\LabFiles\Solutions' folder. Be careful which files you copy and where you place
them to make sure the web server can locate them with the URLs provided in the labs.
http://localhost/css3/box/index.html
Note: The page in this example uses some HTML5 elements that may not be recognized
directly in older Internet Explorer browsers. This might cause the styles to not be
displayed properly to some elements. There is a JavaScript trick included in this page
that can enable HTML5 for some older Internet Explorer versions though.
If you do try testing with Internet Explorer and don't see the behavior the style should be
creating try testing with Firefox or Chrome to see if it is different.
Screenshots in the lab will show how things should appear in Firefox.
61
2. Get familiar with the current style of the page. In particular notice there are some
images (HTML5 <figure> tags) that we will control text flow around in one part of the
lab.
3. Leave the browser open to the page as you will refresh it later.
4. Run the Notepad++ program or a regular text editor.
C:\Software\NotepadPlus\notepad++.exe
Note: A file may appear since Notepad++ opens the last used file. To avoid this in
future, close the file first and then close Notepad++.
5. Once you have the Notepad++ program running (or another text editor if you
prefer), open the following file. This is a stylesheet currently linked from the index.html
file (along with some other stylesheets for font and text styles).
C:\Apache2.2\htdocs\css3\box\box-properties.css
6. Add the following width and height properties in bold to the currently empty 'header'
style.
header {
width: 100%;
height: 135px;
}
62
8. Return to the browser that was showing the page, make sure you are viewing the top
headers of the page, and refresh the page. Open a new one to the following URL if you
closed it:
http://localhost/css3/box/index.html
9. You should see that the chapter number and title are a little closer vertically than
they were to the author name on the right. If you were not viewing the top of the page
before you did the refresh this might be hard to detect.
10. If your browser window is currently maximized, used the 'restore' button so you
can resize the browser window.
11. Drag the width of the browser window to make it much narrower and see if the
various elements in the header start overlapping badly with each other. This is because
the word wrapping of the header is now causing it to want to use more height than we
allowed and it is overlapping the next element. You might also see that the chapter title is
wrapping as well.
63
12. Return to the editor that was editing the 'box-properties.css' file. Add the following
properties in bold to the currently empty 'h1' and 'article' styles.
h1 {
width: 95%;
max-width: 980px;
min-width: 760px;
}
article {
max-width: 980px;
min-width: 660px;
}
Note: Setting height and width in a stylesheet is often only done for structural elements
like headers and body. Height and width of images especially is often done inline within
the HTML element for the image.
64
16. Gradually expand the width of the browser window and you should see the chapter
title and number move right a little once the window is wider than the minimum width of
the <article> content. Depending on your screen size you may also see that eventually
the content starts leaving more empty space on the right because you have hit the
maximum width value.
Note: Depending on how narrow you had the window to start with and your screen size
the behavior here may be slightly different. The key thing is that the text does not wrap
as horribly as before you set a minimum width.
17. Scroll to the very bottom of the page and notice there is an 'About the Author'
section which is an HTML5 <aside> element.
18. Return to the editor that was editing the 'box-properties.css' file. Add the following
properties in bold to the currently empty 'aside' style.
aside {
width: 300px;
height: 400px;
}
65
21. You should now see that this section is narrower. It is hard to tell but the height
should be taller than the value of the 'height' property.
22. Return to the editor that was editing the 'box-properties.css' file. Add the following
new 'overflow' property in bold to the 'aside' style.
aside {
width: 300px;
height: 400px;
overflow: auto;
}
66
24. Return to the browser that was showing the page and refresh the page while still
looking at the bottom of the page.
25. You should now see that the 'height' style property is honored and a scrollbar is
added to scroll through the text within the allowed space.
Note: The narrow width was used not really because it looks good but to show the effect
of “overflow” content. Although you might think the default value of the 'overflow'
property was 'auto' it is actually 'visible' which tells the browser to ignore the height if
needed to display the entire content. There is also a 'scroll' value but this will often add
scrollbars even if they aren't needed. A 'hidden' value will not display overflow content
but provide no way to view it so 'visible' and 'auto' are the two most popular values of
this property.
67
Part 3 - Text Flow
Right now the text of the document does not flow around the images. This section will
change that.
1. Return to the editor that was editing the 'box-properties.css' file.
2. Add the following new style classes in bold to the stylesheet. Make sure they are
not embedded within the brackets of another style.
.floatleft {
float: left;
}
.floatright {
float: right;
}
68
6. Scroll to the top of the page and look at the first letter of the first paragraph. There
is an existing style that makes the letter larger and with a shadow but notice it sticks up
above the top of the line for the rest of the text. You may not see this in some Internet
Explorer versions so use Firefox or Chrome if needed.
h2 + p:first-letter {
float: left;
margin: .2em .1em .1em;
}
69
12. In the browser find one of the figures with the text that now flows around it.
Depending on the browser you may see that the text is either close to or further away
from the figure. Try the page in different browsers to see this.
13. Return to the editor that was editing the 'box-properties.css' file.
14. Add the following new style in bold to the stylesheet.
figure {
margin: .5em;
}
Note: Depending on the browser and version you may not actually see much change
with the rule above. Know that setting the margin yourself and not using the browser
default will be a good thing and bring more consistency.
70
Part 4 - Border and Padding
Some of the last most popular box style properties to use involve borders around
elements and padding.
1. Return to the editor that was editing the 'box-properties.css' file.
2. Add a new property to the 'figure' style and a new 'figcaption' style as shown in bold
below.
figure {
margin: .5em;
border: 6px double blue;
}
figcaption {
border-top: 2px solid blue;
display: block;
}
figure {
margin: .5em;
border: 6px double blue;
padding: 10px;
}
71
8. Save the file but leave it open.
9. Return to the browser that was showing the page and refresh the page.
10. You should now see a little space between the inside of the element border and the
items inside of it. This is different than the 'margin' property which is the space between
the element border and the items outside of it.
Part 5 - Review
There are various style properties that control how the size, placement, and spacing of an
element relates to other elements on the page. Controlling width and height is common
as well as text flow around elements, margins, borders, and padding within the border.
Although the browser will often have default values of what some of these properties
would be, setting them with your own styles can help with consistent display between
browsers.
72
Lab 8 - Intro to JavaScript
In this lab you will copy some files used in the labs and add some basic JavaScript code
to a page.
C:\Software\NotepadPlus\notepad++.exe
73
3. Once you have the Notepad++ program running (or another text editor if you
prefer), open the following file:
C:\Apache2.2\htdocs\JavaScript\intro\intro.html
4. After the existing <noscript> tag but before the ending </body> tag, add the
following bold code. This will use JavaScript to write out a simple message.
<body>
<noscript>
<h2>This page requires JavaScript.</h2>
</noscript>
<h1>
<script>
document.write("Hello, world!");
</script>
</h1>
</body>
</html>
http://localhost/JavaScript/intro/intro.html
7. Observe that the JavaScript code has written out the message to the content of the
page.
8. Leave the browser open as you will refresh the same page in the next part.
74
Part 3 - Link to External Script File
Having the JavaScript code contained within a <script> tag within the page itself is just
one way to define JavaScript code. You can also link the page to an external script file
which can help with reusing the code.
1. Return to the editor that was editing the 'intro.html' page.
2. Add the following link to the external script file in bold in the <head> section of the
page.
<html>
<head>
<title>My first script</title>
<script src="intro.js"></script>
</head>
<body>
C:\Apache2.2\htdocs\JavaScript\intro\intro.js
http://localhost/JavaScript/intro/intro.html
8. Immediately after you reload the page you should see a dialog box with the
message. The dialog itself may vary slightly depending on the browser but you should
easily recognize the message.
75
9. Click the OK button to close the dialog and you should still see the message printed
by the code directly in the page.
Part 4 - Review
In this lab you saw that JavaScript code is added to a page by the <script> tag. This can
either contain direct JavaScript code or link to an external file with code. You also copied
some files and used tools that will be used in other labs to explore JavaScript in more
depth.
76
Lab 9 - Basic JavaScript Syntax
In this lab you will add some more JavaScript code to various pages to explore more the
basic syntax of JavaScript. This will include declaring and using variables, some basic
control structures, and calling simple functions.
C:\Apache2.2\htdocs\JavaScript\basic
Note: If you do not see this folder, you can copy this from the 'C:\LabFiles\JavaScript'
folder or extract the appropriate lab solution for the previous lab from the
'C:\LabFiles\Solutions' folder. Be careful which files you copy and where you place
them to make sure the web server can locate them with the URLs provided in the labs.
Part 2 - Variables
One of the most basic things you will do in JavaScript code is declare, initialize, and use
variables.
1. Run the Notepad++ program or a regular text editor.
C:\Software\NotepadPlus\notepad++.exe
Note: A file may appear since Notepad++ opens the last used file. To avoid this in
future, close the file first and then close Notepad++.
2. Once you have the Notepad++ program running (or another text editor if you
prefer), open the following file:
C:\Apache2.2\htdocs\JavaScript\basic\prompt.js
77
3. There is already an empty function declared that will be called when the page loads.
To the top of this empty function add the following line in bold.
window.onload = initAll;
function initAll() {
var ans = prompt("Are you sure you want to do that?","");
Note: The 'prompt' function is a built-in function that will popup a small dialog window
to collect input from the user. The message and any default value are what are used for
the function parameters.
4. To complete the function add the following bold code. This will check if there was
any value returned by the prompt dialog and use it if there was.
function initAll() {
var ans = prompt("Are you sure you want to do that?","");
if (ans) {
alert("You said " + ans);
document.write("You said " + ans);
}
else {
alert("You refused to answer");
}
}
http://localhost/JavaScript/basic/prompt.html
7. When the page first loads you should see a prompt. Fill in a value and click the OK
button.
78
8. You should see the dialog change to the show the message. Click the OK button.
9. Check that you have the same message written out to the page.
Note: By default, recent versions of Internet Explorer will not allow prompt dialogs
from JavaScript. Even though it looks like there might be a way to “temporarily” allow
the dialog, it appears that when you refresh the page it reverts back to blocking it so that
won't help for this page that only displays the dialog when the page is loaded.
If you wanted to try the page with Internet Explorer you could go into the 'Internet
Options' settings and under the security settings add 'http://localhost' to the list of trusted
sites. The prompt would then work in Internet Explorer. Changing the security settings
of the browser may not be desirable though so we will just use another browser.
10. You can refresh the page and supply a different message.
79
Part 3 - Handle Errors
In some situations you might want to check for certain conditions and raise an error if
something is incorrect. This is done with the “try/catch” syntax you will see in this part.
You will check that the user gave you a positive number before finding the square root of
that number.
1. Run the Notepad++ program or a regular text editor and open the following file:
C:\Apache2.2\htdocs\JavaScript\basic\catchError.js
function initAll() {
var ans = prompt("Enter a positive number","");
try {
if (!ans || isNaN(ans) || ans<0) {
throw new Error("Not a valid number");
}
var sqrt = Math.sqrt(ans);
var message = "The square root of " + ans + " is " + sqrt;
alert(message);
document.write(message);
}
catch (errMsg) {
alert(errMsg.message);
}
}
http://localhost/JavaScript/basic/catchError.html
5. When the page first loads you should see a prompt. Fill in a value and click the OK
button. Start by using a valid positive number.
80
6. You should see a dialog that shows the square root of your number.
7. Click the OK button on the dialog and you should see the same message printed to
the page.
8. Reload or refresh the page and this time enter an invalid response like a negative
number or text that is not a number.
9. You should see a dialog that says the entry is not a valid number and nothing should
be displayed on the page.
81
Part 4 - Modify Style of Page Elements
JavaScript code can also access elements of a page using the DOM API. In this part you
will see just some basics about doing this to modify the style of an element.
1. Run the Notepad++ program or a regular text editor and open the following file:
C:\Apache2.2\htdocs\JavaScript\basic\find.html
2. Observe that the main HTML code for the body of the page is a text box for the user
to enter a value in and a button. This button will trigger a JavaScript function. There are
also some other page elements with text that will have the styles changed. Notice all the
elements have the 'id' attribute.
C:\Apache2.2\htdocs\JavaScript\basic\find.js
5. In the currently empty 'initAll' function, add the following bold line of code. This
will modify the button so that when it is clicked it will call the other function in this file.
function initAll() {
document.getElementById("findById").onclick = findById;
}
82
6. In the currently empty 'findById' function, add the following bold lines of code.
This uses the 'getElementById' function of the built-in 'document' object which is a key
part of the DOM API. This code finds out what the user filled in for the textbox and then
finds the element with that id to modify the style to yellow background.
function findById() {
var id = document.getElementById("id_value").value;
var e = document.getElementById(id);
if (e != null) {
e.style.backgroundColor = "yellow";
} else {
alert("Could not find element by ID: " + id);
}
}
http://localhost/JavaScript/basic/find.html
9. In the textbox of the page enter the id of one of the elements (these are in
parenthesis) and then click the 'Find by ID' button.
83
10. You should see that the background of the matching element changes.
11. Try entering the id of some of the other elements. Also try a value that is not a
valid element id and verify the error dialog appears.
C:\Apache2.2\htdocs\JavaScript\basic\date.js
84
2. In the current 'initAll' function, add the following if/else statements in bold. Leave
some space in the 'if' block as more code will be added there.
function initAll() {
var now = new Date();
if (now.toLocaleDateString) {
}
else {
alert("Your browser does not give a locale-specific date/time");
}
}
Note: The 'toLocaleDateString' function on the Date object that was created is a function
that may not be supported by all browsers so we test to see if it exists first.
Normally, you would write code that might provide an alternative version of the page if
the feature is not supported. Here we are just adding code to show a popup dialog just to
show the pattern of this technique.
3. Within the 'if' block you just added, add the following code in bold. Make sure that
you put in the correct number of curly brackets so they match.
85
4. Save the file but leave it open.
5. Open a web browser (any type) and go to the following URL:
http://localhost/JavaScript/basic/date.html
6. Verify that you get a popup dialog that shows the current time and date.
7. After clicking the OK button you should also see this printed to the page, likely in a
large bold <h1> element.
Note: If you want you might be able to experiment with the regional settings of your
computer and the date/time formatting to see the date and time displayed differently. Do
this with care however to make sure you can switch it back and do not accidentally alter
any important system settings. One thing you should not do is change the language of
the entire operating system.
86
8. Close all open browsers.
9. If you are using Notepad++ then close all open files and then close Notepad++.
Part 6 - Review
In this lab you saw some more about various basics of JavaScript. This included
declaring and using variables, basic statements, simple control structures like if/else and
try/catch, and calling various built-in JavaScript functions. These features will build the
foundation of most of the JavaScript code that you write.
87
Lab 10 - JavaScript Functions
Although you may have already seen some simple JavaScript functions we have not yet
focused on them much. In this lab you will add complete function definitions and the
functions will be a little more complex by accepting parameters and returning values.
C:\Apache2.2\htdocs\JavaScript\function
Note: If you do not see this folder, you can copy this from the 'C:\LabFiles\JavaScript'
folder or extract the appropriate lab solution for the previous lab from the
'C:\LabFiles\Solutions' folder. Be careful which files you copy and where you place
them to make sure the web server can locate them with the URLs provided in the labs.
C:\Software\NotepadPlus\notepad++.exe
Note: A file may appear since Notepad++ opens the last used file. To avoid this in
future, close the file first and then close Notepad++.
2. Once you have the Notepad++ program running (or another text editor if you
prefer), open the following file:
C:\Apache2.2\htdocs\JavaScript\function\bingo.js
88
3. To the existing 'generateNumber' function add the following bold code. This will
return a bingo number which are between 1-75.
function generateNumber() {
return Math.floor(Math.random() * 75) + 1;
}
4. To the existing 'displayNumber' function add the following bold code. This will
call the other function and store what is returned in a variable. The result will then be
used to display a message to the page.
function displayNumber() {
var number = generateNumber();
document.getElementById("number").innerHTML =
"The next BINGO number is: " + number;
}
http://localhost/JavaScript/function/bingo.html
7. Click the 'Pick a BINGO Number' button and verify a number is displayed. You can
click several times to verify they are randomly picked and always between 1-75.
89
9. Return to the editor for the 'bingo.js' file.
10. Modify the entire content of the 'generateNumber' function with the new code in
bold below. This will return an array with the letter for the column along with the
number picked.
function generateNumber() {
var columnLabel = new Array("B", "I", "N", "G", "O");
var columnIndex = Math.floor(Math.random() * 5);
var newNum = Math.floor(Math.random() * 15) + 1
+ (columnIndex * 15);
11. Make the following small modification to the end of the 'displayNumber' function.
Notice that most of the code is the same except where the message is altered with the
number that is returned. Now the column letter and number will be displayed.
function displayNumber() {
var number = generateNumber();
document.getElementById("number").innerHTML =
"The next BINGO number is: " +
number[0] + " - " + number[1];
}
http://localhost/JavaScript/function/bingo.html
14. Click the 'Pick a BINGO Number' button and verify that now the column letter and
the number are displayed. You can click several times to verify that the number is always
within the appropriate range for the column chosen.
90
Part 3 - Pass Function Parameters
All of the functions you have seen until now have not needed any additional information
passed in from where the function is called. Now you will define some functions that
will take parameters to use in calculations.
1. Run the Notepad++ program or a regular text editor and open the following file:
C:\Apache2.2\htdocs\JavaScript\function\primes.js
2. Examine the existing code in the 'initAll' function. It will prompt for a number and
check if it is a positive integer number entered by the user.
3. Add the following bold line of code where the comment indicates. This will call a
function that you will define next. Notice it will take a parameter for the value the user
entered.
function initAll() {
var ans = prompt("Enter a positive integer greater than 1","10");
try {
if (!ans || isNaN(ans) || ans <= 0 || Math.round(ans) != ans) {
throw new Error("Not a valid number");
}
// call function here
calculatePrimes(ans);
}
catch (errMsg) {
alert(errMsg.message);
}
}
4. At the end of the file, add the following declaration of the new function. Make sure
to add it outside of any other current function and add the matching curly bracket on the
end of the function. Notice this function declares the parameter that it takes but does not
declare the type of data it might hold like some other programming languages might.
function calculatePrimes(maxNumber) {
91
5. Within the brackets for the new function declaration, add the following bold code.
This will check each number within the range by calling another function to test that
specific number. The number is added to a String of all the prime numbers if it is found
to be prime.
function calculatePrimes(maxNumber) {
var primeString = "";
for (var testing = 2; testing <= maxNumber; testing++) {
if (testForPrime(testing)) {
primeString += testing + ", ";
}
}
6. To complete the 'calculatePrimes' function, add the bold code below. This will
remove the trailing comma at the end of the prime number list amd call another function
to display the list on the page.
function calculatePrimes(maxNumber) {
var primeString = "";
for (var testing = 2; testing <= maxNumber; testing++) {
if (testForPrime(testing)) {
primeString += testing + ", ";
}
}
// remove last comma
var lastCommaIndex = primeString.lastIndexOf(",");
if (lastCommaIndex != -1) {
primeString = primeString.substring(0, lastCommaIndex);
}
displayPrimes(maxNumber, primeString);
}
7. At the end of the file, add the following declaration of a new function. Make sure to
add it outside of any other current function and add the matching curly bracket on the end
of the function.
function testForPrime(numberToTest) {
92
8. Within the brackets for the new function declaration, add the following bold code.
This code will check to see if it is possible to evenly divide the number being checked by
any of the numbers less than or equal to the square root of a number. If it is found to be
divisible a response is immediately returned that it is not a prime number. If the loop
completes and no divisors have been found it is a prime number.
function testForPrime(numberToTest) {
var modval = Math.ceil(Math.sqrt(numberToTest));
// Check all numbers lower than the square root
for (; modval > 1; modval--) {
if (numberToTest % modval == 0) {
return false;
}
}
9. At the end of the file, add the following declaration of a new function. This will be
the function to display the list of prime numbers on the page. Notice that it takes two
parameters which will be used in the output.
10. Within the brackets for the new function declaration, add the following bold code.
This code will display the number the user entered to use as the maximum number to
check and display a message. Usually the message will be the list of prime numbers but
another message will be displayed if there are none.
93
11. Save the file but leave it open.
12. Open a Firefox or Chrome web browser and go to the following URL:
http://localhost/JavaScript/function/primes.html
13. Enter a positive number in the dialog and click the OK button.
14. Check that you get the expected output printed to the page including a list that has
no comma after the last number.
15. You may refresh the page and enter another maximum number to check for prime
numbers.
16. Close all open browsers.
17. If you are using Notepad++ then close all open files and then close Notepad++.
Part 4 - Review
In this lab you defined and used a few functions within your JavaScript code. These
functions often returned a value to the location they were called from and took some
parameters which were used to modify the behavior of the code being executed. You
should notice that unlike some other programming languages, JavaScript does not require
you to declare that a function returns a value or the type of the function parameter.
94
Lab 11 - Arrays in JavaScript
Arrays are useful when managing large sets of data within JavaScript code. This lab will
show a few examples of using arrays and how using them can make programming certain
algorithms less complex.
C:\Apache2.2\htdocs\JavaScript\array
Note: If you do not see this folder, you can copy this from the 'C:\LabFiles\JavaScript'
folder or extract the appropriate lab solution for the previous lab from the
'C:\LabFiles\Solutions' folder. Be careful which files you copy and where you place
them to make sure the web server can locate them with the URLs provided in the labs.
C:\Software\NotepadPlus\notepad++.exe
2. Once you have the Notepad++ program running (or another text editor if you
prefer), open the following file:
C:\Apache2.2\htdocs\JavaScript\array\bingoCard.html
95
3. Most of this HTML code is standard with a link to a CSS stylesheet and the external
JavaScript file you will edit in a few steps. The important part of this code is that there is
a table with 5 columns and table cells that have an id of 'squareXX' where 'XX' is a
number between 0-23. These would be the valid array indexes in an array with 24
elements which is what we need since the middle square is a “free” space and doesn't
need a number.
<tr>
<th>B</th>
<th>I</th>
<th>N</th>
<th>G</th>
<th>O</th>
</tr>
<tr>
<td id="square0"> </td>
<td id="square5"> </td>
<td id="square10"> </td>
<td id="square14"> </td>
<td id="square19"> </td>
</tr>
C:\Apache2.2\htdocs\JavaScript\array\bingoCard.js
6. Look for the code at the very top of the file and add the following bold line where
the comment mentions a global array. This array will be used to store whether or not a
particular number has been used for this bingo card.
window.onload = initAll;
// global used numbers array
var usedNums = new Array(76);
Note: The array has been declared with a size of 76 so that the legal bingo numbers
(1-75) can be used directly as array indices. The length of the array will not be
important so having the “extra” spot at index '0' will not be an issue. In this case it will
be better to simplify code by preventing the need to always subtract 1 from each number
to find the related array index. In a situation where the length of the array was important
we might not be able to do this.
96
7. Examine the first few lines of the 'setSquare' function. This function is called to
initialize the number for each of the squares in the bingo card. The 'colPlace' array is
created and initialized with various numbers 0-4. These represent the column index the
various squares are related to.
function setSquare(thisSquare) {
var currSquare = "square" + thisSquare;
var colPlace = new
Array(0,0,0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3,3,4,4,4,4,4);
Note: Notice that there are 5 places with each of the values except that the value '2' only
occurs 4 times because of the “free” spot in the middle column. This array was provided
for you because typing out the code to initialize the array may have been error-prone and
lead to tough to debug issues if initialized incorrectly. Storing the column index in this
array and linking the value stored in the array to the column index the square is
associated with will be key in calculating the number in the next calculations.
8. Add the following bold line of code to calculate the “column basis”. This is a
number that will be added to a random number generated in later code and represents the
range of numbers allowed in a particular column. Notice the square number is used to
find the multiplier from the 'colPlace' array.
function setSquare(thisSquare) {
var currSquare = "square" + thisSquare;
var colPlace = new
Array(0,0,0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3,3,4,4,4,4,4);
// calculate column basis
var colBasis = colPlace[thisSquare] * 15;
9. Fill in the condition of the do/while loop to use the value stored in the 'usedNums'
array to indicate if the number has been used in this bingo card yet or not. Also add code
after the loop to mark the position in this 'usedNums' array as being used. Notice how the
random number generated is used as the index into this array which is why we wanted
to be valid indices in this array.
var newNum;
97
Note: The previous code might be a little confusing at first but remember this function is
going to be called several times. If the number that is picked has not been used yet, the
condition will be false and the loop will quit after picking an unused number. If a
number has been used before, the position in the 'usedNums' array will be true meaning
the loop will repeat and pick another number until one that has not been used is found.
10. Find the 'anotherCard' function and add the following 'for' loop in bold. This will
reset all of the positions in the 'usedNums' array to be 'false' when generating another
bingo card.
function anotherCard() {
// clear used numbers
for (var i = 1; i < usedNums.length; i++) {
usedNums[i] = false;
}
newCard();
return false;
}
Note: Remember that no matter how big the array, the value for the length of the array is
never a valid index. This is why the '<' is used in the conditional test. In our case the
length is 76 and the last index that will be reset is 75 which is important to make sure all
the numbers will be marked as available again. Often in using arrays operations at the
very first position and last position may not be performed correctly and should warrant
special attention in testing. In this case we will want to make sure numbers 1 & 75 can
get picked for the bingo card.
11. Save the file but leave it open.
12. Open a web browser and go to the following URL:
http://localhost/JavaScript/array/bingoCard.html
98
13. Verify that you see the bingo card displayed. Check that all squares are filled in
with numbers that are legal for that column (1-15 for B, 16-30 for I, etc).
14. Click on the “Click here” link a few times to generate a new bingo card and ensure
that functions properly. You should check that numbers that had been used on the
previous cards are also used on future cards to verify the array for used numbers is being
reset. Also check that numbers from the edges of the column range (1 & 15, 16 & 30,
etc) are being used.
15. If you want you can even click on a square to use an existing function that will
mark the square red.
99
Part 3 - Use Array for Prime Numbers
Calculating prime numbers, especially a large number of them, can be a brute force
operation. Although it is possible to simply divide a number by every number less than it
to see if it is a prime number there are a few facts that can be used to optimize this
operation.
• You only need to check for divisors up to the square root of the number you are
checking. If there is a number bigger than the square root of a number that
divides evenly into the number there will also be a number less than the square
root, that will have already been checked, that will divide into it. So if no
numbers less than the square root of a number are found that divide a number
evenly you do not need to check the numbers above the square root to prove the
number is a prime number.
• If a number is NOT a prime number it will be divisible by at least one number
less than it that IS a prime number. Therefore in order to check if a number is
prime you only need to try dividing it by the other prime numbers you have
already found.
In order to use the second fact to make the calculation of prime numbers more efficient,
you would need to track the current set of prime numbers that have been found. This will
be the perfect use for an array of the prime numbers that have been found so far.
1. Run the Notepad++ program or a regular text editor and open the following file:
C:\Apache2.2\htdocs\JavaScript\array\primesArray.js
2. Examine the logic of the 'initAll' function but don't make any changes. This code
will prompt the user for how many prime numbers to calculate and make sure they enter a
whole number that is greater than or equal to 1.
3. Find the 'calculatePrimesArray' function and add the bold line of code below at the
beginning to declare and initialize an empty array to store the prime numbers that are
found.
function calculatePrimesArray(numberOfPrimes) {
// array for primes
var primes = new Array(0);
100
4. Find the 'if' test that comes next and add the bold line below to manually add the
value '2' as the first prime number. Manually adding the first prime number will make
other code simpler because it will not have to deal with the possibility that the array is
empty (zero length).
function calculatePrimesArray(numberOfPrimes) {
// array for primes
var primes = new Array(0);
var lastTested = 2;
// loop while array needs primes added
while ( primes.length < numberOfPrimes ) {
// increment tested number
lastTested++;
6. Near the end of the 'while' loop add the bold line of code below to push the value
into the array of primes if the function that is called to test the number returns that it is a
prime number. You will add some code to this function next.
7. Notice the end of this function calls another function to display the prime numbers
and passes in the array as a parameter. You do not need to change this code.
displayPrimes(numberOfPrimes, primes);
101
8. Find the 'testForPrime' function and notice that the function declaration takes the
number to test and the current array of prime numbers. This is key to using the array of
prime numbers to make the test more efficient.
9. Fill in the conditions for the 'for' loop and 'if' statement as shown in bold below
using the elements of the 'primes' array and the index 'I' declared by the 'for' loop. The
'for' loop condition checks if the current prime number being used is less than or equal to
the square root of the number being tested. The 'if' statement condition checks if the
current number being tested is evenly divisible by the current prime number and if it is
immediately returns 'false' because the number being tested is not a prime number.
10. Find the 'displayPrimes' function and add the code in bold at the end of the
function to add the array of primes to the display text.
http://localhost/JavaScript/array/primesArray.html
102
13. When the page first loads you should see a prompt. Fill in a value and click the
OK button.
14. You should see the expected output which includes the list of prime numbers.
Notice how simply adding the entire array to the display text converted the array values
into a comma-separated list.
15. Refresh the page and when the prompt displays enter a large value like 100 for the
number of prime numbers to calculate.
16. You should notice that all the numbers remain on one line which causes the
numbers to go well off the edge of the screen. If you wanted to see all of the numbers
you would need to scroll to the right on the page. This is because there are no spaces for
the browser to break the line at.
17. Return to the editor for the 'primeArrays.js' file and open it again if you closed it.
C:\Apache2.2\htdocs\JavaScript\array\primesArray.js
103
18. Find the 'displayPrimes' function again and add the following code to create a
comma-separated String of the array of prime numbers that has a space after each
comma.
Note: Notice the condition for the 'for' loop subtracts one from the length of the array.
This is so a comma is not added after the last prime number and that is added to the end
of the String after the loop. It is important that we know the array will always have at
least one element because otherwise this subtraction might give a '-1' which would not
be a valid array index and cause an error.
19. Change the last line of code of the function as shown in bold below so that the
String of prime numbers is added to the display text instead of the array itself.
http://localhost/JavaScript/array/primesArray.html
22. When the prompt displays enter a large value like 100 for the number of prime
numbers to calculate.
104
23. Verify that now the output off the prime numbers breaks across multiple lines and
you do not need to scroll to the right. This is because with the spaces in the String, the
browser is able to break the String to the next line when it reaches the right edge of the
window.
24. Refresh the page again and enter a very large number (about 10,000) for the
number of prime numbers to calculate. You should see that the page is still displayed
relatively quickly thanks to the optimizations made.
Part 4 - Review
This lab showed you various aspects of using arrays in JavaScript. You saw that in some
situations arrays are very useful and the features of an array can even be used to the
advantage of simplifying the code. In the bingo card example the array that tracked if a
number had been used could use the number directly as the array index which made the
code simple. The prime number example showed how you could build up the array of
prime numbers as they were discovered and even use that array to make the calculation
more efficient.
105
Lab 12 - Getting Started with jQuery
In this lab, we will setup the basic development environment. We will also learn how to
install jQuery and learn its basic usage.
<html><body><h1>It works!</h1></body></html>
106
Part 4 - Install jQuery
For our labs, we will need jQuery and jQuery UI JavaScript libraries. Those have already
been downloaded for you. All you need to do is copy them over to the right folder.
1. In the APACHE_DIR/htdocs folder, create a new folder called jquery
In Windows XP and Vista, you may have to be an Administrator to create folders within
APACHE_DIR.
2. From folder C:\LabFiles\ copy jquery-1.10.2.min.js and jquery-ui.js to the
APACHE_DIR/htdocs/jquery folder.
<html>
<head>
</head>
<body>
</body>
</html>
<head>
<script type="text/javascript"
src="/jquery/jquery-1.10.2.min.js"></script>
</head>
<body>
<p id="p1"></p>
</body>
107
6. Below the existing <script> tag, add another one.
<script type="text/javascript">
$(function(){
$("#p1").text("Hello World");
});
</script>
We will inspect the code later. For now, continue with testing.
7. Save changes.
Part 6 - Test
1. From the browser, enter the URL: http://localhost/lab/basic.html
2. Make sure that you see:
<script type="text/javascript">
$(function(){
$("#p1").text("Hello World");
});
</script>
$()
Almost all jQuery API is accessible through this one single function. You can also call the
core function through these names:
jQuery()
window.jQuery()
But, $() is short and sweet and that's what most developers use.
108
The core function behaves completely differently depending on the input parameters you
pass to it. In our case, we passed an anonymous function:
function(){
$("#p1").text("Hello World");
}
When you pass a function as input argument, jQuery treats it as a DOM ready event
handler. This event is fired when the DOM document of the page is fully ready. This can
happen before the "onload" event of the body. For example, if there are many images in
the document, the DOM ready event fires before all the images are actually downloaded.
You can start manipulating the DOM as soon as the DOM is ready.
When the DOM document is ready, FireFox fires the “DOMContentLoaded” event and
IE the “onreadystatechange” event for the document object. jQuery makes it easy to
attach an handler for that event in a browser independent manner.
Now, let's look at what our DOM ready event handler function does. Firstly, we see that
the core function is used again.
$("#p1")
This time, the core function is taking a string as an argument. This signifies to the core
function that the argument is an element selector. jQuery borrows heavily from CSS
selector model. According to CSS, "#p1" select a DOM element with the ID of "p1". That
will be the empty paragraph we had added earlier.
$("#p1") will return a jQuery object for the paragraph. We then call the text() function for
the object. This sets the inner text of the element to "Hello World".
What does the core function - $("#p1") – actually return? It returns a jQuery object that
is a collection of all DOM element objects that match the supplied selector rule. This
jQuery object builds on top of the JavaScript array API. For example, you can obtain the
length:
$("p").length; //Number of paragraphs in the page.
To obtain a DOM element object in the collection, simply call get(index).
alert($("p").get(1).innerHTML); //Show inner HTML of the second paragraph.
When you invoke a method of the collection object, jQuery internally applies it to all
DOM elements in the collection:
$("p").text("Hello!"); //Change text of all paragraphs to Hello!.
A getter function normally works on the first DOM element in the collection only.
$("p").text(); //Returns the text of the first paragraph only.
109
To convert a DOM element object into a jQuery collection do:
$(elementObject)
For example:
$(document.getElementById("p1")); //Same as $("#p1").
<p id="p1"></p>
<p id="p2"></p>
$("p").text("Hello World");
Now, $("p") will select all DOM elements with a <p> tag. Once again, jQuery borrows
this from the CSS selector model.
3. Save changes.
4. Refresh the browser. Now, both paragraphs will say "Hello World".
What this means is that the text() function was called for the entire collection of jQuery
objects returned by $("p"). Trying to do this using raw JavaScript will take quite a few
lines of tedious coding.
Part 9 - Review
In this lab, we installed jQuery and wrote a very basic application. We learned about the
core function $(). We wrote a DOM ready handler. We used a simple ID based selector
first. And then a tag based selector.
110
Lab 13 - More on Selectors
In this lab, we will learn a few more advanced uses of selectors. We will also learn about
how to manipulate the CSS styles of elements.
<p id="p1"></p>
<p id="p2"></p>
Let us say that we want to iterate over them and change their text.
1. Change the line:
$("p").text("Hello World");
As follows.
$("p").each(function (index) {
$(this).text("Your ID is: " + this.id + " and index: " + index);
});
2. Save changes.
3. Refresh the browser or enter the URL: http://localhost/lab/basic.html
There is a lot going on with the each() function. It takes as argument a function object.
This function is called repeatedly, once for each jQuery object in the collection. The
function receives the index of the jQuery object in the collection starting with 0.
Important: The "this" keyword within the iteration function points to the DOM
element. We can not directly call the text() method for it since that is not a DOM API.
We must obtain the jQuery object using $(this) and then call the text() function to set the
text.
Since, "this" is a DOM element, we can call this.id to get it's ID.
111
Part 2 - Class Selector
One of the common uses of selector is to select all elements that belong to a CSS class.
This is done using the format $(.class_name). This is same as the CSS class selector.
Now, we will select one of the paragraphs by its class name and change its background
color.
1. Set the class of the second paragraph to "highlighted".
2. At the end of the DOM ready handler function add the line shown in bold face.
$(function(){
$("p").each(function (index) {
$(this).text("Your ID is: " + this.id + " and index: " + index);
});
$(".highlighted").css("background", "yellow");
});
3. Save changes.
4. Refresh the browser. The second paragraph will now have a yellow background.
This was also a good example of how to tweak the style of an element using the css()
function.
If you know that it is a "p" tag that has the "highlighted" class, you can help jQuery a
little by using $(p.highlighted). This will have a performance improvement.
112
We will now use jQuery to create a box widget that looks like this.
Add:
<div class="box">
<div>This is a title</div>
<div>
This is the box<br/>
Body.
</div>
</div>
Basically, any <div> element with style "box" will be converted into a box. The first child
<div> element of the box will be converted into the title.
First, we will draw the border around the box.
5. Below the line:
Add:
$("div.box").css("border-style", "solid");
$("div.box").css("border-width", "2px");
Now, we will change the background color of the first child <div> element to black. We
will change its foreground to white.
If we use $("div div") that will select all div child elements of another div. We don't want
that. We only wish to select the first child.
113
6. Continue to develop the DOM ready function by adding these lines:
Here, we use the "first-child" pseudo selector. This will select the first <div> child
element of any div element that has the box class.
7. Save changes.
8. In the browser, enter the URL:
http://localhost/lab/box.html
<div class="box">
<div>Company News</div>
<ul>
<li>Stock price has gone up</li>
<li>Tomorrow is a holiday</li>
</ul>
</div>
114
Part 4 - Optimize the Code
Selectors require a lot of DOM tree navigation. This can be slow for a large document.
Once you have retrieved a collection, you should reuse it as much as possible. In our
case, we are running the same selector multiple times. We should be able to optimize that.
1. Change the DOM ready function as follows.
$(function(){
//jQuery code here
var box = $("div.box");
box.css("border-style", "solid");
box.css("border-width", "2px");
var title = $("div.box div:first-child");
title.css("background", "black");
title.css("color", "white");
});
115
2. Open APACHE_DIR/htdocs/lab/table.html in your editor.
3. Note that the header is created using <thead> and the body using <tbody>.
4. View the page in a browser:
http://localhost/lab/table.html
Nothing spectacular. Now, we will apply different colors to every alternate rows.
5. Below the line:
Add:
$("tr:even").css("background-color", "grey");
$("tr:odd").css("background-color", "yellow");
6. Save.
7. Refresh the browser.
It worked. But, the <tr> elements within <thead> are also being colored. We can fix that
by combining the even and odd selector with child selector. We want only the <tr>
elements that are children of <tbody> to be colored.
116
8. Change the code as follows.
Now the header is not colored any more. In fact, while we are at it, let's style the header
row.
10. Add this code.
Part 6 - Review
In this lab we played with more selectors. We also learned how to apply basic styling
using the css() function. As you saw, with only a few lines of code, you can apply
consistent look and feel throughout the site.
117
Lab 14 - Dynamic Style Class Assignment
In this lab, we will learn how to add or remove style class to form elements. We will also
learn how to combine multiple selector rules into one.
We will work with a simple login form. When user submits the form, we will validate it
and apply styling to invalid input fields.
http://localhost/lab/form.html
function checkForm() {
118
2. Within the checkForm() function, add a variable:
$("input[type='text'], input[type='password']")
A compound selector has a comma separated list of selectors. In this case, we are
selecting all <input> elements that have the "type" attribute set to either "text" or
"password".
4. Add the each() function to the selected elements as shown in bold face below.
Here, we are using this.value.length to check if the field is empty. Recall that "this"
within an iteration handler points to a DOM element and not a jQuery object.
If the field is empty, we are calling addClass() method of the jQuery object and setting
the class to inputErr. If the field is not empty, we are removing the class.
6. Finally, at the end of the checkForm() function, add the line:
return result;
7. Save changes.
119
Part 3 - Test
1. Refresh the browser or enter the URL:
http://localhost/lab/form.html
2. Leave both fields empty and submit the form. The color should change for both.
3. Now, leave one field empty at a time and submit the form. Make sure that only the
empty field is getting highlighted.
Part 4 - Review
In this lab, we learned how to dynamically add or remove CSS class for an element. We
also saw how compound selectors work.
120
Lab 15 - DOM Manipulation
jQuery makes it super easy to add, remove and move around elements within the
document. We will learn how to add and remove elements in this lab.
We will keep building on top of the log in form that we had worked on previously.
<div id="messages">
</div>
Now, we will work on the checkForm() function. First, we will clear all existing error
messages.
3. Below the line:
Add:
$(".errorMsg").remove();
This will wipe out any element with the CSS style class "errorMsg". That means, when
we dynamically create the error message elements, they must have the class "errorMsg".
Now, we will create the error messages.
121
4. When the input field is empty, use the append() function to add a new error message
as shown below.
if (this.value.length == 0) {
$("#messages").append(
"<p class='errorMsg'>Input can not be empty: " + this.name
+ "</p>");
result = false;
$(this).addClass("inputErr");
} else {
Note that the new <p> elements will be added to the element with the ID "messages".
Also note that we are setting the class of the <p> tags to errorMsg.
5. Save changes.
Part 2 - Test
1. In a browser enter the URL:
http://localhost/lab/form.html
3. Now, leave one field empty at a time and submit the form. Make sure that the correct
error message is displayed.
122
Part 3 - Improve the Error Message Display
Right now the messages look very disjointed. Also there is no instructions to the user
what needs to be done. We will now change things so that the messages look like this.
<div id="messages">
Please fix these problems and submit the form again:
<ul id="messageList">
</ul>
</div>
$("#messages").append(
"<p class='errorMsg'>Input can not be empty: " + this.name
+ "</p>");
To add <li> elements to the messageList <ul> element. This is shown below.
$("#messageList").append(
"<li class='errorMsg'>Input can not be empty: " + this.name
+ "</li>");
Finally, we need to show or hide the messages div tag depending on if there are error
messages.
123
3. Above the "return result;" line add:
if (result == false) {
$("#messages").show();
} else {
$("#messages").hide();
}
return result;
4. By default, when the page is first loaded, the messages div element should be
hidden. Do that from the DOM ready handler.
$(function(){
//jQuery code here
$("#messages").hide();
});
5. Save changes.
6. Refresh the browser and test the form. Make sure that you get the effect shown in
the screenshot earlier.
7. Close all editors and browsers.
Part 4 - Review
In this lab, we learned how to add or remove elements. We also saw how to show or hide
elements.
124
Lab 16 - Form Event Handling
jQuery makes it easy to attach event handlers to elements. Basically, you do not use the
"onsubmit" "onclick" etc attributes for the elements but use jQuery API to attach
handlers. jQuery uses underlying DOM API of the browser to get the job done. This
keeps HTML clean.
We will continue to work on the login form.
This attaches an "onblur" event handler function for all text and password input elements.
3. Save changes.
4. In a browser enter the URL:
http://localhost/lab/form.html
5. Test by clicking on a text box and then clicking or tabbing away from it. Error
messages will be displayed right away.
125
1. Below the line
Add:
$("form").submit(checkForm);
This will attach the checkForm function object as the handler for all forms in the page. In
real life, to attach the handler to a specific form, you can use the ID sector, for example:
$("#myForm")
2. Remove the onsubmit attribute for the form. This will look like.
<form method="post">
3. Save changes.
4. Refresh the browser.
5. Test by submitting a form with invalid input. It should not submit.
6. Close all editors and browsers.
Part 3 - Review
In this lab, we learned how to attach DOM event handler using jQuery. This extracts
event handling code completely away from HTML.
126
Lab 17 - Basic Ajax
In this lab, we will use the jQuery load() function to fetch HTML from the server and
display it. We will build a tabbed sheet like widget.
When a link is clicked, some HTML content will be fetched and displayed below it.
Add:
<div class="tabbed">
<div>
<!--Content will go here-->
</div>
</div>
127
Basically, the <div class="tabbed"> element will work as the whole tabbed widget. Each
<a> element within it will act as a tab. When user clicks on a link, we will fetch the
content from the file mentioned in "href" and show it in the inner <div> element.
6. Save changes.
Add:
$("div.tabbed a").click(function() {
$(this).parent().children().last().load(this.href);
return false;
});
The $("div.tabbed a") selects all <a> elements. The click() function attaches an onclick
event handler. $(this) points to the <a> element that was clicked. parent().children().last()
basically picks the inner <div> element.
Finally, the load() function loads the contents of the URL in href attribute.
We have to make sure that we return false. That way, the browser will not follow the link
and load a separate page.
2. Save changes.
Part 3 - Test
1. Open a browser and enter:
http://localhost/lab/tabs.html
128
3. Similarly, click Event and Safety link. Make sure that the right content is being
displayed.
4. Refresh the page. The content will go blank. That is because, we do not select a tab
by default when the page is loaded. We will fix that next.
$(function(){
//jQuery code here
$("div.tabbed a").click(function() {
$(this).parent().children().last().load(this.href);
return false;
});
$("div.tabbed a").first().click();
});
That line will fire the onclick event for the first <a> element. Note, $("div.tabbed a") will
return all <a> elements that are children of any <div class="tabbed"> element. The first()
function picks the first jQuery object in the returned collection.
2. Save changes.
3. Refresh the browser. Now, the News content will be displayed by default.
<style type="text/css">
.tabSelected {
background: grey;
border-style: solid;
border-width: 1px;
border-color: black;
}
</style>
129
2. In the onclick event handler function add the lines shown in boldface.
$("div.tabbed a").click(function() {
$(this).parent().children().last().load(this.href);
return false;
});
Here, we are taking advantage of the data() method to attach arbitrary JavaScript object
to a jQuery object. We save the jQuery object for the currently selected <a> element with
the parent using the name "last_selected".
3. Save changes.
4. Refresh the browser. Make sure that the selected tab is highlighted.
<div class="tabbed">
<a href="event.html">Event</a> <a href="news.html">News</a> <a
href="safety.html">Safety</a>
<div>
</div>
</div>
3. Save changes.
4. Refresh the page.
130
Does everything look good? No! The first tab of the second widget was not selected by
default. What went wrong?
Look at the code that selects the default tab:
$("div.tabbed a").first().click();
It selects the first one of all <a> elements in the page that are children of <div
class="tabbed">. This is why the tab of the second widget is not getting selected.
5. Change the line that selects a tab by default to:
$("div.tabbed a:first-child").click();
Here, $("div.tabbed a:first-child") will select every first <a> child element of <div
class="tabbed">. That is perfect for us.
6. Save changes.
7. Refresh the browser.
131
8. Work with both tabbed sheet widgets. Make sure that each manages its own state
(selected tab) separately.
9. Close all editors and browsers.
Part 7 - Review
With only a few lines of code, we created a pretty complete tabbed sheet widget. We used
the load() function to fetch HTML data using Ajax. We also learned to use the data()
function to manage state.
132
Lab 18 - Submitting Form Using Ajax
Recall the login application we have developed in form.html.
At this stage, it does a good job validating user input. But, it does not really submit the
form in any meaningful way. In this lab, we will use Ajax to submit the form.
$("form").submit(checkForm);
$("form").submit(function(){
if (checkForm()) {
var data = $(this).serialize();
alert(data);
}
return false;
});
Note that the function must return false at all times to prevent the browser from
submitting the request. We will use Ajax to send the HTTP request.
133
4. Now remove the following code so we don't have to deal with the validation of the
fields anymore when you leave the field, for the following testing this will help not
having this validation. You can leave it if you want, doesn't change the behavior of the
serialized method that we just created.
$("input[type='text'], input[type='password']").blur(function() {
checkForm();
});
http://localhost/lab/form.html
7. Enter some data in both fields and submit the form. The alert dialog will show how
the input data is serialized.
8. Click OK.
http://localhost/cgi-bin/login.exe
134
3. Back in form.html, replace the line:
alert(data);
With:
The first argument to $.get() is the URI that is requested. The second one contains the
input data. The third one is a function that is called when a reply is successfully obtained.
The $.post() method works the same way. Unfortunately, our CGI script only works with
GET requests.
4. Save changes.
Part 3 - Test
The login script will only successfully authenticate user "bob" with password "bobcat".
1. In the browser, enter the URL:
http://localhost/lab/form.html
3. Submit the form. The alert window will look like this.
135
4. Click OK.
5. Enter valid user Id (bob) and password (bobcat) and submit the form.
6. Click OK.
Add:
<div id="replyMsg"></div>
alert(reply);
With:
$("#replyMsg").html(reply);
This will show the reply from the server in <div id="replyMsg">.
3. Save changes.
136
4. Refresh the browser and test the form.
Add:
$(document).ajaxStart(function() {
$("#replyMsg").text("Please wait...");
});
The ajaxStart event is fired before any Ajax request is sent by jQuery. We are handling
that and showing a progress message.
2. Save changes.
3. Close all open browsers. We do not wish to hit the browser cache.
4. Open a new browser and enter the URL:
http://localhost/lab/form.html
5. Enter some data and submit the form. Make sure that you see the "Please wait"
message as shown below and after a moment the validation login message.
In real life, you can use an animated image file to show the progress.
137
Part 6 - Error Handling
When an HTTP request is submitted using Ajax, the browser is not responsible for error
handling. The application code must display a message.
1. Below the line:
Add:
3. Save changes.
4. Refresh the browser.
5. Enter some data and submit the form.
Part 7 - Review
In this lab, we learned how to use the $.get() method to make an Ajax request. The
$.post() method works the same way. We also learned how to show progress indicator and
do error handling.
138
Lab 19 - Build a Drag and Drop Application
In this lab, we will learn how to implement Drag & Drop interactions in your web pages
using jQuery UI JavaScript library. The functionality of the lab is built around two
jQuery UI interactions : Draggable and Droppable that allow creation of dynamic and
interactive web pages and applications using the familiar desktop drag & drop visual
paradigm.
http://localhost/lab/drag_and_drop.html
If you have not done it yet, do it now: use your mouse and drag the Draggable Object
around! Feels great, doesn't it? The power of jQuery UI.
Drop the Draggable Object on the Droppable Object (Target). Nothing happens...
We are going to add animation to this action (more precisely, drop event) and
demonstrate that Drag & Drop type of actions are possible with jQuery UI.
139
Part 2 - Adding Droppable Functionality
When you drop a Draggable object in the area of the Droppable one, the droppable call-
back function usually provides some feed-back to the user on the acceptance of the
object, confirming that the drop event, in fact, took place. This can be as simple as
visually informing the user of the fact or sending an Ajax call to a back-end system with
the user choice in case when there are multiple draggable objects that represent different
available options for the user to choose from (e.g. products or services), and so on.
We are going to visually notify the user that the drop event has occurred by styling the
Droppable Object's area (which is simply an HTML div section) – we will change the
background color from the original green to blue.
1. Open APACHE_DIR/lab/drag_and_drop.html in your editor of choice
2. Locate the following line:
This piece of code will apply the highlighted CSS class to the this object which
represents our Droppable Object (the this pointer is very polymorphic: in our context it
points to the Droppable object since it sits inside the call-back function that handles the
drop event and is attached to the Droppable via the "#droppable" selector.
Note: drop: function( event, ui ) notation denotes that the drop event is bound
to the event call-back function that takes the event object and the ui element as its
parameters.
4. Now we need the highlighted CSS class.
5. Locate the following line:
.highlighted {background:blue;}
The style will set the background color of the target element to blue.
7. Save changes.
140
8. Refresh the browser or enter:
http://localhost/lab/drag_and_drop.html
9. Notice, now the background color of the Droppable Object changes when you drop
the Droppable Object on it.
$( "#droppable" ).droppable({
drop: function( event, ui ) {
// Add droppable object styling code here
$( this ).addClass( "highlighted" );
}
});
jQuery UI web site lists the following supported events for Droppable
(http://api.jqueryui.com/droppable/):
activate
create
deactivate
drop
out
over
141
3. Insert the following fragment:
<script>
$(function() {
$( "#draggable" ).draggable();
$( "#droppable" ).droppable({
out: function( event, ui ) {
alert ("I'm out of here!");
},
drop: function( event, ui ) {
// Add droppable object styling code here
$( this ).addClass( "highlighted" );
}
});
});
</script>
Note: The sequence of event handlers is not important here as the jQuery UI system will
find the one that matches the event triggered by the user action automatically.
4. Save changes.
5. Refresh the browser or enter: http://localhost/lab/drag_and_drop.html
6. Drop the Draggable on the Droppable. As expected, the background color of the
Droppable Object changes from green to blue.
7. Move the Draggable Object out of the Droppable Object's area. You should be
prompted with the Alert dialog that is triggered by the out event and handled by the
attached event handler we just added
142
Of course, there is much more that you can do with this powerful API to make your web
pages really interactive!
This completes our lab.
8. Close the editor and browser.
Part 4 - Review
In this lab, we learned how to use Draggable and Droppable interactions offered by the
jQuery UI JavaScript library.
143
Lab 20 - Build a Slide Show Viewer
In this lab, we will use many of the techniques learned from previous labs to build a
picture slide show tool. The requirements for the tool are as follows:
1. We should be able to specify the list of images in the HTML page or get it
dynamically from an Ajax request.
2. An image can have caption which needs to be displayed.
3. An image needs to be fit within the screen area.
Some of the features of this lab will not work for IE8 or older. Please use FireFox or
Google Chrome.
To use the tool, this is all an HTML designer has to add to the page. The rest will be done
from JavaScript.
5. Add the following styles within the head section.
<style type="text/css">
* {padding: 0; margin: 0;}
body {background: black}
#gallery {
text-align:center;
margin-top:0px;
margin-bottom:0px;
padding:0px;
}
</style>
This is pretty basic styling. All we are doing is eliminating and padding or margin space.
This way, images will take up the entire screen space.
6. Save changes.
144
7. In a browser navigate to:
http://localhost/lab/slideshow.html
</script>
Add:
var imageList = [
{src: "/lab/images/annie.jpg", caption: "Annie the cat"},
{src: "/lab/images/cave.jpg", caption: "Sea cave"},
{src: "/lab/images/desert.jpg", caption: "Neat desert scene"},
{src: "/lab/images/poppy.jpg", caption: "California poppy field"}
];
Caveat: Make sure that the last element in the array does not end with a ",". If it does,
IE 8 considers that another element follows it. That is, IE will think there are 5 images in
the array.
3. Save changes.
145
1. Add the following code.
function showImage() {
++idx;
imgE.src = imageList[idx].src;
}
}
Nothing too complicated. Except, we had to get the DOM object for the <img> element
to set its src property. We did that using $("#gallery img").get(0).
Every time showImage() is called, the next image from the list will be displayed. We will
now call that function when the DOM is ready to show the first image by default.
Add:
$("#gallery img").click(showImage);
showImage(); //Show first image
Here, we are setting up the onclick event handler for the img element. When the image I
clicked, we will go forward and show the next image.
3. Save changes.
4. Refresh the browser or enter the URL:
http://localhost/lab/slideshow.html
146
Make sure that the picture is centered. That is what we had set in the style for the gallery
div.
5. Click the image. It should show the next image and so on. Eventually, the
application will wrap around and show the first image.
function sizeImage() {
var imgE = $("#gallery img").get(0);
147
This function basically scales an image only as much it has to show the entire content
within the screen. It preserves the aspect ratio.
But, when should we call this function? We are dynamically setting the src attribute of
the img element. Images are loaded asynchronously. Unless the image is fully loaded, the
browser has no idea about the width and height of the source image.
The solution is to attach an onload event handler for the img element. This handler will
be called when the image is fully loaded. From there we can safely resize the image.
2. In the DOM ready function, attach an onload event handler for the img element.
$(function(){
//jQuery code here
$("#gallery img").load(sizeImage);
$("#gallery img").click(showImage);
showImage();
});
From the showImage() function, we are setting the src attribute to display another image.
The height and width attributes of the image will remain same as the previous image.
This can throw off the scaling calculation. To get the true width and height of the image,
we must set the values to "auto". We will do that now.
3. Change the showImage() method as shown in bold face below.
Now from sizeImage(), we will get the true width and height of the image.
4. Save changes.
5. Make sure that you are using FireFox or Chrome. Refresh the browser. Now, as you
click through the images, entire images will be shown in the screen. Try resizing the
browser size. Clicking the image will show the next image that will fit in the window.
148
The scaling code shown here does not work in IE8 or older.
There is a slight problem. When an image is smaller than the screen, we scale it up.
Scaling images up make them look bad. We should only scale images down but never up.
The solution is simple.
6. Change the scaling code as shown in bold face.
7. Save changes.
8. Maximize the browser so that some of the images are smaller than the screen size.
9. Refresh the browser. Now, smaller images will not be scaled up. but, large images
will be scaled down.
149
Part 5 - Showing the Caption
We will like to show the caption at the bottom of the image. No matter how high the
image is, the caption should show at the same spot relative to the bottom of the image.
See the desired result below.
1. Below the img element add another div for the caption.
<div id="gallery">
<img src="#"/>
<div>Caption here</div>
</div>
#gallery div {
width: 300px;
position: relative;
top: -50px;
left: 50%;
margin-left: -150px;
border-width: 2px;
border-color: white;
border-style: solid;
border-radius: 5px;
z-index: 99;
color: white;
150
Here, we are positioning the caption div relative to where it would be normally
positioned. It's normal position will be right below the img element. We are moving it up
setting "top: -50px". This way, the caption will be shown right on top of the image. It is
important that we set "z-index: 99" so that the image does not hide the caption. The "left"
and "margin-left" styles are cleverly set so that the div is centered on the screen.
3. Save changes.
4. Refresh the browser.
5. Click through the images and make sure that the caption appears at the same spot
relative to the bottom of the image.
6. Now, we will dynamically set the caption. At the very end of sizeImage() function,
add these lines:
Note how fadeIn, delay and fadeOut are chained together. After the caption is faded in,
jQuery will wait for 3 seconds. Then the caption will be faded out.
7. Save changes.
8. Refresh the browser. Now the caption will pop open and then disappear after a few
seconds.
151
Part 6 - Getting Image List Using Ajax
We can easily convert the application to get the image list dynamically using Ajax.
1. Copy C:\LabFiles\image_list.txt to APACHE_DIR/htdocs/lab folder.
2. Open the file and notice how the data is specified there as JSON.
[
{"src": "/lab/images/annie.jpg", "caption": "Annie the cat"},
{"src": "/lab/images/cave.jpg", "caption": "Sea cave"},
{"src": "/lab/images/desert.jpg", "caption": "Neat desert scene"},
{"src": "/lab/images/poppy.jpg", "caption": "California poppy field"}
]
Important: jQuery's handling of JSON data is extremely picky. Note that the property
names "src" and "caption" are in double quotes. If you do not quote them or use single
quote, the $.getJSON() method will fail.
3. Back in slideshow.html, set the imageList variable to null.
4. In the DOM ready handler function, comment out showImage(). In it's place use the
$.get() method to load the data. This is shown below in bold face.
$(function(){
//jQuery code here
$("#gallery img").load(sizeImage);
$("#gallery img").click(showImage);
//showImage();
$.getJSON("/lab/image_list.txt", function(data) {
imageList = data;
Note: In this example, we have static data in image_list.txt. In real life, the list will be
dynamically created from database.
5. Save changes.
6. Refresh the browser. You should see this message.
152
Rest of the application will work same as before.
7. Close all.
Part 7 - Review
In this lab, we built a full screen slide show application. We paid a lot of attention to scale
large images down to size so that the whole image fits in the screen. We avoided scaling
small images up.
We used fade in and fade out transitions to show the caption.
Finally, we got the image list data from the server using JSON format. We used the
$.getJSON() method for that. Keep in mind, for $.getJSON() to work, the JSON data
must be formatted according to the specification.
153
Lab 21 - Develop a Simple Plugin
In this lab, we will develop a very simple plugin. The goal is to understand the basic
mechanism of writing a plugin.
Initially our plugin will do nothing more than open an alert dialog. This is a "hello world"
type simple plugin.
(function($){
//Plugin code below
}(jQuery));
This creates an anonymous function that is called immediately. The function takes as
parameter the jQuery global object. From within the function, the jQuery object can be
accessed as $ since that is the name of the input variable. This is just a shortcut way of
referring to the jQuery object. We take the trouble of writing this wrapper function so that
the variable name $ will not collide with any global variable by that name. Other toolkits
like Prototype may declare a variable by name $.
If you don't wish to use the short cut name for jQuery object, you don't really need this
wrapper code.
4. At the heart of the plugin code is registration of a new plugin function in the
prototype of the jQuery object. Write the lines in bold face.
(function($){
//Plugin code below
jQuery.prototype.simplePlugin = function() {
alert("Cool plugin");
};
}(jQuery));
This will dynamically add a new method to the jQuery object called simplePlugin.
154
5. In the spirit of the brevity of jQuery, we will now use a few short cuts. First, as we
already discussed, jQuery global variable can be replaced with $. Hence, the line can now
become.
$.prototype.simplePlugin = function() {
6. Finally, jQuery toolkit creates a property for the jQuery object called "fn" that is
nothing other than its prototype. So, we can further shorten the code as follows.
$.fn.simplePlugin = function() {
If you are a JavaScript purist and don't wish to use synonyms like fn, feel free to keep
using the fully spelled out code we entered first. But, most plugin developers use the
shortened version.
7. Your code should look like this:
(function($){
//Plugin code below
$.fn.simplePlugin = function() {
alert("Cool plugin");
};
}(jQuery));
155
5. Below the line:
$().simplePlugin();
Here, we are calling the simplePlugin() function of the jQuery object. We added that
function to the prototype of jQuery in the previous part.
In the $() function, we provide no selector rule as input. Hence, the function will return a
jQuery object with empty collection of DOM element. That is fine for us.
6. Save changes.
Part 3 - Test
1. Open a browser and enter the URL:
http://localhost/lab/testplugin.html
2. You should see the alert dialog. This proves that our little plugin is working fine.
156
This will show us how to handle event from a plugin and how to iterate over all DOM
elements selected by a jQuery selector.
1. In simple_plugin.js, comment out the line:
//alert("Cool plugin");
this.each(function() {
$(this).click(function(e) {
alert("Element class: " + this.className);
});
});
Here, we are using "this" keyword a lot. Depending on the context, "this" either points to
a jQuery object or a DOM element. In the first line (this.each()), "this" points to the
jQuery object. The each() function iterates over all selected DOM elements and calls the
iteration handler function for every element.
From the iteration handler function, we are calling $(this).click(). Here, "this" is the
DOM element object for which the the iteration handler function is called. Hence, the
jQuery wrapper object for it is $(this). By calling click() function we are registering the
onclick event handler. Within the event handler function, "this" points to the DOM
element where the mouse is clicked. We can use the className property of the DOM
element.
3. Save changes.
4. In the testplugin.html file, add the lines in bold face. This will add a few elements
to the body.
Feel free to add any more elements and give them a class name.
157
5. Now, when we call our plugin function, we can supply a selector rule. Change the
code as follows.
This will show the class of all "p" elements. If you wish to peek at every element, you
can also use $("*").simplePlugin().
6. Save changes.
Part 5 - Test
1. Refresh the browser.
2. Click one of the paragraphs. Make sure the alert dialog shows the class of the
element.
3. Close all.
Part 6 - Review
In this lab we developed a very simple plugin. We learned how to iterate over each
selected DOM element and then attach an event handler. This is at the core of what most
plugins need to do. You can then use jQuery API to create amazing plugins.
158
Lab 22 - Media Queries and Responsive Design
Following the principles of responsive web design, we want to adjust the style of a page
dependent on the environment it is being viewed in. There are various techniques,
including querying the browser, that will be explored in this lab.
C:\Apache2.2\htdocs\css3\media
Note: If you do not see this folder, you can copy this from the 'C:\LabFiles\css3' folder
or extract the appropriate lab solution for the previous lab from the
'C:\LabFiles\Solutions' folder. Be careful which files you copy and where you place
them to make sure the web server can locate them with the URLs provided in the labs.
http://localhost/css3/media/index.html
Note: The page in this example uses some HTML5 elements that may not be recognized
directly in older Internet Explorer browsers. This might cause the styles to not be
displayed properly to some elements. You will add JavaScript in future steps to fix this.
159
If you do try testing with Internet Explorer and don't see the behavior the style should be
creating try testing with Firefox or Chrome to see if it is different.
Screenshots in the lab will show how things should appear in Firefox.
2. Get familiar with the current style of the page so you can notice as changes are
made.
3. Leave the browser open to the page as you will refresh it later.
4. Run the Notepad++ program or a regular text editor.
C:\Software\NotepadPlus\notepad++.exe
Note: A file may appear since Notepad++ opens the last used file. To avoid this in
future, close the file first and then close Notepad++.
5. Once you have the Notepad++ program running (or another text editor if you
prefer), open the following file.
C:\Apache2.2\htdocs\css3\media\cssreset-ericmeyer.css
6. Don't make any changes but notice that this style sheet has many properties that are
being "reset" to certain values. These are the properties that might have different default
values between browser types so applying this style sheet will override these defaults so
they are consistent.
160
8. In the Notepad++ program or a regular text editor, open the following file:
C:\Apache2.2\htdocs\css3\media\index.html
9. Near the top of the page and after the <title> but before the end of the </head>
section, add the link to the reset style sheet as shown in bold below.
</head>
Note: You will always want any "reset" style sheet to be the first style sheet referenced.
This is so other style sheets or <style> tags can override the reset values if needed.
10. Save the file but leave it open.
11. Return to the browser that was showing the page and refresh the page. Open a new
one to the following URL if you closed it:
http://localhost/css3/media/index.html
12. What you should see is that the styles of the page are very different because of the
"reset" style sheet.
Note: Remember the goal of the "reset" style sheet is not necessarily to make the page
readable and styled well. You will apply other styles later to override these reset values
and provide other styles to improve the page.
13. Leave the browser open to the page as you will refresh it later.
161
14. Return to the editor that was editing the 'index.html' file.
15. Add the following bold code after the "reset" style sheet but again before the end of
the </head> section. This will add a link to the "default" style sheet to apply to the page.
</head>
18. Leave the browser open to the page as you will refresh it later.
162
2. Add the following bold code after the existing style sheets but again before the end
of the </head> section. This will be viewed as a comment by all browsers except for
Internet Explorer. For IE 8 and below it will load a JavaScript file that will trick Internet
Explorer into recognizing HTML5 tags it would not normally recognize.
</head>
Note: This page may not have as many troubles in Internet Explorer 8 and earlier before
this fix because even though there are HTML5 tags there are also normal <p> tags for
the main text. Other pages that use HTML5 may have major elements missing
completely unless you use this trick to let IE 8 and earlier recognize the HTML5 tags.
3. After the first IE conditional block, add the second IE conditional block as shown in
bold below. Again make sure it is before the end </head> tag. The style sheet that is
imported for IE will make sure many of the HTML5 tags have the 'display: block;'
property set so the default text flow will be consistent with other browsers.
<!--[if IE ]>
<style type="text/css" media="all">
@import url("ie-fix.css");
</style>
<![endif]-->
</head>
http://localhost/css3/media/index.html
163
6. The only change you will likely see is that the main <h1> tag changes in color from
purple to pink. This was added to the 'ie-fix.css' file just to prove that the style sheet is
loaded by Internet Explorer.
7. If you want you can open or refresh the page in Firefox or Chrome and notice there
is no change from before.
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Alice’s Adventures in Wonderland</title>
Note: You could also set values for the 'minimum-scale', 'maximum-scale', and
'user-scalable' properties but this might limit the ability of a user on a small device to
zoom in or out.
164
3. Add the following bold code after the IE conditional style but before the end
</head> tag. You can split the media query across multiple lines as long as the entire
value is surrounded by a single set of quotes.
<!--[if IE ]>
<style type="text/css" media="all">
@import url("ie-fix.css");
</style>
<![endif]-->
</head>
Note: In the code above there are actually two different media query expressions
separated by a comma. This is the same effect as having two separate <link> tags with
one expression each both linking to the same style sheet.
The 'screen' value is only part of the first expression so the second expression mainly
looks for width and landscape orientation, most likely for a tablet.
4. Save the file but leave it open.
5. If you are not already using it, open Firefox or Chrome to the following location.
Refresh the page if you were already using Firefox or Chrome.
http://localhost/css3/media/index.html
6. You should notice some different colors and some additional space between the text
and the image.
165
Note: Since media queries were added with CSS 3, earlier versions of Internet Explorer
will not support them. It is important that the "default" styles applied to a page will
make the content presentable no matter what. The page can then be "enhanced" with
media queries for the browsers that will support the features being added.
7. Leave the browser open to the page as you will refresh it later.
8. Return to the editor that was editing the 'index.html' file.
9. Add the following bold code after the first media query <link> tag but again before
the end </head> tag. You can split the media query across multiple lines as long as the
entire value is surrounded by a single set of quotes.
Note: Remember that the order of how styles are defined can matter when two style
sheets or <style> tags have the same property. This follows a "last one wins" rule so you
want the styles that may set default properties or be overridden to come first and other
styles that may override these style properties to come later. In this case anything in the
'large.css' file will override anything that sets a matching property before it which is
what we want.
10. Save the file but leave it open.
11. Return to the Firefox or Chrome window you were using and refresh the page.
Open the following location with Firefox or Chrome if you had closed it. Maximize the
browser.
http://localhost/css3/media/index.html
166
12. You should now see a very different layout and style for the page. Make sure your
window is maximized and check your screen resolution if you do not see the change.
This is what would be shown perhaps on "normal" web browsers on a computer desktop.
Note: You might not normally make such drastic changes with colors and images
between the different layouts for different size screens. This was done just to make it
more obvious when changes were taking place. Normally you might change things like
where navigation links are placed, how text flows on the page, or how many elements
appear side by side on the page.
13. Open the page in Firefox if you do not already have it open.
14. In Firefox, select 'Tools → Web Developer → Responsive Design View'. You
may also need to click the 'Firefox' menu in the upper left to see the options below. Still
another option could be just pressing the Ctrl-Shift-M short-cut.
Note: You can also do similar testing in other browsers simply by resizing the window
but this tool in Firefox makes it very easy and you can also test exact screen sizes.
167
15. Use the drop-down at the top of the window to select the '360x640' option. The
page should be displayed with the default styles as both media queries will now be false.
This is what the page might look like on a phone.
16. Use the drop-down to select the preset of '768x1024'. You should see the page
displayed with the "medium" styles.
168
17. Click the 'rotate' button next to the drop-down list. The value won't change but the
page should be wider and it should now be displayed with the "large" styles.
18. Click the X at the top left of the window next to the drop-down for screen sizes.
This will close the responsive design view.
http://localhost/css3/media/index.html
2. Depending on the browser you are using open the 'Print Preview' of the page. Ask
other students or the instructor if you are not sure how to do this.
169
3. What you should see is that the page is displayed with the "reset" styles only being
applied. This is because all of the other styles were applied to the 'screen' media which is
the visual display of the page.
4. Close the print preview view but leave the browser open.
5. Return to the editor that was editing the 'index.html' file.
6. Add the following bold code after the two media query <link> tags but again before
the end </head> tag.
170
11. You may or may not see an image in the upper left but you should at least be able
to tell that the styles are different for how the page would be printed.
Part 6 - Review
The main goal of a "responsive design" is to present the same content but adapt it to how
the user is viewing it. Besides providing a better user experience, it allows for the
different "versions" of the web site to be more consistent with each other without having
to maintain more than one source of the content. By applying different style properties
and using media queries to decide how they should be applied the site can adapt to
different viewing conditions.
171
Lab 23 - Responsive Layout
In this lab, we will work through a simple an effective technique that will help us build a
responsive layout of a web page. This technique is based on the CSS float property
which has been around for quite a long time and recently has become a popular choice of
web designers tailoring their web pages for devices with small screens.
http://localhost/lab/responsive_layout.html
2. In Firefox, press Ctr-Shift-M to activate the Responsive Web Design View of the
loaded page.
You should see the following page content:
Resizing the window (by dragging the two little parallel bars located just off the middle
of the right side of the view) has no effect on the layout of the page - all three sections
shown in three colors (red, green and blue) are invariably shown stacked.
We would like to have a layout that would present the three sections as separate in-line
columns on wider screens, dropping a right-most column when the screen becomes
narrower.
172
As you can see, the page is as simple as it gets. Nothing exciting about it - just random
text generated by the Lorem Ipsum web site placed in the standard div elements.
Let's "columnize" the page layout (if there is such a word at all for creating columns on
the page).
2. Enter the following code just above the </style> tag:
.floatLeft {
max-width: 330px;
float: left;
}
This CSS style rules set effectively says that each element styled with it should have a
maximum width of 330 pixels and whenever it is not possible to accommodate it on the
screen, drop and flush it to the left of the screen.
Note: It would be better to convert the absolute dimensions expressed in pixels into
relative em's, but here we are trying to keep it simple for seeing the dynamic screen
widths in Firefox's Responsive Design View which allows only for pixel measurement
units.
3. Update each div section's class by adding floatLeft as the second style class after the
primary one (named col_X, where X takes 1, 2, or 3) so that your div sections will look
as follows:
173
Looks like we got what we were asking for.
Not quite yet.
Let's now run our page in a device emulator that is built-in with latest Chrome desktop
174
browsers (our tests were run in version 35).
http://localhost/lab/responsive_layout.html
Note: The device currently displayed in the Emulation panel of your browser may differ.
5. In the Device drop-down box, select Apple iPhone 4.
6. Click the Emulate button just below the Device drop-down box.
175
You should see that our responsive_layout.html page gets re-rendered as if it were inside
the iPhone's embedded AppleWebKit browser with its KHTML layout manager.
Chrome's mobile device emulator view automatically turns on the touch screen emulation
so that we can use the mouse pointer to simulate the swipe gesture; the touch point is
represented by a transparent gray circle at the mouse positioning point on the emulated
window.
So, as you can see, not everything is good with our page - it did not respond to the
emulator window we selected and the green (middle) column is only available for
viewing when the user scrolls to the right.
So, back to the drawing board (some folks may heave a sigh at this point; bear with me, it
is not going to be long).
Keep Chrome browser with our "unresponsive" page open.
This line inserts the viewport meta tag into our page which will instruct the mobile device
browser's layout manager to adjust the viewable width according to the system's screen
width.
3. Save the file.
4. Switch back to Chrome and reload the page.
176
You should see the properly stacked view of our page as shown in the screen-shot below.
The horizontal scroll-bar has magically disappeared and now all is honky dory ("all
right") and you can view the full page content by scrolling it up and down.
3. Close Chrome.
4. Switch to Firefox, and press Ctrl-Shift-M to close the Responsive Design View
window.
5. Close Firefox.
6. Close the editor.
Part 7 - Review
In this lab we worked through steps needed to make our web page responsive to different
device windows. We used Firefox's Responsive Design View window to test our first cut
changes using the CSS float property. Then we finished off our job by adding the
177
viewport meta tag instructions to the page and tested changes in Chrome's embedded
device emulator.
178
Lab 24 - Orientation Responsiveness
In this lab, we will learn how to identify mobile device orientation and how to react to it.
Techniques covered in this lab will help you improve user experience of your clients and
may well pave your way to creating a number of simple yet interesting and porentially
useful applications.
There will be two main parts in this lab:
• Identifying the Portrait / Landscape orientation using media query rules
• Identifying the 3D device orientation by interfacing with the Accelerometer
sensor
http://localhost/lab/responsive_orientation.html
2. In Firefox, press Ctr-Shift-M to activate the Responsive Web Design View of the
loaded page.
You should see the following page content:
3. Click the Rotate button to simulate the change of the device orientation.
At the moment, the page won't react to your actions and will continue to display the same
content in both orientation views as, currently, the page does not have a way to identify
its orientation.
179
Part 3 - Make the Page Responsive to Portrait and Landscape Views
1. Open the APACHE_DIR/htdocs/lab/responsive_orientation.html page in your
editor.
2. Locate and uncomment the following code fragment (remove the '/*' and '*/'
comment anchors).
/*
@media all and (orientation:portrait){
.portrait{color:red;font-size:1.25em; }
.landscape{display:none;}
}
@media all and (orientation:landscape){
.landscape {color:blue;font-size:1.25em; }
.portrait{display:none;}
}
*/
This code uses media query rules to toggle styles depending on whether the device's
screen is in the portrait or landscape view orientation.
The element styled with the landscape class is hidden
.landscape{display:none;}
when the browser identifies that it is in the portrait orientation (its screen height is pixel-
wise bigger then its width), which is wrapped up in the
orientation:portrait
180
Conversely, when the device is in the landscape position, the element styled with the
portrait style is hidden.
3. Save the page in your text editor.
Keep the editor open on the responsive_orientation.html file as we will need it later in
the lab.
4. Switch to Firefox and reload the page.
Now, when you change page orientation, you should see the expected responsive
behavior of the page.
Now, let's do something a little bit more technically involved, namely identifying the 3D
device orientation.
5. Switch back to the editor open on the responsive_orientation.html file.
6. Locate the following code fragment:
.section1 {
181
}
.section2 {
display: none;
}
7. Swap the visibility of section1 and section2 CSS classes by cutting and pasting the
display:none; rule from section2 over to section1.
The resulting code of your updates should look as follows:
.section1 {
display: none;
}
.section2 {
This swap will allow us concentrate on the second part of our lab, which, again, is
• Identifying the 3D device orientation
http://localhost/lab/responsive_orientation.html
You should see the unhidden section of the page that we will use in our subsequent steps.
182
3. In the top right-hand corner of the Developer Tools View, click the Show drawer
icon.
Note: The device currently displayed in the Emulation panel of your browser may differ.
5. Click the Sensors navigation link.
6. In the Sensors panel that gets activated, click the Accelerometer checkbox.
7. Enter 20 in the α input box (values are in degrees, so we entered a 20 o).
Observe the visual change in the orientation of the device image (displayed as an
unimaginative picture frame to the right of the accelerometer 3D orientation parameters).
183
8. Enter 45 in the β input box.
The device image changes further now tilting towards us at a 45 degree.
Now, if you take a look at our page loaded in Chrome, you will see that it properly
records those simulated accelerometer readings as shown in a screen-shot below.
Note: You can also change the device orientation by moving your mouse with the left
button down.
OK, now it is time to see how our page intercepts device orientation in the 3D world.
Keep Chrome browser with our page loaded open.
184
this experimental technology.
The core of its functionality is based on the availability of the DeviceOrientationEvent
JavaScript global event which we try to intercept by using our anonymous event listener
hooked on to this event as follows:
window.addEventListener('deviceorientation', function(eventData) {
After capturing the event's properties, the event listener passes on those properties to the
deviceOrientationHandler() function for reporting purposes:
window.addEventListener('deviceorientation', function(eventData) {
var tiltLR = eventData.gamma;
var tiltFB = eventData.beta;
var dir = eventData.alpha
Be aware that this technology is still regarded as experimental and even its specification
has not yet been stabilized, so don't rush to start using it in production as the API
(Application Programming Interface) and behavior may change in future versions of
browsers that implement this spec.
For more information, visit the W3C site who sponsors specification for this project
(http://w3c.github.io/deviceorientation/spec-source-orientation.html).
Currently, only Chrome and Firefox offer support for this technology; the support for this
event is checked in this piece of code:
if (window.DeviceOrientationEvent) ...
For you reference, the DeviceOrientationEvent, when fully constructed and passed on to
your event listener's call-back method, has the following properties:
Property Name Description
185
absolute A boolean that indicates whether or
not the device is providing
orientation data absolutely.
3. Close Chrome.
4. Switch to Firefox, and press Ctrl-Shift-M to close the Responsive Design View
window.
5. Close Firefox.
6. Close the text editor.
Part 7 - Review
In this lab, we familiarized ourselves with techniques related to making our web page
186
responsive to device orientation. We took advantage of the media query-based
orientation rules (orientation:portrait and orientation:landscape) as well as the emerging
API (Application Programming Interface) for interfacing with the Accelerometer sensor.
187
Lab 25 - Responsive Images with Media Queries
In this lab, we will show how to make images responsive to changes in the client device's
screen size.
We will need the latest version of Firefox with its built-in Responsive Design View plug-
in (which is now part and parcel of the Firefox browser platform).
http://localhost/lab/responsive-images-via-media-query.html
You should see a satellite picture of the Toronto's City Hall building taken on a beautiful
summer day.
2. Activate the Responsive Design View in Firefox by pressing Ctr-Shift-M
You should see the following picture (the View sizes may differ in your case).
3. Try to re-size the view by dragging the control handle at the bottom right-hand
corner of the page.
188
Note: For better positioning precision, hold the Control key down as you do the dragging.
Currently, the size of the image stays unchanged regardless of the changes to the Mobile
View window - it is not responsive.
We are going to fix it in the next lab part.
4. Resize the Mobile View window to about 540 x 400 px (keep the Control key down
for finer dragging prevision).
That action will set the stage for viewing the changes we are going to make.
5. Keep the browser window open.
3. Locate the <img ...> element and add the following attribute to it:
class="responsive_image"
189
which matches the CSS class references you added in the style section of your page.
After updates, the page code should look as follows (the added lines are shown in bold):
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8"/>
<title>Responsive Image Example</title>
<style>
@media screen and ( max-width: 300px ) {
img.responsive_image { width: 100px; }
}
@media screen and ( min-width:301px ) and ( max-width: 500px ) {
img.responsive_image { width: 200px; }
}
@media screen and ( min-width: 501px ) {
img.responsive_image { width: 430px; }
}
</style>
</head>
<body>
<img class="responsive_image" alt="View of the Toronto City Hall from Above"
src="toronto-city-hall-satellite-view.png">
<p>
Example of resizing an image using CSS3 media queries
</p>
</html>
Consult the media queries you added in the styling section of the page to see how image
190
down-sizing is configured in the media queries.
Part 5 - Review
In this lab we demonstrated how to use the CSS3 media query facility to make an image
responsive to the client device's view width.
191
Lab 26 - Responsive Images with Picturefill
In this lab, we will show how to make images responsive to changes in screen sizes using
the Picturefill JavaScript library (http://responsivedesign.is/resources/images/picture-fill).
We will need the latest version of Firefox with its built-in Responsive Design View plug-
in.
<!doctype html>
<html>
<head>
<title>Responsive Images</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
img.fluid {
max-width: 100%;
}
</style>
<script async type="text/javascript" src="picturefill.js"></script>
</head>
<body>
</body>
</html>
192
<script async type="text/javascript" src="picturefill.js"></script>
which will be doing some dynamic population of the img tag's source depending on the
screen size (as per the "640px.png 640w, 320px.png 320w, 210px.png 210w" rule).
We set the sizes="80vw" attribute to have a better alignment with the Responsive Design
View reported width.
2. Keep the editor open on the file.
Note: If you don't see the bottom menu with the All button, increase the height of the
Network panel:
6. Navigate to:
http://localhost/lab/responsive_images.html
The target page gets loaded, and the Network panel at the bottom of the browser window
193
gets populated with the list of loaded assets.
What is interesting to observe here is that only the 640px.png image file is loaded.
7. Start slowly decreasing the width of the Responsive Design View by dragging the
two parallel bars to the left; keep the Shift button down to get it done in 10px change
increments.
At about 320px window size, you will see the 320px.png image on the page; the loading
of the image is also reported in the Network panel.
Notice that the loading of the image happened when the srcset rules was met.
8. Continue to reduce the width of the Responsive Design View until you get the
210px.png image loaded in the browser.
The sequence of the image loading is shown in the chart below; there are two breakpoints
involved: 210 px and 320 px at which a new image HTTP request is made to the server.
---------------------------------------------------------------------
210px ->| 320px ->| ::Screen resolution
---------------------------------------------------------------------
210px.png | 320px.png | 640px.png ::Image file loaded
---------------------------------------------------------------------
Now, if you started to increase the width of the page, you would see the changing images
which happens without loading them from the server but, rather, serving them from the
browser's cache. In order to see the reverse "slide show" happening, we need to purge the
browser cache.
9. Keep the Responsive Design View screen at the width where you have the 210px.png
image loaded.
194
2. In the Options panel that opens, click the Network tab and clear the cached web
content by clicking Clear Now button, then click OK to close the Options panel.
3. Back in the browser, in the bottom right corner of the Network panel, click the
Clear button to clear the recorded HTTP transactions (adjust the height of the panel if
you don't see the Clear button.)
195
2. Start slowly increasing the width of the Responsive Design View by dragging the
two parallel bars (adjust the height of the Network panel, if you don't see them).
Notice that the loading of the images is now happening in the reverse order.
196
The selective image loading demo
that comes from the alt attribute of our img tag as we don't have the src attribute set.
As you see, disabling the Picturefill script ended our mesmerizing "slide show".
Note: If you actually see the images and everything works fine, that would mean that the
latest Firefox version you run natively supports the srcset rules!
9. Switch back to your text editor.
10. Recover the deleted line by re-doing the previous line deletion:
Part 8 - Review
In this lab we demonstrated how to use the Picturefill JavaScript library to enable the
dynamic loading of images configured in the media query rules set in the srcset attribute.
197
Lab 27 - Getting Started With Bootstrap
In this lab, you will load the bootstrap files into Apache's document root directory. Then
you will configure a simple HTML file to use Bootstrap. .
<!DOCTYPE html>
<head>
<title>Bootstrap Labs</title>
</head>
<body>
</body>
3. First thing add the <meta> tag inside <head> tag specifying the viewport
parameters. This tag will be added in the head section below the title
4. Next add a link to the Bootstrap CSS file right below the <meta> tag:
<head>
<title>Bootstrap Labs</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
</head>
198
5. Finally, add the script references to the end of the body section (before the </body>
tag):
<script src="js/jquery-1.9.1.js"></script>
<script src="js/bootstrap.min.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>Bootstrap Labs</title>
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
</head>
<body>
<script src="js/jquery-1.9.1.js"></script>
<script src="js/bootstrap.min.js"></script>
</body>
</html>
<div class="container">
<div class="jumbotron">
<h1>Hello, JUMBO world!</h1>
<p>
This is an example of a Bootstrap Jumbotron.
This component allows you to highlight content in a
resizeable, responsive manner.
</p>
</div>
199
<div class="row">
<div class="col-sm-12">
Bootstrap is really cool!
Bootstrap is really cool!
Bootstrap is really cool!
Bootstrap is really cool!
Bootstrap is really cool!
Bootstrap is really cool!
Bootstrap is really cool!
Bootstrap is really cool!
Bootstrap is really cool!
Bootstrap is really cool!
Bootstrap is really cool!
Bootstrap is really cool!
</div>
</div>
</div>
Part 4 - Test
1. In a browser connect to http://localhost/bootstrap
You should see:
200
2. Try resizing the browser window to see the responsive behavior.
3. Close all open files and browsers.
Part 5 - Review
In this lab, you added support for Bootstrap to a file and then configured a simple
component, the Jumbotron.
201
Lab 28 - Simple Components
In this lab, you will load the pre built Bootstrap template and a grid for layout and
navigation.
</nav>
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse"
data-target="#bs-example-navbar-collapse-1">
<span class="sr-only">Toggle navigation</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
202
4. Next add the following code after the </div> from the previous step.
5. Next add the following code after the </div> from the previous step.
Note: the poems are in C:\LabFiles\poetry.txt. To get the full effect of the lab, copy the
poems or at least enter multiple paragraphs of text in place of '...'
<div class="container">
<div class="row">
<div class="col-sm-12">
<h1>Robert Frost - Selected Poems</h1>
</div>
</div>
<div class="row">
<div class="col-sm-3">
<h3>Fire and Ice</h3>
Some say the world will end in fire,<br>
...
</div>
<div class="col-sm-3">
<h3>The Plowman</h3>
I hear men say to plow the snow.<br>
...
</div>
203
<div class="col-sm-3">
<h3>The Road not Taken</h3>
Two roads diverged in a yellow wood,<br>
...
</div>
<div class="col-sm-3">
<h3>A Brook in the City</h3>
The farm house lingers, though averse to square<br>
...
</div>
</div>
</div>
Part 2 - Test
1. In a browser connect to http://localhost/bootstrap/poetry.html
You should see:
2. Try resizing the browser window to see the responsible behavior. Note, some IE
version won't show the expected behavior.
3. Close all open files and browsers.
204
Part 3 - Review
In this lab, you used navigation and a grid layout to create a responsive web page.
205
Lab 29 - Integrating jQuery with Bootstrap Components
Most Bootstrap components are static HTML elements wired by stylesheets to make
them responsive for various screen sizes and target browsers' capabilities. This lack of
inherent dynamics can be easily compensated with the power of jQuery.
In this lab, we will explore some of the ways of augmenting Bootstrap components with
jQuery.
This Lab depends on work done in one of the previous Labs, namely the copying of the
C:\LabFiles\bootstrap directory to APACHE_DIR/htdocs/.
<!DOCTYPE html>
<head>
<title>jQuery with Bootstrap Components Labs</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="css/bootstrap.min.css" rel="stylesheet" media="screen">
<script type="text/javascript">
function hide(id) {
}
function show(id) {
}
function addAGlyphicon(glyphiconClass) {
}
function removeAGlyphicon(glyphiconClass) {
}
</script>
</head>
<body>
<div class="container" style="width: 80%">
206
</div>
<script src="js/jquery-1.9.1.js"></script>
<script src="js/bootstrap.min.js"></script>
</body>
As you can see, there are already JavaScript functions' stubs created for you to fill out
with code we are going to write.
3. Open a web browser and navigate to the following URL:
http://localhost/bootstrap/Bootstrap_with_jQuery.html
You should see four in-line buttons grouped together by the <div class="btn-toolbar"
role="toolbar"> element. Each button is reduced in size from the default one by
applying the .btn-sm Bootstrap CSS class.
At page load time, the message is hidden (using the "display: none;" style).
The other two buttons (the two right-most ones) will toggle the Star glyphicon to be
displayed on the Assign me a star rating! button. We will work on those later in the Lab.
So that's our plan.
While you can also write code for these JavaScript functions using plain-vanilla
JavaScript, leveraging jQuery aids in your productivity and ensures your code works the
same way across different browsers. Doing so will also reinforce your newly acquired
knowledge of jQuery.
207
Part 2 - Adding jQuery Code for Component Hiding and Showing
1. Switch to your text editor that has the Bootstrap_with_jQuery.html open and
locate the following code:
function show(id) {
}
This jQuery code takes the id of the hidden alert message ("danger"), formats it by
prefixing it with '#' and, using it, gets the reference to the jQuery object: var ref = $("#"
+ id);
Then it displays a diagnostic message about the action to be performed and shows the
message in slow motion (5 seconds).
3. Locate the following code:
function hide(id) {
}
This code uses jQuery to hide the message box in slow motion.
Your updates to the function stubs should look as follows (we don't do any updates to the
other two functions dealing with the star glyphicon manipulation).
function hide(id) {
var ref = $("#" + id);
var text = ref.html();
alert("About to hide the '" + text + "' message");
ref.hide("slow");
}
208
function show(id) {
var ref = $("#" + id);
alert("About to show the message");
var showTimeMs = 5000;
ref.show(showTimeMs);
}
http://localhost/bootstrap/Bootstrap_with_jQuery.html
7. Click the Show the message … button and discard the "About to show the
message" pop-up by clicking OK.
You should see a gradually appearing Alert message.
8. Click the Hide the message … button and discard the "About to hide the 'Alert!'
message" pop-up by clicking OK.
You should see the gradually disappearing alert message.
function addAGlyphicon(glyphiconClass) {
}
$("#starId").addClass(glyphiconClass);
This jQuery code dynamically attaches the glyphicon glyphicon-star Bootstrap class to
the span tag nested in the Assign me a star rating! button. The span tag is identified with
the "starId" id attribute used by jQuery to locate the element in the page DOM.
209
3. Locate the following code:
function removeAGlyphicon(glyphiconClass) {
}
$("#starId").removeClass(glyphiconClass);
This jQuery code dynamically removes the glyphicon glyphicon-star Bootstrap class.
Your updates to the two functions should look as follows:
function addAGlyphicon(glyphiconClass) {
$("#starId").addClass(glyphiconClass);
}
function removeAGlyphicon(glyphiconClass) {
$("#starId").removeClass(glyphiconClass);
}
http://localhost/bootstrap/Bootstrap_with_jQuery.html
210
Part 5 - Review
In this lab we were able to achieve a great deal of UI dynamics through the courtesy of
jQuery with minimum amount of code and effort.
211
Lab 30 - Mobile Web Testing With Chrome
Mobile web applications are pretty much the same regular web application developed
using standard web technologies. They are deployed on remote web servers where they
can be accessed from a variety of mobile browsers running on handheld devices such as
smartphones or tablets. Communication between the browser and the remote web server
is done either over a mobile or wireless network.
In this lab, we will look at the basic tooling support for mobile web UI testing offered by
Google's Chrome browser which is also useful for testing web pages created using
Responsive Web Design techniques.
Using Chrome's free Device Emulation add-on can help testers complete a bulk of UI
testing of mobile web apps using mobile browser emulators for a variety of mobile
devices.
http://www.yahoo.com
212
4. In the Console (Drawer) tabbed menu, click the Emulation tab.
You should get the following Emulation screen of the Device Emulation add-on:
Note: Chrome team completely overhauled this panel in recent browser versions. In
previous versions, the device emulation settings were under the Overrides tab on the
Settings menu (invoked by clicking the black cog menu icon in the DevTools panel):
The instruction steps below cover device settings under the Emulation tab on the
Console (Drawer) as found in more recent Chrome versions.
As you can see on the Emulation screen, there are a number of options that can be
overridden in its appropriate sections.
For example, in the Sensors section, you can find options for emulating device's
geolocation (latitude and longitude), device orientation along three axis (x, y and z); in
the Screen section, you can specify the CSS media type, e.g. print, screen, speech, etc.
All those settings can really help with testing the above features, if needed.
5. In the Device section, select the BlackBerry Z30 option from the device drop-
down.
213
The Viewport details and User Agent string are automatically updated for the type of the
device selected.
In case of BlackBerry Z30 we just selected, the User Agent string is:
As you see, BlackBerry Z30 uses the AppleWebKit web browser engine (Apple's Safari
and Google's Chrome also use the WebKit engine).
Note: KHTML is the name of the HTML layout engine.
6. Click the Emulate button.
You should see the following updates on the Emulation screen.
214
The Yahoo web site identifies the submitted User Agent string as belonging to a mobile
device and redirects the emulated browser to the mobile version of the site via the 302
HTTP response code listing https://m.yahoo.com/ in the Location response header (you
can see the interaction between the browser and the web site in the Network section of the
DevTools).
Note: Chrome DevTools' Emulation add-on does not provide a direct support for the
Opera mobile browser as Opera Software (company behind it) has developed their own
very good Opera mobile emulator that should be used for testing Opera mobile
browsers.
3. In the User Agent section, check the Spoof user agent checkbox.
4. Select Other in the device drop-down (it should be pre-selected by default), and type
in Boo-Boo for the User Agent string.
215
Part 3 - Lab Clean-up
1. Close the DevTools panel by clicking the X round icon in its upper right-hand
corner.
Part 4 - Review
In this lab, we reviewed mobile browser emulation support offered by Chrome. Using
Chrome's free DevTools with its Device Emulation add-on greatly aids in the testing of
mobile web sites from the desktop computer without the need to test a variety of mobile
browsers running on a wide range of devices.
216
217