• Like
Dev pro html5 jump start guide by chayon shaah (professional web developer) mymensingh bangladesh
Upcoming SlideShare
Loading in...5

Thanks for flagging this SlideShare!

Oops! An error has occurred.

Dev pro html5 jump start guide by chayon shaah (professional web developer) mymensingh bangladesh


Hellow Guys . Do you wanna learn HTML5 easily . You can read this book and get learned about HTML5 easily . I shared it for all interested learners. …

Hellow Guys . Do you wanna learn HTML5 easily . You can read this book and get learned about HTML5 easily . I shared it for all interested learners.
Chayon Shaah ( Professional web developer ) Mymensingh Bangladesh)

Published in Technology , Design
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads


Total Views
On SlideShare
From Embeds
Number of Embeds



Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

    No notes for slide


  • 1. HTML Jump Start 5: Authors: Richard Campbell Daniel Egan Wallace McClure Michael Palermo Dan Wahlin
  • 2. 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 Rocks and The 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 IV is a Microsoft Developer Evangelist based in Phoenix. Michael’s 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.
  • 3. 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 Apps—Today!...............................................................................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
  • 4. 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
  • 5. 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, you’ll find tutorials, boilerplates, and detailed discussions that will help shorten your HTML5 learning curve.
  • 6. 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 you’ve been a developer. For some of you, that journey started recently. For others, it has been years. However long it’s 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 version—wait a minute—is 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 is change, not upgrade or revise. 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, let’s take a brief journey down memory lane and consider the series of events that led to where we are today. Then we’ll discuss where we’ll 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, let’s 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
  • 7. 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 W3C’s 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 didn’t this recommended standard replace HTML altogether? The answer is simple: Developers didn’t 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 wasn’t unpopular, but it wasn’t 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 group’s 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 Pilgrim’s 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 Microsoft’s
  • 8. Chapter 1: The Past, Present, and Future of HTML5   7 recently stated intention to incorporate “native” HTML5 in Windows. So it’s a good idea to start getting familiar with HTML5 now—and you can do so without making dramatic changes to the pages you already have. Let’s 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>
  • 9. 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. Let’s 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, that’s still okay. It’s 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, it’s still a good practice to declare the encoding in the document. These subtle differences clearly confirm the WHATWG’s 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.
  • 10. 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? Let’s 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>
  • 11. 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:
  • 12. 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:
  • 13. 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.
  • 14. 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.
  • 15. 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.
  • 16. 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 we’re 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, “What’s the big deal? Won’t 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> element—which 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 aren’t consistent, as Figure 1 shows.
  • 17. 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 user’s 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. That’s where this very simple and sometimes overlooked portion of the HTML5 specifications come in handy. Although you can’t 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 doesn’t 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, let’s 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.
  • 18. 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 section’s heading (an h1–h6 element or an hgroup element), but this is not required. The header element can also be used to wrap a section’s 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 you’re 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
  • 19. 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 we’ll leave it as is for simplicity’s 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, it’s 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
  • 20. 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.
  • 21. 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, you’ll find plenty of documentation on HTML5, the fifth major installment of HTML. And if you nose around the latest tweets, blogs, and articles, you’ll 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, we’ll 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, we’ll 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>
  • 22. 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>
  • 23. 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=”#”>It’s 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 don’t steal stuff, etc.</p> </footer> </body> </html>
  • 24. Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5  23 Figure 2: The final rendering of the default.htm page Let’s first observe HTML5’s 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’;
  • 25. 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);
  • 26. 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? Don’t worry. This old method is not what we’re 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.
  • 27. 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. Here’s 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
  • 28. 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. Let’s see how simple it is to apply rounded corners using CSS3. In the sidebar sections of default.htm, let’s 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 that’s 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; Don’t let the duplication bother you too much. If the browser doesn’t understand a property, that property is ignored. And if repetition feels wrong to you, welcome to the world of multiple-browser support. Now let’s 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 {
  • 29. 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. Let’s 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
  • 30. 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 7a shows the UI element before the user hovers the mouse over it; Figure 7b shows 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 browsers—as if that wasn’t enough to worry about—we also have to consider various devices, such as mobile phones. With large and small screen
  • 31. 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.
  • 32. Chapter Three: HTML5 Is in Style: Working with CSS3 and HTML5  31 Figure 9: Media query impact   Continuing on the HTML5 Path Obviously, we haven’t 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!
  • 33. 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 isn’t 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, let’s first peer into a simple HTML form that doesn’t 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” />
  • 34. 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?
  • 35. 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 “what’s 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).
  • 36. 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 isn’t 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=”(ddd) ddd-dddd” /> The preceding pattern would require the data to be entered as: (444) 444-4444
  • 37. 36  Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript Wouldn’t it be nice to inform the user what the valid format for any of the text-based inputs is? That is the role of the placeholder attribute. 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=”(ddd) ddd-dddd” /> Figure 6 shows what the rendered form looks like after we’ve added the placeholder attribute. Figure 6: Inputs displaying placeholder data Now what about the input requesting the user’s 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 the required attribute. 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 new autofocus attribute. Unlike the required attribute, 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” />
  • 38. 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);
  • 39. 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) is Please fill out this field. In IE 10.0, the message is This 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 in Figure 10. Although the table in Figure 10 isn’t a complete list of all the new HTML5 input-validation methods
  • 40. 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 display Your full name is required! instead of the browser’s default input-validation message? The code in Figure 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) {
  • 41. 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
  • 42. Chapter 4: HTML5 Form Input Enhancements: Form Validation, CSS3, and JavaScript  37 More Options for Input As you’ve seen, HTML5 offers exciting new enhancements to form inputs. With HTML5’s 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.
  • 43. 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, called semantic elements and 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 the Web 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
  • 44. 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:
  • 45. 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>
  • 46. 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>
  • 47. 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; }
  • 48. 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:
  • 49. 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: What really 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.
  • 50. 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
  • 51. 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
  • 52. 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.
  • 53. 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>
  • 54. 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!
  • 55. 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" />
  • 56. 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.
  • 57. 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>
  • 58. 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.
  • 59. 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
  • 60. 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.
  • 61. 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({
  • 62. 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.
  • 63. 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.
  • 64. 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
  • 65. 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:
  • 66. 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.
  • 67. 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.
  • 68. 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.
  • 69. 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>
  • 70. 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 accordingly—for 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
  • 71. 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.
  • 72. 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
  • 73. 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>
  • 74. 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
  • 75. 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
  • 76. 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.
  • 77. 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.
  • 78. 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.
  • 79. 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 8’s upcoming support for HTML5 and JavaScript, the hype has intensified even more. I’m 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 it’s really nothing new; it’s 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 haven’t 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 exist—such 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 badass’s 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, it’s 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-
  • 80. Chapter 8: Getting Started Using HTML5 Boilerplate  75 port; and CDN-hosted jQuery with a local fallback script—plus quite a bit more. When you visit the HTML5 Boilerplate site, you’re 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, you’ll 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 What’s in HTML5 Boilerplate? If you select the documented or stripped options, you’ll 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
  • 81. 76  Chapter 8: Getting Started Using HTML5 Boilerplate Looking through the folders, you’ll 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 doesn’t 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 you’ve 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, you’ll 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 Boilerplate’s support for printing pages /** * Print styles.
  • 82. 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: “”; } /* Don’t 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, you’ll 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, you’ll 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, you’ll note that the standard HTML5 doctype declaration is defined. I can’t 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 you’ll notice the inclusion of several conditional state-
  • 83. 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 don’t support JavaScript. For example, if you wanted to hide all <h1> elements in the page when a browser doesn’t 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 wouldn’t 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 Boilerplate’s index.html page includes several other interesting features, such as the meta tags shown in Figure 9.
  • 84. 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 it’s 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 isn’t used (even if the user selected it). Although this second meta tag doesn’t pass the latest W3C validation test, it’s 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, you’ll see that Google’s 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, Google’s 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 user’s location will normally be hit. Having a reference to the CDN version of jQuery is nice, but it’s 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 can’t be loaded. It does so by checking for the existence of the window.jQuery object. If the object isn’t found, then the CDN script wasn’t 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 site’s ID in the provided script:
  • 85. 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, you’ll 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 you’re 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
  • 86. 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.
  • 87. 82  Chapter 9: Start Using HTML5 in Your Web Apps—Today! Chapter 9: Start Using HTML5 in Your Web Apps—Today! 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, we’ll 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 isn’t 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 isn’t 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
  • 88. Chapter 9: Start Using HTML5 in Your Web Apps—Today!   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 don’t 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. We’ll use the following libraries: • Modernizr: a library that allows a program to test the browser for capabilities • jQuery: We’ll 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 don’t 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();
  • 89. 84  Chapter 9: Start Using HTML5 in Your Web Apps—Today! } 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 HMTL5’s 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 developer’s 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) {
  • 90. Chapter 9: Start Using HTML5 in Your Web Apps—Today!   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); } };
  • 91. 86  Chapter 9: Start Using HTML5 in Your Web Apps—Today! 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 don’t 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. We’ll test the file size against the maximum size allowed for uploading files on the web server. If any file is too large, we won’t perform an upload; otherwise we’ll 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
  • 92. Chapter 9: Start Using HTML5 in Your Web Apps—Today!   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 file’s 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 don’t 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, let’s 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, we’ll 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]; }
  • 93. 88  Chapter 9: Start Using HTML5 in Your Web Apps—Today! 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 you’re 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.
  • 94. Chapter 9: Start Using HTML5 in Your Web Apps—Today!   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 doesn’t 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?” You’re 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 . We’ve 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. It’s solved for us within many JavaScript libraries -- jQuery, for example, so we don’t need to worry about things there. So how can we integrate feature detection into our code?
  • 95. 90  Chapter 9: Start Using HTML5 in Your Web Apps—Today! 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. I’ve 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”)); } }]);
  • 96. Chapter 9: Start Using HTML5 in Your Web Apps—Today!   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: • Don’t 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 doesn’t magically add functionality. In this situation, it can be used to make existing functionality HTML5 compliant. For example, IE8 and older BlackBerry browsers don’t 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. There’s nothing wrong with this approach, but it’s 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 can’t think of any app that I have built that doesn’t use date or time. Opera was the first web browser to support the date and time HTML5 input types, and now iOS’s 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” />
  • 97. 92  Chapter 9: Start Using HTML5 in Your Web Apps—Today! In this code sample, the type of the asp:TextBox is set to date. If the browser doesn’t 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 HTML5’s datetime input type to display a calendar in iOS 5 and in IE9 using jQuery
  • 98. Chapter 9: Start Using HTML5 in Your Web Apps—Today!   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 doesn’t 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 doesn’t have support for debugging, you can turn to a very old-fashioned mechanism for interrogating objects that I learned a few years ago:
  • 99. 94  Chapter 9: Start Using HTML5 in Your Web Apps—Today! for(m in object) { // do something with m, perhaps some // oldstyle js debugging with an alert(...); } Though it’s 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 don’t have an available debugger. Tools for Modern Web-App Development From this article, you’ve learned various methods that you can use to add HTML5 capabilities to your existing web applications for the desktop and laptop. We’ve 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 you’re 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.
  • 100. 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 aren’t HTML5 compatible. It’s really too much for one developer to handle, and being productive in the today’s 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 document’s 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 browser’s 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 that’s the hard part of today’s web development—there are so many different browsers (with new versions are released every few months) and trying to keep up with the changing capabilities of today’s browsers will make you crazy. Utilizing jQuery for document traversal means that you don’t 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 aren’t specifically focused on HTML5, and today’s web developers want to exploit the latest and greatest in HTML5. But what
  • 101. 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 don’t 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 I’ve described are only a few. It’s well worth your time to look for help rather than solve all web development problems yourself.
  • 102. 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 Microsoft’s 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
  • 103. 98  Chapter 11: Build a jQuery HTML5 Web Application: The Account at a Glance App Figure 1B: The Account at a Glance application screen—final 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
  • 104. 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
  • 105. 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
  • 106. 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 application’s 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.0’s 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 you’re 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.
  • 107. 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 project’s 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; }
  • 108. 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.
  • 109. 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 I’m 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 MVC’s great features). Most of the Account at a Glance application’s 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. (I’ll 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)
  • 110. 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 you’ve 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 I’ll 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 you’d like to explore it in more detail. Download the Account at a Glance application at dl.dropbox.com/u/6037348/AccountAtAGlance.zip.
  • 111. 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, it’s 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 month’s 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, I’ll 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 Papa’s 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
  • 112. 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 Here’s 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.
  • 113. 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 jQuery’s Ajax functionality. 4. Once JSON data is available, scene.tile.binder.js handles the downloading of each tile’s 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 tile’s unique ID, layout scenes, and formatter (used for custom functionality) are defined in the file. Figure 4 shows an example of a single tile’s 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 that’s 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); }
  • 114. 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 }; } ();
  • 115. 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 project’s 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>
  • 116. 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, they’re 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 }; } ();
  • 117. 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 } },
  • 118. 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() doesn’t 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
  • 119. 114  Chapter 12: How to Build a jQuery HTML5 Web Application with Client-Side Coding It’s 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 + ‘rn’ + 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:
  • 120. 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. You’ll 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 (you’ll 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 you’re 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, you’ve 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.
  • 121. 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 wasn’t 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 couldn’t 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 isn’t 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 let’s not forget the iPad and Apple’s 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 you’re 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.
  • 122. 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 isn’t 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, it’s also important to take into account cross-browser issues, given the number of browsers available. As applications move toward incorporating HTML5, it’s 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. It’s 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. Let’s now examine some of those scripts and how they’re 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 aren’t 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
  • 123. 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 }); jQuery’s 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 Mobile’s data-role attribute to define multiple mobile pages. As the div elements in Figure 1 are processed by jQuery Mobile, they’re 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”>
  • 124. 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 jQuery’s 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 you’d 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 isn’t designed to work on older browsers and wasn’t 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 won’t 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” HTML’s syntax to define data bindings, templates, and more.
  • 125. 120  Chapter 13: Explore the New World of JavaScript-Focused Client-Side Web Development This list barely scratches the surface of what’s out there, especially given that I’ve handpicked only a few scripts. You can find a list of some of the more popular JavaScript files currently used in websites on BuiltWith’s 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 that’s relevant for today’s 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. Today’s 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 don’t 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,” we’d rely on general browser detection to determine what HTML or JavaScript to load, but that doesn’t 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, it’s 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-
  • 126. 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 isn’t available, Modernizr’s 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 it’s supported. If the browser doesn’t 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 you’re 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 browser’s Options menu. Figure 3 shows an example of the Chrome Developer Tools in action.
  • 127. 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. I’ve 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 that’s 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.
  • 128. 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. Sencha’s 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, you’ve 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. You’ve 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 it’s 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 you’ve been on the fence about learning to use the client-side web development technologies, now is a great time to take the plunge!
  • 129. 124  Chapter 14: Storing Your Data in HTML5 Chapter 14: Storing Your Data in HTML5 Get a feel for working with HTML5’s 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 month’s 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
  • 130. 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 it—queue the Dr. Evil voice—10 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
  • 131. 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, let’s take a look at how to use them. The HTML5 Web Storage specification defines the following: • Length <attribute> • Key() <function>
  • 132. 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 won’t be limiting yourself to simple key/value pairs, so you will need a way to store more complex structures as strings.
  • 133. 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:
  • 134. 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.
  • 135. 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 browser—such as ellipses, Bézier curves, and other custom shapes—has 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 I’ll 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, it’s 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 Microsoft’s www.beautyoftheweb.com site. Check out Mike Tompkins’ excellent Firework musical demo (see Figure 1).
  • 136. 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, let’s take a moment to consider why you’d 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, I’m a big fan of Silverlight in addition to web technologies. If I’m 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 I’ll 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 I’m 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 I’ll pick standard web technologies. Every application is different and I don’t believe that one size or technology fits all. Of course, you’ll have to evaluate whether your target users have browsers that support the canvas tag and plan an alternative strategy if they don’t. The canvas is definitely a new feature and not supported by many older browsers including pre-IE9 Internet Explorer versions. Now let’s 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’);
  • 137. 132  Chapter 15: Using the HTML5 Canvas Tag var ctx = canvas.getContext(“2d”); }; </script> If you’re 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 you’ll 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. Let’s take a look at a few of the drawing features available. Drawing Shapes, Lines, and Text If you’ve ever used GDI+ (Graphics Device Interface) in the .NET framework (System.Drawing namespace), you’ll feel right at home using the canvas since it’s similar to GDI+ drawing in many ways. If you’ve never touched GDI+, then don’t worry about it; it’s 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
  • 138. Chapter 15: Using the HTML5 Canvas Tag   133 Let’s 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 that’s 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 you’d 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. Here’s 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.
  • 139. 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(); It’s important to note that a call to beginPath() was performed before the arc() function call so that each circle/arc shape stayed distinct and didn’t 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()
  • 140. 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 it’s not required in this case). The final topic that I’ll 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);
  • 141. 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 Bézier and quadratic curves. They’re 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(); }
  • 142. 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 I’ll cover is text rendering. Although rendering shapes can be good for charts and a variety of other tasks, at some point you’ll want to render text to a canvas. Fortunately, that’s an easy proposition and something that’s 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. Here’s an example of using fillText(): ctx.fillStyle = ‘Black’; ctx.font = ‘30pt Arial’; ctx.fillText(‘Drawing with the Canvas’, 0, 550); Canvas Tools—and More to Come Although I’ve 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 you’ve worked with that). Using the canvas definitely involves a fair amount of JavaScript, though. You may wonder (as I did) if there isn’t an easier way to render shapes, especially given that you have to figure out the coordinates yourself. Although the tooling story for the canvas isn’t 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 I’ll 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 I’ll cover to help teach canvas features.
  • 143. 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!
  • 144. 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 isn’t 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 doesn’t 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 I’ll 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 CanvasChart’s render() function.
  • 145. 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. Let’s take a look at how the CanvasChart object was created.
  • 146. 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 that’s available with this article’s 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”);
  • 147. 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 canvas’s 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 context’s 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’; };
  • 148. 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 element’s 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 isn’t 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 state—the state before the rotate transform was applied and the text was rendered. Figure 8: Rotating text vertically using the canvas’s 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(); };
  • 149. 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 context’s 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;
  • 150. 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 CanvasChart’s 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 context’s 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); }
  • 151. 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 there’s a fair amount of JavaScript code required to use the canvas object. However, once the different API functions are understood, it’s 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.