Sei sulla pagina 1di 151

HTML5: Jump Start

Authors:

Richard Campbell
Daniel Egan
Wallace McClure
Michael Palermo
Dan Wahlin

About the Authors 1

About the Authors

Richard Campbell is an architecture and infrastructure consultant, as well as a Microsoft Regional


Director and MVP. He hosts RunAs Radio, and he cohosts.NET RocksandThe Tablet Show. Follow
him on Twitter: @richcampbell.
Daniel Egan is a Microsoft Developer Evangelist based in Los Angeles and the man behind the awardwinning Windows Phone 7 Unleashed events. Learn more about Daniel at his blog www.TheSociableGeek.com, or follow him on Twitter @danielegan.
Wallace Wally B. McClure (wallym@scalabledevelopment.com) is a Microsoft MVP, ASPInsider,
member of the national INETA Speakers Bureau, author of seven programming books, and a partner
in Scalable Development. He blogs at www.morewally.com and co-hosts the ASP.NET Podcast (www.
aspnetpodcast.com). Follow Wally on twitter: @wbm.
J. Michael Palermo IVis a Microsoft Developer Evangelist based in Phoenix. Michaels current passion
is all things HTML5. You can find Michael blogging at www.palermo4.com, or follow him on Twitter
at @palermo4.
Dan Wahlin is a Microsoft MVP and founded The Wahlin Group, which specializes in ASP.NET MVC,
jQuery, Silverlight, and SharePoint consulting and training solutions. Dan has written several books on
.NET and writes for several different technical magazines. He blogs at weblogs.asp.net/dwahlin.

2 Contents

Contents
About the Authors...............................................................................................1
Introduction........................................................................................................3
Chapter 1: The Past, Present, and Future of HTML5............................................5
Chapter 2: Three of the Most Important Basic Elements in HTML5...................15
Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5..................20
Chapter 4: HTML5 Form Input Enhancements:
Form Validation, CSS3, and JavaScript.............................................................32
Chapter 5: HTML5 Syntax and Semantics: Why They Matter............................38
Chapter 6: Introduction to HTML5 for Mobile App Development....................50
Chapter 7: HTML5 for the ASP.NET Developer.................................................63
Chapter 8: Getting Started Using HTML5 Boilerplate.......................................74
Chapter 9: Start Using HTML5
in Your Web AppsToday!...............................................................................82
Chapter 10: Ease HTML5 Web Development
with jQuery, Knockout, and Modernizr Libraries............................................95
Chapter 11: Build a jQuery
HTML5 Web Application:
The Account at a Glance App............................................................................97
Chapter 12: How to Build a jQuery HTML5 Web Application
with Client-Side Coding................................................................................106

Contents 3

Chapter 13: Explore the New World of JavaScript


Focused Client-Side Web Development.........................................................116
Chapter 14:
Storing Your Data in HTML5...........................................................................124
Chapter 15:
Using the HTML5 Canvas Tag..........................................................................130
Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript
and the HTML5 Canvas.................................................................................139

4 Introduction

Introduction

This is an exciting time to be a web developer! Whether you are building public-facing website
applications or creating internal sites for your company, HTML5 has much to offer in providing sorely
needed features that are native to the browser. With growing support among all the major browsers
and with new sites emerging that consistently use it, HTML5 is a must-visit technology for any serious
web developer today.
This eBook, with chapters written by five HTML5 experts, is designed to jump start you into using
HTML5. Not only will you learn the history of HTML and web development, youll find tutorials, boilerplates, and detailed discussions that will help shorten your HTML5 learning curve.

Chapter 1: The Past, Present, and Future of HTML5 5

Chapter 1: The Past, Present,


and Future of HTML5
Ready, set, start your HTML5 learning with a look at the evolution
of HTML and basic HTML5 coding
By Michael Palermo and Daniel Egan
Stop and think for a moment about how long youve been a developer. For some of you, that journey
started recently. For others, it has been years. However long its been, do you realize that less than a
decade ago, the .NET revolution had not officially started? Classic ASP was the primary way we developed for the web, and HTML was at versionwait a minuteis still at version 4.01!
Despite sluggish transformations regarding HTML overall, small to very dramatic changes in technologies that are based on HTML have occurred. Think of the changes that have occurred in web browsers,
JavaScript, and Cascading Style Sheets (CSS). Think of how AJAX has changed the way many web developers approach communications between the browser and server-side resources. The web has seen
many changes but with virtually no change to its core language, HTML. However, that logjam is about
to bust with HTML5.

A Brief History of HTML5


Before we discuss what HTML5 has to offer, we should note that attempts have been made to change
HTML. Note the word ischange, notupgradeorrevise. But what does that mean? Why is it important
to consider the failed attempts to change HTML? So that you can appreciate why HTML5 is worth
investigating and why it is here to stay. For these reasons, lets take a brief journey down memory lane
and consider the series of events that led to where we are today. Then well discuss where well be
tomorrow.
You probably already know who Tim Berners-Lee is and that HTML came into existence as far back
as 1989. You also probably know that the Internet took off in the 1990s, and so on. So instead of
strolling through a step-by-step timeline, lets focus on the attempts to replace HTML with something
else.
Fast-forward to January 2000. The World Wide Web Consortium (W3C) recommended Extensible
HyperText Markup Language (XHTML) 1.0. For an XHTML document to be served correctly, the

6 Chapter 1: The Past, Present, and Future of HTML5


author had to use the new application/xhtml+xml MIME type. However, Appendix C of W3Cs
XHTML 1.0 specification made provision for pages to be served by using the common text/html
MIME type.
More than a year later, in May 2001, the W3C recommended XHTML 1.1. The abstract of the recommendation stated, The purpose of this document type is to serve as the basis for future extended
XHTML family document types, and to provide a consistent, forward-looking document type cleanly
separated from the deprecated, legacy functionality of HTML 4 that was brought forward into the
XHTML 1.0 document types.
According to the abstract, XHTML was prepped to be the future of the web. The abstract boldly
referred to HTML 4 as deprecated, legacy functionality. And version 1.1 of XHTML removed the
Appendix C version 1.0 provision that allowed a page to be served with the text/html MIME type. So
why didnt this recommended standard replace HTML altogether? The answer is simple: Developers
didnt implement it.
To be sure, many developers tried to implement XHTML in their websites. XHTML mandated a wellformed XML document using the classic HTML tags. To be well-formed, a web page would need to
be served with no overlapping tags and no missing end tags, and the values of all attributes had to be
enclosed in quotation marks. The notion of cleaning up our web pages wasnt unpopular, but it wasnt
strictly enforced either. And even if a web developer created a well-formed web document, was it
served with the application/xhtml+xml MIME type? Likely not. In fact, it is estimated that 99 percent
of web pages on the Internet today contain at least one violation of the XHTML standard, which, if
enforced, would cause the page to stop rendering and post an error to the end user. Ouch!
So now what? Exactly. WHAT was born. The Web Hypertext Applications Technology (WHAT)
Working Group, actually known as WHATWG, came into existence in 2004 to put life back into
HTML. This groups intent was to move forward in a manner consistent with how the web was actually being used and to spearhead innovations in HTML while maintaining backward compatibility.
Instead of breaking 99 percent of the web, why not embrace the way in which web pages are actually
served? Browsers have been forgiving. Why make page-breaking changes?
Therefore, the WHATWG came up with Web Applications 1.0 while the W3C worked toward version 2.0 of XHTML. However, near the end of 2006, it was clear that the WHATWG was gaining
momentum while XHTML 2.0 was lacking support by any major browser. Thus, the W3C announced
it would collaborate with the WHATWG. One of the outcomes of this union was to rename Web
Applications 1.0 as HTML5.
Is there a lesson in this for us? Absolutely. Despite noble aims and grand ambitions, whatever the
masses choose to adopt wins. The growing adoption of HTML5 makes it the winner. HTML5 cannot
be ignored. Our brief history lesson demonstrates that HTML5 is here because we willed it to be here.
(For more in-depth coverage of the history leading up to HTML5, check out Mark Pilgrims Dive into
HTML5.)

Start Using HTML5


HTML5 is not an official specification yet, but it will likely have a prominent place in website development, given that the major browsers are gradually incorporating HTML5 features and Microsofts

Chapter 1: The Past, Present, and Future of HTML5 7


recently stated intention to incorporate native HTML5 in Windows. So its a good idea to start getting familiar with HTML5 nowand you can do so without making dramatic changes to the pages
you already have. Lets consider a minimalistic HTML5 document, such as in Figure 1.
Figure 1: Minimalistic HTML5 document
<!DOCTYPE html>
<title>A relatively minimal HTML document</title>
<p>Hello World!</p>

Notice the omission of the <html> and <head> tags. According to the current specs, this is still a valid
document. If these tags are omitted, the browser will still parse the document, and the tags will be
implied. This represents a shift from the strict conformity imposed by the current HTML standard.
Here is another example of how easy it is to adapt to HTML5:
<!DOCTYPE html>

The doctype syntax has been simplified. Compare this to examples of what we have been accustomed to, shown in Figure 2.
Figure 2: Doctype examples
<!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.1//EN
http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd>
<!DOCTYPE html PUBLIC -//W3C//DTD XHTML 1.0 Transitional//EN http://www.
w3.org/TR/1999/REC-html401-19991224/loose.dtd>

The doctype declaration is required. Although it is clearly easier to type the normal HTML5 doctype,
the deprecated doctypes in Figure 2 are still accepted formats. By the way, the doctype declaration is
not case sensitive, so any of the following are acceptable:
<!doctype html>
<!doctype HTML>
<!DOCTYPE HTML>

Now take a look at Figure 3 to see a more realistic starting point for an HTML5 document.
Figure 3: Simple HTML5 document
<!DOCTYPE html>
<html lang=en>
<head>
<meta charset=UTF-8>
<title>Getting Started With HTML5</title>
</head>
<body>

8 Chapter 1: The Past, Present, and Future of HTML5


<p>Simple text.</p>
</body>
</html>

You might find slight differences in this HTML5 document compared to what you are used to. Apart
from the doctype, you might notice the attribute on the <html> tag and the contents of the <meta>
tag. Lets focus first on the <html> tag:
<html lang=en>

The lang=en attribute informs the browser that the contents of this document are in English. This is
much simpler than the following:
<html xmlns=http://www.w3.org/1999/xhtml
lang=en
xml:lang=en>

Look at how much was removed. There is no longer any need to specify the namespace of the document because all elements in HTML5 (unless otherwise noted) belong to the http://www.w3.org/1999/
xhtml namespace. The xml:lang attribute is left over from the XHTML era. So, once again, HTML5
presents a simpler way to do things, but for what it is worth, the older syntax is still acceptable.
Now, how about that <meta> tag? This is how we used to handle it:
<meta http-equiv=Content-Type content=text/html; charset=utf-8>

And as you have noticed, it is now this simple:


<meta charset=UTF-8>

Of course if you want to use the old style, thats still okay. Its a good practice to make this meta
charset tag the first child of the <head> tag because the specification states that the character
encoding declaration must appear within the first 1024 bytes of the document. Why set the encoding
for the document? Failing to do so can cause security vulnerabilities. Although the encoding can also
be set in the HTTP headers, its still a good practice to declare the encoding in the document.
These subtle differences clearly confirm the WHATWGs commitment to maintaining backward compatibility while allowing changes that simplify or enhance HTML. However, not everything from the
past is preserved in HTML5. For good reason, some tags, such as those in Figure 4, have been given a
proper burial.

Chapter 1: The Past, Present, and Future of HTML5 9

Figure 4: Elements absent from HTML5


Tags such as <basefont>, <big>, <center>, <font>, <strike>, <tt>, and <u> are purely presentational
in their function and are better handled through CSS. In addition to these retired elements, a number
of attributes have been removed for similar reasons. All absent or removed items in HTML5 can be
found at www.w3.org/TR/html5-diff.

New Features in HTML5


But what about the changes that give us new features in HTML5? Lets briefly consider some of the
more popular additions that you can start using today.
First are the new elements that are in line with how the web works today. These new tags, shown in
Figure 5, are structural or semantic in nature.

Figure 5: Semantic elements in HTML5


A good number of websites today have very similar structures. Think of footers, for example: Many
sites display footers, which usually contain author information, links, and copyright information. A
typical approach to footers would look something like this:
<div id=footer>&copy; Copyright 2011 Egan &amp; Palermo</div>

10 Chapter 1: The Past, Present, and Future of HTML5


How many <div> tags would you guess there are on the web functioning as the container for footer
information? Well, the count is so high it became obvious that a tag was needed to represent this
information. In HTML5, the tag looks like this:
<footer>&copy; Copyright 2011 Egan &amp; Palermo</footer>

The main purpose of semantic elements is to provide context to the data. These tags are not about
how the content looks. Rather, they are more concerned about the substance of the content. You
modify the appearance of these elements through CSS.
The <input> tag in HTML5 supports new attribute types, shown in Figure 6.

Figure 6: New input attributes


Although not all browsers support these new attribute types, it is clear that these types will map nicely
with our modern entry forms.

Audio and Video Capabilities


Support for multimedia via the <audio> and <video> tags is another welcome addition to HTML5.
What used to require a plug-in is now accomplished with simple HTML tags. Getting started is very
easy. Observe the following markup and the screen shot in Figure 7:

Chapter 1: The Past, Present, and Future of HTML5 11

<video src=big_buck_bunny.mp4 controls>


Sorry, your browser does not support the video tag.
</video>

With just a few lines of code, you can have a video up and running with interactive controls for
your users to manage! The controls attribute can stand by itself, or you can use controls=controls
to provide the XML-friendly approach. Also, note that within the tags you can provide optional text
that will be displayed if the browser does not support the video tag. As you select your video formats,
remember that not all browsers support the same video types.
If adding video seems easy, HTML5 makes it just as easy to add audio to your site. The markup is
fairly similar:
<audio src=music.mp3 controls>
Sorry, your browser does not support the audio tag.
</audio>

Like the <video> tag, the <audio> tag contains a controls attribute for visual display to manage
volume and positioning of audio, as Figure 8 shows.

Figure 8: HTML5 audio control


Although this example features an MP3 audio file, be aware that not all browsers support the same
audio types.
A very exciting addition to HTML5 is the <canvas> tag. With this new feature, developers can add
rich graphical experiences to their web pages. Think of a canvas as you would visual art in the real
world. A painting canvas is usually a blank rectangle waiting to be drawn or painted upon. Likewise,
in your web page, a canvas is a designated section of the page that you can draw on. By using the
<canvas> tag, you eliminate the need for plug-ins that provide animations. Here is an example of how
to declare a simple <canvas> tag:

12 Chapter 1: The Past, Present, and Future of HTML5


<canvas id=myArtwork width=200 height=200>
Your browser does not support the canvas element. </canvas>

To begin your artwork, you need calls in JavaScript are needed. Using the canvas from the preceding
example,Figure 9 shows how to draw a simple blue square.
Figure 9: JavaScript for canvas
<script type=text/javascript>
var art=document.getElementById(myArtwork);
var ctx=art.getContext(2d);
ctx.fillStyle=#FF0000;
ctx.fillRect(0,0,150,75);
</script>

To what degree can the <canvas> tag enhance the user experience? You really must try it yourself
to experience the difference. However, to give you an idea, Figure 10 presents a screen shot of the
game Pirates Love Daisies. This tower-defense game is packed with action, animation, and stimulating sounds. It is so well done that you might find yourself doubting it is a pure HTML5 page.

Figure 10: Pirates Love Daisies game


Another striking demo that showcases a variety of HTML5 features, including Scalable Vector
Graphics (SVG) support, is found at director.bonjovi.com. This page, shown in Figure 11, allows a fan
to drag and drop clips onto a circular timeline, add effects, and publish a custom Bon Jovi video.

Chapter 1: The Past, Present, and Future of HTML5 13

Figure 11: Custom Bon Jovi video

Web Storage
Web storage represents another nice addition to HTML5. Web storage is a highly anticipated feature
that allows larger amounts of data to be stored locally in the browser without generating a performance hit on round trips. The primary way developers handle local storage today is through cookies.
The disadvantage of cookies is that the data is passed back and forth with every HTTP request or
response.
In HTML5, developers can use one of two options: local or session storage. The difference is that session storage expires when the browser session ends, while local storage has no time limit. This webstorage feature is available through objects in JavaScript. Here is an example of how to store a display
name in local storage:
<script type=text/javascript>
localStorage.DisplayName=Egan-Palermo;
</script>

Note that in the preceding example, DisplayName was made up on the fly. The property name can be
whatever you want it to be.

No Better Time to Be a Web Developer


What we have covered so far is just a taste of the new features in HTML5. In upcoming articles in this
series, we will demonstrate how to leverage specific features in greater depth.

14 Chapter 1: The Past, Present, and Future of HTML5


This is an exciting time to be a web developer! Whether you are developing publicly for the web or
creating internal sites for your company, HTML5 has much to offer in providing sorely needed features
that are native to the browser. With growing support among all the major browsers and with new sites
emerging that consistently use it, HTML5 is a must-visit technology for any serious web developer
today.

Chapter 2: Three of the Most Important Basic Elements in HTML5 15

Chapter 2: Three of the Most Important


Basic Elements in HTML5
New HTML5 elements--header, nav, and footer--improve consistency
of web page coding
By Michael Palermo and Daniel Egan
In Chapter 1 we discussed the evolution from HTML to HTML5 in order to provide a firm foundation for understanding HTML5 coding. Now were ready to dive into some of the most important and
useful HTML5 elements.
In the HTML5 world, much emphasis has been placed on features such as animation, the <video>
tag, and hardware acceleration. However, in our opinion, only a small percentage of developers will
be working with these high-profile elements. While the cool factor of sites like html5gallery.com is
definitely a draw for developers and designers, the more mundane but nevertheless important elements will make a much bigger impact. In this article, we will discuss some of the new elements that
are now available in HTML5, specifically <header>, <nav>, and <footer>.
Although these elements are not technically difficult to use, it is important to address why we use
them. A few years ago, I (Daniel Egan) got my first taste of HTML5 at a code camp. As the speaker
discussed elements such as <header>, <footer>, and <article>, I thought, Whats the big deal? Wont
more elements just serve to clutter up HTML even more? Why should I even care about this? What
we have learned since then is that these elements are important for a variety of reasons.

Reasons to Care about HTML5


Although these new elements are quite simple to use, their implications for the web are both subtle
and profound. For example, web developers and designers are very accustomed to the universal,
catch-all <div> elementwhich no longer exists in HTML5. The division element, as the name
implies, divides markup into appropriate sections. But in practice, the <div> element is used for everything. Therefore, it loses its effectiveness as an element itself. Even worse, the IDs used within the div
element arent consistent, as Figure 1 shows.

16 Chapter 2: Three of the Most Important Basic Elements in HTML5

Figure 1: Inconsistent IDs used in the <div> element


Although it would be nice if each and every developer used the same nomenclature, as shown in
Figure 1, we know that individuality reigns supreme. Without consistency, there is no way to have any
hooks into a web page. Hooks might include readers for the visually impaired or keystrokes that hook
into certain areas of a site or that direct the users focus onto a particular section of a page. None of
this can be done at the browser or machine level because there is no consistent naming at that level.
Thats where this very simple and sometimes overlooked portion of the HTML5 specifications come in
handy.
Although you cant count on certain sections of HTML pages to have the same name, a great majority
of developers do use consistent naming practices for particular sections. In 2004, Ian Hickson, editor
of the HTML5 specifications, did a Google search to determine the most common names used by
developers. The names used by HTML5 for the new elements include many of these commonly used
names; you can see the HTML5 and class-name mapping here.
Of course, that doesnt mean you can easily map your HTML code to the new elements; what it does
mean, however, is that developers have a certain comfort level by using these names. While this
simplicity might seem like a small detail, anyone who has ever done a redesign of a system knows
that easing the transition is a big part of making the redesign successful. Simplicity is sometimes both
overlooked and underestimated.
Now that we have discussed why we care about these elements, lets dive right into their use. If you
like digging into functional specifications, go to the W3C HTML5 spec overview page. There you will
find the definition and usage specification for each of these elements.

Chapter 2: Three of the Most Important Basic Elements in HTML5 17

Header Element
We might as well start at the head of the class: the <header> element. According to the aforementioned W3.org site, The header element represents a group of introductory or navigational aids [It]
is intended to usually contain the sections heading (an h1h6 element or an hgroup element), but this
is not required. The header element can also be used to wrap a sections table of contents, a search
form, or any relevant logos. In other words, the header element contains the stuff developers have
been putting in their <div id=header> tag for many years. Figure 2 shows an example of the header
element.
Figure 2: The HTML5 <header> element
<!doctype html >
<html lang=en>
<head>
<title>This is my sample</title>
<meta charset=utf-8/>
</head>
<body>
<header>
<a href=/><img src=HighFive.png alt=main /></a>
<hgroup>
<h1>HighFive HTML5 Training</h1>
<h2>The one stop shop for all things HTML5</h2>
</hgroup>
</header>
<footer>
</footer>
</body>
</html>

You may notice from the code in Figure 2 that the syntax that starts with <!doctype html> is quite different from what youre used to. The syntax has been simplified and no longer requires the long URL
that we have become accustomed to. Additionally, the tag is not case sensitive. For example, <!DOCTYPE html> is the same as <!DoCtyPe html>. As a matter of fact, you can even leave out the <html>,
<head>, and <body> tags because they are implied in HTML5. However, we do not recommend
leaving them out. You will also notice that the <header> section entails a logical grouping of an image
and <h1> and <h2> tags, all contained within an <hgroup> tag.

Nav Element
Developers frequently want to put menus in the header when menus are used as global resources
across the site. This leads us to the use of the next new element, <nav>. The specification for this
element states, The nav element represents a section of a page that links to other pages or to parts
within the page: a section with navigation links. Of course, this specification identifies the basic use
for the <nav> element, but as we discussed earlier, the real importance of these elements resides in
their broader application. The specification goes on to say, User agents (such as screen readers) that

18 Chapter 2: Three of the Most Important Basic Elements in HTML5


are targeted at users who can benefit from navigation information being omitted in the initial rendering, or who can benefit from navigation information being immediately available, can use this element as a way to determine what content on the page to initially skip and/or provide on request. The
code in Figure 3 shows a <nav> element.
Figure 3: The HTML5 <nav> element
<header>
<a href=/><img src=HighFive.png alt=main /></a>
<hgroup>
<h1>HighFive HTML5 Training</h1>
<h2>The one stop shop for all things HTML5</h2>
</hgroup>
<nav>
<ul>
<li>Home</li>
<li>Talks</li>
<li>Training</li>
<li>About Us</li>
</ul>
</nav>
</header>

Of course, this code would normally put hyperlinks inside the <li> elements, but well leave it as is
for simplicitys sake. The specification also helps users determine where not to use this element. For
example, simple links to terms of service or to copyright information in a footer do not typically use
the <nav> element.

The Footer Element


At first glance, you might assume that the <footer> element is meant for the bottom of your page. It
is, but its intended use is broader than that. According to the specification, The footer element represents a footer for its nearest ancestor sectioning content or sectioning root element. This means
that <footer> can go at the end of <article>, <include>, <aside>, <nav>, <section>, <blockquote>,
or <body> elements (all new elements that will need to be discussed in a later article in this series).
There are restrictions to where footer elements can be placed. For instance, you cannot put a <footer>
at the end or <nav> above because they cannot be nested inside a <header>, <footer>, or <address>
element.

Keeping It Simple
Hopefully, by now in this series, its clear why we should care about HTML5. Like most things in programming, simple constructs can have deep underpinnings. Simple elements like <header>, <nav>,
and <footer> can have deeper implications than what initially meets the eye. Understanding why
these elements were created can help us master best practices for their use. We hope you continue

Chapter 2: Three of the Most Important Basic Elements in HTML5 19


this journey with us into the dynamic world of HTML5 as we explore additional elements, their uses,
and their implications.

20 Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5

Chapter Three: HTML5 Is in Style:


Working with CSS3 and HTML5
Use HTML5 with new CSS3 features to optimize user experience on your website
By Michael Palermo and Daniel Egan
If you peer into the HTML5 specifications, youll find plenty of documentation on HTML5, the fifth
major installment of HTML. And if you nose around the latest tweets, blogs, and articles, youll discover many references to HTML5 as a platform. Among the associated technologies that are often
assumed when HTML5 is referenced is Cascading Style Sheets (CSS). In this article, well cover many
of the enhancements to the latest version of CSS (version 3) and explain how CSS3 ties into HTML5.
Obviously, most web developers today are acquainted with CSS, so our focus will remain primarily
on the popular new features in CSS3. To showcase those CSS3 features, well use a simple HTML5
document from a file named default.htm, shown in Figure 1, containing markup that highlights typical
usage scenarios found in many websites today.Figure 2 shows the final rendering of this page.
Figure 1: An HTML5 default.htm page
<!doctype html>
<html lang=en>
<head>
<meta charset=utf-8 />
<title>CSS3 Demos</title>
<link rel=stylesheet href=styles/reset.css />
<link rel=stylesheet href=styles/core.css />
<link rel=stylesheet href=styles/css3.css />
<script src=scripts/modernizr.js type=text/javascript>
</script>
</head>

Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5 21


<body>
<header>
<h1>HTML5 &amp; CSS3</h1>
</header>
<nav>
<ul>
<li class=selected><a href=#>Home</a></li>
<li><a href=#>Demos</a></li>
<li><a href=#>About</a></li>
<li><a href=#>Contact</a></li>
<li class=subscribe><a href=#>RSS</a></li>
</ul>
</nav>
<aside id=banner>
<header>
<h2>Demo Site</h2>
</header>
<p class=upsideDown>Your world, upside-down</p>
<figure class=headingPhoto>
<img src=images/devconsocial.jpg
alt=devconnections social />
<figcaption>The conversation begins here</figcaption>
</figure>
</aside>
<section id=content>
<section id=blogs>
<article class=blogPost>
<header>
h2>HTML5 is in Style!</h2>
<p>Posted by
<a href=http://www.palermo4.com>Michael Palermo</a>
<a href=http://twitter.com/palermo4/>@palermo4</a></p>
</header>
<div>
<figure id=figureAd>
<img src=images/ad.jpg alt=ad />
<figcaption>The next event!</figcaption>
</figure>
<p> The purpose of this sample web page is to showcase the features of CSS3
with HTML5. Consider the list below of the topics that will be demonstrated:
</p>
<ul>

22 Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5


<li>Table Display</li>
<li>Fonts</li>
<li>Rounded Corners</li>
<li>Color Techniques</li>
<li>Box Shadows</li>
<li>Transforms</li>
<li>Media Queries</li>
</ul>
<p> Once you start down the path of developing HTML5 with CSS3, you will not
want to develop or design for the web without it!
</p>
</div>
</article>
</section>
<aside id=sidebar>
<section>
<header>
<h3>Why HTML5?</h3>
</header>
<ul>
<li><a href=#>Less is More</a></li>
<li><a href=#>Its All Semantics</a></li>
<li><a href=#>Hear is Another Reason</a></li>
<li><a href=#>Lights, Camera, Video!</a></li>
<li><a href=#>The Web is Your Canvas</a></li>
<li><a href=#>More Storage</a></li>
<li><a href=#>Better Script</a></li>
</ul>
</section>
<section>
<header>
<h3>Your Thoughts?</h3>
</header>
<p contenteditable=true>
[replace with your feedback!]
</p>
<input type=button value=Submit />
</section>
</aside>
</section>
<footer>
<p>Copyright &copy; 2011.Please dont steal stuff, etc.</p>
</footer>
</body>
</html>

Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5 23

Figure 2: The final rendering of the default.htm page


Lets first observe HTML5s relationship with CSS. The document in Figure 1 references three CSS files:
<link rel=stylesheet href=styles/reset.css />
<link rel=stylesheet href=styles/core.css />
<link rel=stylesheet href=styles/css3.css />

The first link is to the reset.css file. Typically, web designers provide a master or reset type of CSS file
to equalize the defaults across all browsers. In this example, we are using the reset.css file made publicly available by CSS guru Eric Meyer. The next link is to core.css, which contains CSS features up to
version 2.1. The final link is to css3.css (see Figure 3). This file contains features exclusive to CSS3. By
separating CSS into multiple files, we can show how easy it is to distinguish CSS features from one
another. However, all the CSS used in this example could have easily been rolled into one complete
file as well.
Figure 3: Css3.css
@charset utf-8;
@font-face {
font-family
src
font-weight
font-style
}
h1, h2 {
font-family
}

:
:
:
:

TitleFont;
url(michroma.woff) format(woff);
bold;
normal;

: TitleFont;

24 Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5


#sidebar section {
border-radius
-webkit-border-radius
-moz-border-radius
-o-border-radius
}
#banner, #banner img {
border-radius
-webkit-border-radius
-moz-border-radius
-o-border-radius
}
#banner figcaption
{
border-radius
-webkit-border-radius
-moz-border-radius
-o-border-radius
background-color
}
#content {
display
}
#blogs, #sidebar {
display
}

:
:
:
:

11px;
11px;
11px;
11px;

:
:
:
:

22px;
22px;
22px;
22px;

:
:
:
:
:

0 0 22px 22px;
0 0 22px 22px;
0 0 22px 22px;
0 0 22px 22px;
rgba(0,0,0,0.4);

: table;
: table-cell;

#figureAd {
box-shadow
-webkit-box-shadow
-moz-box-shadow
-o-box-shadow
}

:
:
:
:

11px
11px
11px
11px

#figureAd:hover {
transform
-ms-transform
-webkit-transform
-moz-transform
-o-transform
}

:
:
:
:
:

scale(1.5)
scale(1.5)
scale(1.5)
scale(1.5)
scale(1.5)

.upsideDown:hover {
transform
-ms-transform

11px
11px
11px
11px

11px
11px
11px
11px

#777;
#777;
#777;
#777;

rotate(-10deg);
rotate(-10deg);
rotate(-10deg);
rotate(-10deg);
rotate(-10deg);

: rotate(180deg);
: rotate(180deg);

Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5 25


-webkit-transform
: rotate(180deg);
-moz-transform
: rotate(180deg);
-o-transform
: rotate(180deg);
}
@media (max-width: 1000px)
{
nav ul li a {
margin-right
: 0px;
}
#content
{
margin-top
: 50px;
margin-left
: 15px;
display
: inherit;
}
#blogs, #sidebar {
display
: inherit;
}
#banner {
display
: none;
}
}

You may have noticed the <script> tag reference to modernizr.js below the <link> tags in the default.
htm page in Figure 2. Publicly available at www.modernizr.com, the Modernizr JavaScript library lets
us design for the future using HTML5 and CSS3 without sacrificing control over experience in older
browsers. We immediately benefit from this file by simply referencing it.

Using Tables to Define Layouts


How many of us recall using <table> tags to create web page layouts? Dont worry. This old method is
not what were talking about in this section. In CSS3, we can define a table-like layout without using
<table> tags. For example, in Figure 4, look at the layout for the content portion of default.htm.

26 Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5


Figure 4: Layout for the content portion of default.htm
The old approach, using <table> tags, would probably look something like what you see in Figure 5.
Figure 5: HTML5 table layout
<!-- content element surrounds table -->
<table>
<tr>
<td><!-- blogs in first column --></td>
<td><!-- sidebar in second column --></td>
</tr>
</table>

The CSS3 way of doing things is much easier. Heres how we get a simple two-column layout in the
css3.css file:
#content
{display : table;}
#blogs, #sidebar {display : table-cell;}

The <section> tag that has an ID of content is defined visually as a table. The two child tags with
IDs of blogs and sidebar are defined in the CSS file as table-cell, causing each to render visually as a
column in the table.

Fancy Fonts Made Easy


Bringing unique fonts to web pages has always been a challenge. To introduce a nonstandard font,
developers often had to use images. In CSS3, this is no longer the case. CSS3 allows us to welcome
new fonts to our web pages by using the @font-face definition. Consider the following definition, as
found in the css3.css file:
@font-face {
font-family
src
font-weight
font-style

:
:
:
:

TitleFont;
url(michroma.woff) format(woff);
bold;
normal;

The @font-face definition first establishes what the friendly name of the font will be by using the
font-family property. In our example, we named the font TitleFont. The src property requires the
URL of the .woff file that contains the desired font. You can find custom .woff selections at sites such
as www.fontsquirrel.com. The other properties define default behaviors for weight and style.
When serving a web page that uses custom fonts, the web server must be configured to understand
the .woff extension and its MIME type. For Microsoft IIS, this can be accomplished by updating the
web.config file, as we have done in Figure 6.
Figure 6: The web.config file

Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5 27


<configuration>
<system.webServer>
<staticContent>
<mimeMap fileExtension=.woff mimeType=application/x-woff />
</staticContent>
</system.webServer>
</configuration>

The @font-face definition makes the font available only within the web page. We need to define the
location in which we want the font to be used; we do this by referring to the friendly name elsewhere
in the CSS file. In our example, this is how to use the custom font:
h1, h2 {font-family

: TitleFont;}

In this example, the custom font that has the friendly name of TitleFont will be applied to all <h1>
and <h2> tags in the HTML.

Corners, Shadows, and Colors


Although it is true that the little things sometimes matter the most, it is also true that the little feature
requests often cause the most fuss. Rounded corners, color enhancements, and box shadows are
all features that have usually required meticulous tweaking with using images and JavaScript. Once
again, CSS3 comes to our rescue.
Lets see how simple it is to apply rounded corners using CSS3. In the sidebar sections of default.htm,
lets apply a rounded corner as follows:
#sidebar section {border-radius

: 11px;}

The border-radius property defines the radius as either a unit value or a percentage value. The
example here eliminates the need to explicitly specify the radius for each corner. So thats it. Well
sort of. To support older browsers or other browsers, vendor-prefixed versions should also be applied.
Here is the example again, this time with support for Mozilla, WebKit, and Opera:

#sidebar section {
border-radius : 11px;
-webkit-border-radius : 11px;
-moz-border-radius : 11px;
-o-border-radius : 11px;

Dont let the duplication bother you too much. If the browser doesnt understand a property, that
property is ignored. And if repetition feels wrong to you, welcome to the world of multiple-browser
support.
Now lets look at an example of applying the rounded effect to just some of the corners. Here, we
want only the bottom-right and bottom-left corners to be rounded:
#banner figcaption
{

28 Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5


border-radius
-webkit-border-radius
-moz-border-radius
-o-border-radius

:
:
:
:

0
0
0
0

0
0
0
0

22px
22px
22px
22px

22px;
22px;
22px;
22px;

Shadow effects are just as easy to implement. The following example adds a shadow to the <figure>
tag that has an ID of figureAd:
#figureAd {
box-shadow :
-webkit-box-shadow :
-moz-box-shadow :
-o-box-shadow :
}

11px
11px
11px
11px

11px
11px
11px
11px

11px
11px
11px
11px

#777;
#777;
#777;
#777;

Like the border-radius property, vendor prefixes are added to support multiple browsers. The values for
the property indicate the depth of the horizontal shadow, the depth of the vertical shadow, the depth
of the blur effect, and the color of the shadow, in that order. The first two values are required. If negative values are supplied, the shadow goes in the opposite direction.
Color effects are also fairly simple to add. Consider the convention of dimming a photo when it is not
the main attraction. In the past, we had to create a duplicate of the photo and add the dimming effect
with image-editing software. With CSS3, we can define this effect without a modified version of the
original image. Here is an example of applying a dimming effect to the <figcaption> tag associated
with an <img> tag:
#banner figcaption
{
/* other definitions removed for brevity */
background-color : rgba(0,0,0,0.4);
}

The rgba value uses four arguments. The first three define red, green, and blue (RGB) intensities with
a value range of 0 through 255. The remaining value determines opacity, where 1.0 is opaque and
0 is completely transparent. Since the RGB values are all 0 in our example, the color is black, and
the remaining value indicates 40-percent opacity. The effect is a grayish see-through layer above the
image. The <figcaption> tag is absolutely positioned over the <img> in the core.css file. To cover the
entire image with this effect, simply make <figcaption> the same dimensions as the image.

Transformations
In CSS3, transformations take the user experience to the next level. Lets consider just two transformations: scale and rotate. The scale transformation causes any UI element to shrink or grow when a
user hovers over it. Suppose we want a portion of a page to pop out and rotate somewhat when we
hover over it. We can apply the scale transformation to make it grow and the rotate transformation to

Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5 29


provide a rotation effect. In the following example, we want to see the <figure> tag that has the ID of
figureAd grow by 150 percent. We also want to see this tag rotate counter-clockwise by 10 degrees:
#figureAd:hover {
transform :
-ms-transform :
-webkit-transform :
-moz-transform :
-o-transform :
}

scale(1.5)
scale(1.5)
scale(1.5)
scale(1.5)
scale(1.5)

rotate(-10deg);
rotate(-10deg);
rotate(-10deg);
rotate(-10deg);
rotate(-10deg);

The vendor prefixes are all displayed in this example. Did you notice the -ms- prefix? While CSS3
transformations are under development, each browser will continue to have its own implementation.
The first property that contains no prefix is there for future compatibility. Figure 7ashows the UI element before the user hovers the mouse over it; Figure 7bshows the element after hovering over it.

Figure 7a: UI element before hover

Figure 7b: UI element after hover

Media Queries
When using CSS, not only do we factor in the various browsersas if that wasnt enough to worry
aboutwe also have to consider various devices, such as mobile phones. With large and small screen

30 Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5


dimensions, certain features may need to be tweaked to display correctly. With CSS3 media queries,
we can alter the state of the display based on factors such as screen dimensions.
Consider the media query syntax in Figure 8.
Figure 8: Media query
@media (max-width: 1000px)
{
nav ul li a {
margin-right : 0px;
}
#content
{
margin-top : 50px;
margin-left : 15px;
display : inherit;
}
#blogs, #sidebar {
display : inherit;
}
#banner {
display : none;
}
}

If the screen width is less than 1,000 pixels, we apply new styles accordingly. In our case, we
adjusted margins in the menu, removed the table layout features so the sidebar would fit under the
content, and removed the banner from the display. Figure 9 shows the effect of the media query on
the page.

Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5 31

Figure 9: Media query impact

Continuing on the HTML5 Path

Obviously, we havent covered all the new features in CSS3, and the features we did cover can be
explored much further. We simply aimed to provide an easy place to start with HTML5 and CSS3.
Most of the new features can save you needless grunt work. With just one line of code in CSS, you
can sometimes do what used to take a lot of work and many lines of code. We are confident that
once you start down the path of creating web sites with HTML5 and CSS3, you will never go back to
anything else!

32 Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript

Chapter 4: HTML5 Form Input


Enhancements: Form Validation, CSS3,
and JavaScript
Get to know HTML5 form input features, which improve form validation and
enhance CSS3 form styling

By Michael Palermo
Can you imagine what the web would be like if it were truly read-only? What if there were no way
for a user to interact with a site by providing personal data? With no way to input data, the Internet
would be full of brochure-ware sites that could not engage in any real business exchanges. The
value of the Internet would be insignificant compared with what it is today.
So it goes without saying that a required factor for many successful websites is the ability to acquire
data from a user. And because user interaction plays such a key role in the overall web experience,
it isnt surprising that among the many improvements found in HTML5 are feature enhancements to
form input. In this article, I will introduce these new form features, exploring some of the new elements and attributes, how to apply styles, and new ways to control validation in script. Rather than try
to cover everything that is new, instead I will focus on some practical aspects of HTML5 form development that you can start using today.

Examining a Simple HTML Form


To provide some context for the new features, lets first peer into a simple HTML form that doesnt use
any of the new features, as shown in Figure 1. With some Cascading Style Sheets (CSS) styles applied,
the rendering of the simple form, shown in Figure 2, is a grouping of text boxes with a submit button.
Figure 1: Simple HTML form
<form>
<label
<input
<label
<input
<label
<input

<!-- action & method attributes supplied by developer -->


for=name>Name</label>
id=name name=name type=text />
for=email>Email</label>
id=email name=email type=text />
for=site>Site</label>
id=site name=site type=text />

Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript 33
<label for=phone>Phone</label>
<input id=phone name=phone type=text />
<input id=submit name=submit type=submit
value=Send Data />
</form>

Figure 2: Simple HTML form, rendered in a browser


The simple form is functional, but it poses some common data-collection challenges. For example,
consider the same form containing data entered by a user, as shown in Figure 3. When the user clicks
the Send Data button, will the data entered be valid according to the requirements of the web developer? In the simple HTML form, the data will be submitted as is.

Figure 3: Data entered into simple HTML form


As web developers, when we observe how users might use (or abuse) our forms, we should contemplate the following questions when developing an application:
Are all fields required?
Does the user understand what data is being requested?
Will the data entered by the user adhere to format requirements?
If the user does not complete the form accurately, what should happen?

34 Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript
A consideration of these typical scenarios will help us to appreciate the addition of the new HTML5
form input features. In the remainder of this article, I will discuss the advantages of whats new
while walking through the process of upgrading the simple HTML form one feature at a time.

New Form Elements and Attributes


HTML5 supports most of the existing form inputs and elements, as well as new features to support
data entry in the modern world. Figure 4 lists the input types supported in HTML5.

Figure 4: Input type values in HTML5


Looking over the data being requested in the simple HTML form, we can see an obvious opportunity
to explore three new input types: email, url, and tel. What would be the advantage of using these new
input types instead of text? The first advantage is semantics. Applying a more specific type than text to
form data gives parsing engines a better understanding of what the data means. The other advantages
all lie in the power of the browser, which raises a valid concern: What browsers support these new
features?
To answer the browser support question, I will first acknowledge what browsers I used to support
the examples in this article: Internet Explorer (IE) 10.0 (Platform Preview) and Google Chrome (14.0).

Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript 35
Although other modern browsers also support many of the new form features, I wanted to keep the
focus primarily on the what and how, not on the where. As browsers (and standards) continue to
evolve, we will have plenty of opportunities to learn about varying implementations.
What about browsers that do not support the new HTML5 form input features? Depending on what
new feature is being introduced, there is a different impact and possible way to manage. For example,
consider the following type-attribute changes to these input elements in the simple HTML form:
<input id=email name=email type=email />
<input id=site name=site type=url />
<input id=phone name=phone type=tel />

What will happen when a browser that does not support the new type values renders these inputs?
The browser will render these the same as type=text. In other words, the form will behave just as it
did prior to the changes.
Yet what will happen if the browser supports the new features? Using the same data input, notice how
the browser responds to the click of the Send Data button in Figure 5.

Figure 5: Invalid email format on submit


As you might suspect, the input asking for a site URL will give a similar validation message if the data
isnt entered properly (i.e., the URL must begin with http://). The input requiring a phone number,
however, still behaves like a free-text input. Because there are so many ways to represent a phone
number across the world, the initial benefit to indicating an input with a type=tel is the metadata it
provides the parsing engine. However, with the new pattern attribute, we can enforce a custom telephone format using a regular expression, as follows:
<input id=phone name=phone type=tel
pattern=\(\d\d\d\) \d\d\d\-\d\d\d\d />
The preceding pattern would require the data to be entered as:
(444) 444-4444

36 Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript
Wouldnt it be nice to inform the user what the valid format for any of the text-based inputs is? That is
the role of theplaceholderattribute. It acts as a watermark for the input, giving the user direction as to
how to enter the data. We will update the three new input types so that they all have placeholders:
<input id=email name=email type=email
placeholder=name@domain.com/>
<input id=site name=site type=url
placeholder=http://www.yoursite.com />
<input id=phone name=phone type=tel
placeholder=(###) ###-#### pattern=\(\d\d\d\) \d\d\d\-\d\d\d\d />

Figure 6 shows what the rendered form looks like after weve added the placeholder attribute.

Figure 6: Inputs displaying placeholder data


Now what about the input requesting the users name? It is still set to accept any text. However, if the
user submits the form with no text, the name will be submitted with no value. What if we require the
user to provide a name? This is the purpose of therequiredattribute. HTML5 allows it to exist in the
input element without a value, as follows:
<input id=name name=name type=text required />

However, many developers probably feel uncomfortable seeing an attribute without a value. Therefore, this is also acceptable:
<input id=name name=name type=text required=required />

And because this is the first input in the form, we can enhance the user experience by giving it immediate focus with the newautofocusattribute. Unlike therequiredattribute,autofocusshould be given
a value of true or false, as in the following updated name input:
<input id=name name=name type=text required=required
autofocus=true />

Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript 37
Now when the user pulls up the form and submits it without any data entry, the resulting impact on
the displayed form is what is shown in Figure 7.

Figure 7: Input required validation message

Adding Style to New Inputs


With new forms of validation come new states for our data. We can style our form to respond to different validation states in CSS. These are the states of data that CSS recognizes:
:valid
:invalid
:required
:optional
Microsoft has introduced another state supported in IE 10.0, known as placeholder state, which
allows CSS developers to control the style of placeholder data. Note that this is not the same as
optional state, as a required field can have placeholder data in it. The syntax for styling placeholder data is as follows:
:-ms-input-placeholder

When states are mixed with the :focus or :not(focus) qualifiers, multiple dimensions of styles emerge.
To demonstrate, look at the CSS markup in Figure 8. Required data will have a faint yellow background, valid data will be green, and invalid data will be red. When the styles are applied to the
page, the result is seen as in Figure 9.
Figure 8: CSS definitions for new HTML5 form inputs
input.data:required
{
background-color: rgba(255, 255, 0, 0.04);

38 Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript
}
input.data:not(:focus):valid
{

color: rgba(102, 172, 0, 1);


}
input.data:not(:focus):invalid
{
color: rgba(255, 0, 0, 1);
}
input.data:focus
{
border: 5px solid #ff5400;
background-color: rgba(255, 255, 255, 1);
}
/* IE10 only */
input.data:-ms-input-placeholder:valid,
input.data:-ms-input-placeholder:invalid
{
font-style: italic;
color: rgba(0, 0, 0, 0.4)
}

Figure 9: CSS styles applied

Controlling Behavior from Script


With the new form input types, the manner in which each browser handles validation rules can vary
slightly. For example, in Figure 7 notice that the message displayed by the browser (Chrome) isPlease
fill out this field.In IE 10.0, the message isThis is a required field.What if we want a consistent message across all browsers, or simply want control over the messaging itself?
To assist with more complex scenarios, modern browsers that support these new input types also
allow access to new behaviors in script. With regard to the new input types, take a look at the new
methods and attributes of the form element that can be queried from code, as shown inFigure 10.
Although the table in Figure 10 isnt a complete list of all the new HTML5 input-validation methods

Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript 35
and attributes, it represents the core validation behavior that you need to have greater control over the
process.

Returning to the issue of how browsers provide error messages, what if we wanted to create our own
messages? For example, what if we wanted the browser to displayYour full name is required!instead
of the browsers default input-validation message? The code inFigure 11provides a solution. After you
include this JavaScript module in the page, the code will hook into the validation process and allow
the developer to control the error messages, as shown in Figure 12.
Figure 11: JavaScript functions for custom validation
(function() {
// helper functions
function id(elementId) {
return document.getElementById(elementId);
}
function addEvent(src, eventName, func) {

36 Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript
src.addEventListener(eventName, func, false);
}
// custom validation
function validate(evt) {
// reset any existing messages
this.setCustomValidity();
if (!this.validity.valid) {
// if custom message exists, use it
if (this.errMessage) {
this.setCustomValidity(this.errMessage);
}
}
}
// initialize validation for input
function initValidate(src, errMessage) {
// if errMessage provided, set to input
if (errMessage) { src.errMessage = errMessage; }
addEvent(src, change, validate);
addEvent(src, invalid, validate);
}
// initialize javascipt module
function initialize() {
initValidate(id(name), Your full name is required!);
}
// wire up to loading of document
if(document.addEventListener) {
document.addEventListener(DOMContentLoaded, initialize, false);
} else {
window.attachEvent(onload,initialize);
}
})();

Figure 12: Custom validation message

Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript 37

More Options for Input


As youve seen, HTML5 offers exciting new enhancements to form inputs. With HTML5s modern
input types, additions to CSS that let you set style based on validation state, and new methods and
attributes in JavaScript for controlling behavior in code, developers and designers now have a better
approach to the task of getting data from the user.

38 Chapter 5: HTML5 Syntax and Semantics: Why They Matter

Chapter 5: HTML5 Syntax and


Semantics: Why They Matter
Use semantics to structure HTML5 source logically and make your website
parser friendly
By Michael Palermo and Daniel Egan
Many web developers new to HTML5 initially ask the question, what are the new tags or elements in
HTML5? Some of the new elements (e.g., <video>, <audio>, <canvas>) provide an immediate, beneficial effect on the user experience (UX) when they are rendered in a browser. Yet many of the new
elements, calledsemantic elementsand listed in Figure 1, have no visual impact whatsoever on UX.
What are these elements, and why should you care about them?

In Chapter 2 we introduced the concept of semantic tags by considering the <header>, <nav>, and
<footer> elements. This article extends the discussion by going into more depth about the overall
structure of an HTML5 document and the key reasons for using any of the new semantic elements.

Examining a Typical HTML Template


To demonstrate the "how and why" of semantics, let's consider how you could use HTML5 semantic
elements to upgrade the default template of an ASP.NET MVC 3 Razor website in Visual Studio 2010.
(Our example assumes that Visual Studio 2010 SP1 has been installed, as well as theWeb Standards
Update. To follow along, simply create a new website in Visual Studio 2010 and choose ASP.NET
Web Site (Razor), as shown in Figure 2. Note that although the example website in this article is based

Chapter 5: HTML5 Syntax and Semantics: Why They Matter 39


on ASP.NET, it will demonstrate aspects of semantic elements that you can apply to your own website
development.

Figure 2: Creating a new ASP.NET Razor website


The resulting files produced when creating an ASP.NET website using Razor syntax include a file
named _SiteLayout.cshtml (or .vbhtml, for a site created using Visual Basic). This file is used as a template, so that other pages can focus more on the main content of the page. Take a look at the overall
markup (minus the contents of the <body> element) of this HTML5 document, shown in Figure 3.
Figure 3: Overall markup of _SiteLayout.shtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
BEGIN CALLOUT A
<title>@Page.Title</title>
END CALLOUT A
<link href="@Href("~/Styles/Site.css")" rel="stylesheet" />
<link href="@Href("~/favicon.ico")" rel="shortcut icon"
type="image/x-icon" />
</head>
<body>
<!-- see figure 4 -->
</body>
</html>

The content in the <title> element in callout A contains the following syntax:

40 Chapter 5: HTML5 Syntax and Semantics: Why They Matter


@Page.Title

This is a placeholder for the title content, which will be provided by the requested page. We'll see an
example of this shortly.
For now, let's examine the markup between the <body> tags of _SiteLayout.cshtml, shown in Figure 4.
Callouts A and B show code changed from the default content. This is a <div>-centric document typical of websites today. However, the only way to understand the purpose of a <div> in this example
is by inference of the id attribute. Found in this file are id values such as page, header, login, main,
content, and footer.
Figure 4: Markup inside <body> tags of _SiteLayout.shtml
<div id="page">
<div id="header">
<p class="site-title">HTML5 Demo Site</p>
<div id="login">@if (WebSecurity.IsAuthenticated)
{
<p>Welcome
<a href="@Href("~/Account/ChangePassword")"
title="Change password">@WebSecurity.CurrentUserName</a>!
<a href="@Href("~/Account/Logout")">Logout</a>
</p>
} else {
<ul>
<li><a href="@Href("~/Account/Register")">Register</a></li>
<li><a href="@Href("~/Account/Login")">Login</a></li>
</ul>
}
</div>
<ul id="menu">
<li><a href="@Href("~/")">Home</a></li>
<li><a href="@Href("~/About")">About</a></li>
</ul>
</div>
<div id="main">
<div id="content">
<h1>@Page.Title</h1>
<h2>@Page.Subtitle</h2>
@RenderBody()
</div>
<div id="footer">&copy; @DateTime.Now.Year, Don't steal me</div>
</div>
</div>

Note the <div> with an id of "content" in Figure 4, which contains the following syntax:
<h1>@Page.Title</h1>

Chapter 5: HTML5 Syntax and Semantics: Why They Matter 41


<h2>@Page.Subtitle</h2>
@RenderBody()

These lines will render content from the requested page. For example, if the requested page is default.
cshtml, the contents of that file will be rendered where the @RenderBody() syntax is located. Values
for @Page.Title and @Page.Subtitle will be assigned in a code block in the requested page. So for
completeness, we will use default.cshtml as the requested file. Figure 5 shows the adjusted markup of
that file.
Figure 5: Markup of default.cshtml
@{
Layout = "~/_SiteLayout.cshtml";
Page.Title = "Semantics Demonstrated!";
Page.Subtitle = "The Secret is in the Source...";
}
<div id="logo">
<img src="http://bit.ly/html5semantics_logo"
width="133" height="64"
alt="HTML5 Powered with Semantics"
title="HTML5 Powered with Semantics" />
<span>HTML5 Semantics</span>
</div>
<p>
A list of semantic elements
</p>
<ul>
<li>article</li>
<li>aside</li>
<li>figure</li>
<li>figcaption</li>
<li>footer</li>
<li>header</li>
<li>hgroup</li>
<li>nav</li>
<li>mark</li>
<li>section</li>
<li>time</li>
</ul>
<div id="sidenote">
<h1>
<p>
What does semantic mean? A relevant definition is:
<span class="definition">to show, indicate by sign</mark>
In HTML5, the "sign" is the element.
</p>
</div>

42 Chapter 5: HTML5 Syntax and Semantics: Why They Matter


To support the modifications to the initial files of the website, the site.css file has been updated to
contain additional style rules, as Figure 6 shows. When the default.cshtml file is requested and rendered, it will appear as shown in Figure 7.
Figure 6: Style rule changes to site.css
/* all ul#menu replaced with #menu */
h2
{
padding-top: 0;
margin-top: 0;
font-size: 1.3em;
color: #5c87b2;
}
img
{
display: block;
float: next;
}
#sidenote
{
width: 330px;
border: 1px dashed #990000;
padding: 5px;
float: next;
}
#sidenote h1
{
font-size: 1.2em;
color: #990000;
}
section h1
{
font-size: 1.1em;
}
nav h1
{
display: none;
}
#logo
{
float: right;
}
.definition
{
font-style: italic;
background-color: #e8eef4;
}

Chapter 5: HTML5 Syntax and Semantics: Why They Matter 43

Figure 7: Default.cshtml rendered in a browser


At this point, none of the new semantic elements have been introduced, but the scene has been set
for showcasing how and why we will use them.
To <div> or not to <div>

As noted earlier, _SiteLayout.cshtml (see Figure 3) is structured primarily using <div> elements. And
although doing so is now commonplace (and is perfectly legal in HTML5), we have opportunities to
provide more meaning to our content by making minor modifications to the HTML source. But before
we do that, we have to ask whether or not a <div> is truly the right choice for grouping content.
What about the first <div> in our example:
<div id="page"> ... </div>

What purpose does the above <div> serve? As the only direct child element of body, it appears to be
a container for the entire page. Why is this here? The following definition in the site.css file gives the
answer:

44 Chapter 5: HTML5 Syntax and Semantics: Why They Matter


#page
{
width: 90%;
margin-left: auto;
margin-right: auto;
}

This style definition is applied to <div> to provide value to the presented page. Because the sole
purpose for this <div> is to support presentation, it does not need to be changed-nor does it have
any semantic value.
Now let's consider the next <div> (displaying what is relevant):
<div id="header">
<p class="site-title">HTML5 Demo Site</p>
...
</div>

With HTML5, semantic elements can replace the <div> and <p> tags to provide more meaning.
But wait-who really cares whether or not our data has more meaning? The answer might lie in the
rephrasing of the question:Whatreally cares whether or not our data has more meaning? How will
your page be parsed by search engines? What will the logical outline be according to the browser?
Fortunately, a number of online resources are available to help provide insight about how HTML
pages will appear in "outline" form. For our example, I will use gsnedders.html5.org/outliner. When
we feed the outliner site with the rendered source of the site with no modifications, the site should
output an outline similar to the one that Figure 8 shows.

Figure 8: Example HTML5 source outline


There are several logical problems in the resulting outline:
The site's header is ignored.
The subtitle supports the title; it should not be its own section.

Chapter 5: HTML5 Syntax and Semantics: Why They Matter 45


The "side note" of the page is given too much importance.We will solve all these problems by using
semantic elements.

Introducing Semantics
Returning to our <div id="header">, we will now change it to the following:
<header id="header">
<h1 class="site-title">HTML5 Demo Site</h1>
...
</header>

The <header> element contains content that is page- or site-wide, and usually includes navigation
(something we will visit shortly). In the example above, an <h1> tag is used inside the <header> tag
to provide the heading title. In the past, it was considered proper form for only one <h1> element to
exist in the page. That is not true for HTML5 documents. The context of its placement is what gives it
weight.
Was it necessary to keep the id and class attributes in the above changes? No. However, removing
the attributes could affect style definitions in the site.css file. To demonstrate a smooth transition, we
elected to keep all id and class values in their new semantic element homes. If you decide to remove
them in your sites, you should modify dependent CSS files accordingly.
Let's revisit the following markup in the _SiteLayout.cshtml file:
<div id="content">
<h1>@Page.Title</h1>
<h2>@Page.Subtitle</h2>
@RenderBody()
</div>

The primary "content" of this page can really be viewed as an article with a title, subtitle, and body of
information. Thus, here is how it looks with semantic markup:
<article id="content">
<hgroup>
<h1>@Page.Title</h1>
<h2>@Page.Subtitle</h2>
</hgroup>
@RenderBody()
</article>

The <div> was replaced with an <article> element. The <h1> and <h2> elements are now grouped
in an <hgroup> element, so that the <h2> tag does not introduce a new section into the outline. In
fact, if we run the page through the outliner site now, we will see the improvements shown in

46 Chapter 5: HTML5 Syntax and Semantics: Why They Matter


Figure 9. The site-level heading now appears, and the subtitle has disappeared! Notice that despite
multiple <h1> elements, there is correct indentation between the first two.

Figure 9: Example HTML5 source outline after first set of code modifications
The source of the final line in the outline is the last <div> in default.cshtml (see Figure 5). Since this
data is considered "side note" data, and is not regarded as the main content of the article, we can reengineer it to use semantics, as follows:
<aside id="sidenote">
<h1>What does semantic mean?</h1>
<p>
A relevant definition is:
<mark class="definition">to show, indicate by sign</mark>
In HTML5, the "sign" is the element.
</p>
</aside>

Once again, the <div> has been replaced-this time with the <aside> element. Although the <aside>
contains an <h1> element, it will be regarded with less importance by the search-engine parser
because of its ambient container. The <span> was replaced with a more appropriate choice, the
<mark> element. As the name implies, it represents text to be marked or highlighted. After one more
run-through with the outliner after all the code changes, we see a proper indentation of the outline,
shown in Figure 10.

Figure 10: Example HTML5 source outline after second set of code modifications

Chapter 5: HTML5 Syntax and Semantics: Why They Matter 47

More Semantics
There are other areas in the document that are easy to identify for semantic markup. For example, in
the _SiteLayout.cshtml file (see Figure 3), the final <div> on that page is for the footer. We can replace
it as follows:
<footer id="footer">
&copy;
<time datetime="@DateTime.Now.ToString("yyyy-MM-dd")">
@DateTime.Now.Year
</time>, Don't steal me...
</footer>

Note the insertion of the <time> element. It simply provides a stronger context for any date or time
provided in the HTML markup.
How about the links to other pages in the site? The following code:
<ul id="menu">
<li><a href="@Href("~/")">Home</a></li>
<li><a href="@Href("~/About")">About</a></li>
</ul>
can be changed to this:
<nav id="menu">
<h1>Site Navigation</h1>
<li><a href="@Href("~/")">Home</a></li>
<li><a href="@Href("~/About")">About</a></li>
</nav>

Because the links in this code are regarded as the primary navigation within our site, it is appropriate
to use the <nav> element in this case. But why did an <h1> tag sneak in? The <nav> element is factored in the outlining of the document. An <h1> element provides the semantic meaning, though the
site.css file prevents it from being viewed.
What about the HTML5 logo in default.cshtml (Figure 5)? It can be transformed to be semantic, as
follows:
<figure id="logo">
<img src="http://bit.ly/html5semantics_logo"
width="133" height="64"
alt="HTML5 Powered with Semantics"
title="HTML5 Powered with Semantics" />
<figcaption>HTML5 Semantics</figcaption>
</figure>

Not only was the <div> replaced with <figure>, the span was replaced with a more suitable option,
the <figcaption> element.

48 Chapter 5: HTML5 Syntax and Semantics: Why They Matter

The Final Section


The co-author of this series, Daniel Egan, and I are often asked by those new to HTML5 when to use
the <section> element. It is our opinion that this element has the potential to be the most misused or
unused of the semantic elements. In our example, our "article" is rather small. The larger an article,
the more likely it will be divided into manageable "sections" (as is the case with the article you are
reading). You can use the HTML5 Semantic Notepad tool (bit.ly/semanticnotepad) as an aid in visualizing the <section> as well as other semantic elements in an HTML5 document, as shown in Figure
11.

Figure 11: Viewing an HTML5 document's semantic elements using the HTML5 Semantic Notepad
Despite the small amount of content in the demo article, there is an appropriate use for the <section>
element in it. In the default.cshtml file, we will change the list of semantic elements to be in its own
"section," as shown in Figure 12.
Figure 12: Adding a <section> element to an HTML5 document
<section>
<h1>A list of semantic elements</h1>
<ul>

Chapter 5: HTML5 Syntax and Semantics: Why They Matter 49


<li>article</li>
<li>aside</li>
<li>figure</li>
<li>figcaption</li>
<li>footer</li>
<li>header</li>
<li>hgroup</li>
<li>nav</li>
<li>mark</li>
<li>section</li>
<li>time</li>
</ul>
</section>

Because this content can be logically grouped together, it makes sense to put it in a <section>. This is
especially the case when you have reason to provide a heading for the content. Other uses for a <section> could be to indicate sidebar content with its own heading or a grouping of links with its own
heading.
When we run our example HTML5 one last time through the outliner site, we see a rich HTML5
outline generated as a result of the correct usage of semantic elements in the document, as shown in
Figure 13.

Figure 13: Example HTML5 source outline after final set of code modifications

Make HTML Code More Meaningful


Semantic tags may not impact your users visually, but they provide meaningful data to modern parsers
and search engines-so they can potentially have significant impact on your site's search-engine
ranking and web traffic. I've shown you how, with a few adjustments, you can start using semantic
elements now in your own websites. Get accustomed to using these new elements now-you'll be glad
you did!

50 Chapter 6: Introduction to HTML5 for Mobile App Development

Chapter 6: Introduction to HTML5 for


Mobile App Development
Get your HTML5 mobile development bearings using this in-depth guide
By Wallace McClure
Download the code:

http://www.devproconnections.com/content/content/141262/141262_ExampleApp.zip
HTML5 is the umbrella term for the next major evolution of markup, JavaScript, and Cascading Style
Sheets (CSS) for web applications. HTML5 is becoming an ever-more important mobile development
technology -- especially in light of Adobe's recent announcement that it's ceasing development on
Flash Player for mobile browsers and increasing its investments in HTML5. In this article, I intend to
provide a comprehensive overview of HTML5 with an emphasis on features oriented toward mobile
development. We'll dive into some specific examples of HTML5 features and focus specifically on
what is available with mobile devices. I will focus on what developers can do today as opposed to
what is part of the specific set of standards. I'll also mention where a product may have a slightly different outcome than expected.

Markup
HTML5 introduces many new tags and attributes. In this section, we'll take a look at the ones you as
a developer will likely need to use immediately.
HTML5 page. First off, an HTML5 page is much easier to set up than a web page in earlier HTML
versions. Previous versions of HTML and XHTML had very complicated XML namespace support that
average developers were confused by and honestly didn't pay much attention to. HTML5 has a much
simpler page definition and will be simpler for developers to get started with.
Figure 1: Sample HTML5 page
<!DOCTYPE html>
<html @Page["CacheManifestFile"]>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-compatible" content="IE=edge,chrome=1" />

Chapter 6: Introduction to HTML5 for Mobile App Development 51


<title>@Page.Title</title>
<!--These styles and scripts aren't required, merely show what is available.-->
<link rel="stylesheet" href="http://code.jquery.com/mobile/1.0b1/jquery.mobile1.0b1.min.css" />
<script src="http://code.jquery.com/jquery-1.6.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0b1/jquery.mobile-1.0b1.min.js"></
script>
<script src="@Href("~")js/jquery.tmpl.min.js" ></script>
<script src="@Href("~")js/Modernizr-2.0.6.js" ></script>
<script src="http://maps.google.com/maps/api/js?sensor=true"></script>
@RenderSection("head", required: false)
</head>
<body>
<div data-role="page">
<header data-role="header" >
@RenderSection("header", required: false)
</header>
<section>
<div data-role="content">
@RenderBody()
</div>
</section>
<footer data-role="footer">
<div align="center">
@RenderSection("footer", required: false)
</div>
</footer>
</div>
</body>
</html>

Let's look at an HTML5 template, shown in Figure 1, which I created for my HTML5 samples (available for download with the online article; see the top of page for the download button). There are a
few items to note in the sample code:
The <DOCTYPE/> tag is much simpler than we formerly saw in HTML. The tag instructs the browser
to run in standards-compliant mode.
The <meta/> tag with the http-equiv attribute instructs the browser to use the most recent version
of the HTML engine in the browser. In addition, if the user has the Google Chrome Frame plug-in
installed, the Chrome Frame engine is used in Internet Explorer (IE). (See the sidebar "Author's Notes"
at the end of this article for more information about Chrome Frame.)
The code download includes a set of jQuery and jQuery Mobile CSS and JavaScript libraries.
Although use of these libraries is clearly not a strict requirement for HTML5, they will be used to hook
into the HTML5 page and provide features that will make development easier.

52 Chapter 6: Introduction to HTML5 for Mobile App Development


The <script/> tag does not have the type or language attribute. These attributes are not required for
HTML5. There is a new attribute for the <script/> tag named async. The async attribute allows for the
script to be executed asynchronously, or not.
The jquery.tmpl.min.js and Google maps files are used for their templating capabilities and are not a
requirement for HTML5.
Modernizr-2.0.6.js contains the Modernizr development library. Modernizr (modernizr.com) is a
JavaScript library that makes development much easier and simpler when testing browsers as well as
when building HTML5 apps. (See Dan Wahlin's article "HTML5 and CSS3 Feature Detection with
Modernizr" for more information about Modernizr.)
Within the <body/> tag, there are additional content sections. These include the <header/>, <section/>, <article/>, <footer/>, and other tags. These tags allow for a page to be divided into logical sections that can provide additional information to a page.
Multimedia tags. The most discussed, and controversial, feature in HTML5 is its support for video,
which is provided by the <video/> and <audio/> tags. Before these tags existed, developers had to opt
for building Rich Internet Application (RIA) type of solutions that may have included Silverlight and
Flash to get support for audio and video.
Let's look at the <audio/> tag first. The <audio/> tag offers developers a standardized way to provide
audio to web applications. The following example shows how to use the <audio/> tag:
<audio controls="controls" preload="none" title="HTML5 Audio Example">
<source src="@Href("~")Content/HTML5.mp3" type="audio/mpeg" />
</audio>

As you can see, the <source/> tag indicates that HTML5 supports the .mp3 file type. Various file types
can be specified in the <source/> tag (e.g., .ogg).
HTML5's <video/> tag provides video support. There is a major difference between audio and video
in the browser world. With audio, MP3 has widespread support among the various browsers that
developers will encounter. There's no equivalent "default" video format in the marketplace. Figure 2
shows a short example that uses the <video/> tag.
Figure 2: Using HTML5's <video/> tag
<video controls="controls" onclick="this.play();"
poster="@Href("~")images/PlayVideo.png">
<source src="@Href("~")Content/HTML5.mp4" preload="none" />
<source src="@Href("~")Content/HTML5.webm" preload="none" />
<source src="@Href("~")Content/HTML5.ogv" preload="none" />
<source src="@Href("~")Content/HTML5.m4v" preload="none" />
<source src="@Href("~")Content/HTML5264.mp4" preload="none" />
Your browser does not support html5 video. Try some flash.
</video>

Chapter 6: Introduction to HTML5 for Mobile App Development 53


Just as the <audio/> tag does for audio, the <video/> tag provides the basic infrastructure for supporting video. The biggest problem with the <video/> tag is the lack of agreement by major vendors
on which formats they support. I won't bore you with the details of this ongoing disagreement. But
as you can see in the example in Figure 2, you can specify a number of different formats via the
<source/> tag.
The biggest problem for developers will be creating the video files in the necessary formats for display
to users. And in addition to creating and specifying the file formats, developers will need to be careful
with the MIME types that are loaded and set up on the server. The installation of Microsoft IIS 7.5
that I used needed to be configured to send these files to the user, so you will most likely need to set
up these features. In my example, I set up the necessary MIME types by adding the entries shown in
Figure 3 to the web.config file. I've found two tools very helpful in creating the video in the necessary
format: Firefogg and HandBrake.
Figure 3: Adding MIME type entries to web.config
<system.webServer>
..........
<staticContent>
<mimeMap fileExtension=".mp4"
<mimeMap fileExtension=".ogv"
<mimeMap fileExtension=".web"
<mimeMap fileExtension=".m4v"
</staticContent>
</system.webServer>

mimeType="video/mp4"
mimeType="video/ogg"
mimeType="video/web"
mimeType="video/mp4"

/>
/>
/>
/>

Both the <audio/> and <video/> tags and the browsers that support them provide support for JavaScript methods and events. Some of these methods and events can be used to start playing the multimedia, pause the multimedia, handle the multimedia finishing, and initiate numerous other changes
and events.

Input tags and attributes. We've had the same set of input tags in HTML for many years. These include
<input/>, <select/>, <form/>, and others. These tags have served us well. We've learned over the past
few years that there are numerous user input scenarios that we can optimize. For example, how many
times have you used a text field to allow the user to input a phone number? You may have had to use
some logic to limit the input to numbers or another similar form. It would be nice if we had a tag that
was optimized for a phone number. HTML5 provides this along with other new input types. The following examples demonstrate how to use HTML5 input tags:
<input id="phone" name="phone" type="tel" placeholder="Phone"/>
<input id="email" name="email" type="email" placeholder="Email"
autocapitalize="off" />

For a desktop web browser, this may not be a big deal, but for a mobile user, the tel and email input
types can be a godsend. The tel type is used as a hint to the browser to open a keyboard that is optimized for phone input, like the one shown in Figure 4. This keyboard will handle primarily numeric
input. The email type will result in a keyboard being opened that is optimized for inputting an email
address.

54 Chapter 6: Introduction to HTML5 for Mobile App Development

Figure 4: Keyboard for the input type tel in the Android browser running in the emulator
I'm sure that developers are now thinking, "This is great, but what happens when I run this on IE8 or
another browser that doesn't support these new input types?" Thankfully, when a browser, such as an
old version of IE or Firefox, encounters an input type that it does not understand, the browser will display the input tag as a text field. This allows a developer to start using these new input types and still
have backward compatibility with existing browsers. Note that I've covered only a few of the input
types. HTML5 provides more input types to handle dates, numbers, and other types of input data.
In addition to new input types, numerous new attributes are available. Two new attributes worth mentioning here are placeholder and autocomplete attributes. The placeholder attribute allows for text to
be placed within a TextField class as a watermark, as shown in Figure 5.

Figure 5: Placeholders in the Android browser

Chapter 6: Introduction to HTML5 for Mobile App Development 55


The content in the watermark is not stored as input, it is merely displayed. This capability can be used
to display helpful information to the user without taking up valuable screen real estate. For example,
the downloadable code examples I've provided include a user registration sample, in which a test is
performed on the page-ready event. In this test, if the browser supports the placeholder attribute, the
textual explanations for the input fields are turned off, and instead a placeholder is used to provide
the user with information regarding the TextField while conserving on-screen space, which is at a
premium in a mobile device. The autocomplete attribute can be used to turn off the browser's autocompletion help.
Two additional attributes, though not part of the official HTML5 specification, are useful in the mobile
world with the iPhone and Android. The first, the autocorrect attribute, can be used to turn on/off
auto-correction. This can be helpful depending on how users feel about auto-correction. The second,
the autocapitalize attribute, can be handy when inputting proper names. The following example
shows how to use these attributes.
<input id="firstName" name="firstName" type="text" placeholder="First Name"
autocorrect="off" autocapitalize="on" autocomplete="off" autofocus="true" />

There are more new tags and attributes in the HTML5 specification. You can find a larger listing of the
tags here.

JavaScript
HTML5 includes a number of new JavaScript methods and JavaScript support for HTML5 tags and
features. There are a number of new methods for supporting <audio/>, <video/>, and other supported
features. Let's look at some of them.
Geolocation. Although geolocation support is not an official part of the HTML5 specification, it's hard
to overlook it. For the purposes of this article, we'll consider it a part of HTML5. With geolocation, it's
possible for a browser to request the location information from the underlying operating system. This
occurs by performing the following steps:
1. A browser check is performed to verify that the browser supports geolocation. In the example in
Figure 6, the check is performed using the Modernizr library.
2. The getCurrentPosition method is called with the three parameters. The first parameter is required,
and the second two are optional.
a. The first parameter is a callback on success. This callback will be called when the geolocation
value is determined.
b. The second parameter is a callback on error. This callback method happens when there is an
error determining the user location.
c. The third parameter is options that can be passed in. In this example, enableHighAccuracy is
turned on.

56 Chapter 6: Introduction to HTML5 for Mobile App Development


3. The web browser will ask the user if they want to provide the web app access to the user's location
information.
4. In this example, a map point of the user's location is displayed on a map.
5. In this example, the watchPosition method is used to display location updates.
6. Though not shown, the timeout and maximumAge options can be used. The timeout option is the
maximum time allowed for obtaining the location. The maximumAge option is used to determine
how many milliseconds to cache the location.
Figure 6: Using geolocation in a mobile app
//timeout and maximumAge are other options.
var PosOptions = "{ enableHighAccuracy : true }";
if (Modernizr.geolocation) {
var navgeo = navigator.geolocation;
navgeo.getCurrentPosition(WhereIsUser,
WhereIsUserError, PosOptions);
}
var MapNow;
function WhereIsUser(result) {
// personal paranoia to check for null.
if (result != null) {
var myCoords = result.coords;
//coords.altitude, coords.accuracy, coords.altitudeAccuracy,
//coords.heading, coords.speed, timestamp
//are other items that are possible.
var Lat = myCoords.latitude;
var Lon = myCoords.longitude;
var ZoomLevel = 14;
$("#MapNowDiv").show("slow");
if (MapNow == null) {
var latlng = new google.maps.LatLng(Lat, Lon);
var myOptions = {
zoom: ZoomLevel,
center: latlng,
mapTypeId: google.maps.MapTypeId.ROADMAP
};
var mapMostRecent = document.getElementById("MapNowDiv");
MapNow = new google.maps.Map(mapMostRecent, myOptions);
}
if ((Lat != null) && (Lon != null)) {
var sde = new String("I am here!");
var marker = new google.maps.Marker({

Chapter 6: Introduction to HTML5 for Mobile App Development 57


position: new google.maps.LatLng(
Lat, Lon),
map: MapNow,
title: sde.toString(),
clickable: true
});
}
}
// This is only necessary for this example.
if (Calls == null) {
Calls = navigator.geolocation.watchPosition(WhereIsUser, WhereIsUserError, PosOptions);
// Can stop watching by calling navigator.geolocation.clearWatch(Calls);
}

Figure 7 displays the results of the code in Figure 6, with a map showing the user's location.

Figure 7: Geolocation in IE9 running in Windows 7


One problem that should be mentioned is that the watchPosition method seems to have a bleed-over
of the various types of geolocation functions in the device. As a result, it is important to pay attention
to the accuracy of values that are returned. In my own experience, I have found that the iPhone is
more accurate than Android devices; however, this may be due to my specific location and not the
device OS itself. You can find more information about the Geolocation API here.
Canvas. The <canvas/> tag allows you as a developer to draw 2D shapes programmatically. With this
tag, developers can draw using JavaScript. The code example in Figure 8 draws a simple red square,
shown in Figure 9.

58 Chapter 6: Introduction to HTML5 for Mobile App Development


Figure 8: Code that draws a red square
if (Modernizr.canvas) {
var example = document.getElementById('myCanvas');
var context = example.getContext('2d');
context.fillStyle = "rgb(255,0,0)";
context.fillRect(30, 30, 50, 50);
}

You can find a complete listing of the features of the <canvas/> tag here. Also see Dan Wahlin's
articles "Using the HTML5 Canvas Tag" and "HTML5 Tutorial: Build a Chart with JavaScript and the
HTML5 Canvas."

Figure 9: A red square in the canvas tag in Internet Explorer 9

Web SQL. Storing data is a problematic issue with web applications. Web developers are familiar
with cookies, a type of persistent data storage. Over time, the need for data storage support for web
apps has grown. To solve some of these problems, the localStorage and sessionStorage attributes have
been added and accepted into web browsers. Unfortunately, these attributes don't provide the more
complex types of storage support that developers need. To address this need, the Web SQL standard
was created. Web SQL allows for more data to be stored in a relational format that many developers
are familiar with.
Unfortunately, Web SQL has run afoul of the standards process. Although the Web SQL standard
exists, it is not being enhanced further. For the desktop, this is an issue; however, Web SQL has been
supported in Android and iPhone, so it has tremendous support in the mobile environment.
Let's look at a short JavaScript example, shown in Figure 10, which demonstrates using Web SQL,
with the results of the code shown in Figure 11.

Chapter 6: Introduction to HTML5 for Mobile App Development 59


Figure 10: JavaScript to call into Web SQL
<script language="javascript" type="text/javascript">
var db;
jQuery(function ($) {
db = openDatabase('mydb', '1.0', 'Test DB', 2 * 1024 * 1024);
db.transaction(function (tx) {
tx.executeSql('DROP TABLE IF EXISTS CONF');
tx.executeSql('CREATE TABLE IF NOT EXISTS CONF (CityID unique,
tx.executeSql('INSERT INTO CONF (CityID, City) VALUES (?, ?)',
gas"]);
tx.executeSql('INSERT INTO CONF (CityID, City) VALUES (?, ?)',
ville"]);
tx.executeSql('INSERT INTO CONF (CityID, City) VALUES (?, ?)',
tx.executeSql('INSERT INTO CONF (CityID, City) VALUES (?, ?)',
tx.executeSql('INSERT INTO CONF (CityID, City) VALUES (?, ?)',
DC"]);
});
db.transaction(function (tx) {
//tx.executeSql(query, params, success, failure);
tx.executeSql('Select CityID, City from CONF', [],
function (tx, results) {
try {
var i = 0;
var rowLength = results.rows.length;
var str = "";
str += "Total Records: " + rowLength + "<br />";
str += "<table>";
for (i = 0; i < rowLength; i++) {
str += "<tr>";
str += "<td>" + results.rows.item(i).CityID + "</td>";
str += "<td>" + results.rows.item(i).City + "</td>";
}
str += "</table>";
$("#outputVal").html(str);
}
catch (e) {
alert("error: " + e.message);
}
},
function (t, e) {
// couldn't read database
alert(e.message);
});
});
});

City)');
[1, "Las Ve[2, "Knox[3, "Atlanta"]);
[4, "Houston"]);
[5, "Washington

60 Chapter 6: Introduction to HTML5 for Mobile App Development


</script>
<div id="outputVal"></div>
</div>

Figure 11: Output of the Web SQL in Google Chrome


Here are the steps that the code performs:
1. The openDatabase command is used to create a database if it doesn't already exist. Otherwise the
database is opened.
2. Various SQL commands are passed in as necessary. These commands include commands to drop
a table, create a table, and fill that table using a parameterized SQL command. In this example, the
database commands are wrapped in a transaction.
3. An SQL statement is used to query the database table.
4. The data is output into an HTML table.
Although the Web SQL standard exists, further work on it has been shelved pending changes in
the marketplace and standards process. What are developers to do regarding local data in a web
application? Work is currently going on for a standard called IndexedDB. Hopefully, this standard
will gain support in the mobile marketplace in the near future. You can find more information about
IndexedDB here.

Other HTML5 Features


Although I've covered a number of HTML5 features in this article, it is by no means a complete list.
Here are some additional features in HTML5:

Chapter 6: Introduction to HTML5 for Mobile App Development 61


Drag and drop -- With drag and drop, users can grab objects and drag them around the screen to
operate on them.
Web workers -- Developers with experience in the server and desktop world are familiar with the use
of threads to accomplish long-running operations in parallel. Web workers is effectively threading in
JavaScript for the web browser.
Cross-document messaging -- For a number of years, web developers have known that it is impossible
to make Ajax requests to domains that are not a part of the domain as well as script across windows
loaded from different domains. This is a security feature. With support for cross-document messaging,
pages can communicate with each other with basic security features enabled.
Browser history support -- Support for the forward and backward buttons in a web application with
Ajax is problematic. Various methods have been devised for this purpose; however, browser support
has been spotty. With browser support for history built in, developers will be better off. The window.
history object supports several methods worth mentioning:
pushState(state, title, url) allows for the pushing of state into the browser's history stack.
window.onpopstate is an event that will be raised when a user navigates through a page supporting
history.
history.replace, .back, .forward, and .go are methods that will allow users to navigate through the
history as needed by the application.
Microdata -- With microdata, it will be possible to add additional meaning to web applications in the
browser. Microdata will give more meaning to the content so that search engines can provide better
search results.
File access -- There are several APIs that provide access to the file system on the client computing
device.
Along with these features, there is CSS3, which space limitations prevent me from discussing here.
You can find more information about HTML5 features as well as CSS3 in the HTML5 articles by
Michael Palermo and Dan Wahlin at www.DevProConnections.com. See, for example, "HTML5 Is in
Style: Working with CSS3 and HTML5."

Further Explorations
One final note: As you develop applications that use HTML5, you may also want to make use of
frameworks. The examples here are based on the jQuery Mobile framework. I have used it to due to
the popularity of jQuery among ASP.NET developers. However, jQuery Mobile is by no means the
only framework that you can use. Some of the others are jQTouch, Sencha touch, iWebKit, Wink,
and others. I hope that you have enjoyed this introduction to HTML5 and will use this article as a
jumping-off point in your explorations of these and other HTML5-related technologies and tools.

62 [sidebar]

[sidebar]
Author's Notes
Here are a few considerations to be aware of as you're reading this article:
As a developer, I have many "interesting" things installed on my system. One of those things is the
Google Chrome Frame, which is a Google-written plug-in for Internet Explorer (IE). Google Chrome
Frame is not the Google Chrome browser for IE. Rather, it is a plug-in that brings some HTML5 features to IE 6, 7, and 8. This was on my system before I installed IE 9 -- thus, you may experience some
differences in output when you run the code samples.
There are various third-party browsers for Android. Some support the HTML5 features mentioned
in the article, some do not. For example, Firefox on Android does not support Web SQL, whereas the
built-in Android browser does. Because of these variations, I highly recommend using the Modernizr
framework to test a browser for feature support.
Because of the number of browsers and combinations, it's important to use feature detection in an
application as opposed to browser detection.
The HTML5 samples written with this article use Razor and ASP.NET Web Pages. The key pieces are
in the individual pages. (For more information on these topics, see Brian Mains' article "Using ASP.
NET Web Pages with the Razor View Engine."
The jQuery Mobile libraries used are based are the daily build of jQuery Mobile. This can result in
breakage one day and everything working properly on another day.

Chapter 7: HTML5 for the ASP.NET Developer 63

Chapter 7: HTML5 for the ASP.NET


Developer
Start taking advantage of HTML5 features to optimize websites
for desktop and mobile browsers
By Wallace McClure
HTML standards have been an important part of web development since the beginning of the web.
HTML5, the most recent version of HTML, is a work in progress. After several attempts, the World
Wide Web Consortium (W3C) formally began work on an update to the HTML specifications. (See
Chapter 1 for detail about the history of HTML5.) This work first bore fruit with the publication of
a public draft of HTML5 standards in January 2008. Hopefully, the final specifications will occur
over the next several years, but the lack of formal specifications doesn't mean that we as developers
can't take advantage of the HTML5 features that browser companies have already incorporated into
their products. Specifically, Microsoft, Mozilla, Apple, Google, and Opera have begun implementing
parts of the HTML5 specifications in their browsers. In this article, we'll take a look at some of those
specifications and discuss what we developers need to do to make our applications compliant with
HTML5.

New Features in HTML5


HTML5 is an umbrella term for the new HTML, JavaScript, and Cascading Style Sheets (CSS) features
that are being standardized. New HTML tags include the <nav> tag, which is used for general website
navigation; the <video> tag, which is used for displaying video content; and the <audio> tag, which
is used for playing audio content. In general, these tags replace the <object> tag that websites used
previously. HTML5 also includes new input controls that are designed to handle some of the more
common input scenarios, such as issues with dates and times. Finally, numerous attributes have been
added to existing controls. Many of the existing input controls have new and enhanced attributes that
allow browsers to expose users to new functionality.
Along with the new markup specifications, new JavaScript classes let programmers capitalize on the
latest features that developers have been asking for. The following paragraphs discuss some of these
features.
JavaScript selectors. There are new JavaScript selectors for getElementById and getElementByTagName. There are also selectors, such as getElementByClassName and querySelector.

64 Chapter 7: HTML5 for the ASP.NET Developer


LocalStorage. Developers have long been using cookies for local storage. However, cookies are sent
across the wire and back to the server, a transfer that increases sent data volumes. HTML5 introduces
support for a storage feature named LocalStorage. With this feature, data is no longer sent across the
wire with each server request. Also, more data can be stored with LocalStorage than with cookies.
WebSQL. Although WebSQL is no longer a part of the HTML5 standard, this feature has been implemented in several browsers, such as iPhone's Safari and the Android browser. This feature can be
tested for and used.
Threads. On a desktop application, a long-running operation can be spun off into another thread,
allowing the user to continue working without blocking the application's UI. HTML5 introduces this
concept of threads in the browser environment, a feature known as Web Workers.
Application caching. What happens when an application cannot connect to its web server? There
may be a variety of reasons, but the user only knows that the application is offline. HTML5 provides
an offline application-caching API that allows an application to degrade more gracefully when it
cannot connect to its web server.
Web sockets. When there is a long-running event on the server, the browser can be set to poll for a
completion. What happens when 100,000 users continually nag the server with the online equivalent
of "Are we there yet?" To address this issue, the HTML5 standard has web sockets. However, there are
some security issues in the underlying communications protocol that must be addressed.
Drawing. It's possible to draw in the browser by using the Canvas tag and its associated JavaScript
commands.
Geolocation. Geolocation is not a part of, but is associated with, the HTML5 specifications. Because
it is often discussed as a part of HTML5, we'll consider it that way for this article. Geolocation allows
a browser to determine its current location so that the user can be presented with local information. Geolocation allows for more accurate location information than is typically possible through IP
address lookup services.
Other features allow for drag-and-drop support, audio and video tag manipulation, server-sent events,
and other features. Some of these features will also require server support for optimal performance.

A Peek at HTML5
Let's take a peek at a simple HTML5 web page and make some key observations about the code.
Figure 1 shows some sample source code.
Figure 1: Sample HTML5 source code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-compatible" content="IE=edge,chrome=1" />
<title>About My HTML5 Site</title>

Chapter 7: HTML5 for the ASP.NET Developer 65


</head>
<body>
<div id="container">
<header >
<h1>About My HTML5 Site</h1>
</header>
<p>
This web page was built using ASP.NET. For more information, visit the
<a href="http://www.asp.net">ASP.NET homepage</a>.
</p>
<footer>
<span style="margin-left:auto;margin-right:auto;"><a href="http://www.scalabledevelopment.com">SDI</a></span>
</footer>
</div>
</body>
</html>

Notice that the doctype tag, which tells a browser which version of HTML to use, is now much simpler. In HTML5, there is only one doctype tag. The X-UA-Compatible meta tag tells the browser to
use the most recent engine available. My system has the Google Chrome frame plug-in installed, so
this information is included, as well as the instruction to use the most recent version of the Internet
Explorer (IE) engine. Finally, the page is logically divided by header, content, and footer tags. These
tags instruct a browser to separate the content visually. This instruction is particularly important for a
mobile web browser.

Browsers Galore
Currently, there is no single dominant browser. We've got IE, Firefox, Chrome, Safari, and Opera for
the desktop. Add to those the many mobile device browsers such as Safari, the Android browser, and
the mobile IE for Windows Phone 7, along with the various versions of each browser. Developers are
presented with a vast and complex array of scenarios to code for. In this vein, you may be familiar
with the following JavaScript code:
If ( navigator.useragent.indexOf(.) > -1)
{
// do something...

This code determines whether the browser is of a specific type. It then responds accordinglyfor
example, by redirecting the browser to a page optimized for that browser.
Similar functionality exists on the server. The ASP.NET developer can use the Request.Browser serverside object. Some of the properties of this object that you may find useful include the following:
Request.Browser.IsMobileDevice
Request.Browser.MobileDeviceManufacturer

66 Chapter 7: HTML5 for the ASP.NET Developer


Request.Browser.MobileDeviceModel
Request.Browser.ScreenPixels
Along with the Request.Browser server-side object, ASP.NET controls contain support for various
browsers, based on the user-agent header value. You can also use the Wireless Universal Resource
File (WURFL) project. The WURFL project contains a more current set of browser definitions that
allow a user to determine device features on the server, such as device input method, audio format
support, and other features that are not part of the built-in ASP.NET capabilities. This general technique is referred to as browser detection. While conceptually simple, browser detection tends to be
problematic. Browser detection typically results in a large number of if/else statements. This can be
confusing and difficult to change.
Feature detection is another useful HTML5 option. A browser is tested for its support of various features. If it supports a particular feature, the browser uses it; if support for the feature is not available in
the browser, the feature is not used. Although slightly different from browser detection, feature detection results in simpler code that is ultimately easier to maintain. Although browser detection was fairly
common for years, feature detection is better for creating maintainable code.
Along with feature detection, a JavaScript library named Modernizr helps developers implement reliable feature detection. The following code sample uses the Modernizr library to test for geolocation
support and then apply geolocation.
if (Modernizr.geolocation) {
var navgeo = navigator.geolocation;
navgeo.getCurrentPosition(WhereIsUser, WhereIsUserError, PosOptions);
}

Native IE9
At the MIX11 conference, Microsoft made a lot of predictable noise in support of IE because of its
"native" status. Terms like native HTML were bandied about. Add to that an early June 2011 demo
of Windows 8 with HTML and JavaScript, and there has been some understandable confusion in the
marketplace. With all these terms and ideas being tossed around, what's a developer to do? Microsoft will have its BUILD conference in September, so hopefully we'll know more then. In the mean
time, there are a few things that we do know about IE9 regarding its optimizations and hardware
acceleration.
First, we know that the JavaScript engine has been rewritten to support multiple processor cores. Specifically, a background compilation takes JavaScript and converts it into machine code that runs faster
on a given system. Secondly, the machine code that the JavaScript engine produces takes advantage
of the most recent and optimized machine commands. Finally, we know that the HTML, Scalable
Vector Graphics (SVG), CSS, audio, and video support have been reconfigured for hardware acceleration. Microsoft may have added these features to support modern hardware capabilities such as
graphics processing units (GPUs), multiple cores, and other new developments. For example, the
<canvas> tag will attain a big boost in performance when it is used in IE9. Overall, it appears that the
folks at Microsoft are promoting their browser as the best platform because there are fewer operating
system layers to go through when you use IE in a Windows environment.

Chapter 7: HTML5 for the ASP.NET Developer 67

How ASP.NET Developers Can Be Involved


If you're an ASP.NET developer, you're faced with a couple of questions when designing an ASP.NET
application to support HTML5. The first question concerns how to present an application to the user.
Currently, HTML5 browsers are more frequently found in mobile devices than in desktop browsers.
Since there is a profound difference between a four-inch mobile device and a 25-inch desktop
browser, you must understand the differences between the two. A web application designed for a
desktop browser (as shown in Figure 2) will most likely present a horrible experience to a user who
connects to the application over a mobile device (as shown in Figure 3).

Figure 2: The default ASP.NET Web Forms project as displayed in desktop IE

Figure 3: The default ASP.NET Web Forms project displayed in the Android 2.3 Emulator browser

68 Chapter 7: HTML5 for the ASP.NET Developer


Given the significant differences in device dimensions, successful sites, such as ESPN and Ruby
Tuesday design their applications for a general display size. If a user comes to a site through a desktop
browser, the user goes right on into the site. If a user comes to a site through a mobile browser, the
user is redirected to a mobile version of the application. The code to detect the type of browser and
perform the redirection can be placed within the session's Start event.
The second question concerns which ASP.NET display technology to use. Thankfully, it doesn't matter
if an application uses ASP.NET Web Forms, ASP.NET MVC, or ASP.NET Web Pages (aka Razor). All
these technologies can be used to build an HTML5 ASP.NET application. ASP.NET, MVC, and Web
Pages let you directly interact with the HTML output, so you don't need to do anything special when
using these types of projects. You only need to write valid HTML5 code for the devices you're planning to support. With a few changes of the standard features in ASP.NET Web Forms, you can use
HTML5 features quickly and easily.

Web Forms
ASP.NET Web Forms is a very popular development framework. The problem with Web Forms is that
some of its standard features create confusion. The most problematic features in HTML5 and mobile
spaces are ViewState, ClientIDs, and MasterPages. We'll walk through ways to provide users with a
more optimal solution to the problems encountered when using these features.
ViewState. ASP.NET developers are used to working with ViewState, the feature that makes Web
Forms work. However, ViewState increases the size of the web page. For example, if you bind a set of
objects to a grid, the size of the page increases dramatically. While the size of the page is not necessarily a big deal for applications that are running over a fairly reliable network, increased page size
greatly increases the risk of an error when the page is transmitted over wireless 3G and 4G networks.
To work around this issue, you have two options.
First, you can turn off ViewState unless it's needed by a specific control on a page. When you turn off
ViewState, it is minimized unless it's absolutely needed, as determined by a developer. However, a
page may still be too large because ViewState is stored on the client web page. In this scenario, ViewState can be turned off at the container, page, application, or server level. Turning it off at these levels
eliminates the ViewState payload unless it's absolutely necessary for a control.
ASP.NET 4 introduces a feature that lets you turn off ViewState at a higher level in the hierarchy, then
turn it on as necessary. Specifically, ViewState can be modified by the ViewStateMode attribute in an
ASP.NET control. In the examples in Figure 4 and Figure 5, a grid of data is displayed to the user. The
GridView doesn't require many of the more complicated features typically associated with HTML5,
so turning off ViewState has no effect on the application or the user. Note that the ViewState mode
is turned off within the Content2 container. Figure 4 shows the code for the content view. Figure 5
shows the output of the code in Figure 4.
Figure 4: Code for the content view
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"
ViewStateMode="Disabled">
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></
script>

Chapter 7: HTML5 for the ASP.NET Developer 69


View State Size: <span id="ViewStateSize"></span>
<script language="javascript" type="text/javascript">
$(document).ready(function () {
// put all your jQuery goodness in here.
var vs = document.getElementById("__VIEWSTATE");
var outPut = document.getElementById("ViewStateSize");
outPut.innerHTML = vs.value.length;
});
</script>
<asp:GridView ID="gvCustomer" runat="server">
<Columns>
<asp:TemplateField AccessibleHeaderText="Get Info" HeaderText="Get Info">
<ItemTemplate>
<asp:HyperLink ID="hl" runat="server" Text="Get Info"
NavigateUrl='<%# String.Format("CustomerInformation.aspx?CustomerID={0}", Container.DataItem) %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Content>

Figure 5: Output of code in Figure 4


The second option is to store ViewState on the server. When you use this option, the data is never
transferred across the wireless connection. This requires some setup on the pages, but once configured, this option is relatively painless. There are a number of articles about this topic on the web, so
there's not much reason to go over the details here.
ClientIDs. Automatically generated ClientIDs represent the next issue that ASP.NET developers must
negotiate. By default, the client IDs that are generated comprise a munged version of the server-side
parent containers and control IDs. For example, the grid shown in the ViewState example has the ID

70 Chapter 7: HTML5 for the ASP.NET Developer


MainContent_gvCustomer. You can use the following JavaScript command to get a client-side reference to a server-side object:
var serverObject = document.getElementById('<%: gvCustomer.ClientID%>');

Unfortunately, developers are not the only folks who work on a project. Designers are also involved,
and they may not be familiar with the functionality behind control IDs. Therefore, a new feature was
introduced in ASP.NET 4 to grant programmers complete control over the client IDs that are generated. This feature is controlled by the ClientIDMode attribute. The values of particular interest for this
attribute are Static and Predictable. The Static attribute makes sure that the client ID that is generated
remains the same as the server ID. The Predictable attribute is used in conjunction with the databound controls and the Static value to generate repeatable client IDs in a grid.
MasterPages. Although not necessarily a requirement for Web Forms developers, MasterPages is a
great tool for sharing display layout among pages. I don't recommend that you try to use the same
general layout for both a desktop web application and a mobile web application. Instead, it makes
sense to create a master page optimized for mobile devices and to continue using this design and
layout technique, although MasterPages will certainly be different because of the difference in the
layout capabilities of a mobile device and a desktop web browser.

HTML5 Validation
In the Visual Studio 2010 SP1 release, the April 2011 ASP.NET MVC 3 Tools update, and the June
2011 release of the Visual Studio Web Standards update, Microsoft not only updated its MVC tools,
but it also added support for HTML5, as illustrated in Figures 6A and 6B. Developers now get support
for HTML5, CSS3, and the JavaScript objects that support the new features. With CSS3 support, even
the IE, Mozilla, and Safari extensions are supported.

Figure 6A: HTML5 validation setting and IntelliSense support for HTML5 tags in Visual Studio 2010 SP1

Figure 6b: CSS3 and IntelliSense support in Visual Studio 2010 SP1

Chapter 7: HTML5 for the ASP.NET Developer 71

Saving Bandwidth with CDNs


Most developers are accustomed to copying files locally to a solution, then running the application
as a self-contained unit. There are a number of files that applications share, not only across a single
company but also across many applications. These are libraries such as jQuery and many of the
JavaScript libraries that are a part of the ASP.NET 4 framework. Many companies and organizations
share these libraries. Instead of using this bandwidth on your servers and routinely downloading these
files, based on caching settings, it makes sense to use the same copies that others may have already
downloaded to their systems. This means that instead of loading JavaScript files, CSS files, and others
from your web server, the user's browser downloads the files from various content delivery networks
(CDNs). Although this approach may not sound like a significant improvement, your users will typically obtain a better response time for various libraries from these CDNs. Along with shipment of ASP.
NET 4, Microsoft has provided support for its CDN within the ASP.NET ScriptManager by setting the
EnableCdn attribute to true.
To illustrate the difference between using a CDN and using content from your own local web server,
let's look at the results from a simple ASP.NET Web Form by using the Firebug and YSlow tools. Let's
look at a simple page with only the master page and the script manager installed, as shown in Figure
7.

Figure 7: Web server performance when using the CDN


Once the four standard ASP.NET JavaScript files are cached locally, 56.6KB of data is being pulled
from the local cache. This may not sound like a lot of data, but in an HTML5 mobile world, this
amount can be significant.
Now, what would have happened if we had not used the CDN? As you can see from Figure 8, YSlow
reports that the files are cached coming from our own web server.

72 Chapter 7: HTML5 for the ASP.NET Developer

Figure 8: Web server performance when using locally cached files


However, it is highly unlikely that other applications are pulling this content from our servers; at least
we hope that they aren't. By using the files from our local server, users are paying the "bandwidth tax"
instead of using the files that may already be cached locally from another application. Every little bit
of bandwidth savings helps, especially in the mobile space. A second advantage is that on publicfacing websites where bandwidth may cost money, the bandwidth cost for your website will most
likely go down by using a CDN.

ASP.NET MVC
In pages and applications based on the MVC design pattern, the presentation logic is decoupled from
the underlying application logic. If an application needs to present different views of the same data to
a desktop and a mobile client web client, it is possible to reuse the underlying models and controllers
and merely swap the views as necessary. I think this is a huge win for web developers who are using
the ASP.NET MVC framework.
With the recent MVC3 Tools update, the ASP.NET team has added the ability to use HTML5 by
default. You can do so by selecting the Use HTML5 semantic markup check box, as shown in Figure
9.

Chapter 7: HTML5 for the ASP.NET Developer 73

Figure 9: Selecting HTML5 as the default in ASP.NET MVC 3

Dive in to HTML5
I hope this introduction to making applications work with HTML5 has been helpful. HTML5 already
has a lot of support in ASP.NET and Visual Studio, and many more features and capabilities are
coming down the pipeline. I hope you are now as excited as I am about the new features that are
possible with HTML5. They're definitely making ASP.NET fun again for me, and I think you'll enjoy
them, too.

74 Chapter 8: Getting Started Using HTML5 Boilerplate

Chapter 8: Getting Started Using


HTML5 Boilerplate
Get to know a handy resource for web developers that simplifies the process of
writing HTML5-compliant web pages
By Dan Wahlin
Whether we like it or not, HTML5 is all the rage now days. With the recent news on code-name
Windows 8s upcoming support for HTML5 and JavaScript, the hype has intensified even more. Im
personally in favor of what HTML5 brings to the table, although I do worry about browser compatibility issues that will naturally crop up. Compatibility issues are something that web developers have
been dealing with since the days of Netscape 4 (layers) and Internet Explorer 4 (divs), though, so its
really nothing new; its just intensified with all the new functionality that the various HTML5 specs
define. Fortunately, several options are available that can help reduce cross-browser issues.
Getting started building HTML5-compatible sites can be challenging, especially for people who
havent been involved in web development projects for a while. Fortunately, there are a few sites
available that greatly simplify the process of getting started building HTML5 websites and offer some
excellent boilerplate code that can help both new and experienced web developers. One of the best
ones out there is called HTML5 Boilerplate, and others existsuch as initializr.com (which is based
on HTML5 Boilerplate). The creators of the HTML5 Boilerplate site (including JavaScript guru Paul Irish
from the jQuery and Google Chrome teams) define the functionality offered by HTML5 Boilerplate in
the following way:
HTML5 Boilerplate is the professional badasss base HTML/CSS/JS template for a fast, robust, and
future-proof site. After more than three years in iterative development, you get the best of the best
practices baked in: cross-browser normalization, performance optimizations, even optional features
like cross-domain Ajax and Flash. A starter apache .htaccess config file hooks you the eff up with
caching rules and preps your site to serve HTML5 video, use @font-face, and get your gzip zipple on.
Boilerplate is not a framework, nor does it prescribe any philosophy of development, its just got some
tricks to get your project off the ground quickly and right-footed.
Features offered in HTML5 Boilerplate include cross-browser compatibility (they deal with IE6, IE7,
and IE8 in a clever way); inclusion of caching and compression rules; utility classes such as .no-js and
.clearfix; .png support in IE6; Modernizr support; Google analytics support; mobile browser optimizations; IE-specific classes for maximum cross-browser control; JavaScript profiling and testing sup-

Chapter 8: Getting Started Using HTML5 Boilerplate 75


port; and CDN-hosted jQuery with a local fallback scriptplus quite a bit more. When you visit the
HTML5 Boilerplate site, youre presented with three options, as shown in Figure 1: Boilerplate Documented, Boilerplate Stripped, and Boilerplate Custom.

Figure 1: HTML5 Boilerplate options


If you select Boilerplate Documented, youll get a .zip file with the skeleton code needed to get
started building an HTML5 site, including documentation, built-in jQuery CDN support, CSS,
caching, and more. Boilerplate Stripped contains the same HTML/CSS/JS but removes comments,
and Boilerplate Custom allows you to build a custom site skeleton and control what gets added or
removed. Figure 2 shows an example of the custom options that can be selected.

Figure 2: HTML5 Boilerplate custom options

Whats in HTML5 Boilerplate?


If you select the documented or stripped options, youll get a .zip file that contains an HTML5 skeleton to help jumpstart your web development. Figure 3 shows what the site structure looks like.

Figure 3: HTML5 Boilerplate project files and folders

76 Chapter 8: Getting Started Using HTML5 Boilerplate


Looking through the folders, youll see that they contain CSS, JavaScript, and HTML files as well as
favicon.ico, crossdomain.xml for Flash and Silverlight, a 404.html page, robots.txt for search engines,
and QUnit testing functionality.

CSS Support
Two CSS files are included out of the box: the main CSS file used by the site, named style.css, and a
starter script for hand-held devices, named handheld.css. The style.css file includes several different
tips, tricks, and best practices that can be used to handle rendering HTML across multiple browsers
(including IE6). It adds in some clever features, such as hiding content from a page and ensuring the
content doesnt take up any space while still making it available to screen readers. Figure 4 shows an
example of a CSS class named visuallyhidden that performs the screen reader trick.
Figure 4: Screen reader trick employed by HTML5 Boilerplate
/* Hide only visually, but have it available for screenreaders: by Jon Neal.
www.webaim.org/techniques/css/invisiblecontent/ & j.mp/visuallyhidden */
.visuallyhidden { border: 0; clip: rect(0 0 0 0); height: 1px; margin: -1px;
overflow: hidden; padding: 0; position: absolute; width: 1px; }
/* Extends the .visuallyhidden class to allow the element to be focusable when
navigated to via the keyboard: drupal.org/node/897638 */
.visuallyhidden.focusable:active,
.visuallyhidden.focusable:focus { clip: auto; height: auto; margin: 0; overflow:
visible; position: static; width: auto; }

The style.css file also includes the popular clearfix solution that can be used to prevent margins from
collapsing on child elements when the children are floated. If youve ever written HTML and CSS
where you floated children left or right, then had to add a final child with clear:both in the style
to make things look right, youll find that this fix greatly simplifies the process since you can simply
apply the clearfix class, as the code in Figure 5 shows.
Figure 5: The clearfix used to handle floating children in HTML pages
/* The Magnificent Clearfix: Updated to prevent margin-collapsing on child elements. j.mp/bestclearfix */
.clearfix:before, .clearfix:after { content: \0020; display:
block; height: 0; overflow: hidden; }
.clearfix:after { clear: both; }
/* Fix clearfix: blueprintcss.lighthouseapp.com/projects/15318/tickets/5-extramargin-padding-bottom-of-page */
.clearfix { zoom: 1; }

Print styles are also included to simplify the process of removing backgrounds, handling links, printing
table rows, handling images, and more, as shown in Figure 6.
Figure 6: Using HTML5 Boilerplates support for printing pages
/**
* Print styles.

Chapter 8: Getting Started Using HTML5 Boilerplate 77


*
* Inlined to avoid required HTTP connection: www.phpied.com/delay-loading-yourprint-css/
*/
@media print {
* { background: transparent !important; color: black !important; textshadow: none !important; filter:none !important;
-ms-filter: none !important; }
/* Black prints faster: sanbeiji.com/archives/953 */
a, a:visited { color: #444 !important; text-decoration: underline; }
a[href]:after { content: ( attr(href) ); }
abbr[title]:after { content: ( attr(title) ); }
.ir a:after, a[href^=javascript:]:after, a[href^=#]:after {
content: ; }
/* Dont show links for images, or javascript/internal links */
pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
thead { display: table-header-group; }
/* css-discuss.incutio.com/wiki/Printing_Tables */
tr, img { page-break-inside: avoid; }
@page { margin: 0.5cm; }
p, h2, h3 { orphans: 3; widows: 3; }
h2, h3{ page-break-after: avoid; }
}

Moving into the js folder in the project, youll find jQuery, IE6 .png support, and Modernizer scripts
included in the js/libs folder. Custom scripts can go in the scripts.js file, and plug-in scripts can go
in plugins.js. Any custom libraries used in the site can go in the mylibs folder. Keep in mind that the
folders are only a recommended folder structure, and as the HTML5 Boilerplate site likes to say, all
the code is delete-key friendly, so feel free to reorganize things to fit your needs.

The index.html File


When you open the index.html file provided by HTML5 Boilerplate, youll find some interesting code
right at the top, as shown next:
<!doctype html>
<!-- paulirish.com/2008/conditional-stylesheets-vs-css-hacks-answer-neither/ -->
<!--[if lt IE 7 ]> <html class=no-js ie6 lang=en> <![endif]-->
<!--[if IE 7 ]> <html class=no-js ie7 lang=en> <![endif]-->
<!--[if IE 8 ]> <html class=no-js ie8 lang=en> <![endif]-->
<!--[if (gte IE 9)|!(IE)]><!--> <html class=no-js lang=en>
<!--<![endif]-->

First, youll note that the standard HTML5 doctype declaration is defined. I cant tell you how happy
it makes me to have this simple definition since the different XHTML doctype options were hard to
remember. Immediately under the doctype youll notice the inclusion of several conditional state-

78 Chapter 8: Getting Started Using HTML5 Boilerplate


ments to check for IE6, IE7, IE8, and IE9 along with other modern browsers. By default this code adds
a no-js CSS class name and the appropriate IE class on the root <html> element if Internet Explorer is
hitting the site. If another browser such as Chrome or Firefox is hitting the page, then only the no-js
class is added to the <html> element. The no-js class is used to handle browsers that dont support
JavaScript. For example, if you wanted to hide all <h1> elements in the page when a browser doesnt
support JavaScript, you could add the following definition into style.css:
.no-js h1 { display: none; } /* Hide h1 tags if Javascript is disabled */

At this point, you may wonder how the no-js class gets removed from the <html> element when a
browser does support JavaScript. After all, if the browser supports JavaScript, it wouldnt make much
sense to have a no-js class defined. To handle this situation, the HTML5 Boilerplate code adds a reference to the Modernizr script within the head section of index.html:
<script src=js/libs/modernizr-1.7.min.js></script>

By default, Modernizr will locate the <html> element and change no-js to js if JavaScript is supported
by the browser. Figures 7 and 8 show an example of how Modernizr modifies the <html> element;
the example in Figure 7 uses the IE9 developer tools (press F12 when viewing a site in IE9 to get to
the developer tools), and the Figure 8 example uses the Chrome developer tools (Ctrl+Shift+I).

Figure 7: Viewing the <html> element using the IE9 developer tools

Figure 8: Viewing the <html> element using the Chrome developer tools
HTML5 Boilerplates index.html page includes several other interesting features, such as the meta tags
shown in Figure 9.

Chapter 8: Getting Started Using HTML5 Boilerplate 79


Figure 9: Meta tags added by HTML5 Boilerplate that handle encoding and rendering functionality
<meta charset=utf-8>
<!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame.
Remove this if you use the .htaccess -->
<meta http-equiv=X-UA-Compatible content=IE=edge,chrome=1>

The first meta tag sets the character set to utf-8 and is a shorthand version of what was used previously in web pages:
<meta http-equiv=Content-Type content=text/html;charset=utf-8 >

At first glance, setting the character set may seem trivial and unimportant, but it can actually stop
some script attacks that rely on utf-7, so its recommended that you define it in your pages. The
second meta tag shown in Figure 9 is used to force Internet Explorer to use its most modern rendering
engine. This comes into play with IE8 and IE9 since they have compatibility modes that a user can
select in the address bar and ensures that Internet Explorer compatibility mode rendering isnt used
(even if the user selected it). Although this second meta tag doesnt pass the latest W3C validation test,
its good to have to prevent IE8/IE9 browsers from reverting back to IE7 mode due to the user enabling
compatibility mode.
Moving down further in the <head> element within index.html, youll see that Googles Content
Delivery Network (CDN) is used to load jQuery:
<script
src=//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js></script>

This provides several benefits related to caching and location. A user visiting a site that references the
Google CDN URL for jQuery will have the script cached in their browser. If they then visit your site
that references the same CDN script file, the cached version will be used, resulting in faster page load
times. Also, Googles CDN servers (note that Microsoft also provides a CDN for jQuery) are located
throughout the world, so when the jQuery script gets loaded for the first time, a server close to the
users location will normally be hit.
Having a reference to the CDN version of jQuery is nice, but its always good to have a fallback in
case the CDN is inaccessible for any reason. HTML5 Boilerplate uses a trick I like to use as well to
embed a local copy of jQuery if the CDN version cant be loaded. It does so by checking for the existence of the window.jQuery object. If the object isnt found, then the CDN script wasnt loaded successfully and a local version of the script is loaded instead:
<script>window.jQuery || document.write(<script src=js/libs/jquery-1.5.1.min.
js>\x3C/script>)</script>

Another key item added into index.html is a reference to the Google Analytics script for tracking page
hits and other details. If you have a Google Analytics account, you can update your sites ID in the
provided script:

80 Chapter 8: Getting Started Using HTML5 Boilerplate


<script>
var _gaq=[[_setAccount,UA-XXXXX-X],[_trackPageview]];
(function(d,t){var g=d.createElement(t),
s=d.getElementsByTagName(t)[0];g.async=1;
g.src=(https:==location.protocol?//ssl://www)+
.google-analytics.com/ga.js;
s.parentNode.insertBefore(g,s)}(document,script));
</script>

Testing Features
In addition to the HTML, CSS, and JavaScript features added by HTML5 Boilerplate, support for
QUnit is also included out of the box. QUnit is a JavaScript test library used to test the Query project
code but can also be used to test JavaScript code that you write. Within the project created by HTML5
Boilerplate, youll find a folder named test that contains the qunit.js and associated CSS file as well as
a sample test HTML page and test script. The test script provides a few basic examples of using QUnit
to perform assertions and test logging functionality available in the plugins.js file included with the
project (see Figure 10). A complete discussion of QUnit is outside the scope of this article, but you
can read more about it on the jQuery QUnit page.
Figure 10: QUnit test script provided by HTML5 Boilerplate
module(example tests);
test(HTML5 Boilerplate is sweet,function(){
expect(1);
equals(boilerplate.replace(boilerplate,sweet),sweet,
Yes. HTML5 Boilerplate is, in fact, sweet);
})
// these test things from plugins.js
test(Environment is good,function(){
expect(3);
ok( !!window.log, log function present);
var history = log.history && log.history.length || 0;
log(logging from the test suite.)

equals( log.history.length - history, 1, log history keeps track )


ok( !!window.Modernizr, Modernizr global is present)

})

HTML5 Jump-Start
Whether youre an experienced web developer or someone looking to get into HTML5 web
development, the code generated by the HTML5 Boilerplate site can help jump-start your projects and also serve as a good learning environment. HTML5 Boilerplate includes several tips
and tricks to handle cross-browser issues that crop up, implements proven best practices, and

Chapter 8: Getting Started Using HTML5 Boilerplate 81

ultimately simplifies the process of writing HTML5-compliant web pages. Although the code
generated by HTML5 Boilerplate only provides skeleton HTML/CSS/JS code, you can visit other
sites such as initializr.com that build on the skeleton code while supplying functional pages with
graphics and placeholders.

82 Chapter 9: Start Using HTML5 in Your Web AppsToday!

Chapter 9: Start Using HTML5


in Your Web AppsToday!
You can include HTML5 features in your web apps -- even if they run
on older browsers
By Wallace McClure
Download the code:
http://www.devproconnections.com/content/content/141812/141812_HTML5_DesktopLaptop_code.
zip
HTML5 is the direction for web-based applications. All you have to do is listen to the material from
any technical conference or keep an eye on web developer online community discussions to know
that HTML5 is important. Each day, I read about new and exciting HTML5 features and uses for those
features -- witness the many new features in the latest versions of Internet Explorer (IE), Chrome, and
Firefox.
Mobile application development is definitely where HTML5 has gotten its start, but HTML5 is not limited to mobile. Here, I will build on the information in Chapter 6 along with many other great articles
on HTML5 published in DevProConnections and delve into some of the HTML5 features that are
available today and that you can use immediately to provide solutions for your customers now. In this
article, well see what can be done in ASP.NET running in a modern web browser, such as Chrome,
Firefox, Safari, and the recently released IE10. (As an FYI, in December 2011 Chrome 15 was named
the most popular web browser version by StatCounter, though Internet Explorer is the most popular
browser family.)

Drag and Drop to Upload Files


Who isnt familiar with the concept of dragging an object from one place in a computer UI and dropping it somewhere else on screen, resulting in an action occurring? This capability has been around
for a long time in Windows, Mac, and other operating systems. Although this fact isnt widely known,
browser support for drag and drop is available for web apps. You may have seen this in Google+.
Going further, there is also the ability to upload files via a drag-and-drop visual interface. I have found

Chapter 9: Start Using HTML5 in Your Web AppsToday! 83


that drag and drop for file uploading works in the most recent versions of Chrome, Firefox, and IE10.
Unfortunately, this means that IE9 and earlier dont support the necessary APIs for file upload.
The first step in building a drag-and-drop file-upload capability into your web application is to
assemble the necessary libraries. Well use the following libraries:
Modernizr: a library that allows a program to test the browser for capabilities
jQuery: Well use jQuery for its ability to modify the document object model (DOM) in browsers.
The first step in creating the file-upload capability is to create a couple of divs that will be used for
our file upload. Figure 1 shows the HTML that accomplishes this. In this example, we have two divs.
The dropArea div will be used to accept drops. The oldUpload div will be used for browsers that
dont support the necessary APIs to allow for the user to upload files via drag and drop.
Figure 1: Creating divs for the file upload
<div id=dropArea class=dZone>
</div>
<div id=oldUpload class=dZone>
Upload files:<br />
<input type=file id=fileUp name=fileUp /><br />
<input type=submit id=fileSubmit name=fileSubmit value=Upload />
</div>

The next step is to determine whether the browser supports the necessary drag-and-drop APIs along
with the browser-based file-reading APIs. This is done by using the following code:
var supported = ((Modernizr.draganddrop) &&
(typeof (window.FileReader) != undefined));

This code uses the Modernizr library to determine whether the browser supports the necessary dragand-drop interface. If the browser in use supports drag and drop, the value true is returned. The next
step is to check the browser for file-reader support. Once we have determined whether the browser
supports drag and drop and file-reading APIs, our code will then really get going.
Figure 2 shows the sample code for determining whether the application should display the drag-anddrop file user interface or the old-style upload interface.
Figure 2: Determining the file-upload interface style
dz = $(#dropArea);
dropZone = dz[0];
dz.removeClass(error);
isdnds = IsDragAndDropFileUploadSupported();
old = $(#oldUpload);
if (isdnds) {
dz.text(startUpText);
old.hide();

84 Chapter 9: Start Using HTML5 in Your Web AppsToday!


}
else {
dz.hide();
}

In this code, we need to get references to the dropArea div and the oldUpload div area. If the browser
supports drag and drop as well as the FileReader APIs, the oldUpload div area is hidden. If the
browser does not support drag and drop and the FileReader APIs, the dropArea div is hidden. Figure 3
shows how the upload interface will appear, depending on browser type.

Figure 3: File-upload interface for older and newer browsers

Drag and Drop


HMTL5s drag and drop is a powerful API for enabling users to copy, move, and delete items with
just a few mouse clicks. Drag and drop provides a set of events that a developers JavaScript code can
monitor and respond to. These events are set up:
drag: an event that is fired during the drag operation
dragend: an event that is fired when a drag operation is finished; this event typically occurs when
the mouse button is released or the Esc key is pressed
dragenter: an event that occurs when the mouse is moved over an element while a drag is currently
underway
dragleave: occurs when the mouse is moved over an element while a drag is currently underway
dragover: occurs when the mouse is moved over an element while a drag is currently underway
dragstart: an event that is fired when a user begins dragging an object
drop: an event that occurs when the dragged elements are dropped/released onto an element that
accepts data
Your next question might be, What types of elements can accept drag/drop events? Elements that can
accept these drag-and-drop events include editable controls and content areas, such as the <div/> tag.
Figure 4: Setting up drag-and-drop events
// Alter text and add a drag effect
dropZone.ondragover = function () {
if (isdnds) {

Chapter 9: Start Using HTML5 in Your Web AppsToday! 85


dz.addClass(hover);
dz.text(Drop files here to watch the processing start.);
}
return false;
};
// Update the text
dropZone.ondragleave = function () {
if (isdnds) {
dz.text(Drop files here to begin processing.);
}
}
// Remove the drag effect when stopping our drag
dropZone.ondragend = function () {
if (isdnds) {
dz.removeClass(hover);
dz.text(startUpText);
old.show();
}
return false;
};
// The drop event handles file upload.
dropZone.ondrop = function (event) {
// Stop the browser from opening the file in the window
event.preventDefault();
if (isdnds) {
dz.removeClass(hover);
// Get the file and the file reader
iFiles = event.dataTransfer.files.length;
files = event.dataTransfer.files;
var i = 0;
var strOut = ;
for (i = 0; i < iFiles; i++) {
// Validate file size
if (files[i].size > @MaxFileSize) {
strOut += File name: + files[i].name +
is too large to upload. File size: + files[i].size + . ;
}
}
if (strOut != ) {
dz.text(strOut);
dz.addClass(error);
return false;
}
fileUploadMethod(0);
}
};

86 Chapter 9: Start Using HTML5 in Your Web AppsToday!


The next step is to set up the events for dragging and dropping files into a web browser, as shown in
the code in Figure 4. These events are set up:
dragover: used to instruct the user what to do when the mouse is positioned over the dropArea
dragleave: used to provide additional instructions to the user when the mouse leaves the dropArea
but is still in drag mode
drop: When the drop event occurs within the dropArea, this is where the fun begins; this event is
called when the drop event occurs within the dropArea
The first line of the ondrop event method in Figure 4 is to call the .preventDefault(). This method will
stop the browser from opening the file(s), which is the default action. We dont want the code to open
the files, merely to send the files to the browser.
The next step is to note that we can upload multiple files with one drag. Because of this, the event.
dataTransfer.files object is actually an array of file objects in what is called a FileList. When we get
the files, we need to verify that the files are not too big to upload. As such, we can loop through the
files and get information about these files -- for example, their size. Well test the file size against the
maximum size allowed for uploading files on the web server. If any file is too large, we wont perform
an upload; otherwise well start the upload in the method fileUploadMethod, shown in Figure 5.
Figure 5: Initiating the upload via fileUploadMethod
function fileUploadMethod(fileToUpload) {
try {
var file = files[fileToUpload];
// Send the file
var xhr = new XMLHttpRequest();
xhr.upload.addEventListener(progress, uploadProgress, false);
xhr.onreadystatechange = stateChange;
xhr.open(POST, @Href(~)UploadHandler.ashx, true);
xhr.setRequestHeader(X-FILE-NAME, file.name);
xhr.send(file);
}
catch (exc) {
alert(exception: + exc);
}
}
// Show the upload progress
function uploadProgress(event) {
var percent = parseInt(((event.loaded / event.total) * ( 1 / iFiles) +
( currentFile / iFiles) )* 100);
dz.text(Uploading: + percent + %);
}
// Show upload complete or upload failed depending on result

Chapter 9: Start Using HTML5 in Your Web AppsToday! 87


function stateChange(event) {
if (event.target.readyState == 4) {
if (event.target.status == 200 || event.target.status == 304) {
if ( currentFile == (iFiles - 1) ) {
dz.text(Upload Completed! Upload some more files.);
}
else{
currentFile++;
fileUploadMethod(currentFile);
}
}
else {
dropZone.text(Upload Failed!);
dropZone.addClass(error);
}
}
}

Remember when we got the array of files to be uploaded? The file array was saved off in a page-level
object. Our code will pass in a reference to the first element in the array (the zeroth element). The
code will then get it and manually create an XMLHttpRequest object. If you have peeked ahead in
this article, you may be wondering why this is sent whe
n the server-side code to accept the upload looks for the files ContentType. The reason is that the
ContentType does not always come through. For example, the current version of the Chrome browser
and the preliminary developer version of IE10 dont seem to expose the ContentType, whereas Firefox
seems to send the ContentType. Sending the filename enables the server side to also see that we have
some data that we can pull out regarding the filename -- more specifically, the file extension.

Server-Side Code
Finally, lets look at the server code for uploading files, shown in Figure 6. Files in the upload process
need to be saved to a location on the server. In this case, well get a directory to save the files via the
Server.MapPath method. The next step is to create a unique filename, which we do with a GUID, and
then get a file extension. We can always use the filename that is uploaded in the header. The content
type is also available.
Figure 6: Server-side code for uploading files
public void ProcessRequest (HttpContext context) {
// Save Files
var localDir = context.Server.MapPath(~/files);
var contentType = context.Request.ContentType;
string fileExtension = String.Empty;
if (!String.IsNullOrEmpty(contentType))
{
fileExtension = context.Request.ContentType.Split(/.ToCharArray())[1];
}

88 Chapter 9: Start Using HTML5 in Your Web AppsToday!


else
{
var rhFileName = context.Request.Headers[X-FILE-NAME];
var sArray = rhFileName.Split(..ToCharArray());
if (sArray.Length > 0)
{
fileExtension = sArray[sArray.Length - 1];
}
}
var saveTo = Path.ChangeExtension(Path.Combine(localDir, System.Guid.NewGuid().
ToString()), fileExtension) ;
FileStream writeStream = new FileStream(saveTo, FileMode.Create, FileAccess.
Write);
ReadWriteStream(context.Request.InputStream, writeStream);
context.Response.Write({ \Success\: true });
}
private void ReadWriteStream(Stream readStream, Stream writeStream)
{
int Length = 256;
Byte[] buffer = new Byte[Length];
int bytesRead = readStream.Read(buffer, 0, Length);
while (bytesRead > 0)
{
writeStream.Write(buffer, 0, bytesRead);
bytesRead = readStream.Read(buffer, 0, Length);
}
readStream.Close);
writeStream.Close();

Security
If youre focused particularly on security, you might have looked at the preceding code examples with
horror and thought, Oh my, you mean a browser can read files on my system and magically upload
them to a web server? This is horrible, and we never want to enable or turn on any HTML5 stuff
ever. Or maybe you are running through the halls of your office screaming this in terror. To address
security concerns, the World Wide Web Consortium (W3C) working draft for drag and drop includes
the following information about implementing security in the browser:
Data is not added to the DataTransfer object until the drop event occurs. This keeps data from
being made available during the other events.
A drop is only successful if a drop event is caused by the user. If a script attempts to implement a
drop event, the browser is not supposed to fire the drop event.

Chapter 9: Start Using HTML5 in Your Web AppsToday! 89


Scripts should not be able to start drag-and-drop actions.
Thankfully, this area is the responsibility of the browser, not the JavaScript developer.

File Reading
The DataTransfer object is part of the drag-and-drop specification. The DataTransfer object contains
the files that have been selected. The files are made available to us through the FileReader window
interface, which is a part of the File API W3C Working Draft. In our file-upload code, we are using
the .size and .name properties of the files, which are fairly self-explanatory. Some of the other properties that are available are type, mozSlice, mozFullPath, fileSize, webkitRelativePath, fileName, and
webkitSlice. The properties that have the moz prefix are available on Firefox. The properties that
have the webkit prefix are available on Chrome. I expect that other browser vendors have created
their own properties as well.

Along Came Polyfills (and Modernizr and Script


Loaders)
There is an unfortunate downside to HTML5 and all its new and cool features. This downside is that
not every web browser supports it! For each of the latest HTML5-compliant copies of IE10, Firefox,
Chrome, Safari, mobile Safari on iOS, mobile Android browser, and others that I have crammed onto
my systems, there are hundreds of my clients end users who run IE7 or IE8 and access my applications that have been running since 2003 or earlier (yes, I have a web app that has been running for
more than eight years). The problem is, then, how can the application that I am authoring provide all
these new and cool HTML5 features to users that have HTML5-capable web browsers while at the
same time not alienating those who are using your applications over older browsers like IE7 running
on Windows XP? Into this gap steps the polyfill.
Strictly speaking, a polyfill is a piece of software, or shim, that offers some fallback mechanism to
provide support that is not natively available. Typically, the term polyfill is used with JavaScript. For
example, a geolocation polyfill could be used to provide HTML5 standard geolocation for an older
BlackBerry device that doesnt provide the native HTML5 geolocation support.
Now, I am sure that your next question is, How does my program know that the browser supports an
HTML5 feature? Youre probably thinking that you will need to check the browser along with its version and then code an application along those lines. This is referred to as browser detection . Weve
all probably done this in our development lives and understand what a nightmare this is from a support standpoint. We would rather be able to test to determine whether a browser supports a given
feature, referred to as feature detection. If the browser supports the feature, then the native feature will
be used. If the browser does not support a given feature natively, a polyfill can be used to provide the
feature.
Thankfully, this detection problem has been solved. Its solved for us within many JavaScript libraries
-- jQuery, for example, so we dont need to worry about things there. So how can we integrate feature
detection into our code?

90 Chapter 9: Start Using HTML5 in Your Web AppsToday!


Thankfully, there is Modernizr. Modernizr is a JavaScript library that detects the features available
natively in web browsers. These features can be based on HTML5 or Cascading Style Sheets level 3
(CSS3). Modernizr goes through the detection of features in the loaded browser. It does this for us by:
creating a JavaScript object named Modernizr. This JavaScript object allows custom code to determine the features that are natively supported within the browser based on a set of properties that
return Booleans.
adding classes to the HTML element that allows code to determine the features that are natively
supported.
providing a script loader. This script loader can be used to load polyfills, so that older browsers can
be supported as necessary.
Here are some of the ways that we can use Modernizr:
Modernizer can be used to test for input types. Modernizr can be used to test the functionality of a
browser by doing something like this:
if (!Modernizr.inputtypes.date) {
}

You can test the browser on your own and load browser support as necessary. Ive seen developers
do things like this:
<script> !window.google && document.write(<script src=gears_init.js><\/
script>);</script>

You can use Modernizr and a script loader named yepnope to load some JavaScript files. In this
situation, our code will perform a test to see whether the browser supports HTML5 geolocation, as
shown in Figure 7. If it does, the yep.js file is loaded. If the browser does not support HTML5 geolcoation, the nope.js file is loaded. Once the files are loaded, the complete event fires and the defined
function is called, which will output the results to a div on the page. Figure 8 shows the output in IE.
Figure 7: yepnope test for HTML5 geolocation support
yepnope([{
test: Modernizr.geolocation,
yep: [js/yep.js],
nope: [js/nope.js],
complete: function () {
output(document.getElementById(outputDiv));
}
}]);

Chapter 9: Start Using HTML5 in Your Web AppsToday! 91

Figure 8: Output of yepnope geolocation test


There is a polyfill for nearly every HTML5 feature. You can find a list of polyfills provided by the Modernizr folks on Github (see the HTML5 Resources sidebar at the end of this article for the link and a
list of other helpful information sources).
A few words of warning with polyfills:
Dont try to use too many of them. If a user comes to your application using IE6 and you need
to load eight polyfills to make your application work properly, the user might find the added delay
caused by the polyfills loading to be unacceptable.
Be aware that a polyfill doesnt magically add functionality. In this situation, it can be used to make
existing functionality HTML5 compliant. For example, IE8 and older BlackBerry browsers dont support HTML5 geolocation. IE8 can be made to support geolocation via Google Gears. Older BlackBerry browsers do support geolocation, but not the HTML5-defined APIs. There are polyfills available
that can help with this.

Input Types
Over the years, many mechanisms have been created to provide date and time support. Applications may use third-party Web Forms controls, jQuery UI plug-ins, or another type of third-party support. Theres nothing wrong with this approach, but its always good to make application developers
lives easier so that we can provide higher-value support to our customers. As more browsers support
HTML5 input types, developers and users will have access to this functionality. For example, we
would like some easy way to get the following:
<input type=datetime id=dateStart name=dateStart />

In HTML5 for the ASP.NET Developer, I mentioned that there are some new input types in HTML5,
including support for various date and time inputs. How many web applications have you built that
use time and dates in some form? I cant think of any app that I have built that doesnt use date or
time. Opera was the first web browser to support the date and time HTML5 input types, and now
iOSs mobile Safari has this support as well. ASP.NET MVC developers have immediate support for
HTML5 because these developers are responsible for building the user interface. But what about ASP.
NET Web Forms developers? HTML5 support will be built into .NET Framework 4.5, but it is not
available currently for a production setting. What can developers do now?
Thankfully, there is a solution that Web Forms developers can use now to enable date and time support in their web apps. To do so, Web Forms developers can use the following server-side code:
<asp:TextBox ID=dateText type=date runat=server />

92 Chapter 9: Start Using HTML5 in Your Web AppsToday!


In this code sample, the type of the asp:TextBox is set to date. If the browser doesnt support that
input type, the browser will display the input element as an input type of text. In cases where the
browser does not support the date input type, you can use the following JavaScript code to provide
date support:
$(document).ready(function () {
if (!Modernizr.inputtypes.datetime) {
$(#<%:dateText.ClientID %>).datepicker();
}
});

Note that this code requires jQuery and jQuery UI, so you have to add in the necessary scripts to use
it, as shown in Figure 9.
Figure 9: Calling jQuery and jQuery UI scripts to display a calendar in a Web Forms app
<link rel=stylesheet href=http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/themes/base/jquery-ui.css type=text/css media=all />
<link rel=stylesheet href=http://static.jquery.com/ui/css/demo-docs-theme/
ui.theme.css type=text/css media=all />
<script type=text/javascript src=http://code.jquery.com/jquery-1.6.4.min.
js></script>
<script src=https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.
min.js type=text/javascript></script>

Figure 10 shows the results of using the datetime input type to display a calendar in iOS 5 (left) and
IE9 (right). And there you have it: Web Forms developers can start using some of these new HTML
input types now and not have to wait for .NET 4.5.

Figure 10: Using HTML5s datetime input type to display a calendar in iOS 5 and in IE9 using
jQuery

Chapter 9: Start Using HTML5 in Your Web AppsToday! 93

Debugging
The combination of Visual Studio and Internet Explorer results in a great experience for developers,
but how can developers debug in Firefox and Chrome? After all, Visual Studio hooks directly into IE
but doesnt seem to have the same support for other browsers. Thankfully, there are solutions to this.
Firefox has Firebug (a Firefox plug-in), which provides JavaScript debugging as one of its features.
Chrome has some debugging tools built into it as well. Figures 11 and 12 show examples of debugging using the Chrome and Firefox tools.

Figure 11: Debugger in Chrome

Figure 12: Debugger in Firefox


If you are within a browser that doesnt have support for debugging, you can turn to a very old-fashioned mechanism for interrogating objects that I learned a few years ago:

94 Chapter 9: Start Using HTML5 in Your Web AppsToday!


for(m in object)
{
// do something with m, perhaps some
// oldstyle js debugging with an alert(...);
}

Though its exceedingly simple, this code will allow you to determine the properties of an object. This
is helpful when you are running in a browser for which you dont have an available debugger.

Tools for Modern Web-App Development


From this article, youve learned various methods that you can use to add HTML5 capabilities to your
existing web applications for the desktop and laptop. Weve looked at file uploading, script loading,
what polyfills are, Modernizr, and a few other items. For your customers, the future is now in terms
of the capabilities they want for their users. Fortunately, regardless of whether youre developing Web
Forms apps for a mix of newer and older browsers or are building apps for the latest web technologies, you have plenty of options for adding into your apps some of the modern features that end users
expect.

Chapter 10: Ease HTML5 Web Development with jQuery, Knockout, and Modernizr Libraries 95

Chapter 10: Ease HTML5 Web


Development with jQuery, Knockout,
and Modernizr Libraries
Utilize development frameworks and libraries to solve common HTML5 web
development problems

By Richard Campbell
HTML5 has opened the door to a significant number of new features and capabilities in the browser.
Unfortunately, those capabilities vary from version to version, and developers must consider browsers
that arent HTML5 compatible. Its really too much for one developer to handle, and being productive
in the todays web development world means using frameworks and libraries. So which development
frameworks and libraries should you use? The most ubiquitous library for web development, at least in
the Microsoft space, is the jQuery library. Today, jQuery has evolved into the jQuery Core and jQuery
UI versions. In jQuery Core, key JavaScript techniques, such as traversing a web documents objects,
handling events, and even directly coding AJAX, are simplified with this library. Microsoft has also
contributed to the jQuery library and includes the library with many of its latest web technologies.
jQuery UI is useful for handling effects and widgets for the browsers UI. Built on top of jQuery Core,
jQuery UI works with CSS to create theme frameworks for a consistent UI across all of your pages, as
well as handling animations, shading, and other more advanced effects.
But the most important aspect of jQuery is that it works equally well across all major browsers, even
Internet Explorer (IE). And thats the hard part of todays web developmentthere are so many different browsers (with new versions are released every few months) and trying to keep up with the
changing capabilities of todays browsers will make you crazy. Utilizing jQuery for document traversal
means that you dont have to deal with the changes caused by future browser versions. Instead, you
can download the latest version of jQuery and deploy it with your application.
Knockout is a JavaScript library that plays a similar role to jQuery, but for declarative data binding.
Clean-coded data access in web pages is a constant challenge and using a framework can greatly
simplify the process, as well as dealing with future changes. And, similar to jQuery, Knockout handles
all the different browsers that developers care about.
Although jQuery and Knockout take advantage of HTML5, these libraries arent specifically focused
on HTML5, and todays web developers want to exploit the latest and greatest in HTML5. But what

96 Chapter10:EaseHTML5WebDevelopmentwithjQuery,Knockout,andModernizrLibraries
do you do about users with an older browser? This is where libraries such as Modernizr and CSS PIE
come in.
Modernizr uses a technique called polyfills that lets you write code that exploits new HTML5 features,
such as Location classes. The code degrades gracefully with older browsers that dont have HTML5
functionalities. CSS PIE helps level the playing field of CSS implementation across different versions of
IE. You can code for IE 9 and let CSS PIE deal with the older versions of IE.
There are many more libraries out there to help you be productive in this complex world of web
development; these four libraries that Ive described are only a few. Its well worth your time to look
for help rather than solve all web development problems yourself.

Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App 97

Chapter 11: Build a jQuery


HTML5 Web Application:
The Account at a Glance App
Build the Account at a Glance app using cutting-edge web dev technologies:
jQuery, HTML5, and more

By Dan Wahlin
As web technologies continue to evolve, developers have to learn new technologies so that they can
build successful web-based applications that stand above the crowd. This can be a challenging proposition, especially for developers moving from desktop or Rich Internet Application (RIA) development
frameworks. To help developers learn the latest HTML5, Cascading Style Sheets Level 3 (CSS3), and
JavaScript technologies, several developer colleagues and I built a sample application for demonstration at Microsofts MIX 11 conference. The application, called Account at a Glance, takes advantage
of key web technologies and uses them to display brokerage account information to consumers. (See
the end of this article for the code-download URL.)
The application was built in Q1 2011 by Dan Wahlin (client-side and server-side coding); Corey
Schuman; Jarod Ferguson (client-side coding); and John Papa (Entity Framework Code First coding).
John Papa, Giorgio Sardo, and Scott Guthrie also provided feedback and offered several key suggestions and ideas that were incorporated into the application. Figure 1a shows the Account at a Glance
application as it was first conceived on a whiteboard, and Figure 1b shows how it ended up after the
project was completed.

Figure 1A: The Account at a Glance application as originally conceived

98 Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App

Figure 1B: The Account at a Glance application screenfinal version


We built the Account at a Glance application to demonstrate how cutting-edge web technologies can
be used together to build a dynamic application capable of displaying account information, video
news, quotes and charts, market news, and more without the use of plug-ins. The app loads data
dynamically, using AJAX technologies, into tiles that are displayed within the application. As tiles are
dragged and dropped to different locations in the interface, data is re-rendered, depending upon the
size of the tile that is targeted, as shown in Figures 2a and 2b (small, medium, and large tile sizes
exist). This allows data to be displayed in several different ways and provides a means for customers to
customize how account information is displayed by moving tiles around.

Figure 2A: Dragging a tile to a different area of the screen

Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App 99

Figure 2B: Automatic resizing of tiles on screen, via jQuery templates

The Account at a Glance application uses these technologies:


HTML5 features
Modernizr: www.modernizr.com/
HTML5 Boilerplate: html5boilerplate.com, tinyurl.com/5v22eo9
jQuery along with several jQuery plug-ins: jquery.com
jQuery Templates: http://api.jquery.com/category/plugins/templates
Canvas: tinyurl.com/66kbj2n
Scalable Vector Graphics (SVG): www.w3.org/TR/SVG
CSS3: www.w3.org/TR/CSS/#css3
JavaScript Object Notation (JSON) and AJAX technologies
ASP.NET MVC 3: www.asp.net/mvc
ADO.NET Entity Framework 4.1 Code First: tinyurl.com/6g2dlef
Repository Pattern for data access: tinyurl.com/43xzpet
Unity IoC container: unity.codeplex.com
SQL Server 2008: tinyurl.com/2bev6tk
NuGet: nuget.org

100 Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App
This article provides an overview of the Account at a Glance application. Part 2 will provide details
about the client-side technologies used, including HTML5 features such as jQuery templates, SVG,
Canvas, and video.

The Account at a Glance Solution


The Account at a Glance application is comprised of a single solution with two projects. The first
project is named AccountAtAGlance and uses the ASP.NET MVC 3 project template. The second
project is named AccountAtAGlance.Model and is a Class Library project. Figure 3 shows the solution
and project structure.

Figure 3: The Account at a Glance solution


The AccountAtAGlance project follows the standard ASP.NET MVC 3 folder structure. The Controllers folder contains the controller classes used in the application; the views are located in the Views
folder. The Account at a Glance application relies heavily on client-side technologies such as jQuery,
and the scripts used in the application can be found in the Scripts folder. Several jQuery plug-ins
were used to create the application: jQuery UI, Flot (Canvas rendering), Raphael (SVG rendering),
and DataTables. JSON data is exchanged between the client browser and server using ASP.NET MVC

Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App 101
actions and rendered using jQuery Templates that are dynamically loaded from the server. CSS is used
heavily throughout the application. The .css files are located in the Content folder.
The AccountAtAGlance.Model project contains the applications data-access functionality. The project
contains the Code First classes that define the structure of model classes used throughout the application and also a DbContext class named AccountAtAGlance.cs. The Repository folder contains dataaccess classes that perform Create, Read, Update, and Delete (CRUD) operations on behalf of the
application. LINQ technologies are used in the application to simplify the data-access code and provide filtering and sorting functionality. The application makes RESTful service calls to ASP.NET MVC 3
actions that expose data and objects defined in the AccountAtAGlance.Model project. It also calls out
to a Google financial service to retrieve stock quotes and simulates random market index quotes on a
timed basis.
The next sections provide details on the data-access technologies and web framework used in the
application.

Code First and the Repository Pattern


When we started building the Account at a Glance application, we used Entity Framework 4.0s
Model First option. However, Entity Framework Code First was about to be released, so we converted
to that technology in the middle of the project (thanks to Scott Guthrie for the suggestion to go with
Code First and John Papa for doing the conversion from Model First). If youre new to Code First,
Entity Framework 4.1 provides a Code First approach that shifts the focus to working with Plain Old
CLR Objects (POCO), which keeps your data model classes nice and clean. To use Code First, install
NuGet, then go to View, Other Windows, Package Manager Console and type the following command at the prompt, as shown in Figure 4:
Install-Package EntityFramework

Figure 4: Using the NuGet Package Manager Console to install Entity Framework 4.1 and Code First
POCOs are used to define entities used in the application. Figure 5 shows an example of the BrokerageAccount POCO class, which defines several different properties as well as three navigation
properties.

102 Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App

Figure 5: The BrokerageAccount class


namespace AccountAtAGlance.Model
{
public class BrokerageAccount
{
public BrokerageAccount()
{
Positions = new HashSet<Position>();
Orders = new HashSet<Order>();
}
// Primitive properties
public int Id { get; set; }
public string AccountNumber { get; set; }
public string AccountTitle { get; set; }
public decimal Total { get; set; }
public decimal MarginBalance { get; set; }
public bool IsRetirement { get; set; }
public int CustomerId { get; set; }
public decimal CashTotal { get; set; }
public decimal PositionsTotal { get; set; }
public int WatchListId { get; set; }
// Navigation properties
public ICollection<Position> Positions { get; set; }
public ICollection<Order> Orders { get; set; }
public WatchList WatchList { get; set; }
}

}POCO classes defined in the application are used to automatically generate the database that the
application uses. A class named AccountAtAGlance that derives from DbContext is used to query the
database, as shown in Figure 6. This class is located in the AccountAtAGlance.Model projects Repository folder.
Figure 6: The AccountAtAGlance class, which is used to query the database
using System.Data.Entity;
namespace AccountAtAGlance.Model.Repository
{
public class AccountAtAGlance : DbContext
{
public AccountAtAGlance() : base(name=AccountAtAGlance) { }
public DbSet<BrokerageAccount> BrokerageAccounts { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<Exchange> Exchanges { get; set; }

Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App 103
public
public
public
public
public
public
public
public

DbSet<MarketIndex> MarketIndexes { get; set; }


DbSet<Order> Orders { get; set; }
DbSet<OrderType> OrderTypes { get; set; }
DbSet<Position> Positions { get; set; }
DbSet<Security> Securities { get; set; }
DbSet<MutualFund> MutualFunds { get; set; }
DbSet<Stock> Stocks { get; set; }
DbSet<WatchList> WatchLists { get; set; }

public int DeleteAccounts()


{
//return base.Database.SqlCommand(DeleteAccounts);
return base.Database.ExecuteSqlCommand(DeleteAccounts);
}
public int DeleteSecuritiesAndExchanges()
{
return base.Database.
ExecuteSqlCommand(DeleteSecuritiesAndExchanges);
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// base.OnModelCreating(modelBuilder);
// inherited table types
// Map these class names to the table names in the DB
modelBuilder.Entity<Security>().ToTable(Securities);
modelBuilder.Entity<Stock>().ToTable(Securities_Stock);
modelBuilder.Entity<MutualFund>().ToTable(Securities_MutualFund);
// Many to many resolver
// Map the WatchList and Securities navigation property using
// the WatchListSecurity Many-to-Many table.
// To avoid a Cycle condition, WatchList has Securities,
// but Security does not have WatchLists.
modelBuilder.Entity<WatchList>().HasMany(w =>
w.Securities).WithMany()
.Map(map => map.ToTable(WatchListSecurity)
.MapRightKey(SecurityId)
.MapLeftKey(WatchListId));
}
}
}

The AccountAtAGlance class relies on the new fluent API to map some POCO classes to database
tables, such as mapping Security to Securities and Stock to Securities_Stock. This is accomplished by
overriding the OnModelCreating() method and defining the necessary mappings.

104 Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App
Classes that follow the Repository Pattern are located in the Repository folder of the AccountAtAGlance.Model project. Several different classes are provided to handle various query functionality.
Figure 7 shows a section of the AccountRepository class that handles querying customer account
information. It uses the AccountAtAGlance DbContext class to perform the query.
Figure 7: The AccountRepository class, which uses DbContext to query the database for customer
account information
namespace AccountAtAGlance.Model.Repository
{
public class AccountRepository : RepositoryBase<AccountAtAGlance>,
IAccountRepository
{
public Customer GetCustomer(string custId)
{
using (var context = DataContext)
{
return context.Customers
.Include(BrokerageAccounts)
.Where(c => c.CustomerCode == custId).SingleOrDefault();
}
}
}

JSON and MVC Actions


Im a big fan of ASP.NET MVC because it provides complete control over the HTML returned from
the server, provides a solid architecture and well-defined conventions, and allows JSON objects to be
returned from the server easily with minimal code (to name just a few of MVCs great features). Most
of the Account at a Glance applications functionality occurs on the client side with JavaScript, but the
application still needs to get data from the server. We initially planned on using Windows Communication Foundation (WCF) REST features to serve up JSON, but because we were using ASP.NET MVC
as the application framework, we decided to use controller actions instead.
Using controller actions provides a simple way to return custom JSON objects back to the client
where they can be manipulated using jQuery templates. jQuery APIs such as getJSON() are used to
call the ASP.NET MVC actions. (Ill provide additional details in the next article.) Figure 8 shows an
example of actions that return account details and security quotes.
Figure 8: Serializing CLR objects into JSON using the Json() method available in controller classes
public ActionResult GetAccount(string acctNumber)
{
return Json(_AccountRepository.GetAccount(acctNumber),
JsonRequestBehavior.AllowGet);
}
public ActionResult GetQuote(string symbol)

Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App 105
{
return Json(_SecurityRepository.GetSecurity(symbol),
JsonRequestBehavior.AllowGet);
}

Each action calls into the appropriate repository class, which handles retrieval of data from the
database. Once the data is retrieved and mapped to model objects, the objects are serialized to
JSON using the built-in Json() method in ASP.NET MVC controllers and passed back to the client for
processing.

An Integrated Approach
The Account at a Glance application provides a robust example of how different technologies can
integrate together from server side to client side. In this first article youve seen how the application
solution is structured and the different technologies that were used on the server side, including Entity
Framework Code First and ASP.NET MVC. In the next article Ill provide more details about the clientside coding and scripts that were used, including patterns that the team used to structure JavaScript
code. Until then, you can download the application code at the URL below if youd like to explore it
in more detail.

Download the Account at a Glance application at dl.dropbox.com/u/6037348/AccountAtAGlance.zip.

106 Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding

Chapter 12:
How to Build a jQuery HTML5 Web
Application with Client-Side Coding
Walk through client-side coding for the Account at a Glance App
By Dan Wahlin
As I discussed in Chapter 9, its important for web developers to get comfortable working with the
latest technologies, such as HTML5, Cascading Style Sheets Level 3 (CSS3), and JavaScript, so that
they can build leading-edge business applications. The Account at a Glance application, introduced
in last months article, demonstrates the use of a number of modern web development technologies.
In part 1, I talked about the back-end technologies used to build the Account at a Glance app: Entity
Framework 4.1 Code First and ASP.NET MVC 3. I also covered the data-access techniques used to
query the database, such as the Repository Pattern, as well as how C# model objects were converted
into JavaScript Object Notation (JSON) using ASP.NET MVC. In this article, the second and final
article in the series, Ill focus on the client-side aspect of the application and demonstrate a few of the
key HTML5, JavaScript, and jQuery features that it offers.
As a quick recap, the Account at a Glance application started as a simple whiteboard idea, shown in
Figure 1 (this was my good friend John Papas office whiteboard at Microsoft). John, Corey Schuman,
Jarod Ferguson, and I then took the whiteboard concept and created the final application, shown in
Figure 2. The application relies on multiple technologies, such as Entity Framework, ASP.NET MVC,
JSON, Ajax, jQuery, JavaScript patterns, HTML5 semantic tags, canvas, Scalable Vector Graphics
(SVG), video, and more.

Figure 1: The initial application concept on the whiteboard

Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding 107

Client-Side Object Framework


Account at a Glance has a client-side layout framework that is responsible for animating tiles, performing drag-and-drop operations, and changing scenes. The application initially loads with a cloudview scene, then dynamically changes to the scene shown in Figure 2. Figure 3 shows the key files
used in the client-side framework.

Figure 2: The Account at a Glance application screen

Figure 3: Client-side objects used in the Account at a Glance application


Heres how the different scripts are used from start to finish:
1. The scene.startup.js script is loaded by the main page.
2. Scene.statemanager.js loads all the information about the tiles from scene.layoutservice.js. This
includes knowing how to render tiles in cloud view and tile view. Each tile has two scenes
defined, which control where the tile is positioned in the page.

108 Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding
3. Scene.statemanager.js also handles calling into a DataService object located in scene.dataservice.js,
which is responsible for accessing JSON data on the server using jQuerys Ajax functionality.
4. Once JSON data is available, scene.tile.binder.js handles the downloading of each tiles HTML template and binds the JSON to the template using jQuery Templates functionality.
5. Once the tiles have data, scene.tile.renderer.js handles rendering of the tiles in the page based
upon the target size (each tile has three different potential sizes).
6. Finally, tiles that need special formatting (such as canvas or SVG rendering) call into scene.tile.formatter.js, which performs custom functionality for different tiles.
The scene.layoutservice.js file contains a JSON array that defines all the tiles shown earlier in Figure
2. The tiles unique ID, layout scenes, and formatter (used for custom functionality) are defined in the
file. Figure 4 shows an example of a single tiles definition.
Figure 4: Defining tiles in the scene.layoutservice.js file
{ name: Account Details,
tileId: AccountDetails,
formatter: TileFormatter.formatAccountDetails,
scenes: [
( height: s1Mh, width: s1Mw, top: 0, left: 0, opacity: 1, size: 1,
borderColor: #5E1B6B, z: 0 },
height: 90, width: 210, top: 80, left: 250, size: 0,
borderColor: #5E1B6B, z: 2000, opacity: .5 }
]
}

The tile data in scene.layoutservice.js is processed by scene.statemanager.js, which handles iterating


through the JSON array to process each tile and generate a div container for it. Once thats done, a
call is made to a DataService object to retrieve JSON data from the server; this data is then fed into
a renderTile() function. Figure 5 shows a few key functions from scene.statemanager.js. (Note that
this sample has been minimized because of space constraints -- you can find the complete file in the
sample code download for more details. See the Downloading the App section of this article for the
code-download URL.)
Figure 5: Starting the data-retrieval and tile-rendering process
renderTiles = function(acctNumber) {
DataService.getMarketIndexes(renderMarketTiles);
}
renderMarketTiles = function(json) {
renderTile(json, $(#DOW), 0);
renderTile(json, $(#NASDAQ), 0);
renderTile(json, $(#SP500), 0);
}

Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding 109
renderTile = function(json, tile, fadeInAmount) {
TileBinder.bind(tile, json, TileRenderer.render);
}

Looking through the code in Figure 5, you can see that it calls a TileBinder object (located in scene.
tile.binder.js). Figure 6 shows the scene.tile.binder.js script that is used to convert JSON data retrieved
from the server to HTML using jQuery templates. The TileBinder object (as well as others within the
Account at a Glance application) follows the JavaScript Revealing Module Pattern detailed here.
Figure 6: Scene.tile.binder.js, which uses jQuery templates to bind JSON data to HTML templates
//Handles loading jQuery templates dynamically from server
//and rendering them based upon tile data
var TileBinder = function () {
var templateBase = /Templates/,
bind = function (tileDiv, json, renderer) {
var tileName = tileDiv.attr(id);
$.get(templateBase + tileName + .html, function (templates) {
$(body).append(templates);
var acctTemplates = [
tmpl(tileName, Small, json),
tmpl(tileName, Medium, json),
tmpl(tileName, Large, json)
];
tileDiv.data().templates = acctTemplates;
tileDiv.data().json = json;
renderer(tileDiv);
});
},
tmpl = function (tileName, size, json) {
var template = $(# + tileName + Template_ + size);
if (json != null)
return template.tmpl(json);
else
return template.html();
};
return {
bind: bind
};
} ();

110 Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding
The bind() function shown in Figure 6 receives the tile that must be rendered, the JSON data used to
render it, and a renderer object that handles placing rendered HTML into the appropriate container in
the page displayed to the user. The bind() function uses the jQuery get() function to call the server and
retrieve the small, medium, and large templates for a given tile.
The different template sizes for a tile are defined in a single file that lives within the AccountAtAGlance projects Templates folder. Figure 7 shows an example of templates used to render the S&P
500 tiles. The ${ token } token syntax found in each of the templates defines the JSON properties that
should be bound once each template is rendered. See my blog post Reducing Code by Using jQuery
Templates for more details about jQuery templates.
Figure 7: HTML templates used along with jQuery template functionality to render the S&P 500 tiles
<script id=SP500Template_Small type=text/x-jquery-tmpl>
<div class=content>
<header>
<div class=Left>S&P 500</div>
<div class=MarketQuoteLast Right>${ SP500.Last }</div>
</header>
<section>
<div class=MarketQuoteDetails>
{{tmpl #SP500QuoteDetails_Template }}
</div>
</section>
</div>
</script>
<script id=SP500Template_Medium type=text/x-jquery-tmpl>
<div class=content>
<header>
<div class=Left>S&P 500</div>
<div class=MarketQuoteLast Right>${ SP500.Last }</div>
</header>
<section>
<div class=MarketQuoteDetails>
{{tmpl #SP500QuoteDetails_Template }}
</div>
<div id=SP500Canvas class=canvas></div>
</section>
</div>
</script>
<script id=SP500Template_Large type=text/x-jquery-tmpl>
<div class=content>
<header>
<div class=Left>S&P 500</div>
<div class=MarketQuoteLast Right>${ SP500.Last }</div>

Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding 111
</header>
<section>
<div class=MarketQuoteDetails>
{{tmpl #SP500QuoteDetails_Template }}
</div>
<div id=SP500Canvas class=canvas></div>
</section>
</div>
</script>
<script id=SP500QuoteDetails_Template type=text/x-jquery-tmpl>
<span class=MarketQuoteChange>{{if parseFloat(SP500.Change) > 0}}+{{/if}}
${ SP500.Change }
</span>&nbsp;&nbsp;
<span class=MarketQuotePercentChange>${ SP500.PercentChange }%</span>
</script>

The tile templates rely on HTML5 semantic elements such as header and section to define containers
for content. Each tile uses these elements in a similar manner.
The ID of the tile defined in the scene.layoutservice.js file (see Figure 4) determines which template
file to download -- convention is used for this functionality. Once the template for a given tile is
downloaded, it is added into the body of the page using the jQuery append() function. Then each
tile size is rendered by calling the tmpl function, shown in Figure 6. As the different tile sizes are rendered, theyre stored along with the JSON data in the tile by using the jQuery data() function.
The final step in the process is to call the tile renderer passed into the bind() function (see Figure 6) to
load the appropriate tile size into the page. Figure 8 shows the renderer object (called TileRenderer)
that is responsible for adding HTML content into the page for display to the user.
Figure 8: The scene.tile.renderer.js file defining a TileRenderer object
var TileRenderer = function () {
var render = function (tileDiv, sceneId) {
if (sceneId == null) {
sceneId = 0;
}
var size = tileDiv.data().scenes[sceneId].size,
template = tileDiv.data().templates[size],
formatterFunc = tileDiv.data().formatter;
tileDiv.html(template);
if (formatterFunc != null) {
formatterFunc(tileDiv);
}
};
return {
render: render
};
} ();

112 Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding

Working with Canvas and SVG


HTML5-enabled browsers such as Internet Explorer 9 and Chrome provide canvas and SVG support that are used to generate charts used in the Account at a Glance application. The canvas tag can
be used to render shapes, text, and graphics using a pixel-based approach. The application uses the
canvas tag to render stock-quote charts. SVG relies on a variety of tags to render vector graphics and
is used to generate a pie chart for account positions within the application. Generating charts and
graphs can be an involved process, so the Account at a Glance application relies on two jQuery plugins to simplify the process. The scene.tile.formatter.js script (available in the code download file) contains the code to handle rendering canvas and SVG charts.
A jQuery plug-in named Flot (code.google.com/p/flot/) is used to render stock-quote charts in the
application. It provides a significant boost to development productivity and can result in charts being
created in only a few hours (including learning the programming interface -- you can find an example
of building a simple canvas chart at tinyurl.com/cqsxyzb). Figure 9 shows an example of the charts in
action within the Quote tile, and Figure 10 shows the code used to render the chart.

Figure 9: The Quote tile, which uses the canvas tag to render a stock quote chart
Figure 10: Using the Flot jQuery plug-in to render a canvas chart
renderCanvas = function(canvasDiv, width, height, color, itemJson, dataPointsJson) {
if (dataPointsJson != null && dataPointsJson.length > 0) {
var quoteData = [];
for (var i in dataPointsJson) {
var dp = dataPointsJson[i];
quoteData.push([dp.JSTicks, dp.Value]);
}
var maxY = itemJson.Last + (itemJson.Last * .3);
var chartOptions = {
series: {
lines: { show: true, fill: true },
points: { show: true, radius: 5 }
},

Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding 113
grid: { hoverable: true, autoHighlight: true },
legend: { position: se },
yaxis: { max: maxY, min: 0 },
xaxis: { minTickSize: [1, hour], mode: time, timeformat: %h %P,
twelveHourClock: true }
};
canvasDiv.attr(style, width: + width + px;height: + height + px;);
//Required....css() doesnt work properly for this
$.plot(canvasDiv, [{
color: color,
shadowSize: 4,
label: Simulated Data,
data: quoteData
}], chartOptions);
canvasDiv.bind(plothover, function(event, pos, item) {
if (item) {
if (previousPoint != item.datapoint) {
previousPoint = item.datapoint;
$(#CanvasTooltip).remove();
//var x = item.datapoint[0].toFixed(2),
var y = item.datapoint[1].toFixed(2);
showTooltip(item.pageX, item.pageY, y);
}
}
else {
$(#CanvasTooltip).remove();
previousPoint = null;
}
});
}
}

Figure 11 shows the SVG chart displayed in the Account Details tile that is used to display security
positions within the account.

Figure 11: The SVG positions pie chart displayed in the Account Details tile

114 Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding
Its generated using a jQuery plug-in named Raphael along with a specific Raphael plug-in used to
handle pie charts (Raphael-pie.js in the project). Figure 12 shows the code that handles rendering the
positions pie chart.
Figure 12: The Raphael jQuery plug-in, which is used to render an SVG chart
formatAccountDetails = function(tileDiv) {
tileDiv.find(.Currency).formatCurrency();
var scene = tileDiv.data().scenes[0];
if (Modernizr.inlinesvg) {
if ($(#AccountPositionsSVG).length > 0) {
var values = [];
var labels = [];
$(tileDiv.data().json.Positions).each(function() {
labels.push(this.Security.Symbol + \r\n + this.Shares + shares);
values.push(this.Shares);
});
raphael(AccountPositionsSVG, 500, 420).pieChart(scene.width / 2, scene.height
/ 4 + 10, 66, values, labels, #fff);
}
}
}

Integrating Video
Video is an important part of many web-based applications and is used in the Account at a Glance
application to display video news, as shown in Figure 13.

Figure 13: Displaying video using the HTML5 <video> element


The Video News tile relies on the new HTML5 video element available in modern browsers to display
a market news video. The following code demonstrates using the video element:

Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding 115
<video id=VideoPlayer controls
preload=auto poster=/content/images/video-poster.jpg>
<source type=video/mp4 src=.../031411hubpmmarkets_320k.mp4 />
</video>

Downloading the App


Download the Account at a Glance application. Perform the following steps to run the application:
1. Extract the application files from the .zip archive. Youll need Visual Studio 2010 with SP1 and a
SQL Server 2008 database.
2. Locate the AccountsAtAGlance.exe file in the root folder and run it (youll need a SQL Server 2008
database). This will create a database named AccountsAtAGlance.
3. Locate the web.config file in the AccountAtAGlance project and update the connection string to
point to the AccountsAtAGlance database you created in step 2.

Jump In to Modern Web Development


If youre looking to see how multiple server-side and client-side technologies can be used together, the
Account at a Glance application provides a nice starting point. In this article, youve seen the clientside features provided by the application and learned how different HTML5 technologies can work
together with jQuery and other JavaScript frameworks. This information, along with the part 1 article,
can help you become more confident in working with the latest technologies to build modern business apps for the web.
Dan Wahlin, a Microsoft Regional Director and MVP, founded The Wahlin Group (www.TheWahlinGroup.com), which specializes in .NET, Silverlight, HTML5, jQuery, and SharePoint consulting and
training solutions. He blogs at weblogs.asp.net/dwahlin.

116 Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development

Chapter 13:
Explore the New World
of JavaScript-Focused Client-Side
Web Development
Learn about the scripts and tools that can help you
write JavaScript client-side apps
By Dan Wahlin
It was fairly easy to figure out client-side web development 10 years ago. If an application needed
to run consistently across browsers, HTML was dynamically generated on the server and sent to the
browser for rendering. Some of the more modern applications integrated Ajax and JavaScript into the
mix, but many apps worked with little or no JavaScript at all. Although I personally enjoyed working
with JavaScript back then, it wasnt exactly the most popular language on the planet, and many developers avoided JavaScript entirely because of a variety of issues associated with it.
In situations in which web-based applications required rich client-side functionality, Adobe Flash
was used because it provided animation, media services, and a host of other features that HTML,
Cascading Style Sheets (CSS), and JavaScript couldnt offer. Around 5 years later, Silverlight began its
rapid evolution as a client-side rich Internet application (RIA) development option. The world of RIAs
looked extremely bright. Then the RIApocalypse occurred, and things seemed to change in the blink
of an eye.
RIA frameworks such as Flash and Silverlight are certainly still viable for building different types of
applications and offer some functionality that isnt quite ready yet in HTML5 or JavaScript. However,
over the past 2 years, technology has quickly moved in a different direction for applications that need
to reach a broad audience. As a consequence of the large increase in the number mobile devices in
use, more powerful CPUs, more memory, and easier access to wireless data (and lets not forget the
iPad and Apples general view toward plug-ins), a major shift has occurred that has ushered in the rise
of HTML5 and JavaScript.
Some developers like the shift; some developers hate it. Regardless of which side of the fence youre
on, the shift has happened, and it has definitely had an effect on the way applications are built. My
intent here is to help you negotiate the shift by providing an overview of the current state of clientside development and some popular scripts and tools that will help you build robust client-centric
web applications.

Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development 117

Rise of the Script: Pros and Cons


JavaScript has taken center stage in web development, in response to the trend of moving to the
client application functionality previously run on the server. This client-side approach provides several benefits, including fewer page postbacks, less data passed over the network, and a better overall
client experience when done correctly. In many cases, the role of the web server has morphed from
primarily serving HTML content to more of a focus on serving JavaScript Object Notation (JSON) data
that gets processed in the browser using JavaScript. This can have a positive effect on both traditional
browser applications and mobile applications because less data is sent over the wire.
Client-side web application development isnt all roses, though. Developers used to writing server-side
code need to learn JavaScript and other client-side technologies and deal with cross-browser issues
that can make even the best developers pull their hair out. The way that code is tested in client-side
development also changes somewhat, although unit tests can be run against JavaScript using frameworks such as QUnit, Jasmine, or others. Security must also be factored into the mix as more and
more functionality moves to the client and applications call back to the server to retrieve and validate
data. In addition to these considerations, its also important to take into account cross-browser issues,
given the number of browsers available.
As applications move toward incorporating HTML5, its also natural that more and more JavaScript
code will be written. After all, HTML5 technologies such as geolocation, canvas, web storage, web
sockets, and others rely heavily on JavaScript. As a result, careful planning must go into a project to
ensure that JavaScript code is structured in a way that promotes reuse, testability, and simplified maintenance. Randomly scattering functions (I call it function spaghetti code) across one or more script
files and pages is no longer an option as the amount of JavaScript code included in an application
increases. Its more important than ever for developers to study different patterns and techniques that
can be used to structure code.
Even with these various challenges, the world of client-side web development is consistently
improving. Although some developers choose to write all their scripts by hand, many script libraries
are available that can simplify some of the client-side development challenges. Lets now examine
some of those scripts and how theyre being used for client-side development.

Client-Side Script Libraries and Responsive Design


The reigning king of script libraries is jQuery, which has been around since 2006. According to
builtwith.com, jQuery is used in nearly 58 percent of the top 10,000 sites. More than 24 million sites
are using jQuery, and that number continues to grow. If you arent already using jQuery, should you
take the time to learn it? The simple answer is yes, but in reality the answer depends on the functionality that your application needs.
jQuery provides a cross-browser way to locate Document Object Model (DOM) nodes, handle
events, perform animations, make Ajax calls, and do much more using a minimal amount of code
(see the articles listed in the Learning Path for more information about jQuery and other client-side
web development topics discussed in this article). No sane developer wants to worry about browser
incompatibilities, and jQuery significantly eases the cross-browser headache. For example, rather than
writing custom code to check what type of XmlHttpRequest object a browser supports before making

118 Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development
an Ajax call, you can write code similar to the following to make the call and let jQuery handle the
rest:
$.getJSON(/DataService/GetCustomer, { id: custID }, function(data) {
//process data returned from the controller action
});

jQuerys core strength lies in its ability to easily select DOM elements using a small amount of code.
For example, to find all li elements in divs that have a panel class on them, you can use the following
jQuery selector:
var liTags = $(div.panel li);

After one or more nodes are found, you also attach events in a cross-browser manner using shortcut
functions, as shown next. (You could also use bind(), on(), or other similar functions.)
liTags.click(function() {
var li = $(this); //grab clicked item
//do something!
});

This technique significantly minimizes the amount of code required to locate DOM nodes, the text or
HTML within the nodes, or even attributes. It can also be used to animate elements, add or remove
nodes, and do much more. Also available are script libraries based on jQuery, such as jQuery UI
and jQuery Mobile. jQuery UI provides a set of widgets and effects that can be used to render dialog
boxes and pop-up calendars, add drag-and-drop and autocomplete functionality, and add other capabilities. jQuery Mobile is a relatively new script library that provides a simple yet robust way to build
mobile-enabled websites that work well on many types of mobile devices.
When you include jQuery and jQuery Mobile scripts in a page, HTML5 data attributes can be used
to define one or more mobile pages that resize dynamically to different device sizes. Figure 1 shows
an example of using jQuery Mobiles data-role attribute to define multiple mobile pages. As the div
elements in Figure 1 are processed by jQuery Mobile, theyre automatically converted into pages that
can be navigated to by the user.
Figure 1: Data attributes used to define pages for mobile sites with jQuery Mobile
<body>
<div data-role=page
</div>
<div data-role=page
</div>
<div data-role=page
</div>
<div data-role=page
</div>

id=home>
id=products>
id=about>
id=contact>

Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development 119
</body>

In addition to script libraries such as jQuery UI and jQuery Mobile, thousands of jQuery plug-ins are
also available that can be used to render grids, show charts, display images, play videos, and provide
many other types of features. The large number of jQuery plug-ins plays a big part in jQuerys overall
popularity.
Although jQuery is extremely popular, it can be overkill in some cases in which only a subset of the
functionality it offers is needed. Future versions of jQuery will provide more modular script options
that let you select the specific functionality youd like (resulting in smaller scripts being used in an
application). For now, when you need only a subset of jQuery features, you can use alternative scripts
such as zepto.js or xui. Zepto.js is less than one fourth the size of jQuery yet provides many features.
Zepto.js isnt designed to work on older browsers and wasnt built with Internet Explorer (IE) in mind;
even so, it can be an appropriate choice in some situations. Xui is designed to work specifically with
the DOM and is only around 4KB in size when compressed.
In addition to core script libraries such as jQuery, jQuery UI, jQuery Mobile, and others, several additional scripts are available to fill different client-side development needs. Because of space constraints,
I wont provide an exhaustive discussion of these scripts here, but I can mention a few of the more
interesting ones. Figure 2 lists some scripts that have been getting a lot of attention lately.
Figure 2: Scripts that can be used in web apps to simplify coding and provide core functionality and
frameworks
Script
AngularJS

Description

AmplifyJS

AmplifyJS provides a unified API to access different types of


data sources. For example, Ajax calls can be registered using
AmplifyJS, then called throughout an application. Client-side
components can also communicate using a pub/sub model.

Backbone.js

Backbone is a framework for building MVC-like JavaScript


applications.

Bootstrap

Bootstrap provides UI components and interactions. Components are built with responsive design in mind, so that they
adjust to different resolutions and devices.

JsRender

JsRender, a replacement for jQuery Templates, allows clientside templating that can significantly reduce the amount of
JavaScript code required to convert JSON data to HTML.

KnockoutJS

Knockout provides built-in data-binding support, lets you


write JavaScript code that follows the MVVM pattern, supports client-side templates, and more.

LESS

LESS adds enhancements to CSS, such as the ability to define


and reuse variables, nest CSS rules, and others.

Underscore

Underscore provides many helpful utility functions for JavaScript, such as sorting arrays, grouping items, finding min and
max values, and many others.

AngularJS is a framework that lets you extend HTMLs


syntax to define data bindings, templates, and more.

120 Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development
This list barely scratches the surface of whats out there, especially given that Ive handpicked only a
few scripts. You can find a list of some of the more popular JavaScript files currently used in websites
on BuiltWiths JavaScript Libraries Growth page. Third-party companies such as Telerik, Infragistics,
and others have also released script libraries.
In addition to script libraries, another topic thats relevant for todays web applications is responsive
design and CSS media queries. More and more sites now support multiple resolutions and screen
sizes. These sites respond dynamically to the screen size that a webpage is displayed in and fill it
accordingly. Todays modern browsers support CSS media queries that can be used to target specific
screen sizes. By using media queries appropriately, you can enable a website to look good in the
browser, on a mobile device, and even on a tablet. The following example shows a simple CSS media
query to override CSS styles when a device is 320 pixels wide:
@media screen and (max-width:320px) {
/* override default styles here */
nav ul > li {
float: none;
}
}

Feature Detection
Although nearly all modern browsers support HTML5 and CSS3 features, they dont consistently support the same set of features. Given the number of existing browsers and browser versions, knowing
what features a particular browser supports is crucial. In the old days, wed rely on general browser
detection to determine what HTML or JavaScript to load, but that doesnt work well now. We need a
more fine-grained approach that determines specific features supported by a browser.
You can use the Modernizr script library to detect specific features supported by a browser. Modernizr can test for the presence of CSS3 features, canvas support, geolocation, animations, and much
more. In fact, its capable of testing more than 40 features across multiple browsers. Modernizr also
adds feature-specific CSS classes, such as no-touch, cssanimations, cssgradients, and opacity to the
root <html> element as appropriate. These classes can be used to enable or disable CSS styles in an
application.
The following code shows an example of using Modernzr to test for HTML5 canvas support:
if (Modernizr.canvas) {
//get canvas and 2d context
}
else {
//run fallback code
}

The Modernizr object shown in this code example is made available by including the modernizr.js
script in your web page. After the Modernizr object is available, you can test for many different fea-

Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development 121
tures. For example, you can test for the presence of CSS3 features such as rounded corners using the
following code:
if (Modernizr.borderradius) {
//rounded corner support is available
}

In situations in which a feature isnt available, Modernizrs YepNope functionality can be used to load
a polyfill script. A polyfill is a script designed to fill in missing features in older browsers. (See the
HTML5 Cross Browser Polyfills page on GitHub for a nice list of polyfills.) Following is an example
of using Modernizr to detect features, then dynamically load different scripts:
Modernizr.load({
test: Modernizr.canvas,
yep : canvas.js,
nope: canvas-polyfill.js
});

This code tests for the presence of the HTML5 canvas in a browser and loads canvas.js if its supported. If the browser doesnt support the HTML5 canvas, a polyfill script named canvas-polyfill.js
is loaded instead to provide fallback functionality (note that multiple scripts can be loaded as well).
Using Modernizr gives you an edge in building cutting-edge web applications that take advantage of
new HTML5 and CSS3 features while still providing graceful fallbacks for older browsers.

Web Tools
One of the big complaints I hear about JavaScript is that no good tools exist for writing and debugging JavaScript code. It turns out there are actually many great editors available to help you write
JavaScript. Tools such as Sublimeand Notepad++ provide text-editing functionality with support for
code highlighting, plug-ins, and more features, and browser-based tools such as Cloud 9 IDE or
CodeMirror are also available. If you want more robust features and integrated debugging, Aptana
Studio or Visual Studio 2012 provide excellent JavaScript features and the ability to set breakpoints,
step through code, and other features.
Some of the best available tools are free and built directly into modern browsers. IE, Firefox, Safari,
and Chrome have integrated developer tools that can be used to tweak HTML, CSS, and JavaScript
live in the browser while youre viewing a site. Although my personal favorite is the Chrome Developer Tools, similar functionality is available across all the major browsers. In most cases, you access
these tools by pressing F12 or via the browsers Options menu.
Figure 3 shows an example of the Chrome Developer Tools in action.

122 Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development

Figure 3: Using the Chrome Developer Tools to view HTML and CSS
HTML from the page is shown on the left, and styles, margins, borders, and other metrics are on the
right. You can tweak HTML and CSS directly in the tool, and changes are reflected immediately in the
page. Ive found this capability very helpful when I need to figure out where extra padding is coming
from or get a live view of how a particular change will affect a page.
You can also debug JavaScript directly in the tool without having to leave the browser and jump back
to another editor. To debug a script, select the Scripts tab, pick the script from the tree thats displayed
at the left, then click in the left gutter area to set a breakpoint. Figure 4 shows an example.

Figure 4: Debugging JavaScript code using the Chrome Developer Tools


You can step through scripts using hotkeys such as F10 or F11 (or click debug icons in the developer
tools menu) and even mouse over variables or use the console to see their values, as shown in Figure
5. It goes without saying that learning how to use the browser developer tools is essential if you want
to maximize your productivity as a client-side web developer.

Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development 123

Figure 5: Inspecting variables using browser developer tools


In addition to editors, software vendors are releasing new tools to support animations, CSS3 features,
and more. Adobe has released an early version of a tool called Adobe Edge that provides a visual
editor for building complex web animations. Senchas new Sencha Animator is another tool that can
be used to build animations and interactive HTML5 and JavaScript content.

The Client-Side Future Beckons


Web development has evolved considerably in a short amount of time. Where RIAs once dominated,
HTML5 and JavaScript are now taking their place because of the enhanced functionality available
in modern browsers and increasing availability of mobile devices and tablets. In this article, youve
seen some of the pros and cons associated with the move to HTML5 and JavaScript, as well as several
libraries and technologies that can help support client-centric development. Youve also seen several
different tools that can be used to simplify JavaScript development and debug scripts.
After reading this article, you might wonder whether HTML5 and JavaScript offer the answer to all
your web development needs going forward. Although some supposed experts might try to make
that case, in reality its more important than ever to use the correct language, framework, and tool for
the correct job. There are plenty of cases in which RIA frameworks excel and are appropriate to use.
However, the future indeed looks bright for HTML5 and JavaScript; these technologies are definitely
changing the way applications are being written for both desktop and the mobile web. If youve been
on the fence about learning to use the client-side web development technologies, now is a great time
to take the plunge!

124 Chapter 14: Storing Your Data in HTML5

Chapter 14:
Storing Your Data in HTML5
Get a feel for working with HTML5s flexible web storage
By Daniel Egan
In the world of application development, data rules. Every application, whether on the desktop or
web, requires the storage of some sort of data, and developers have been saving their stuff in different places for many years. There have been many techniques to store information on the web. From
cookies to sessions to forms, working in a stateless world has always been a challenge. In this months
article, we are going to continue on the developer side and look at one of the more useful and widely
needed aspects of HTML5: web storage.

In the Beginning
You will hear web storage called different things: DOM storage, local storage, HTML5 storage. But its
true name, as defined by the HTML5 Web Storage specification, is web storage.
The cool thing about web storage is that it is supported by all the major browsers, including mobile
browsers:
On the desktop:
Microsoft Internet Explorer (IE) 8 and later
Mozilla Firefox 3.5 and later
Apple Safari 4 and later
Google Chrome 4 and later
Opera 10.5 and later
On mobile devices:
Windows Phone 7 and later

Chapter 14: Storing Your Data in HTML5 125


Apple iPhone 2 and later
Android 2 and later
This widespread support is quite an accomplishment; few of the HTML5 specifications can claim the
same level of support. We find it interesting how nonchalantly disk space (web storage) is described in
the specification:

A mostly arbitrary limit of five megabytes per origin is recommended. Implementation feedback is
welcome and will be used to update this suggestion in the future.
This size is supported in most browsers (i.e., Firefox, Chrome, and Opera), although IE supports 10MB
(or as the documentation puts itqueue the Dr. Evil voice10 million bytes). In addition, Opera
allows the user to decide how much storage each site can use, although this figure is not known to
the developer at design time. Because you will need to make sure that your web application works
across all browsers, I suggest keeping the 5MB in mind while developing. If you exceed this limit,
you will receive a QUOTA_EXCEEDED_ERR and will need to process that error appropriately. At this
point, if you are used to other mediums, such as Adobe Flash or Silverlight, you might be wondering
whether you can prompt the user to request additional space. Unfortunately, the answer is no.
Since we do not live in a perfect world, you will have users running browsers that do not fit into the
previous list. Therefore, you will need to check whether the browser supports web storage. You can
use the following code to do so:
function supportsStorage() { return (localStorage in window) &&
window[localStorage] !== null;
}

You can use this code as shown in Figure 1; this code allows you to perform a simple check whenever
you attempt to save something to storage.
Figure 1: Checking whether a browser supports HTML5 web storage
if (!supportsStorage()) {
alert(Your browser does not support HTML5 localStorage. Try upgrading.);
} else {
try {
//save something
} catch (e) {
if (e == QUOTA_EXCEEDED_ERR) {
alert(Quota exceeded!);
//save some other way??
}
}
}

As you can see, we are also catching the specific quota exceeded error so that we can handle it
and alert the user. You can then decide the best option for your application: using a different storage

126 Chapter 14: Storing Your Data in HTML5


option or showing the user the error. Understand that this quota is a per-domain quota (a domain
being a combination of schema, host, and port). So you will have separate quotas for http:// and
https://. But this also means that if another application on the host http://www.YourAppSite.com uses
up the quota, then you are out of luck. This issue is described in the HTML5 Web Storage specification section 7.2. I particularly like the reference to geocities.com:

Different authors sharing one host name, for example users hosting content on geocities.com, all share
one local storage object. There is no feature to restrict the access by pathname. Authors on shared
hosts are therefore recommended to avoid using these features, as it would be trivial for other authors
to read the data and overwrite it.
So be certain that you know who is writing applications for the domain that you are using, or you
expose your saved data to others. In addition, do not save sensitive data in web storage. Anyone
sharing your domain would find it all too easy to loop through and read your data.
Before we dive too deeply into the saving of data, you need to know that there are actually two types
of defined storage: session storage and local storage.

Session Storage
Session storage is designed for scenarios in which the user is carrying out a single transaction. The
HTML5 sessionStorage attribute is available only to the window or tab in which it was initiated and
only while that window stays active. When the window or tab is closed (i.e., the session has ended),
the data ceases to exist. This approach has an advantage over cookies, not only because you have
more room to store data (5MB versus 4KB for a cookie), but because this attribute is scoped only for
the window that is open. Cookies can leak to another window if you open another browser instance
while your session is still active.

Local Storage
Local storage is designed for scenarios in which you want the data to persist beyond a single session.
This storage spans all windows that you might have open on that domain. If you set or modify data in
one window, that data will be available to all other windows that are opened to that domain. In addition, the data stays available after you close your browser, unless explicitly deleted by the developer
or user. This approach allows you to store data over instances, across windows, and on the client side,
without using cookies.

Using HTML5 Storage


Now that we have examined the different kinds of storage, lets take a look at how to use them. The
HTML5 Web Storage specification defines the following:
Length <attribute>
Key() <function>

Chapter 14: Storing Your Data in HTML5 127


getItem<function>
setItem()<function>
removeItem()<function>
clear()
These attributes and functions are available for both sessionStorage and localStorage. In essence, we
are saving key/value pairs of data. Because both types of storage use the same methods, we will show
examples using only session storage.

Setting and Retrieving Data


Using the Web Storage API, you can set and retrieve data in several ways. We can use the setItem and
getItem methods to place and retrieve data:
sessionStorage.setItem(firstName, Daniel);
sessionStorege.setItem(lastName, Egan);
var fName = sessionStorage.getItem(firstName);
var lName = sessionStorage.getItem(lastName);

If you want to save your fingers from doing some typing, then you can also use Expandos to add and
retrieve data:
sessionStorage.firstName = Daniel;
sessionStorage.LastName Egan;
var fName = sessionStorage.firstName;
var lName = sessionStorage.lastName;

Understanding that all data is saved as a DOMString is vital for several reasons. First, because the
API stores numbers as strings, a developer needs to be sure to convert numbers when retrieving data,
as the example in Figure 2 shows. Remember that the + symbol serves a dual purpose: It performs
both arithmetic and concatenation. Second, as a developer you wont be limiting yourself to simple
key/value pairs, so you will need a way to store more complex structures as strings.

128 Chapter 14: Storing Your Data in HTML5


Figure 2: Converting strings to numbers
sessionStorage.setItem(price, 32);
sessionStorage setItem(tax, 11);
// will return 3211
var totalPrice = sessionStorage.getItem(price ) + sessionStorage.getItem(tax
);
//instead you will need to parse the data
var intPrice = parseInt(sessionStorage.getItem(price);
var intTax = parseInt(sessionStorage.getItem(tax);
var totalPrice = intPrice + intTax;

Saving More Complex Structures


Although saving key/value pairs locally in a 5MB storage area is convenient, most developers will
want to save more complex objects. As noted previously, all data is stored as a string, so the process
of saving an object into storage saves the object name [Person person], not the actual data. To get
around this limitation, we can use JavaScript Object Notation (JSON), an open-source and text-based
way of storing data. Take a look at this simple example of JSON as a person object:
var person = { firstName : John,
lastName : Doe,
age
: 23 };

If we want to store this object in session storage, we can encode and decode it, using the JSON.stringify and JSON.parse methods. First, we save the object to storage:
sessionStorage.setItem(person, JSON.Stringify(person));

Later, when we want to retrieve the data, we use JSON.Parse:


var person = JSON.Parse(sessionStorage.getItem(person);

Clearing Data
Now that we have filled our storage with data, we need a way to remove it. There are two ways to
remove data that you have placed in storage: removeItem and clear. The removeItem method is very
similar to getItem, in that if you pass it a key, it will remove the value associated with that key:

Chapter 14: Storing Your Data in HTML5 129


sessionStorage.removeItem(firstName);

If you want to remove everything that you have stored in storage, you can use the clear method:
sessionStorage.clear();

Keep in mind that the examples we have been using are for session storage and will go away when
the browsing session is completed. The same is not true for local storage. Because we have a limit of
5MB per domain, make sure that you keep your storage area clear.
In this article, we have focused specifically on web storage as a way to store data locally. As we mentioned previously, web storage has been widely implemented across all major browsers. This type of
storage is a step up from cookies and is a much simpler and cleaner way to save your data, whether
you need to save information for one session or across sessions.

130 Chapter 15: Using the HTML5 Canvas Tag

Chapter 15:
Using the HTML5 Canvas Tag
The HTML5 canvas tag expands your options
for rendering text, images, shapes, and more
By Dan Wahlin
Rendering complex graphs or designs to the web has always been a challenge that has typically
been solved by using images, server-side processes, or plug-ins such as Silverlight or Flash. Although
drawing charts with straight lines has never been a problem (with the use of some creative CSS), rendering different types of shapes and colors natively in the browsersuch as ellipses, Bzier curves,
and other custom shapeshas always been a problem. With the addition of the HTML5 canvas tag,
available in the latest version of all major browsers, you can now do a lot using only JavaScript and
HTML tags. In this article Ill provide an introduction to the canvas tag and demonstrate some of the
fundamental tasks you can perform using it.

The Canvas: What Is It, and Why Use It?


So what is the canvas tag? Put simply, its a way to render pixels on the client side using JavaScript.
This includes rendering text, images, shapes, linear and radial gradients, and more. Unlike Scalable
Vector Graphics (SVG), which is vector based (and also available in many modern browsers now),
the canvas is pixel-based. This makes it more challenging in scenarios where a user can zoom in or
out since code has to be written to re-render pixels based upon a specific zoom level. However, the
canvas performs very well, making it a good candidate for many types of complex rendering scenarios, such as graphs, charts, and games. The performance is especially good in Internet Explorer 9
(IE9) because of the hardware acceleration it provides. On the web you can find several great examples of using the canvas, such as Microsofts www.beautyoftheweb.com site. Check out Mike Tompkins excellent Firework musical demo (see Figure 1).

Chapter 15: Using the HTML5 Canvas Tag 131

Figure 1: Putting the canvas into action with other HTML5 features such as audio and video
Before jumping into a discussion of using the canvas, lets take a moment to consider why youd want
to use it instead of using Silverlight, Flash, or server-side image generation processes. Determining
when to use the canvas (or, in my mind. any HTML5 feature) comes down to the target audience.
For example, Im a big fan of Silverlight in addition to web technologies. If Im building a line of
business (LOB) application that will be deployed on only Windows or Macintosh machines using
in-browser or out-of-browser techniques, then Ill generally look to Silverlight first since it works very
well in that scenario and brings a lot of power and productivity to the table. However, if Im writing
an application that will be released on the Internet or an intranet and may be used by different
devices such as iPads or iPhones, Android phones and tablets, or others, then Ill pick standard web
technologies. Every application is different and I dont believe that one size or technology fits all. Of
course, youll have to evaluate whether your target users have browsers that support the canvas tag
and plan an alternative strategy if they dont. The canvas is definitely a new feature and not supported
by many older browsers including pre-IE9 Internet Explorer versions.
Now lets get started with an overview of how to define and interact with the canvas.

Getting Started with the Canvas


Canvas functionality is available in the latest versions of the major browsers (IE9, Chrome, Safari,
Firefox and Opera) and can be defined using the <canvas> tag, as shown in the following example:
<canvas id=canvas width=800 height=600></canvas>

Once a canvas is defined (or dynamically added) in HTML, you can interact with it using standard
JavaScript. I generally prefer to use jQuery in any JavaScript-oriented page, but you can also use the
standard document.getElementById() function to locate a canvas tag and then interact with it. The following code demonstrates how to locate a canvas tag defined in a page and get access to its 2D context for drawing:
<script type=text/javascript>
window.onload = function () {
var canvas = document.getElementById(canvas);

132 Chapter 15: Using the HTML5 Canvas Tag


var ctx = canvas.getContext(2d);
};
</script>

If youre using jQuery it would look something like the following:


<script type=text/javascript>
$(document).ready(function () {
var canvas = $(#canvas);
var ctx = canvas[0].getContext(2d);
});
</script>

Notice that once the canvas object is located, you must access its 2D drawing context. The W3C
defines the 2D context: The 2D context represents a flat Cartesian surface whose origin (0,0) is at the
top left corner, with the coordinate space having x values increasing when going right, and y values
increasing when going down.
You can think of the 2D context as the drawing surface that youll programmatically interact with
using JavaScript. Once you have a reference to the 2D context object, you can use methods such as
lineTo(), fillText(), and fillRect() to perform drawing operations. Lets take a look at a few of the drawing
features available.
Drawing Shapes, Lines, and Text
If youve ever used GDI+ (Graphics Device Interface) in the .NET framework (System.Drawing
namespace), youll feel right at home using the canvas since its similar to GDI+ drawing in many
ways. If youve never touched GDI+, then dont worry about it; its simple to get started using the
canvas once you know a few fundamentals. Drawing is accomplished by calling standard JavaScript
functions that handle rendering lines, shapes, colors, styles, and more. Figure 2 shows several of the
key functions you can use.

Figure 2: Key canvas functions

Chapter 15: Using the HTML5 Canvas Tag 133


Lets look at a few things you can do with the canvas starting with rendering rectangles or squares. To
draw rectangles or squares you can use the fillRect(topLeftCornerX,topLeftCornerY,width,height) function. It accepts the x/y coordinates of where to start the shape as well as its height and width. Figure 3
shows an example of defining a rectangle.
Figure 3: Rendering a rectangle using the fillRect() function
<script type=text/javascript>
window.onload = function () {
var canvas = document.getElementById(canvas);
var ctx = canvas.getContext(2d);
//Render a rectangle
ctx.fillStyle = Green;
ctx.fillRect(0, 0, 200, 100)
};
</script>

In this example, the 2D context has its fillStyle set to a color of Green. The square thats rendered by
calling fillRect() will be displayed in the upper left of the screen (0,0 point) and have a width of 200
and a height of 100.
If youd like to render an arc or circle, the arc() function can be used. It has the following signature:
arc(centerX,centerY,radius,startAngle,endAngle,antiClockwise);

The centerX and center Y parameters define where the middle of the ellipse will be, the radius defines
the size of the ellipse, and the startAngle and endAngle parameters control the start and end points
of the ellipse (note that the startAngle and endAngle parameters are defined using radians rather than
degrees). The antiClockwise parameter will draw an arc (part of a circle) in an anticlockwise direction
when set to true. Heres an example of using the arc() function:
//Render a circle
ctx.arc(100, 200, 50, 0, 2 * Math.PI, false);
ctx.fillStyle = Navy;
ctx.fill();

Passing a value of 0 and 2 * Math.PI for the start and end angle parameters will result in a complete
circle being rendered. To render part of a circle, simply supply a different value for the startAngle or
endAngle parameter, as shown next. This example will result in 1/2 of a circle being rendered. Figure
4 shows the rectangle, circle and arc that are rendered to the canvas.

134 Chapter 15: Using the HTML5 Canvas Tag

Figure 4: The results of rendering a rectangle, circle, and arc


ctx.beginPath();
ctx.arc(100, 300, 50, 0, Math.PI, false);
ctx.fillStyle = Navy;
ctx.fill();

Its important to note that a call to beginPath() was performed before the arc() function call so that
each circle/arc shape stayed distinct and didnt merge into the following one as shown in Figure 5.

Figure 5: The result of two shapes combining as a result


of not making a call to beingPath()

Chapter 15: Using the HTML5 Canvas Tag 135


The beginPath() function tells the canvas to start rendering a new path, while fill() ends the path (you
can also add a call to closePath() after each call to fill() if desired although its not required in this
case).
The final topic that Ill cover in this section is rendering lines. This is accomplished by using moveTo()
and lineTo() along with the stroke() or fill() functions. The moveTo() function positions the virtual pen
at a specific location which can then draw a line to a specific x/y coordinate by using lineTo(). Figure
6 shows an example of drawing lines. The complete code for the shapes and lines rendered to this
point is shown in Figure 7.
Figure 6: Drawing lines and filling an area
ctx.beginPath();
ctx.moveTo(100, 400);
ctx.lineTo(50, 500);
ctx.lineTo(150, 500);
ctx.lineTo(100, 400);
ctx.strokeStyle = Red;
ctx.lineWidth = 4;
ctx.stroke();
ctx.fillStyle = Yellow;
ctx.fill();

Figure 7: Rendering shapes and lines using the canvas


<!DOCTYPE>
<html>
<head>
<title>Canvas Fundamentals</title>
<script type=text/javascript>
window.onload = function () {
var canvas = document.getElementById(canvas);
var ctx = canvas.getContext(2d);
//Draw a rectangle
ctx.fillStyle = Green;
ctx.fillRect(0, 0, 200, 100);
//Draw a circle
ctx.arc(100, 200, 50, 0, 2 * Math.PI, false);
ctx.fillStyle = Navy;
ctx.fill();
//Draw an arc
ctx.beginPath();
ctx.arc(100, 300, 50, 0, Math.PI, false);

136 Chapter 15: Using the HTML5 Canvas Tag


ctx.fillStyle = Navy;
ctx.fill();
//Draw lines
ctx.beginPath();
ctx.moveTo(100, 400);
ctx.lineTo(50, 500);
ctx.lineTo(150, 500);
ctx.lineTo(100, 400);
ctx.strokeStyle = Red;
ctx.lineWidth = 3;
ctx.stroke();
ctx.fillStyle = Yellow;
ctx.fill();
};
</script>
</head>
<body>
<canvas id=canvas width=800 height=600></canvas>
</body>
</html>

There are certainly other types of shapes you can draw with the canvas, including Bzier and quadratic curves. Theyre useful when you need to draw nonstandard shapes or add rounded corners to
something like a rectangle. The Mozilla canvas documentation provides an example of using lines and
quadatric curves to render a rectangle with rounded corners (see Figure 8).
Figure 8: Drawing a rectangle with rounded corners
function roundedRect(ctx, x, y, width, height, radius) {
ctx.beginPath();
ctx.moveTo(x, y + radius);
ctx.lineTo(x, y + height - radius);
ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
ctx.lineTo(x + width - radius, y + height);
ctx.quadraticCurveTo(x + width, y + height, x + width,
y + height - radius);
ctx.lineTo(x + width, y + radius);
ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
ctx.lineTo(x + radius, y);
ctx.quadraticCurveTo(x, y, x, y + radius);
ctx.strokeStyle = Black;
ctx.lineWidth = 10;
ctx.stroke();
ctx.fillStyle = Lime;
ctx.fill();
}

Chapter 15: Using the HTML5 Canvas Tag 137


The roundedRect() function can be called as shown next and will render the rectangle shown in
Figure 9.

Figure 9: Using lineTo() and quadraticCurveTo() to draw a rounded rectangle


roundedRect(ctx, 250, 5, 150, 150, 15);

The final topic that Ill cover is text rendering. Although rendering shapes can be good for charts and
a variety of other tasks, at some point youll want to render text to a canvas. Fortunately, thats an easy
proposition and something thats also quite flexible since the canvas supports different types of transforms as well (e.g., scaling and rotating objects). To render text to the canvas, you can use the fillText()
method, which accepts the text to add as well as the x and y coordinates of where to add it. Heres an
example of using fillText():
ctx.fillStyle = Black;
ctx.font = 30pt Arial;
ctx.fillText(Drawing with the Canvas, 0, 550);

Canvas Toolsand More to Come


Although Ive only scratched the surface of what can be done with the canvas, at this point you can
see that using it to perform basic drawing functions is pretty straightforward (and much like GDI+ if
youve worked with that). Using the canvas definitely involves a fair amount of JavaScript, though. You
may wonder (as I did) if there isnt an easier way to render shapes, especially given that you have to
figure out the coordinates yourself. Although the tooling story for the canvas isnt great quite yet, there
are plug-ins for tools such as Adobe Illustrator that can be used to export shapes and even animations to JavaScript. One example is Ai->Canvas. A project that provides a library of shapes and other
samples for the canvas can be found at code.google.com/p/html5-canvas-graphics/. And several open
source script libraries such as Flot are available as well.
In future articles Ill provide additional examples of using the canvas to generate more useful graphics
that can be displayed in a web application. Figure 10 shows an example of the types of topics that Ill
cover to help teach canvas features.

138 Chapter 15: Using the HTML5 Canvas Tag

Figure 10: Building a chart using the HTML5 canvas


Until then, enjoy trying out your newfound HTML5 knowledge!

Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas 139

Chapter 16:
HTML5 Tutorial: Build a Chart
with JavaScript and the HTML5 Canvas
Learn how to use HTML5 to build charting features
such as lines, shapes, and gradients into your web applications
By Dan Wahlin
Download the code: http://www.devproconnections.com/content/content/139802/139802_CanvasDemos.zip
The HTML5 canvas is capable of rendering lines, shapes, images, text, and more without relying on a
plug-in. Although the canvas element isnt supported by older browsers, the latest version of all major
browsers (Internet Explorer, Safari, Chrome, Firefox, and Opera) now support the canvas, making it an
option for rendering charts, graphs, and other types of visual data. In cases where a browser doesnt
support the canvas, a fallback can be provided that renders data using Silverlight, Flash, or another
type of plug-in.
In Chapter 14, I walked through the fundamentals of using the HTML5 canvas to render different
types of shapes. In this article Ill discuss how the canvas can be used to render a line chart using
JavaScript. An example of the chart that will be discussed is shown in Figure 1.

Figure 1: Building a chart using the HTML5 Canvas


To render the chart, a JavaScript object named CanvasChart was created that handles rendering all the
lines, shapes, and text shown in Figure 1. Figure 2 shows an example of defining CanvasChart settings
and calling the CanvasCharts render() function.

140 Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas
Figure 2: Using a CanvasChart JavaScript object to render a chart using the HTML5 canvas
<!DOCTYPE html>
<html>
<head>
<title>Canvas Chart Demo</title>
<script src=Scripts/jquery-1.6.min.js type=text/javascript></script>
<script src=Scripts/canvasChart.js type=text/javascript></script>
<script type=text/javascript>
$(document).ready(function () {
var dataDef = { title: US Population Chart,
xLabel: Year,
yLabel: Population (millions),
labelFont: 19pt Arial,
dataPointFont: 10pt Arial,
renderTypes: [CanvasChart.renderType.lines,
CanvasChart.renderType.points],
dataPoints: [{ x: 1790, y: 3.9 },
{ x: 1810, y: 7.2 },
{ x: 1830, y: 12.8 },
{ x: 1850, y: 23.1 },
{ x: 1870, y: 36.5 },
{ x: 1890, y: 62.9 },
{ x: 1910, y: 92.2 },
{ x: 1930, y: 123.2 },
{ x: 1950, y: 151.3 },
{ x: 1970, y: 203.2 },
{ x: 1990, y: 248.7 },
{ x: 2010, y: 308.7}]
};
CanvasChart.render(canvas, dataDef);
});
</script>
< /head>
<body style=margin-left:50px;margin-top:50px;>
<canvas id=canvas width=800 height=600></canvas>
</body>
</html>

The render() function accepts the canvas element ID as well as a JSON object that defines chart properties and data to be used in the rendering process.
The CanvasChart object demonstrates several key features of the canvas element that can be used in
applications, including rendering lines, shapes, gradients, text, and even transformed text. Lets take a
look at how the CanvasChart object was created.

Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas 141

Rendering Gradients and Text


The code for the CanvasChart object is located in a file named canvasChart.js thats available with
this articles downloadable code. The code starts by defining a CanvasChart object that exposes two
members named renderType and render. renderType is used to define what will be rendered on the
chart (currently it supports rendering lines and points), while render() is used to render the data on the
canvas as well as the associated labels for the x and y axes. The skeleton code for CanvasObject is
shown in Figure 3.
Figure 3: The skeleton structure of the CanvasChart object
var CanvasChart = function () {
var ctx,
margin = { top: 40, left: 75, right: 0, bottom: 75 },
chartHeight, chartWidth, yMax, xMax, data,
maxYValue = 0,
ratio = 0,
renderType = { lines: lines, points: points };
//functions go here
return {
renderType: renderType,
render: render
};
} ();

The code follows a JavaScript pattern referred to as the revealing module pattern, which provides a
convenient way to write objects that expose specific members only to outside callers. This example
exposes the renderType variable and render function.
The render() function shown in Figure 4 accepts the canvas ID defined within the page (see Figure 2)
as well as a JSON object that defines details about labels, font sizes, data points, and more that are
used for charting.
Figure 4: The render function, which is exposed to the client and used to trigger different canvasrendering processes
var render = function(canvasId, dataObj) {
data = dataObj;
getMaxDataYValue();
var canvas = document.getElementById(canvasId);
chartHeight = canvas.getAttribute(height);
chartWidth = canvas.getAttribute(width);
xMax = chartWidth - (margin.left + margin.right);
yMax = chartHeight - (margin.top + margin.bottom);
ratio = yMax / maxYValue;
ctx = canvas.getContext(2d);

142 Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas
renderChart();
};

The render function starts by assigning the dataObj parameter to a variable within the CanvasChart
object, then calls an internal function named getMaxDataYValue(). The getMaxDataYValue() function
determines the maximum Y value for the data points. From there, the render() function locates the
target canvas element within the page, calculates width and height values, and accesses the canvass
2D context that will be used to draw. Finally, a call is made to renderChart() to start the rendering
process.
The renderChart() function (see Figure 5) orchestrates different drawing functions and handles rendering the background, lines, labels, and data by calling the respective functions.
Figure 5: The renderChart function, which handles rendering a background gradient, text, lines, and
labels along the X and Y axes
var renderChart = function () {
renderBackground();
renderText();
renderLinesAndLabels();
//render data based upon type of renderType(s) that client supplies
if (data.renderTypes == undefined || data.renderTypes == null)
data.renderTypes = [renderType.lines];
for (var i = 0; i < data.renderTypes.length; i++) {
renderData(data.renderTypes[i]);
}
};

Different canvas features are used in the CanvasChart object, such as gradients and transforms. For
example, the renderBackground() function shown in Figure 6 demonstrates how linear gradients can
be created. The renderBackground() function uses the 2D contexts createLinearGradient() function to
define a gradient that has four gradient stops. Once the gradient is defined, it is assigned to the fillStyle property, then rendered to a rectangular area using the fillRect() function.
Figure 6: The renderBackground function showing how gradients can be rendered within a canvas
using the createLinearGradient function
var renderBackground = function() {
var lingrad = ctx.createLinearGradient(margin.left, margin.top,
xMax - margin.right, yMax);
lingrad.addColorStop(0.0, #D4D4D4);
lingrad.addColorStop(0.2, #fff);
lingrad.addColorStop(0.8, #fff);
lingrad.addColorStop(1, #D4D4D4);
ctx.fillStyle = lingrad;
ctx.fillRect(margin.left, margin.top, xMax - margin.left,
yMax - margin.top);
ctx.fillStyle = black;
};

Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas 143
CanvasChart also demonstrates how text can be manipulated using transforms. The text displayed on
the Y axis is rotated so that it displays vertically, as shown in Figure 7.

Figure 7: Using the canvas to rotate text vertically


Text rotation is accomplished by using the canvas elements rotate transform functionality, which is
found in the renderText() function shown in Figure 8. The key section of this code is the call to ctx.
save() (toward the bottom of the function shown in Figure 8), which saves the current state of the
canvas so that it can be restored. This is necessary so that the entire canvas isnt rotated. Once the current canvas state is saved, a call to the rotate() function is made to rotate the canvas. The text is then
drawn for the vertical axis using the fillText() function. Once the rotated text is rendered, the canvas
is restored back to its saved statethe state before the rotate transform was applied and the text was
rendered.
Figure 8: Rotating text vertically using the canvass rotate function
var renderText = function() {
var labelFont = (data.labelFont != null) ? data.labelFont : 20pt Arial;
ctx.font = labelFont;
ctx.textAlign = center;
//Title
var txtSize = ctx.measureText(data.title);
ctx.fillText(data.title, (chartWidth / 2), (margin.top / 2));
//X-axis text
txtSize = ctx.measureText(data.xLabel);
ctx.fillText(data.xLabel, margin.left + (xMax / 2) - (txtSize.width / 2),
yMax + (margin.bottom / 1.2));
//Y-axis text
ctx.save();
ctx.rotate(-Math.PI / 2);
ctx.font = labelFont;
ctx.fillText(data.yLabel, (yMax / 2) * -1, margin.left / 4);
ctx.restore();
};

144 Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas
After the x and y axis text is rendered, the CanvasChart object makes a call to renderLinesAndLabels()
(see Figure 9) to handle rendering the horizontal and vertical lines.
Figure 9: Rendering lines and labels using the canvas
var renderLinesAndLabels = function () {
//Vertical guide lines
var yInc = yMax / data.dataPoints.length;
var yPos = 0;
var yLabelInc = (maxYValue * ratio) / data.dataPoints.length;
var xInc = getXInc();
var xPos = margin.left;
for (var i = 0; i < data.dataPoints.length; i++) {
yPos += (i == 0) ? margin.top : yInc;
//Draw horizontal lines
drawLine(margin.left, yPos, xMax, yPos, #E8E8E8);
//y axis labels
ctx.font = (data.dataPointFont != null) ? data.dataPointFont :
10pt Calibri;
var txt = Math.round(maxYValue - ((i == 0) ? 0 : yPos / ratio));
var txtSize = ctx.measureText(txt);
ctx.fillText(txt, margin.left - ((txtSize.width >= 14) ?
txtSize.width : 10) - 7, yPos + 4);
//x axis labels
txt = data.dataPoints[i].x;
txtSize = ctx.measureText(txt);
ctx.fillText(txt, xPos, yMax + (margin.bottom / 3));
xPos += xInc;
}
//Vertical line
drawLine(margin.left, margin.top, margin.left, yMax, black);
//Horizontal Line
drawLine(margin.left, yMax, xMax, yMax, black);
};

Lines are normally drawn using the 2D contexts moveTo() and lineTo() functions, which are wrapped
in a function named drawLine() to simplify the process. Figure 10 shows the drawLine function. At this
point the canvas looks like the image shown in Figure 11.
Figure 10: Wrapping canvas functionality for drawing lines into a function named drawLine
var drawLine = function(startX, startY, endX, endY, strokeStyle, lineWidth) {
if (strokeStyle != null) ctx.strokeStyle = strokeStyle;

Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas 145
if (lineWidth != null) ctx.lineWidth = lineWidth;
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX, endY);
ctx.stroke();
ctx.closePath();
};

Figure 11: Rendering the background, lines, text, and axes text components
of a chart using the HTML5 canvas

Rendering Data
Once the labels and lines are rendered, CanvasChart handles rendering the data points by calling
a function named renderData(). This function handles iterating through the JSON data points and
drawing lines, points, or both depending upon the settings passed to CanvasCharts render() function.
Lines are drawn to connect the different data points through calls to the drawLine() function shown
earlier in Figure 10, while circles are drawn for specific data points by making calls to the 2D contexts arc() function. The circles that are rendered have a radial gradient applied to them using the createRadialGradient() function. The complete renderData function is shown in Figure 12.
Figure 12: Chart data passed into the CanvasChart object in a JSON format
var renderData = function(type) {
var xInc = getXInc();
var prevX = 0,
prevY = 0;
for (var i = 0; i < data.dataPoints.length; i++) {
var pt = data.dataPoints[i];
var ptY = (maxYValue - pt.y) * ratio;
if (ptY < margin.top) ptY = margin.top;
var ptX = (i * xInc) + margin.left;
if (i > 0 && type == renderType.lines) {
//Draw connecting lines
drawLine(ptX, ptY, prevX, prevY, black, 2);
}

146 Chapter 16: HTML5 Tutorial: Build a Chart with JavaScript and the HTML5 Canvas
if (type == renderType.points) {
var radgrad = ctx.createRadialGradient(ptX, ptY, 8, ptX - 5,
ptY - 5, 0);
radgrad.addColorStop(0, Green);
radgrad.addColorStop(0.9, White);
ctx.beginPath();
ctx.fillStyle = radgrad;
//Render circle
ctx.arc(ptX, ptY, 8, 0, 2 * Math.PI, false)
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = #000;
ctx.stroke();
ctx.closePath();
}
prevX = ptX;
prevY = ptY;
}
};

The renderData function handles iterating through the JSON data points and calling the appropriate
canvas function to render the data. Once the data points are rendered, the chart looks like the image
shown in Figure 13.

Figure 13: The completed chart rendered using the HTML5 canvas

Canvas Insights
You can see that theres a fair amount of JavaScript code required to use the canvas object. However,
once the different API functions are understood, its simply a process of calling the appropriate functions to render lines, text, or shapes. Although the CanvasChart object shown here is only a prototype
at this point, I hope it provides insight into what the HTML5 canvas is capable of rendering and how
some of the features it provides can be used.

Potrebbero piacerti anche