Chapter 6

Creating Windows 8 Style Applications with HTML5, CSS, and JavaScript

WHAT YOU WILL LEARN IN THIS CHAPTER:

  • Understanding the basics of HyperText Markup Language, cascading style sheets, and JavaScript
  • Accessing Windows Runtime from HTML5 applications
  • Creating Windows 8 style applications with JavaScript

WROX.COM CODE DOWNLOADS FOR THIS CHAPTER

You can find the wrox.com code downloads for this chapter on the Download Code tab at www.wrox.com/remtitle.cgi?isbn=012680. The code is in the Chapter06.zip download and individually named, as described in the corresponding exercises.

Earlier in this book, you learned that Windows 8 brings new opportunities to web developers. Traditionally, web developers could use their technologies to create websites that consist of programming logic running on a web server, and a user interface (UI) that can be accessed only via a web browser. Windows 8 changes this landscape by allowing web developers to reuse their existing knowledge to create applications that run on the desktop. Technologies that previously lived only on web servers and inside web browsers are now first-class citizens for creating classic rich client applications.

This chapter provides a brief overview of these technologies. First, you learn about how to create a classic web page and how to design it, and then you learn how to use the same technologies for creating full desktop applications on Windows 8.


NOTE This chapter contains a short introduction to HTML5, CSS and JavaScript. If you already have experience with these technologies, you can skip the introduction and jump to the, “HTML5 Applications on Windows Runtime,” section in this chapter.

HTML5 and CSS on the Web

When Tim Berners-Lee invented the World Wide Web, he needed a language to describe content that is richly decorated with images, arbitrarily formatted, and consisted of pages that were connected together. Because there was no such language in 1989, he created the HyperText Markup Language (HTML), which has become the standard for building web pages.

In the past 20 years, HTML has been slowly (but constantly) changing to follow the new requirements of the emerging Internet. Today, most websites are built using HTML4, but since the World Wide Web Consortium (W3C) published the Working Draft of HTML5 in January 2008, more and more browser vendors have started supporting the new features, which opens the road for web creators to utilize the advantages of HTML5.

HTML was originally designed to describe the static content of web pages, and today this is the primary purpose of this language. However, when discussing HTML5, it often encompasses a broader scope. The term HTML5 is commonly used as an umbrella term, which covers more than 100 specifications that are used by next-generation websites. These technologies are developing standards for supporting the new requirements to play multimedia, store data, work with files, access the user’s geographic coordinates, make websites functional offline in the browser, and so on.

In this chapter, you first learn about the enhancements of the HTML language itself in version 5. Later in this chapter, you get a sneak peek into the related standards, because many of them are also available for Windows 8 applications.

Getting to Know HTML5 Technologies

In the strictest sense, HTML5 is the next version of the HTML standard that inherits most of its features from HTML4, makes a few of them obsolete, and extends them with new ones. Because the language itself is made up of HTML elements and their attributes, this essentially means that HTML5 adds new elements and attributes to the language.

You can group the new elements and attributes into the following categories:

  • Semantic and structural elements
  • Media elements
  • Form elements and input types
  • Drawing

New Semantic and Structural Elements

Previously, web developers mainly used the div container element to wrap simple elements into a bigger section, so they could refer to them as a whole and format them. For example, div elements are used to create headers, menus, and footers, too. Today, the markup code of most web pages is built up of numerous meaningless div elements embedded into each other, which are difficult to maintain.

HTML5 introduces new structural elements such as header, nav, footer, figure, summary, aside, and so on. These new elements not only help you to understand your markup more easily, but because they provide semantics to the code, they help search engines and screen readers understand the purpose of a particular content section.

New Media Elements

Previously, if a web developer wanted to embed an audio or video file into a web page, he or she was forced to rely on third-party browser plug-ins, because there was no direct support for multimedia in the browser. However, these plug-ins raise numerous questions related to their deployment, stability, and security on the desktop. Additionally, browser plug-ins are not available on most mobile devices, which makes the multimedia content unavailable on these devices.

To solve all these problems, HTML5 introduces new media elements, like audio, video, track, and so on. With these new elements, browsers are able to play multimedia content natively, without requiring the user to install any third-party plug-ins.

New Form Elements and Input Types

Forms are integral parts of the HTML standard because they are used to post data to the server. Although previous HTML versions had strong support for forms, they left tons of repetitive work for the web developers. For example, if you want to let your users enter a number, a date, an e-mail address, or a URL into a form, all you could give him or her was a generic text box, and then it was your task to validate the entered input and check if it was a valid number, date, or e-mail address.

To make your life easier, HTML5 introduces new input types, like color, date, time, e-mail, and so on. All you have to do is set your input to these types, and the browser will render the proper input field (for example, a date picker for dates) and will do the appropriate input validation, too.

Drawing

HTML5 introduces the new canvas element, which you can use to draw graphics on-the-fly via scripting. Because the graphics are no longer hard-coded into your web pages, they can adapt themselves to the devices, or the current state of your page, and they can even be interactive. Some browsers even support hardware-accelerated rendering for canvas, which makes the web a perfect environment for graphics-intensive applications and games.

As you can see, HTML5 extends the previous version in several areas. The common theme among these areas is that these new features help you to create modern websites with very clean markup, with much less coding, and without browser plug-ins.

First Steps with HTML

Before you create your first web page with HTML5, you must learn the basic syntax of HTML elements. If you understand the syntax, it is much easier to understand how your page works.

An HTML page consists of HTML elements. An HTML element usually contains content decorated with some markup. The following is a sample element that renders the text with strong typography:

<strong>This will be printed in bold in most browsers.</strong>

The first part of the element is the opening tag that is followed by the content, and finally the element is finished by the closing tag. Very important is the fact that the set of tags are fixed by the HTML standard, so you cannot invent new tags, because the web browsers will not understand them.

The strong tag in the previous example instructs the browser to render the content of the element with strong highlight (that means boldfaced letters in most browsers). The tags are separated from the content using angle brackets (<>), and the closing tag is differentiated from the opening tag with a forward slash character (/) after its opening angle bracket.

Some elements do not have content, and you mark them with self-closing tags. Self-closing tags are single tags with a forward slash (/) before the closing angle bracket. For example, the following br tag instructs the browser to render a line break:

<br />

Some elements require additional parameters to work properly. For example, the img element renders an image, but you must define which image file should be displayed. You can use HTML attributes on those elements that expect this kind of additional configuration. Attributes are name-value pairs that you define within the opening tag. The following example shows how you can use the src attribute of the img tag to display the image file budapest.png:

<img src="budapest.png" />

A single element can have multiple attributes separated by whitespace. For example, the img tag can have an alt attribute, too, that may contain alternate text that is displayed when the image cannot be rendered for some reason:

<img src="budapest.png" alt="A nice photo of Budapest, capital of Hungary." />

The next thing you must keep in mind regarding HTML elements is that you cannot overlap them. That means you can embed one element fully into another, but you cannot embed it partly. The following example correctly uses the em element to emphasize and the strong element to force the content even more. Most browsers render the em element with italic-faced and the strong element with boldfaced letters. In this example, the word important will be bold and italic.

<strong>The is <em>important!</em></strong>

Note that the full em element is within the strong element. However, if you re-order the closing tags, you will get incorrect markup, because the outer strong element is closed before the inner em element, as shown here:

<strong>This is <em>important!</strong></em>

This is called overlapping. You must avoid it (even if many web browsers render it correctly without any errors).


NOTE If you want to be sure that your markup is correct, use the W3C Markup Validation Service available at http://validator.w3.org.

This is the basic syntax of the HTML language, and you use it in the next “Try It Out” exercise to create a web page. After the exercise, you learn how you can add some fancy design to it.


NOTE You can find the complete code to download for this exercise on this book’s companion website at www.wrox.com in the folder HTMLTryItOut within the Chapter06.zip download.


Try It Out: Creating a Web Page with HTML5
To create an HTML web page, follow these steps:
1. Start Visual Studio 2012 by clicking its icon on the Start screen.
2. Select File &menuarrow; New &menuarrow; Web Site (or press Alt+Shift+N) to display the New Web Site dialog box.
3. Select the Installed &menuarrow; Templates &menuarrow; Visual C# category from the left tree, and then select the ASP.NET Empty Web Site project type in the middle pane.
4. Click OK, and Visual Studio creates an empty project skeleton.
5. Open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L). In the Solution Explorer window, right-click the WebSite1 item and select Add &menuarrow; Add New Item. In the Add New Item dialog box, select the HTML Page template and enter default.html in the Name text box. Click Add.
6. Visual Studio creates a new HTML file with some default content and opens it in the editor. Find the <title> and </title> tags and replace them with the following code:
<title>My first webpage</title>
7. Find the <body> and </body> tags and add the following code between them:
<h1>Hello World!</h1>
 
This is a link that opens the 
<a href="http://wrox.com" target="_blank">Wrox homepage</a> 
on a new browser window.
 
<h2>Text elements</h2>
 
<p>
  This is a paragraph with a line break and
  <br />
  some <strong>important</strong> information.
</p>
 
<h2>Lists</h2>
 
<section>
  <h3>Numbered list</h3>
  This is a numbered list of programming languages:
  <ol>
    <li>JavaScript</li>
    <li>C++</li>    
    <li>C#</li>
  </ol>
</section>
 
<section>
  <h3>Bulleted list</h3>
  This is a bulleted list of colors:
  <ul>
    <li>red</li>
    <li>white</li>    
    <li>green</li>
  </ul>
</section>
 
<h2>Form elements</h2>
 
<form>
  <label for="txtName">Name:</label>
  <input type="text" id="txtName" /> <br />
 
  <label for="txtEmail">E-mail:</label>
  <input type="email" id="txtEmail" /> <br />
 
  <label>Gender:</label> 
  <label for="radFemale">Female</label>
  <input id="radFemale" name="gender" type="radio" /> 
  <label for="radMale">Male</label>
  <input id="radMale" name="gender" type="radio" /> 
  <br />
 
  <label for="selContinent">Continent:</label>
  <select id="selContinent">
    <option>Asia</option>
    <option>Africa</option>
    <option>North America</option>
    <option>South America</option>
    <option>Antarctica</option>
    <option selected="selected">Europe</option>
    <option>Australia</option>
  </select>
  <br />
 
  <label for="chkAccept">I accept the terms:</label>
  <input id="chkAccept" type="checkbox" /> 
  <br />
 
  <button>Save</button>
</form>
8. Start the application by clicking the Debug &menuarrow; Start Without Debugging menu item (or by pressing Ctrl+F5). Visual Studio starts the developer web server and opens the page in your default web browser. The results should resemble those shown in Figure 6-1.

Figure 6-1: Basic web page without any formatting

c06f001.tif
How It Works
In this exercise, you created a simple web page that demonstrates the most commonly used HTML elements.
In Step 5, you created a basic HTML page skeleton that contains the elements that appear in most web pages.
The <!DOCTYPE html> declaration in the first line tells the browser that it should follow the HTML5 standard when processing this page.
After the DOCTYPE comes the root html element, which encloses a head and a body element. The body contains the content of the page, and the head contains additional information about the page for the browser. In Step 6, you set the title of the page, which is displayed on the browser tab that renders the page.
In Step 7, you added the markup that defines the page content. The first line contains an h1 element that renders the top-level heading on the page. The markup also contains h2 and h3 elements, which are responsible for displaying the second-level and third-level headings, respectively.
After the top heading, there is a sentence that contains an a (anchor) tag that transforms its content into a clickable hyperlink. Note that the sentence is broken into three lines in the source code, separated by line breaks and multiple whitespaces, but it is rendered in a single line by the browser. This is because the formatting of the markup doesn’t influence the rendered page. If you want the browser to do something, you must explicitly tell it to do so by using a tag. That’s why so many <br /> tags exist in the markup that create line breaks.
After the second-level Text elements heading, there is a <p> tag that defines a paragraph, which provides good practice for wrapping longer content.
The ul and ol elements define an unordered (bulleted) and an ordered (numbered) list, respectively, which contain the list items defined by the li elements. The two lists with the corresponding introduction sentences and headings are wrapped into section elements. The section element is a new HTML5 tag that you can use to divide your page into smaller sections, with or without changing the visual representation of its content.
The form element defines a form that contains input elements. The form itself is not necessarily used for gathering data from the user, but it is a good practice to use it that way. Within the form element, input elements render the text boxes, radio buttons, and the check box based on the value of their type attribute. The select element transforms its option sub-elements into a combo box in the browser.
Note the label tags that contain the text for the input elements. The connections between the labels and the input elements are created using the for and the id attributes. The for attribute of the label refers to the id input element to which the label belongs. If you click the label text in the browser, the focus is set to the corresponding input element.
At the bottom of the form, there is a button that doesn’t do much at this point. Later, you write some client-side code to react to user clicks.

In the previous exercise, you created a web page by defining its content using HTML markup. Because you didn’t define how the browser should render it, the content is displayed with the default (a bit modest) style. In the next section, you learn how you can customize the visual look and feel of your web pages.

Styling Pages with CSS

Originally, HTML was an independent standard in the sense that you could use it to define the structure of the content, as well as the visual representation of the content. You could use HTML elements like big, center, and color, and attributes like align, height, and width to define how you wanted to render your page in the browser.

You can still use these elements and attributes in today’s websites, but they were removed from HTML5, because they have two important drawbacks:

  • Using these elements and attributes makes your code more complex and difficult to read. Other HTML elements define the structure and semantics of the content, but these presentation elements define the visual representation of the content. Mixing the “what” with the “how” results in unnecessary complexity.
  • When you use these presentational HTML elements, you tightly couple the content with the design. The content and the definition of how to display it in the browser resides in the same HTML file, and it is very difficult to give a new look to your page independently from the content.

Both of these disadvantages point to a direction of separating the structural and semantic parts of the content from the visual representation of the content. This separation has the following advantages:

  • Separating the design from the content helps you to create much more maintainable code. One file contains the HTML content, and another file contains the presentation semantics.
  • You can easily change the content and the visual presentation independently from each other. If you are a web developer or content manager, you must alter only the HTML file. But if you are a web designer, you must change only the design file.
  • It’s much easier to create consistent design, because you can easily attach the design to all your web pages within your website.

For many years, there was a standard to help with this separation, called cascading style sheets (CSS). Thanks to its obvious advantages, CSS was a widely used technology among web creators for many years, and it is the technology you can now use to define the look and feel of your Windows 8 style application.

First Steps with CSS

Before styling your previously created web page with CSS, you must learn how CSS works.

You can describe the look and feel of some content by using CSS declarations. CSS declarations are property name-value pairs that define position, size, color, border, font, and so on. In the following example, you can see the text-align, color, and margin properties:

text-align: center;
color: red;
margin: 5px 10px;

Syntactically, the property name and the value are separated by a colon (:), and multiple declarations are separated by a semicolon (;).

You can attach the CSS settings directly to the HTML element you want to format by using its style attribute. In the following example, you can see a custom-formatted HTML paragraph:

<p style="font-style: italic; border: 1px solid blue; margin-left: 30px; 
          width: 300px; padding: 10px; text-align: center;">
  Everything is difficult for one, nothing is impossible for many. 
       (István Széchenyi)
</p>

This paragraph is rendered by the browser in a blue-bordered box with italic and centered text. The box has a slight internal margin (padding), and it is indented by setting a larger left margin, as you can see it in Figure 6-2.

This technique is called inline style, and although it works as expected and concentrates all formatting into the single style attribute, it does not detach the formatting from the content, because if you want another similarly formatted paragraph, you must repeat all style settings.

Figure 6-2: Simple formatted content

c06f002.tif

A better approach is to use a style block. The style block is an HTML style element within the page, which can contain multiple formatting rules, as you can see in the following code snippet:

<style type=“text/css”>
  /* Style rules come here… */
</style>

With style blocks, you can concentrate all style definitions you use into a single location within the page. You can easily reuse them within the same page. However, if you want to use the same style on multiple pages, you must repeat the style block on those pages.

To solve this, you can move all style settings into an external file, called the external style sheet. The external style sheet is a plain-text file (usually named with a .css extension) that you attach to multiple pages using the HTML link tag within the head section of the page, as shown here:

<link href="style.css" rel="stylesheet" type="text/css" />

External style sheets are the most commonly used approach, because with them, you can easily reuse your existing formatting definitions on multiple pages in your website, and you can still manage your design in a single central location. If you follow the best practices, you must modify only the CSS file when you redesign your website.

Another benefit of this approach is that the browser must download the CSS file only once, and can store it in the download cache. When the next page refers to the same CSS file, the browser doesn’t have to download it, sparing network bandwidth and rendering the page much faster.

However, if you detach the style definition from the content with style blocks or external style sheets, you must specify which part of the page you want to format with it. This is where CSS selectors come into the picture. With CSS selectors you can attach a style definition to the following:

  • All instances of an HTML tag (such as to all h1 headings)
  • Multiple HTML elements
  • A single HTML element

If you want to format all occurrences of an HTML tag, you can select them by the name of the tag. For example, if you want to format all h2 second-level headings to have underlined text, you can use the following CSS rule that consists of a selector and a declaration:

h2 { text-decoration: underline; }

In this case, the CSS selector is h2, and it attaches the CSS declarations in the following {} block to all h2 elements in the page. A single CSS rule can contain multiple CSS selectors, and can contain multiple CSS declarations, too.

If you want to format multiple elements in the page, you can use CSS class selectors. Within a style sheet, you can define a new CSS class by giving it a name and typing a period (.) before it, as you can see in the following example:

<style type=“text/css”>
.famous 
  { 
    font-style: italic; 
    font-size: 120%;  
  }
</style>

Then you can attach your new class to any HTML element using the class HTML attribute, as shown here:

<p class=famous>Albert Wass</p>

Note that the CSS class itself does not define the name of the tag you can format with it. That means you can attach the same CSS class to various HTML elements, as shown here:

<span class=famous>László Bíró</span>

NOTE A good practice is to name your classes based on their purpose and not on how they look, because if you redesign your site, they will probably look different, but will serve the same purpose. For example, a class named highlight is good, because it clearly tells what it is used for, regardless of how exactly it highlights the content. But a class named bigredtext may look strange after you change the look and feel of your site, and you decide to highlight content with blue borders and yellow background, instead of red color and larger letters.

Now you know how you can style all or some elements in a page. However, if you want to format only a single HTML element, classes are overkill. Thankfully, there is a third type of CSS selector you can use to select a single HTML element — by its HTML id attribute. The id attribute, as the name suggests, must contain an arbitrary value that uniquely identifies a single element within the page. You can refer to this value by the CSS id-selector that starts with a # sign, as you can see in the following example:

<style type=“text/css”>
#first 
  { 
    font-weight: bold; 
    color: red;  
  }
</style>

<p>
  Lake <span id=first>Balaton</span> is the largest lake in Central Europe.
</p>

NOTE What if you want to format a few words, and you won’t have an HTML element that contains only those words? In this case, you can use the inline span element to wrap your content, as you can see in the following example:
<p>
  Did you know that <span class=important>Harry Houdini</span> 
     was born in Budapest?
</p>
If you want to format a larger part of your page, you can wrap that into an HTML div element. Both the span and div elements can have style, class, and id attributes that you can use to format the wrapped content.

Now that you have learned about the three basic types of selectors, you are ready to combine them. For example, you can select only those list items (li elements) that have the important class attached (which is useful if the important selector is also attached to other elements):

<style type=“text/css”>
.important
  {
    color: red;
  }
li.important
  {
    font-variant: small-caps;
  }
</style>

<p class=important>
  This paragraph will be rendered with red letters.
</p>

<ul>
  <li>orange</li>
  <li class=important>apple</li>
  <li>grape</li>
</ul>

In the preceding example, the paragraph and the second list item will be rendered as red, thanks to the important CSS class. Additionally, the second list item will be rendered in small capitals, because of the li.important mixed selector.

HTML elements inherit most of their style settings from their parent element, which is very useful because you don’t have to define every style setting on every element. If you format a parent element, its style will be propagated to its child element. Because the body is the outermost element that wraps all content elements, it is a good practice to define page-level settings on the body element, as you can see in the following example:

body
{
  font-family: Verdana, Arial, Sans-Serif;
  font-size: 75%;
}

This selector sets the font family and font size for all elements on the page, because these CSS attributes are inherited. However, not all CSS properties behave this way, and CSS has a very good reason for that. For example, the border property is not inherited, because in most cases, when you add a border to an element, you don’t want to add a similar border to all of its child elements.

Now you know that a value of a CSS property can come from various sources:

  • From the default style of the browser
  • From an external style sheet
  • From an in-page style block
  • From an inline style attribute
  • From a parent element

Another aspect of CSS that relies on the element hierarchy is hierarchical selectors. With descendant selectors, you can select elements that are a descendant of another. In the following code snippet, you can see two CSS rules. The first applies to all links (HTML anchors), but the second applies only to those links that are used within a list item.

a { text-decoration: none; }
li a { text-decoration: none; }

Of course, you can also use class and ID selectors with hierarchical selectors, too. The following CSS rule applies to all links that have the error class within a list item that has the errors value in its id attribute:

li#errors a.error { font-weight: bold; }

This section briefly introduced the syntax of CSS. However, it could only present the most frequently used parts of it, which you will probably also use in your Windows 8 application. If you want to learn about pseudo-classes, pseudo-elements, child, adjacent sibling, and attribute selectors, visit the “Understanding CSS Selectors” article in the MSDN Library at http://msdn.microsoft.com/en-us/library/aa342531.aspx.


NOTE If you want to be sure that your style sheet is correct, use the W3C CSS Validation Service available at http://jigsaw.w3.org/css-validator/.

Now you have everything you need to style a full web page. In the next exercise, you format your previously created HTML5 web page with CSS.


NOTE You can find the complete code to download for this exercise on this book’s companion website at www.wrox.com in the folder CSSTryItOut within the Chapter06.zip download.


Try It Out: Using CSS Features to Add Design and Layout to a Web Page
To learn how you can format the web page you created in the previous exercise with CSS, follow these steps:
1. Start Visual Studio 2012 by clicking its icon on the Start screen.
2. Select File &menuarrow; Open &menuarrow; Web Site (or press Alt+Shift+O) to display the Open Web Site dialog box. Select the folder where you created the website in the previous exercise, and click Open.
3. Open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L). In the Solution Explorer window, right-click the WebSite1 item and select Add &menuarrow; Add New Item. In the Add New Item dialog box, select the Style Sheet template, and enter default.css in the Name text box. Click Add.
4. Visual Studio creates a new CSS file with some default content and opens it in the editor. Replace the template-generated content with the following code, and then press Ctrl+S to save your changes:
body {
  font-family: "Segoe UI";
  font-size: 11pt;
  font-weight: 300;
  line-height: 1.36;   
  margin: 20px;   
}
 
h1, h2, h3 {
  color: #8c2633;
  clear: both;
  font-weight: 200;
}
h1 { font-size: 42pt; margin-top: 0; margin-bottom: 10px; }   
h2 { font-size: 20pt; margin-bottom: 5px; }            
h3 { font-size: 11pt; margin: 0; }
 
a { text-decoration: none; }
a:hover { text-decoration: underline; }
 
.left-column  { width: 60%; float: left; margin-right: 10%; }
.right-column { width: 30%; float: left; }
 
form { line-height: 2; }
 
label {
  display: inline-block;
  width: 120px;
}
label[for^=rad] { width: auto; }
 
input[type=radio] { margin-right: 20px; }
input[type=checkbox] { padding: 0; }
 
button {
  background-color: rgba(182, 182, 182, 0.7);
  line-height: 1;
  border-width: 0;
  padding: 6px 8px 6px 8px;
  min-width: 80px;
  margin-left: 124px;
} 
5. In the Solution Explorer window, double-click the default.html file to open it in the editor. Add the following code before the closing </head> tag:
<link rel="stylesheet" type="text/css" href="default.css" />
6. Scroll down and add the class="left-column" attribute to the first section element, and the class="right-column" attribute to the second section element. At this point, your section elements should look like this:
<section class="left-column">
  <h3>Numbered list</h3>
  This is a numbered list of programming languages:
  <ol>
    <li>JavaScript</li>
    <li>C++</li>    
    <li>C#</li>
  </ol>
</section>
 
<section class="right-column">
  <h3>Bulleted list</h3>
  This is a bulleted list of colors:
  <ul>
    <li>red</li>
    <li>white</li>    
    <li>green</li>
  </ul>
</section>
7. Start the application by clicking the Debug &menuarrow; Start Without Debugging menu item (or by pressing Ctrl+F5). Visual Studio starts the developer web server and opens the page in your default web browser. The results should resemble those shown in Figure 6-3.

Figure 6-3: The formatted web page

c06f003.tif
How It Works
In this exercise, you formatted the previously created web page with CSS. In Step 4, you created the CSS code in a separate CSS file, and in Step 5 you connected it to the HTML page.
The first CSS rule you added in Step 4 formats the body element. Because the body element contains all content, this rule efficiently defines the font style and the line spacing for all elements on the page.
The second CSS rule defines the text color and the font weight for all h1, h2, and h3 headings on the page. This rule applies to all headings, and it is followed by three separate rules that define the different font sizes and margins for the three heading levels.
After the heading rules are two rules that format the links on the page. The a selector applies to all links and removes the underlines. The a:hover selector applies only to those links that are currently selected by the mouse and displays the underline.
The .left-column and the .right-column selectors place the two section elements next to each other. By default, the section is a block element, which means that it is as wide as the page. By reducing the width and using the float property, you can place it in a single line.
The next form selector applies to the form element, and increases the 1.36 line spacing inherited from the body to 2. This gives a little vertical space between the input elements within the form.
The following CSS rules format the form content. To align all input elements vertically, you must make the labels the same width. However, label is an inline element, which means you can’t set its width and height properties, because they work only with block elements. You can combine the inline and the block behavior by setting the display property to inline-block. As you can see, the label selector formats all label elements to 120 pixels wide. However, this would cause problems for the labels of the radio buttons, so the next line fixes it:
label[for^=rad] { width: auto; }
This is a really tricky selector applying to all input elements that have a for attribute that starts with rad. Within the square brackets ([]), you can define filters for HTML attributes and their values. The next two CSS rules use the same technique to format the radio buttons and the check box on the page.
Finally, the button is formatted on the bottom of the page. Note how you removed its border by setting the border width to zero, and aligned it to the other input controls by setting its left margin.

In the previous exercise, you customized the look and feel of an HTML page. However, the page is still static, which means it doesn’t react to user actions. If you want to create an interactive page, you have to learn how you can write code that runs in the browser.

Running Client-Side Code

The HTML and the CSS standards provide you with an elegant and convenient way to create a web page, and define the look and feel of it. However, these standards focus on the static content, and they don’t give you any option to create interactive pages. To create web pages that can react to user actions and change dynamically, you need some code that can execute on the client side, within the browser.

Currently, only one language is supported by all major browsers without installing any plug-ins, and allows you to create client-side logic: JavaScript. JavaScript is an interpreted, object-oriented, dynamic scripting language, which means it has types, operators, core objects, and methods. Its syntax comes from the Java language, which itself inherits from the C language, so if you know the C language or C#, many coding structures will be familiar to you.

First Steps with JavaScript

Just like many other languages, the basic building blocks of the JavaScript language are the types. It has five basic types: number, string, boolean, object, and function.

When you declare a variable, you don’t have to specify its type. It is automatically inferred by the browser from the value you store in the variable:

var a = 9;               // Number
var b = "Hello World!";  // String
var c = true;            // Boolean

JavaScript is a dynamic language, which means that the types are associated with values, not with variables. As a result, you can change the type of a variable by storing a different type of value in it, which naturally can change how the various operators work on the variable:

var d = 9;        // d is of type Number
var e = d + 27;   // e is 36
d = 'September';  // d is of type String now
var f = d + 2;    // f is 'September27'

This dynamic nature provides the power of the language. For example, you can create an object and dynamically add properties to it later when you need them, as shown here:

var city = { Name: 'Budapest', Population: 2551247 };
city.Founded = 1873;   
// Here you can access the values as city.Name, city.Population and city.Founded.

Note that you don’t have to specify the class you want to instantiate. Instead, you just define the values you want to store in the object. JavaScript is an object-oriented language with objects, but without classes.

Functions are also first-class citizens in JavaScript. They can take zero or more parameters, and can optionally return a value using the return statement, as shown here:

function add( a, b )
{
  return a+b;
}

Function parameters are also weakly typed, which means that it’s up to you how you use them. For example, you can call the previous add function with number or string parameters, as shown here:

add(5, 21);              // returns 26
add('Hello', 'World'),   // returns 'HelloWorld'

You can even omit any number of parameters from the end of the parameter list, as shown in the following:

add(1998);   // This returns "NaN" which means “Not-a-Number”, 
             // that indicates that the return value is not a legal number.

If you don’t give a value to a function parameter, or don’t assign a value to a variable, it becomes undefined:

add('May'),  // Returns 'Mayundefined'

You can check whether a variable has a value by testing it against undefined:

function add( a, b )
{
  if( b !== undefined )
    return a+b;
  else
    return a;
}
add('May'),       // Returns 'May'
add('May', 'a'),  // Returns 'Maya'

A very unique feature of JavaScript is that functions behave just like any other variables; therefore, you can use them in objects as well. For example, you can create an object that has properties and functions, as shown here:

function getPerson( title, firstName, lastName )
{
  return {
    Title: title,
    FirstName: firstName,
    LastName: lastName,
    getDisplayName: function()
    {
      return title + ' ' + firstName + ' ' + lastName;
    }    
  };
}
var p = getPerson( 'Dr.', 'James', 'Plaster'),  // The parts of the 
                                                // name are accessible
                                                // via the p.Title, 
                                                // p.FirstName and 
                                                // p.LastName properties here.

var name = p.getDisplayName();                  // name is 'Dr. James Plaster'

You can also pass functions as parameters, just like any other variables:

function getEnglishName( firstName, lastName )
{
  return firstName + ' ' + lastName;
}

function getHungarianName( firstName, lastName )
{
  return lastName + ' ' + firstName;
}

function getPerson( firstName, lastName, nameFunc )
{
  return {
    FirstName: firstName,
    LastName: lastName,
    getDisplayName: function()
    {
      return nameFunc( firstName, lastName );
    }
  };
}

var en = getPerson( 'Ernő', 'Rubik', getEnglishName ).getDisplayName();    
var hu = getPerson( 'Ernő', 'Rubik', getHungarianName ).getDisplayName();  
// en is 'Ernő Rubik' and hu is 'Rubik Ernő' here

You can even use functions as parameters without giving them a name and inline them in the function call, as shown here:

var p = getPerson( 'Flórián', 'Albert', function(fn, ln) { 
  return fn + ' ' + ln;
} );
var en = p.getDisplayName();    // en is 'Flórián Albert' 

NOTE This is just a short introduction into the JavaScript language, focusing on the features that you use later in this chapter when you create Windows 8 style applications in JavaScript. You can read more about JavaScript in the W3Schools JavaScript Tutorial at http://www.w3schools.com/js.

In the next exercise, you use JavaScript to react to a user action on the web page you created in the previous exercise.


NOTE You can find the complete code to download for this exercise on this book’s companion website at www.wrox.com in the folder JavaScriptTryItOut within the Chapter06.zip download.


Try It Out: Adding Client-Side Code to a Web Page
To learn how you can use JavaScript to add interactivity to the web page you created in the previous exercise, follow these steps:
1. Start Visual Studio 2012 by clicking its icon on the Start screen.
2. Select File &menuarrow; Open &menuarrow; Web Site (or press Alt+Shift+O) to display the Open Web Site dialog box. Select the folder where you created the website in the previous exercise and click Open.
3. Open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L). In the Solution Explorer window, right-click the WebSite1 item and select Add &menuarrow; Add New Item. In the Add New Item dialog box, select the JavaScript File template and enter default.js in the Name text box. Click Add.
4. Visual Studio creates a new JavaScript file and opens it in the editor. Add the following code to the default.js file, and then press Ctrl+S to save your changes:
function load() {
  var btn = document.getElementsByTagName('button')[0];
  btn.disabled = true;
 
  btn.addEventListener('click', function (event) {
    var lbl = document.getElementById('lblMessage'),
    var txt = document.getElementById('txtName'),
    var name = txt.value;
 
    txt.addEventListener('keypress', function () {
      lbl.innerText = '';
    });
 
    lbl.innerText = name.length === 0 ?
      'Please enter your name!' : 
      'Thank you, ' + name + '!';
    
    event.preventDefault();
  });
 
  var chk = document.getElementById('chkAccept'),
  chk.addEventListener('click', function (event) {
    btn.disabled = !this.checked;
  });
}
5. In the Solution Explorer window, double-click the default.html file to open it in the editor. Add the following code before the closing </head> tag:
<script type="text/javascript" src="default.js"></script> 
At this point, your head element should look like this:
<head>
  <title>My first webpage</title>
  <link rel="stylesheet" type="text/css" href="default.css" />
  <script type="text/javascript" src="default.js"></script>
</head>
6. Scroll down and add the following attribute to the opening <body> tag:
onload="load();"
At this point, your <body> tag should look like this:
<body onload="load();">
7. Scroll down and add the following element between the closing </button> and </form> tags:
<span id="lblMessage" />
8. In the Solution Explorer window, double-click the default.css file to open it in the editor. Add the following code to the end of the file:
#lblMessage { color: red; }

Figure 6-4: The interactive form

c06f004.tif
9. Start the application by clicking the Debug &menuarrow; Start Without Debugging menu item (or by pressing Ctrl+F5). Visual Studio starts the developer web server and opens the page in your default web browser.
Note that you cannot click the Save button, because it is disabled when the page loads. Check the “I accept the terms” check box and the Save button becomes enabled.
Click the Save button and a “Please enter your name!” error message appears. Enter your name in the Name text box, and note that the error message disappears as soon as you start typing into the text box. Click the Save button again and a “Thank you” message appears next to the button, as shown in Figure 6-4.
How It Works
In this exercise, you added JavaScript logic to your web page that runs on the client within the browser.
In Step 4, you created the JavaScript code in a separate JavaScript file, and then you connected it to the HTML page by adding a script tag into the head in Step 5.
In Step 6, you attached an event handler to the load event of the body element, which executes the load function in the default.js file after the body element is completely loaded into the browser. The order of the actions is important, because the JavaScript code refers to the page elements. So, first the page must be completely loaded.
In Step 7, you added a new placeholder element to the page that is used by the JavaScript code to display the messages, and then in Step 8 you formatted this element with CSS.
The load function you added in Step 4 accesses the HTML elements on the page, and modifies them according to the user actions. The most commonly used technique to reference an HTML element from JavaScript is to use the document.getElementById function, which uses the value of the id attribute of the element. The document.getElementsByTagName function has a similar purpose, but it returns the list of elements with the specified tag name.
When the page loads, the load function is immediately executed. It first gets a reference to the Save button by its name, then disables the button. Next, you used the addEventListener function to attach an event handler to the click event of the Save button.
The event handler is a code block that is executed when the user clicks the button. This code first gets a reference to the label that displays the messages and the Name text box. The following code gets the entered text from the Name text box and stores it in the name variable:
   var name = txt.value;
Then, you subscribed a simple handler to the keypress event of the Name text box, which is called every time when the user presses a key while typing into the text box. The handler is just a single line that clears the message by setting it to an empty text.
The next three code lines (which is a single expression) display the appropriate message based on the length of the entered name:
lbl.innerText = name.length === 0 ?
    'Please enter your name!' : 
    'Thank you, ' + name + '!';
This is how you can read it. When the name is empty, the message is “Please enter your name!”; otherwise, the name is “Thank you [name comes here]!”. Actually, this is the short form of the following code:
if(name.length === 0)
{
   lbl.innerText = 'Please enter your name!';
}
else
{
   lbl.innerText = 'Thank you, ' + name + '!';
}
The last event.preventDefault(); code line within the click event handler is required to suppress the default action that the browser would perform when the button is clicked. In this case, the browser would post the form to the server, which you want to avoid.
After the button click event handler, the last three code lines attach an event handler of the click event of the check box. Within the event handler, the this object refers to the HTML element to which the handler is attached, which is the check box in this case, so you can use its checked property to query whether the user checked or unchecked it. According to this value, the button is enabled or disabled with a single line of code, which is the short form of the following:
if(this.checked === true)
{
    btn.disabled = false;
}
else
{
    btn.disabled = true;
}

In this exercise, you learned the basic JavaScript techniques to manipulate objects on the page. In the subsequent parts of this chapter, you learn how you can use this knowledge to create a Windows 8 style application.


NOTE If you would like to learn more about HTML5, CSS and JavaScript, you can find quick tutorials about these technologies at http://www.w3schools.com.

HTML5 Applications on Windows Runtime

Earlier in this chapter, you learned the basic technologies that web developers use to create applications that run in the web browser. Traditionally, it was only the web browser that understood HTML, CSS, and JavaScript, and was capable of executing complex application logic built with these technologies. If a developer wanted to utilize web technologies in a desktop application, he or she had to embed the web browser into the application, because desktops were not able to execute web code directly.

However, with Windows 8, Microsoft extended this web platform for client applications, and now you can create a Windows 8 style application that runs fully on the client using HTML, CSS, and JavaScript. The Windows 8 platform contains everything built in that is required to execute web code natively.

In Figure 6-5, you can see how Windows 8 style applications written in JavaScript compare with the traditional desktop applications. On the right, you can see that for desktop applications, the web browser is responsible for hosting and running the JavaScript application code. On the other hand, for Windows 8 style applications, Microsoft provides a JavaScript Engine (codename “Chakra”) that hosts and executes the HTML, CSS, and JavaScript code of the application.

Figure 6-5: The difference between Windows 8 style and desktop applications

c06f005.eps

You can also note another component for Windows 8 style applications called the Windows Library for JavaScript, which you learn about in the next section.

The Windows Library for JavaScript (WinJS)

If you are a web developer, you can love or hate JavaScript. You can love JavaScript because it is a very powerful and flexible programming language. It is fully focused on the web, and you can write quite complex logic with very few lines of code, thanks to its weakly typed nature. However, writing good code or debugging faulty code is another story. JavaScript coding and debugging tools are not as advanced as the C# and Visual Basic tools, because of the characteristics of the language.

JavaScript developers usually solve this problem by using client-side libraries that provide ready-made solutions for the typical programming tasks. With libraries, you can speed up your application development, and give standard solutions for similar problems. Several libraries are available for download, but none of them is optimized for Windows 8. To make a developer’s life easier, Microsoft created a new library called the Windows Library for JavaScript (WinJS) that contains tons of useful namespaces, classes, and functions that you can rely on when you create your Windows 8 style application in JavaScript.

WinJS provides the following components:

  • Helper functions to organize your code into namespaces and classes
  • A WinJS.Promise object that encapsulates the functionality of JavaScript promises and is used by all asynchronous functions in WinJS
  • An application model that manages the life cycle of your application
  • A navigation framework that you can use to create multi-page user interfaces
  • Template-based data binding to seamlessly flow data from the storage variables to the UI elements
  • User interface (UI) controls that wrap and enhance the typical HTML controls
  • Default CSS styles and animations to build UIs consistent with other Windows 8 style applications and the Windows 8 OS itself
  • Helper functions that solve typical coding tasks

As you can see from this list, WinJS is a huge and very useful library that provides natural integration of Windows Runtime features into the JavaScript programming language.

Creating Windows 8 Style Applications with JavaScript

In the next sections, you learn about the various aspects of creating Windows 8 style applications with JavaScript. First, you learn about the new filesystem application programming interface (API), then about the data binding services of Windows Runtime for JavaScript. After understanding data management, you learn about querying device properties and adding direct touch manipulation to your application. In the final sections of this chapter, you create images and Windows 8 style animations dynamically.


NOTE Because of the limitations of this book, this chapter cannot show you every detail of creating Windows 8 style applications in JavaScript. Note that JavaScript is a first-class citizen on the Windows 8 platform, and you can access all Windows Runtime features from JavaScript, just like from C# or Visual Basic.

Accessing the Filesystem

Windows Runtime provides a brand new API for applications that require access to the filesystem to read and write files. Because file operations can be lengthy, methods of the new API are asynchronous, thus forcing developers to avoid blocking the UI thread and creating responsive applications. In JavaScript, you can conveniently manage the asynchronous methods via promises, and chain them using the then method.

The FileIO class in the Windows.Storage namespace provides the following methods for reading and writing files:

  • appendLinesAsync
  • appendTextAsync
  • readBufferAsync
  • readLinesAsync
  • readTextAsync
  • writeBufferAsync
  • writeBytesAsync
  • writeLinesAsync
  • writeTextAsync

These methods can work on an IStorageFile instance that provides information about the file and its content, and ways to manipulate them. You typically get an IStorageFile object by showing the user the file open or the file save pickers. File pickers are very similar to the old file open and file save dialog boxes, but they are completely redesigned for Windows 8 style applications. You can find the FileOpenPicker and the FileSavePicker classes in the Windows.Storage.Pickers namespace.

In the next exercise, you create a simple Notepad-like application, which you can use to open, edit, and save text files.


NOTE You can find the complete code to download for this exercise on this book’s companion website at www.wrox.com in the folder FileSystemTryItOut within the Chapter06.zip download.


Try It Out: Accessing the Filesystem from an HTML5 Application
Before starting this exercise, ensure that you have TXT text files (that is, plaintext files) on your desktop. You can use Notepad to create some plaintext files with simple content. In this exercise, you create an application that displays the content of these files.
To learn how you can access the filesystem from an HTML5 application, follow these steps:
1. Start Visual Studio 2012 by clicking its icon on the Start screen.
2. Select File &menuarrow; New Project (or press Ctrl+Shift+N) to display the New Project dialog box.
3. Select the Installed &menuarrow; Templates &menuarrow; JavaScript &menuarrow; Windows Store category from the left tree, and then select the Blank App project type in the middle pane.
4. Click OK. Visual Studio creates an empty project skeleton and opens the main default.js file in the code editor.
5. Open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L).
6. In the Solution Explorer window, double-click the default.html file to open it in the code editor.
7. Find the content between the <body> and the </body> tags, and replace it with the following code:
<p>
  <button id="btnOpen">Open...</button>
  <button id="btnSave">Save as...</button>
  Selected file: 
  <span id="lblPath">(No file selected, click Open to select a file)</span>
</p>
<textarea id="txtContent" style="width: 100%; height: 100%;"></textarea>
8. Click the Save icon on the toolbar (or press Ctrl+S) to save your changes. Close the editor tab of the default.html file to return to editing the default.js file.
9. Find the Initialize your application here comment line within the app.onactivated event handler, and add the following code right after it:
var btnOpen = document.getElementById('btnOpen'),
btnOpen.addEventListener('click', onOpenButtonClicked);
 
var btnSave = document.getElementById('btnSave'),
btnSave.addEventListener('click', onSaveButtonClicked);
10. Append the following code to the end of the default.js file:
 
function onOpenButtonClicked() {
  var picker = new Windows.Storage.Pickers.FileOpenPicker();
  picker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.desktop;
  picker.fileTypeFilter.replaceAll(['.txt', '.ini', '.log']);
 
  picker.pickSingleFileAsync().then(function (file) {
    if (file !== null) {
      var lblPath = document.getElementById('lblPath'),
      lblPath.innerText = file.path;
 
      Windows.Storage.FileIO.readTextAsync(file).then(function (content) {
        var txtContent = document.getElementById('txtContent'),
        txtContent.value = content;
      });
    }
  });
}
 
function onSaveButtonClicked() {
  var txtContent = document.getElementById('txtContent'),
  var content = txtContent.value;
 
  var picker = new Windows.Storage.Pickers.FileSavePicker();
  picker.suggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.desktop;
  picker.fileTypeChoices.insert('Plain text', ['.txt']);
  picker.pickSaveFileAsync().then(function (file) {
    if (file !== null) {
      Windows.Storage.FileIO.writeTextAsync(file, content).then(function () {
        var dlg = new Windows.UI.Popups.MessageDialog(
          'Your content is successfully saved to ' + file.path, 'Save completed'),
        dlg.showAsync();
      });
    }
  });
}
11. Start the application by clicking the Debug &menuarrow; Start Debugging menu item (or by pressing F5). The results should resemble those shown in Figure 6-6.
12. Click Open to start the File Open Picker. Select a file, and then click Open in the lower-right corner in the picker dialog box. Your application loads the content into the editable area, as shown in Figure 6-7.
13. Change the text in the editable area, and then click Save as to save your changes into a new file. Enter a name for the file in the bottom of the File Save Picker, and then click Save in the lower-right corner of the picker dialog box.
14. Click Close to dismiss the pop-up message dialog box that notifies you about the result of the save operation, as shown in Figure 6-8.

Figure 6-6: The main screen of the text editor application

c06f006.tif

Figure 6-7: The main screen of the text editor application after a file is opened

c06f007.tif

Figure 6-8: The notification dialog box after successful save

c06f008.tif
How It Works
According to the project template you selected, Visual Studio generated an empty skeleton that contains everything you need to start creating your Windows 8 style application in JavaScript. This project contains two main files:
  • The default.html file contains the HTML markup that defines the UI elements of your application.
  • The default.js file contains the JavaScript logic that defines the behavior of your application.
In Step 7, you created the UI of your application in the default.html file. The UI consists of two buttons (Open and Save), a span element that displays the path of the selected file, and a textarea that provides the text-editing features. Note that all the buttons, the span, and the textarea elements have id attributes, which are required in order to reference them later from JavaScript code.
In Step 9, you extended the initialization code of the application. As you learned earlier in this chapter, the WinJS.UI.processAll function is responsible for initializing the markup of your Windows 8 style application. Because it returns a promise, you can use the then function to run your custom initialization code right after the markup initialization is successfully completed.
Here you initialized the two buttons by attaching an event handler to them. First, you used the document.getElementById function to get a reference to the button using the value of its id attribute, and then you called the addEventListener function to subscribe with a custom function to the click event of the button. This ensures that your function is called when the user clicks the button. The same logic is repeated once for the Open button and once for the Save button, with different handler functions.
In Step 10, you added the event handler functions for the Open and the Save buttons.
The onOpenButtonClicked function is called when the user clicks the Open button. In this function, you first created an instance of the FileOpenPicker class, and configured the folder in which it will open and the type of files it will show. After configuring the picker, you used the pickSingleFileAsync function to open the picker dialog box. Note that this is an asynchronous function that returns a promise, so you could use the then function to handle its return value. The pickSingleFileAsync function returns a StorageFile instance, which your code receives directly in the file parameter of the then function. If the user closes the picker dialog box without opening a file, the file parameter contains null value.
After the user selects a file, you display the path of the file on the UI. For this, you used the HTML span element as a placeholder for the path, and replaced its default using its innerText property.
To read the content of the selected file, you used the readTextAsync function of the FileIO class. Note that this is also an asynchronous function, which returns the string content of the file that is displayed in the textarea element on the UI.
The textarea element provides built-in features to edit its content, so your logic contains no special code for handling any events during editing.
When the user clicks the Save As button, the onSaveButtonClicked function is called. First, you used the value property of the textarea to retrieve the edited text and stored it in the content variable. Then, you instantiated the FileSavePicker class, which behaves very similarly to the FileOpenPicker class. After you configured its default folder and file type, you used the pickSaveFileAsync function to open the picker dialog box. This asynchronous function returns a StorageFile instance that can be null if the user canceled the save dialog box. Next, you used the writeTextAsync function of the FileIO class to write the string content to the target file. After the save function was returned asynchronously, you created a new MessageDialog instance, and called is showAsync method to display the notification dialog box about the successful save.

Managing Data

Data management is a key component of every application. The data is read from a database, from a file, or from a network service, and then it is displayed on the UI. The user searches the data and modifies it, and later the changes are propagated back to the original data source. The data is flowing first from the data source to the UI, and then from the UI to the data source.

Because data management is a typical programming task, modern programming environments have several features to make it easier. Typically, they have data source components that you can use to connect to the database, file, or network service, and UI controls that can display the data and provide input features to the users. The connection between the data source and the UI components is set up via data binding.

Data binding ensures that there is seamless data flow to and from the UI elements. One-way data binding pumps the data from the storage variable to the UI, and ensures that the UI is updated automatically when the underlying data is changed. Two-way data binding extends the functionality of the one-way binding by pumping the data back to the underlying data source after the data is modified on the UI.

Based on the size and structure of the data, two types of binding exist:

  • Simple binding connects a single value to a single property of a single UI element. For example, you can display a name, stored in a string variable, in a text box.
  • List binding connects multiple values to a UI element that can manage lists. For example, you can take a list of country names stored in a string array and display it in a table or a combo box.

In Windows 8, the WinJS supports only one-way binding, which means you can easily pump data from a variable to the UI. To handle data modifications, you must wire up event handlers for change events of the UI elements, and manually write the modified data back to the data source.

You can define your binding in a declarative or programmatic way. With declarative binding, you extend the HTML markup with expressions that describe which properties of the data object should be bound to an attribute of the current element. For example, the following img element renders an image whose URL is stored in the avatarUrl property of the data object:

<img data-win-bind="src: avatarUrl" />

The WinJS also supports programmatic binding. This means that you can use objects and functions in the WinJS.Binding namespace to set up and manipulate data bindings from your JavaScript code. For example, the following code displays an image whose URL is stored in the data.avatarUrl property:

var data = WinJS.Binding.as({ avatarUrl: 'myphoto.png' });
data.bind('avatarUrl', function (newValue, oldValue) {
    var target = document.getElementById('picture'),
    target.src = newValue;
});

In the next exercises, you create an image browser application, and learn how you can declaratively bind data in an HTML5 Windows 8 style application.


Try It Out: Using Simple Data Binding in an HTML5 Application
Before starting this exercise, ensure that you have image files in your Pictures Library folder. If you need images, you can find some in the C:WindowsWeb folder. In this exercise, you create an HTML5 Windows 8 style application that displays these image files.
To learn how you can use data binding in an HTML5 application, follow these steps:
1. Start Visual Studio 2012 by clicking its icon on the Start screen.
2. Select File &menuarrow; New Project (or press Ctrl+Shift+N) to display the New Project dialog box.
3. Select the Installed &menuarrow; Templates &menuarrow; JavaScript &menuarrow; Windows Store category from the left tree, and then select the Blank App project type in the middle pane.
4. Click OK. Visual Studio creates an empty project skeleton and opens the main default.js file in the code editor.
5. Open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L).
6. In the Solution Explorer window, double-click the default.html file to open it in the code editor.
7. Find the template-generated content between the <body> and the </body> tags and replace it with the following code:
<h1>
  Your
  <span data-win-bind="innerText: name"></span>
  Library
</h1>
8. Click the Save icon on the toolbar (or press Ctrl+S) to save your changes.
9. In the Solution Explorer window, double-click the default.css file within the css folder to open it in the code editor.
10. Add the following code to the end of the file:
h1 {
  margin: 20px;
}
 
h1 span {
  font-weight: bold;
}
11. Click the Save icon on the toolbar (or press Ctrl+S) to save your changes.
12. In the Solution Explorer window, double-click the default.js file within the js folder to open it in the code editor.
13. Find the WinJS.UI.processAll() function call within the app.onactivated event handler and replace it with the following code:
args.setPromise(WinJS.UI.processAll().then(function () {
  var lib = Windows.Storage.KnownFolders.picturesLibrary;
  var data = WinJS.Binding.as({ name: lib.name });
  var element = document.getElementById('span'),
  WinJS.Binding.processAll(element, data);
}));
14. Click the Save icon on the toolbar (or press Ctrl+S) to save your changes.
15. Open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L). In the Solution Explorer window, double-click the package.appxmanifest file to open it in the manifest editor.

NOTE The manifest file is an XML file that contains all information that is used during the deployment process. You can read more about the manifest file in Chapter 9.

16. In the manifest editor, go to the Capabilities tab and check the Pictures Library Access option in the Capabilities list.
17. Start the application by clicking the Debug &menuarrow; Start Debugging menu item, or by pressing F5. The results should resemble those shown in Figure 6-9.

Figure 6-9: The main screen of the image browser application

c06f009.tif
How It Works
According to the project template you selected, Visual Studio generated an empty skeleton that contains everything you need to start creating your Windows 8 style application in JavaScript.
In Step 7, you created the UI of your application in the default.html file. The simple UI contains only an h1 heading element with the words “Your” and “Library,” and a span element that acts as a placeholder between them. This placeholder will render the name of the library. Note the data-win-bind attribute of the span element, which defines that the name property of the data source object, is bound to the innerText property of the span element.
In Step 10, you used CSS to slightly modify the look and feel of your application by adding a margin around the heading, and by highlighting the name of the library with boldfaced text.
In Step 13, you extended the initialization code of the application. Because the WinJS.UI.processAll function returns a promise, you can use the then function to run your custom initialization code right after the markup initialization is successfully completed.
First, you created a reference to the Pictures Library folder. It is a well-known folder, and Windows Runtime provides a property to access it conveniently.
Next, you used the as function of the WinJS.Binding class to store the name of the Pictures Library in the local data variable in an observable way.
Next, you created a reference to the HTML span element that is the root element in the markup hierarchy to where the data should be bound.
Finally, you used the WinJS.Binding.processAll function to connect the UI element with the data source, and update all bindings and transfer the values from the data source objects to the UI controls. This causes the name of the Pictures Library displayed in the heading.
This application accesses the Pictures Library, which is a security-sensitive operation and, by default, not allowed to any application. To solve this, your application must explicitly request permission to access the Pictures Library. This is a feature of your application, and you must indicate it to Windows 8 by using the manifest file of your application. This is why you had to check the Pictures Library Access option among the application Capabilities in Step 15. If you run your application in Debug mode without checking this option, you receive the exception shown in Figure 6-10.

Figure 6-10: The Access Denied exception thrown only in Debug mode

c06f010.tif

In the previous exercise you learned how you can bind a single data value to an attribute of a single HTML element. This is called simple binding. In the next exercise you learn how you can bind multiple values to a single UI control using list binding.


Try It Out: Using List Binding in an HTML5 Application
To learn how you can use list binding in an HTML5 application, follow these steps:
1. Open the application you created in the previous exercise.
2. Open the default.html file in the code editor and insert the following code right after the closing </h1> tag:
<div id="tmpl" data-win-control="WinJS.Binding.Template">
  <div>
    <img src="#" data-win-bind="alt: name; src: url; title: path" />
    <br>
    <span class="name" data-win-bind="innerText: name"></span>
    <br />
    <span class="date" data-win-bind="innerText: date"></span>
  </div>
</div>
 
<div id="lv" 
  data-win-control="WinJS.UI.ListView" 
  data-win-options="{itemDataSource : files.dataSource, itemTemplate: 
       select('#tmpl')}">
</div>
3. Click the Save icon on the toolbar (or press Ctrl+S) to save your changes.
4. In the Solution Explorer window, double-click the default.css file within the css folder to open it in the code editor.
5. Add the following code to the end of the file:
#lv.win-listview 
{
  height: 500px; 
  width: 500px; 
}
 
#lv .win-container {
  margin: 20px;
  padding:  10px;
}
 
#lv .win-item {
  width:  205px;
  height: 165px;
}
 
#lv .win-item img {
  width: 192px;
  height: 120px;
}
 
.name {
  font-weight: bold;
}
 
.date {
  font-size: small;
}
6. Click the Save icon on the toolbar (or press Ctrl+S) to save your changes.
7. In the Solution Explorer window, double-click the default.js file in the js folder to open it in the code editor.
8. Create a global variable by adding the following code to the top of the file:
var files = new WinJS.Binding.List;
9. Find the WinJS.Binding.processAll(element, data); line and add the following code after it:
lib.getItemsAsync().then(function (items) {
  items.forEach(function (item) {
    if (item.isOfType(Windows.Storage.StorageItemTypes.file)) {
      files.push({
        url: URL.createObjectURL(item),
        name: item.name,
        path: item.path,
        date: item.dateCreated
      });
    }
  });
});

Figure 6-11: The image browser application with images

c06f011.tif
10. Start the application by clicking the Debug &menuarrow; Start Debugging menu item (or by pressing F5). The results should resemble those shown in Figure 6-11.
Note that if you hover the mouse over an image, a tooltip pops up containing the full path of the image. Additionally, if you have more than four images, you can scroll the list horizontally.
How It Works
In this exercise, you extended your existing code with a ListView control that displays the images in your Pictures Library using declarative data binding.
In Step 2, you added two div elements to the page. The second div element is marked with the data-win-control attribute, and it is transformed into a WinJS.UI.ListView control when the WinJS.UI.processAll function is executed. This div element has a data-win-options attribute that contains the settings for the ListView control:
  • The itemDataSource property defines the object that contains the data to display by the ListView control. In this case, it is the dataSource property of the files object created in a later step.
  • The itemTemplate property points to another HTML element in the page that is used to render a single item in the ListView. In this case, it is the div element that precedes the ListView. Because the template is referenced by the ListView, the template must be declared before the ListView within the page.
The template div is also marked by the data-win-control attribute, and it is transformed into a WinJS.Binding.Template instance. Within the template, the data-win-bind attributes connect the properties of the data source to the properties of the HTML elements.
In Step 5, you added some CSS classes that control the rendering of the ListView. The ListView uses nine built-in CSS classes, and you can use these classes to customize the rendering of the whole control and the containing items. Here you used the win-listview, the win-container, and the win-item classes to change the default look and feel of the ListView.
In Step 8, you created a global variable that is used as the data source for the ListView. ListView supports any data type that implements the IListDataSource interface. The WinJS provides several types of IListDataSource objects, and the WinJS.Binding.List is one of them.
In Step 9, you populated the data source with the data of the files in your Pictures Library folder. With the getItemsAsync and the forEach functions, you asynchronously enumerated through all items in the library, and added a custom-shaped object about every file to the data source. The data source contains a single object about every file with a url, a name, a path, and a date property. You can see in Step 2 that you referenced these properties in the item template of the ListView.

You have seen in the previous exercise that data binding provides a convenient way to display data from a variable on the UI. In the next exercise, you see that data binding builds a live connection between the data source and the UI control, and can update the UI automatically when the underlying data changes. To demonstrate this, you extend your image library browser application and provide remove functionality for the image list.


NOTE You can find the complete code to download for this exercise on this book’s companion website at www.wrox.com in the folder BindingTryItOut within the Chapter06.zip download.


Try It Out: Updating the Data Source
To learn how you can update the underlying data source using list binding in an HTML5 application, follow these steps:
1. Open the application you created in the previous exercise.
2. In the Solution Explorer window, double-click the default.js file in the js folder to open it in the code editor.
3. Find the following code block:
args.setPromise(WinJS.UI.processAll().then(function () {
  var lib = Windows.Storage.KnownFolders.picturesLibrary;
  var data = WinJS.Binding.as({ name: lib.name });
  var element = document.getElementById('span'),
  WinJS.Binding.processAll(element, data);
 
  lib.getItemsAsync().then(function (items) {
    items.forEach(function (item) {
      if (item.isOfType(Windows.Storage.StorageItemTypes.file)) {
        files.push({
          url: URL.createObjectURL(item),
          name: item.name,
          path: item.path,
          date: item.dateCreated
        });
      }
    });
  });
// Place code in this exercise here.
}));
4. Add the following lines of code into the line that is marked with the “Place code in this exercise here” comment in the previous code snippet:
var lv = document.getElementById('lv'),
lv.addEventListener('iteminvoked', function (eventObj) {
  eventObj.detail.itemPromise.then(function (listViewItem) {
    var binding = files.dataSource.createListBinding();
    binding.fromIndex(listViewItem.index).then(function (dataItem) {
      files.dataSource.remove(key);
      binding.release();
    });
  });
});
At this point, your code should look like this:
args.setPromise(WinJS.UI.processAll().then(function () {
  var lib = Windows.Storage.KnownFolders.picturesLibrary;
  var data = WinJS.Binding.as({ name: lib.name });
  var element = document.getElementById('span'),
  WinJS.Binding.processAll(element, data);
 
  lib.getItemsAsync().then(function (items) {
    items.forEach(function (item) {
      if (item.isOfType(Windows.Storage.StorageItemTypes.file)) {
        files.push({
          url: URL.createObjectURL(item),
          name: item.name,
          path: item.path,
          date: item.dateCreated
        });
      }
    });
  });
 
  var lv = document.getElementById('lv'),
  lv.addEventListener('iteminvoked', function (eventObj) {
    eventObj.detail.itemPromise.then(function (listViewItem) {
      var binding = files.dataSource.createListBinding();
      binding.fromIndex(listViewItem.index).then(function (dataItem) {
        var key = dataItem.key;
        files.dataSource.remove(key);
        binding.release();
      });
    });
  });
}));
5. Start the application by clicking the Debug &menuarrow; Start Debugging menu item (or by pressing F5). Click any of the images. If you did everything right, the clicked image should disappear from the list, and the list should re-order itself. Don’t worry; the image files are not deleted from your disk.
How It Works
In this exercise, you extended your existing ListView control with a custom event handler that removes an item from the data source of the ListView.
The first two lines of the code you added in Step 4 attached a new event handler to the iteminvoked event of the ListView control. The iteminvoked event is raised when the user clicks or taps (on a touch-based device) on one of the items in the list.
In this event handler, you first accessed the clicked item of the ListView using the detail property of the event handler’s eventObj parameter. Using the itemPromise property of this object, you can handle the clicked item as a promise, and chain a then function to it. When the promise is fulfilled, the inline function of the then function is called, and the clicked item is passed to it in the listViewItem parameter. The listViewItem object represents the visible object that is rendered by the ListView. Note that this is not the original data item, just a projected version of it that is displayed on the UI.
This is where data binding comes into the picture. Data binding can help you to get back the underlying data item from the list view item. The list view item has an index property, and you used the fromIndex function, which returns the original data item that is the source of the list view item.
The next step is to request the data source to remove this data item. To manipulate any data item in the data source, you must reference it via its unique identifier, called the key. When you add items to the data source, you can create a unique key to every item, or if you don’t do that, the data source creates one automatically. You can get the key of the data item via its key property. In this code, you used this key to call the remove function of the data source to remove the specified item.
In the last line of this code block, you called the release function of the binding object, which signals the binding that you are finished with all modifications, and it should notify all subscribed UI controls about the changes. This causes the ListView to remove the specified item from the UI, and automatically re-order itself.

In the previous three exercises, you learned how you can use data binding to render and manipulate data on the UI. Data binding is a very powerful tool because it helps you eliminate several lines of code, so you will use it every day when you create data-driven applications.

Respecting the User’s Device

Previously, client applications could run only on classic desktop computers and laptops. But Windows 8 brings a new type of device to the picture: the tablet. The tablet differs significantly from the desktops and laptops, because it provides new types of interactions. You can take a tablet with you, hold it in your hand in landscape or portrait mode, and control the applications using touch gestures. Tablets usually have a set of built-in sensors that your applications can access to detect the position of the device, the location of the user, the light level in the environment, and so on.


NOTE You can read more about sensors in Chapter 12.

Windows 8 can run on a broad range of devices, and your application must gracefully handle the various characteristics of these devices. Even if your application doesn’t rely on the built-in sensors, it must respect at least the different screens of the various devices. Your application must adapt itself to the four characteristics of the screen:

  • Size — This is the physical size of the display of the device.
  • Resolution — This is the number of pixels in the display. The minimum resolution to have all Windows 8 features enabled is at least 1366 &times; 768 pixels.
  • Orientation — This indicates how the user is holding the device in his or her hand (that is, in landscape or portrait mode).
  • Mode — On Windows 8, the user can run Windows 8 style applications in full-screen mode or in snapped mode. In full-screen mode, the application consumes the whole screen, whereas in snapped mode, the application is docked in a 320 pixels-wide column to the edge of the screen.

Windows Runtime provides APIs to query the device parameters and react to screen changes. To provide the best user experience, your Windows 8 style application must use these APIs to optimize itself to the current display conditions. When the user rotates the device or changes the application from full-screen mode to snapped mode, you can reposition or resize your UI elements.

In the next exercise, you create a picture browser application that adapts itself to the various screen sizes.


NOTE You can find the complete code to download for this exercise on this book’s companion website at www.wrox.com in the folder ViewStateTryItOut within the Chapter06.zip download.


Try It Out: Creating Flexible Layout
Before starting this exercise, ensure that you have at least ten image files in your Pictures Library folder. If you need images, you can find some in the C:WindowsWeb folder.
To learn how you can create an application that reacts to screen size changes, follow these steps:
1. Start Visual Studio 2012 by clicking its icon on the Start screen.
2. Select File &menuarrow; New Project (or press Ctrl+Shift+N) to display the New Project dialog box.
3. Select the Installed &menuarrow; Templates &menuarrow; JavaScript &menuarrow; Windows Store category from the left tree, and then select the Blank App project type in the middle pane.
4. Click OK. Visual Studio creates an empty project skeleton and opens the main default.js file in the code editor.
5. Open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L).
6. In the Solution Explorer window, double-click the default.html file to open it in the code editor.
7. Find the template-generated <p>Content goes here</p> content between the <body> and the </body> tags and replace it with the following code:
<div id="tmpl" data-win-control="WinJS.Binding.Template">
  <section>
    <img src="#" data-win-bind="src: url" />
    <div>
      <span class="name" data-win-bind="innerText: name"></span>
      <br />
      <span class="date" data-win-bind="innerText: date"></span>
    </div>
  </section>
</div>
 
<div id="host">
  <div id="lv" data-win-control="WinJS.UI.ListView" 
               data-win-options="{ itemDataSource: data.items.dataSource, 
                                   itemTemplate: select('#tmpl'), 
                                   layout: {type: WinJS.UI.GridLayout} }" />
</div>
8. Add the following code right before the closing </head> tag:
<script src="/js/data.js"></script>
9. Click the Save icon on the toolbar (or press Ctrl+S) to save your changes.
10. In the Solution Explorer window, double-click the default.css file within the css folder to open it in the code editor.
11. Add the following code to the end of the file:
#host {
  height: 100%;
  width: 100%;
}
 
#lv {
  height: 100%;
  width: 100%;
}
 
  #lv .win-item {
    width: 410px;
    height: 350px;
    padding: 10px;
  }
 
    #lv .win-item img {
      width: 400px;
      height: 300px;
    }
 
.name {
  font-weight: bold;
}
 
.date {
  font-size: small;
}
12. Click the Save icon on the toolbar (or press Ctrl+S) to save your changes.
13. In the Solution Explorer, right-click the js folder and select Add &menuarrow; New item. In the Add New Item dialog box, select JavaScript File and enter data.js into the Name text box. Click OK.
14. Add the following code into the data.js file:
(function () {
  "use strict";
 
  var images = new WinJS.Binding.List;
  var lib = Windows.Storage.KnownFolders.picturesLibrary;
 
  lib.getItemsAsync().then(function (items) {
    items.forEach(function (item) {
      if (item.isOfType(Windows.Storage.StorageItemTypes.file)) {
        images.push({
          url: URL.createObjectURL(item),
          name: item.name,
          date: item.dateCreated
        });
      }
    });
  });
 
  WinJS.Namespace.define("data", {
    items: images
  });
})();
15. Click the Save icon on the toolbar (or press Ctrl+S) to save your changes.

Figure 6-12: Starting the application in the Simulator

c06f012.tif
16. Open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L). In the Solution Explorer window, double-click the package.appxmanifest file to open it in the manifest editor.
17. In the manifest editor, go to the Capabilities tab and check the Pictures Library Access option in the Capabilities list.
18. Start the application by selecting the Simulator on the toolbar, as shown in Figure 6-12.
You can see the running application in Figure 6-13.

Figure 6-13: The image browser application in the Simulator

c06f013.tif

Figure 6-14: The rotate icons of the Simulator

c06f014.tif
Note that you can scroll the application horizontally to see all images.
19. Use the rotate icon on the right (shown in Figure 6-14) to rotate the Simulator from landscape mode to portrait mode.
You can see the application in portrait mode in Figure 6-15. Note that although the images are automatically rotated, the layout is less than optimal, because the application doesn’t use the full device screen.
Rotate the application back to landscape mode using the buttons on the right of the Simulator.
20. Drag the top edge of the application and move it to the left of the screen (within the Simulator) to switch it to snapped mode, as shown in Figure 6-16.

Figure 6-15: The application in portrait mode

c06f015.tif

Figure 6-16: The application in snapped mode

c06f016.tif

Figure 6-17: The Change Resolution feature in the Simulator

c06f017.tif
If the application doesn’t switch to snapped mode, it is probably because the Simulator runs with too low of a resolution. Windows 8 requires at least 1366 &times; 768 resolution to support snapped mode. You can use the Change Resolution button on the right of the Simulator to simulate this screen size, as shown in Figure 6-17.
Note that although the size of the application automatically adapted to the snapped mode, the images are too large and scrolling the list horizontally is not convenient.
In the next steps you optimize the application to automatically adapt to the portrait and snapped modes.
21. Open the default.css file from the Solution Explorer. Add the following code to the end of the file:
@media screen and (-ms-view-state: snapped) {
  #lv .win-item {
    width: 100%;
    height: 210px;
    padding: 5px;
  }
 
    #lv .win-item img {
      width: 280px;
      height: 210px;
    }
 
    #lv .win-item div {
      display: none;
    }
}
 
@media screen and (-ms-view-state: fullscreen-portrait) {
  #lv .win-item {
    width: 100%;
    height: 310px;
  }
 
    #lv .win-item div {
      display: inline-block;
      margin-left: 10px;
      height: 300px;
      vertical-align: bottom;
      font-size: 20pt;
    }
 
  .date {
    font-size: 14pt;
  }
}
22. Open the default.js file from the Solution Explorer. Find the code line that starts with var activation and add the following code after it:
var appView = Windows.UI.ViewManagement.ApplicationView;
var appViewState = Windows.UI.ViewManagement.ApplicationViewState;
23. Find the code line args.setPromise(WinJS.UI.processAll()); and replace it with the following code:
args.setPromise(WinJS.UI.processAll().then(function () {
  window.addEventListener('resize', onResize);
}));
24. Find the code line app.start(); and add the following two functions after it:
function onResize(eventArgs) {
  refresh(appView.value);
}
 
function refresh(newViewState) {
  var newLayout;
 
  switch (newViewState) {
    case appViewState.snapped:
      newLayout = new WinJS.UI.ListLayout();
      break;
    case appViewState.filled:
      newLayout = new WinJS.UI.GridLayout();
      break;
    case appViewState.fullScreenLandscape:
      newLayout = new WinJS.UI.GridLayout();
      break;
    case appViewState.fullScreenPortrait:
      newLayout = new WinJS.UI.ListLayout();
      break;
  }
 
  var lv = document.getElementById('lv').winControl;
  WinJS.UI.setOptions(lv, {
   layout: newLayout
  });
}
25. Run and test the application in landscape, portrait, and snapped modes in the Simulator. Note that the application now fully adapts its layout to the available screen size, and changes the scroll direction according to the view mode, as shown in Figures 6-18 and 6-19.

Figure 6-18: The optimized layout in portrait mode

c06f018.tif

Figure 6-19: The optimized layout in snapped mode

c06f019.tif
How It Works
In this exercise, you created an image browser application that is very similar to the one you created in previous exercises. However, this version respects the user’s device.
In Step 7, you created the UI of the application. This application uses a WinJS.UI.ListView control to display the images from your Pictures Library folder. Note the configuration parameters of the ListView control set in the data-win-options attribute:
  • The itemDataSource property configures the data object that will be bound to the ListView control. You created the data.items.dataSource object in Step 14 in the data.js file you connected to this page in Step 8.
  • The itemTemplate property points to the div element above the ListView that is used to define the layout and the content of every single item in the list.
  • The layout property is very important here, because it defines the layout of the whole list. The default that you set here is the WinJS.UI.GridLayout object that provides horizontal scrolling, and renders the items in multiple rows and columns. This is the default rendering that is used in landscape mode.
In Step 11, you used CSS to define the look and feel of your application. Note that you referred to the ListView control by its id attribute (#lv), and formatted the list items with the built-in .win-item CSS class of the ListView control.
In Steps 13 and 14, you created the data source object of the ListView. The code is very similar to the code you have seen earlier in this chapter, but this time the code is completely isolated from other parts of the application. The self-executing function (note the () at the bottom) provides code encapsulation, and the define function in the last code line ensures that only the necessary data is published from this scope.
In Steps 18–20, you tested the default behavior of the application. Windows 8 automatically re-renders your application when the view state of the application changes. However, it doesn’t know how to use the screen effectively. That is completely up to your application.
In Step 21, you added two sets of CSS rules that are wrapped into @media blocks. These @media blocks are media queries that rely on the -ms-view-state property to apply the CSS rules only when the application is in snapped and portrait modes. The CSS rules defined in these media queries are added to the rules that are defined previously without any media query block. For snapped mode, the div element (which renders the texts) is hidden, and the images are scaled to 280 &times; 210 pixels to fit into the 320-pixel width of the snapped mode. For portrait mode, the texts are rendered not below, but on the right of the image with larger font.
Media queries are very powerful when you change the look and feel of your application, but you cannot use them to change its behavior. In this example, you had to add some code to change the scrolling direction of the ListView according to the view state.
In Step 24, you added a refresh function that changes the layout of the ListView from GridLayout to ListLayout, because GridLayout provides horizontal scrolling, and ListLayout provides vertical scrolling that is much better for snapped and portrait modes.
In Step 23, you ensured that the list layout is refreshed when the user changes the screen size of the application. For this, you subscribed the onResize event handler to the resize event.

As you saw in the previous exercise, creating flexible UIs is very easy with HTML5 and CSS3 in Windows 8. Media queries provide a convenient way to change the look and feel of your application using only CSS, and Windows 8 provides events and APIs to fine-tune your application in JavaScript code.

Scrolling and Zooming

Touch gestures are the primary way of interacting with Windows 8 style applications on modern, touch-based devices. Direct manipulation is a natural way of controlling applications, but only if the gestures are used consistently in the operating system and all applications. Microsoft did profound research to develop the Windows 8 touch-interaction scheme, and integrated the best implementation of touch handling deep into the operating system. To ensure that gestures are handled consistently and optimally in every application, the controls in the WinJS have built-in support for touch interactions.

Because a lot of content cannot fit on small screens, the two basic interactions are scrolling and zooming. You can scroll content using a slide and zoom with a pinch gesture. Users quickly become familiar with the scroll and zoom gestures, because they can navigate within the Windows 8 Start screen and other Windows 8 style interfaces with them as well.

In the next exercise, you create an image browser application in that you can zoom, pan, and scroll using touch gestures.


NOTE You can find the complete code to download for this exercise on this book’s companion website at www.wrox.com in the folder ZoomTryItOut within the Chapter06.zip download.


Try It Out: Implementing Zooming and Panning
To learn how you can create an application in which you can zoom and pan using touch gestures, follow these steps:
1. Start Visual Studio 2012 by clicking its icon on the Start screen.
2. Select File &menuarrow; New Project (or press Ctrl+Shift+N) to display the New Project dialog box.
3. Select the Installed &menuarrow; Templates &menuarrow; JavaScript &menuarrow; Windows Store category from the left tree, and then select the Blank App project type in the middle pane.
4. Click OK. Visual Studio creates an empty project skeleton and opens the main default.js file in the code editor.
5. Open the C:WindowsWebWallpaperNature folder in Windows Explorer and copy the img1.jpg, img2.jpg, img3.jpg, and img4.jpg files to the clipboard.
6. Switch back to Visual Studio and open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L). Right-click the images folder and click Paste.
7. In the Solution Explorer window, double-click the default.html file to open it in the code editor.
8. Find the template-generated <p>Content goes here</p> content between the <body> and the </body> tags and replace it with the following code:
<div class="step">
  <img src="images/img1.jpg" />
</div>
9. Double-click the default.css file within the css folder in the Solution Explorer window to open it in the editor. Add the following code to the end of the file:
.step {
  overflow: auto;
  -ms-content-zooming: zoom;
  -ms-content-zoom-limit-min: 10%;
  -ms-content-zoom-limit-max: 500%;
  width: 100%;
  height: 100%;
}
 
  .step img {
    width: 100%;
    height: 100%;
  }
10. Start the application by selecting the Simulator on the toolbar, as shown in Figure 6-20.
If you have a device that supports touch gestures, you can also run the application without the Simulator. But if your computer supports only mouse and keyboard, the Simulator can help you to test your application and simulate various touch gestures.
11. On the right of the Simulator, you can see buttons that you can use to simulate touch gestures. If you hover your mouse over them, a tooltip pops up, as shown in Figure 6-21.

Figure 6-20: Starting the application in the Simulator

c06f020.tif

Figure 6-21: The touch buttons of the Simulator

c06f021.tif
12. Click the Touch emulation pinch/zoom button of the Simulator and hover your mouse over the image displayed by your application. Hold down the left mouse button and rotate the mouse wheel forward (away from you) to zoom in or backward (toward you) to zoom out.
13. Click the Basic touch mode button of the Simulator (the second button from the top), and hover your mouse over your application. Move the mouse while holding down the left button to pan the enlarged image.
How It Works
In this exercise, you created a simple image viewer application that lets you zoom and pan using touch gestures.
In Step 8, you created the simple UI of the application. Note that the image is displayed with a classic img tag that is wrapped into a div element. The div element has a CSS class named step that you defined in Step 9.
You implemented the zooming and panning feature using only CSS in Step 9 for the step class. Only the -ms-content-zooming: zoom and the overflow: auto CSS declarations are required to enable zooming. With the -ms-content-zoom-limit-min and the -ms-content-zoom-limit-max properties, you defined the minimum and the maximum zoom level. The former one is required if you want to enable zooming out, because the default minimum zoom level is 100 percent.

As you saw in the previous exercise, implementing zooming and panning is very easy using nothing more than CSS. In the next exercise, you extend the previous application with scrolling.


NOTE You can find the complete code to download for this exercise on this book’s companion website at www.wrox.com in the folder ZoomAndScrollTryItOut within the Chapter06.zip download.


Try It Out: Implementing Scrolling
To learn how you can create an application in which you can scroll using touch gestures, follow these steps:
1. Start Visual Studio and open the application you created in the previous exercise.
2. Open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L).
3. In the Solution Explorer window, double-click the default.html file to open it in the code editor.
4. Find the <body> element and replace its content (what you added in the previous exercise) with the following:
<div id="scroller">
  <div class="step">
    <img src="images/img1.jpg" />
  </div>
  <div class="step">
    <img src="images/img2.jpg" />
  </div>
  <div class="step">
    <img src="images/img3.jpg" />
  </div>
  <div class="step">
    <img src="images/img4.jpg" />
  </div>
</div>
5. Double-click the default.css file within the css folder in the Solution Explorer window to open it in the editor. Add the following code to the end of the file:
#scroller {
  overflow: auto;
  display: -ms-flexbox;
  width: 100%;
  height: 100%;
}
6. Start the application by selecting the Simulator on the toolbar. Click the Basic touch mode emulation icon on the right of the Simulator to enable touch gestures. Hover your mouse over the image, then hold down the left mouse button and move the image to left. Note that the image scrolls and the next image appears on the right.
7. Switch back to Visual Studio and add the following two code lines to the #scroller CSS rule:
-ms-scroll-snap-type: mandatory;
-ms-scroll-snap-points-x: snapInterval( 0%, 100% );
At this point your code should look like this:
#scroller {
  overflow: auto;
  display: -ms-box;
  width: 100%;
  height: 100%;
  -ms-scroll-snap-type: mandatory;
  -ms-scroll-snap-points-x: snapInterval( 0%, 100% );
}
8. Start the application in the Simulator and scroll the images using touch gestures. Note that now you always see a full image, because the scrolling is snapped to image boundaries.
You can test that the zooming and panning feature you created in the previous exercise also works.
How It Works
In this exercise, you extended the previous image viewer application with scrolling features, so your users now can use natural touch gestures to switch between the images.
In Step 4, you changed the UI of the application to display not only a single image, but four images. The images are independently wrapped into div separate elements with the step CSS class attached, which provides the zooming features as you learned in the previous exercise. All four images are wrapped into an outer div named the scroller that provides the scrolling functionality.
In Step 5, you configured the scroller div in CSS. To implement scrolling, you added the overflow: auto and the display: -ms-box CSS rules. With these two rules, the div automatically becomes scrollable using touch gestures.
In Step 7, you configured the snapping behavior of the scrolling. By setting the -ms-scroll-snap-type property to mandatory, you defined that the scrolling is always adjusted so that it will land on a snap-point. The snap-point that is selected is the one that is closest to where the scroll position would normally stop.
In the -ms-scroll-snap-points-x property, you defined where snap-points will be located along the x-axis. The 0% means the left edge and the 100% means the right edge of the image. The snapInterval defines that the specified distance should be repeated along the x-axis.

Canvas Graphics in Windows 8 Style Applications

Many applications require a drawing surface, where users can paint custom shapes, render text, and manipulate images on the fly. This challenge has been solved for a long time on the desktop, but in the browser, programmatic drawing was a painful issue before HTML5.

HTML5 introduces the <canvas> element, which provides a rectangular area where you can draw anything you want using the canvas drawing API. With the canvas element, you can do the following:

  • Draw shapes
  • Fill them with colors
  • Create gradients and patterns
  • Render texts and images
  • Manipulate pixels

In short, you can use canvas to dynamically create raster images in JavaScript.

It’s important to note that the canvas element behaves like a real canvas: it remembers only the last painted image. canvas doesn’t support layers, objects, or event handlers, so you cannot manipulate the previously created graphics. If you want to modify the image, you must redraw the canvas.

The disadvantage of this low-level API is that you cannot easily add interactivity to your drawings. On the other hand, this direct image drawing is really fast in modern web browsers. The latest browsers also support hardware-accelerated rendering that further speeds up the canvas operations, and makes the canvas element a perfect host even for graphics-intensive applications and games.

In Windows 8, you can use the canvas API in your Windows 8 style applications. In the next exercise, you learn the basics of the canvas API by drawing a smiling face in JavaScript.


NOTE You can find the complete code to download for this exercise on this book’s companion website at www.wrox.com in the folder CanvasTryItOut within the Chapter06.zip download.


Try It Out: Drawing on the Windows 8 Canvas
To learn how you can draw on the canvas in a Windows 8 style application, follow these steps:
1. Start Visual Studio 2012 by clicking its icon on the Start screen.
2. Select File &menuarrow; New Project (or press Ctrl+Shift+N) to display the New Project dialog box.
3. Select the Installed &menuarrow; Templates &menuarrow; JavaScript &menuarrow; Windows Store category from the left tree, and then select the Blank App project type in the middle pane.
4. Click OK. Visual Studio creates an empty project skeleton and opens the main default.js file in the code editor.
5. Open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L). Double-click the default.html file to open it in the code editor.
6. Find the template-generated <p>Content goes here</p> content between the <body> and the </body> tags and replace it with the following code:
<canvas id="canvas" width="400" height="400"></canvas>
7. In the Solution Explorer window, double-click the default.css file within the css folder to open it in the editor.
8. Add the following code to the end of the default.css file:
canvas {
  background-color: White;
  border: 3px solid orange;
  margin: 15px;
}
9. In the Solution Explorer window, double-click the default.js file within the js folder to open it in the editor.
10. Find the line that contains args.setPromise(WinJS.UI.processAll()); and add the following code lines after it:
var canvas = document.getElementById('canvas'),
var ctx = canvas.getContext('2d'),
 
var line = '#000';
var head = '#ffff00';
var eye = '#fff';
var pupil = 'green';
var mouth = '#FF0000';
var nose = 'BLACK';
 
ctx.save();
 
ctx.shadowColor = "#999";
ctx.shadowBlur = 20;
ctx.shadowOffsetX = 5;
ctx.shadowOffsetY = 5;
 
ctx.fillStyle = head;
ctx.beginPath();
ctx.arc(200, 200, 100, 0, Math.PI * 2, false);
ctx.fill();
 
ctx.restore();
 
ctx.strokeStyle = line;
ctx.lineWidth = "2";
ctx.stroke();
 
ctx.strokeStyle = mouth;
ctx.beginPath();
ctx.moveTo(135, 225);
ctx.quadraticCurveTo(200, 285, 265, 225);
ctx.stroke();
 
ctx.moveTo(135, 225);
ctx.quadraticCurveTo(200, 310, 265, 225);
ctx.stroke();         
 
ctx.strokeStyle = line;
ctx.fillStyle = eye;
ctx.lineWidth = '1';
 
ctx.beginPath();
ctx.arc(160, 160, 15, 0, Math.PI * 2, false);
ctx.stroke();
ctx.fill();
 
ctx.beginPath();
ctx.arc(240, 160, 15, 0, Math.PI * 2, false);
ctx.stroke();
ctx.fill();
 
ctx.fillStyle = pupil;
ctx.beginPath();
ctx.arc(162, 162, 6, 0, Math.PI * 2, false);
ctx.fill();
 
ctx.beginPath();
ctx.arc(238, 162, 6, 0, Math.PI * 2, false);
ctx.fill();
 
ctx.save();
 
ctx.fillStyle = nose;
ctx.translate(200, 190);
ctx.rotate(45 * Math.PI / 180);
 
ctx.beginPath();
ctx.fillRect(0, 0, 16, 16);
ctx.fill();
 
ctx.restore();
 
ctx.font = '48px Calibri';
var text = 'Smile!';
var textSize = ctx.measureText(text);
var textx = 200 - textSize.width / 2;
ctx.strokeText(text, textx, 360);
ctx.fillText(text, textx, 360);

Figure 6-22: The drawing on the canvas

c06f022.tif
11. Start the application by clicking the Debug &menuarrow; Start Debugging menu item (or by pressing F5). The results should resemble those shown in Figure 6-22.
How It Works
In this exercise, you created a simple Windows 8 style application that draws a smiling face on the canvas.
In Step 6, you added the canvas element to your HTML markup that hosts the drawing. Note that you explicitly specified the width and the height of the canvas element in the markup, which is very unusual, because, as you learned earlier, CSS is a much better place for these types of layout settings.
However, canvas is not an ordinary element! The width and the height attributes control the size of the coordinate space. If these attributes are missing, the coordinate space of the canvas defaults to 300 pixels width and 150 pixels height. Then, when you specify the width and the height for the canvas in CSS, the 300 &times; 150 pixels coordinate space is stretched to the specified size, which usually results a distorted drawing. To ensure that the drawing is not stretched, you should define the width and the height in the HTML. In this case, the canvas is 400 pixels wide and 400 pixels high.
In Step 8, you added the CSS settings for the canvas element. As you can see, you can control the borders, the background color, and the layout of the canvas, just like any other HTML element.
In Step 10, you added the code that renders the drawing. With the first two lines of code, you created the context object that exposes the API you can use to draw on the canvas.
Next, in the six code lines that begin with var, you defined the colors that you used later for styling fills and strokes. Note that you can define the colors in several ways, using their names, their RGB codes, uppercase, lowercase, and so on.
Next, with the first ctx.save() function, you saved the current drawing context. It is required, because the next lines that start with ctx.shadow change the shadow settings. Because these settings are global, all drawing elements inherit them later. The first object that is drawn is the yellow circle using the arc and the fill functions. Because shadow is only required for this object, the original context is restored with the ctx.restore function right after the circle is drawn.
The next three lines of code draw a 2-pixel black line around the previously drawn circle:
ctx.strokeStyle = line;
ctx.lineWidth = "2";
ctx.stroke();
In the next step, you drew the mouth with two lines. The first quadraticCurveTo function drew the upper lip, and the second drew the lower lip.
After the mouth, you drew the eyes with four circles. First, the style of the eyes is set to white fill color and thin black stroke with the following lines:
ctx.strokeStyle = line;
ctx.fillStyle = eye;
ctx.lineWidth = '1';

Figure 6-23: The translated and rotated coordinate space

c06f023.tif
Next, you drew the left eye and the right eye, and then the left pupil and the right pupil.
After the eyes, you drew the nose. The nose is a bit tricky, because it is a rotated rectangle. With the translate function, you moved the canvas origin from the upper-left corner to the center of the location of the nose, and then rotated the coordinate space by 45 degrees with the rotate function. At this point, the coordinate space is positioned as shown in Figure 6-23.
Because you wanted to apply this transformation only to the nose rectangle, the context is saved before drawing the nose, and then restored.
With the last six lines of code, you displayed the “Smile!” text under the face. measureText is a very useful function, because you can use it to calculate the required width for any text using the font size and font face currently set in the context. In this example, you used it to correctly position the text in the horizontal center of the drawing. Finally, with the strokeText and the fillText functions, you rendered the outlined text.

Using the Windows 8 Animation Library

Animations play an important role on the Windows 8 platform, because they bring Windows 8 style applications to life. Good animations are not just beautiful, but they also enhance the user experience by giving users the confidence of knowing what has happened, or what will happen. Animations are an integral part of the Windows 8 design language.

However, creating good animations is difficult. Although animations can add beauty and unique personality to your application, they must be consistent throughout the whole platform to be purposeful and not distracting. Additionally, in the world of battery-powered devices, animations must be optimized and fully respect the user’s device.

To answer these challenges, Microsoft provides the Windows 8 Animation Library, which helps you to easily add optimized and consistent animations to your Windows 8 style application. The Windows 8 Animation Library covers the following scenarios:

  • Application navigation
  • Animating content
  • Revealing or hiding UI elements
  • Animating collection changes
  • Animating selections

Just like many other functions within the WinJS, animations are also using promises. To provide a fast and fluid user experience, animations are played on a separate thread and not blocking the UI. The functions are all asynchronous, and return promise objects that you can use to chain animations. Internally, the animations are built on standards-based CSS3 animations and transitions, and optimally utilize the hardware capabilities of the device.

In the next exercise, you create a Windows 8 style application and enhance the user experience by adding the most common animations.


NOTE You can find the complete code to download for this exercise on this book’s companion website at www.wrox.com in the folder AnimationTryItOut within the Chapter06.zip download.


Try It Out: Using the Windows 8 Animation Library
To learn how you can use the Windows 8 Animation Library in a Windows 8 style application, follow these steps:
1. Start Visual Studio 2012 by clicking its icon on the Start screen.
2. Select File &menuarrow; New Project (or press Ctrl+Shift+N) to display the New Project dialog box.
3. Select the Installed &menuarrow; Templates &menuarrow; JavaScript &menuarrow; Windows Store category from the left tree, and then select the Blank App project type in the middle pane.
4. Click OK. Visual Studio creates an empty project skeleton and opens the main default.js file in the code editor.
5. Open the Solution Explorer window by selecting the View &menuarrow; Solution Explorer menu item (or by pressing Ctrl+Alt+L). Double-click the default.html file to open it in the code editor.
6. Find the template-generated <p>Content goes here</p> content between the <body> and the </body> tags and replace it with the following code:
<h1>Animations</h1>
 
<h2>Content</h2>
 
<p id="content1">
  Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh
  euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad
  minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut 
  aliquip ex ea commodo szeretlek. Tucsok autem vel eum iriure dolor in hendrerit 
  in vulputate velit esse molestie consequat, vel illum dolore eu feugiat nulla
  facilisis at vero eros et accumsan et iusto odio dignissim qui blandit praesent 
  luptatum zzril delenit augue duis dolore te feugait nulla facilisi. 
</p>
 
<p id="content2">
  At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis 
  praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias
  excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui 
  officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem 
  rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est
  eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere 
  possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem 
  quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et 
  voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic 
  tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias  
  consequatur aut perferendis doloribus asperiores repellat.
</p>
 
<button id="btnShow">Show content</button>
<button id="btnNext">Next content</button>
<button id="btnHide">Hide content</button>
 
<h2>Panels</h2>
 
<p>
  <button id="btnShowPanel">Show panel</button>
  <button id="btnHidePanel">Hide panel</button>
</p>
 
<div id="panel">
  <p>Hello from a side panel!</p>
</div>
You can write any content between the <p> tags. For example, you can copy and paste the well-known Lorem ipsum placeholder text (as shown here) from http://lipsum.com.
7. In the Solution Explorer window, double-click the default.css file within the css folder to open it in the editor.
8. Replace the template-generated content with the following code:
body      { margin: 15px; }
p         { line-height: 1.8em; }
h2        { margin-top: 20px; }
#content1 { opacity: 0; }
#content2 { display: none; }
#btnNext  { display: none; }
#btnHide  { display: none; }
    
#panel
{
  position: fixed;
  right: 0px;
  top: 0px;
  width: 450px;
  height: 100%;
  background-color: #323232;
  opacity: 0;
  z-index: 1;
}
 
#panel p
{
  position: absolute;
  top: 45%;
  text-align: center;
  width: 100%;
}  
9. In the Solution Explorer window, double-click the default.js file within the js folder to open it in the editor.
10. Find the line that contains the Initialize your application here comment and add the following code lines after it:
var headings = document.querySelectorAll('h1, h2'),
WinJS.UI.Animation.enterPage(headings, { top: '100px', left: '500px' });
 
btnShow.addEventListener('click', onBtnShowClicked);
btnNext.addEventListener('click', onBtnNextClicked);
btnHide.addEventListener('click', onBtnHideClicked);
 
btnShowPanel.addEventListener('click', onBtnShowPanelClicked);
btnHidePanel.addEventListener('click', onBtnHidePanelClicked);
11. Scroll down and insert the following code after the app.start(); line:
function onBtnShowClicked() {
  WinJS.UI.Animation.enterContent(content1);
  btnShow.style.display = 'none';
  btnNext.style.display = 'inline';
}
 
function onBtnNextClicked() {
  WinJS.UI.Animation.exitContent(content1).then(function() {
    content1.style.display = 'none';
    content2.style.display = 'block';
    btnNext.style.display = 'none';
    btnHide.style.display = 'inline';
    return WinJS.UI.Animation.enterContent(content2);
  });
}
 
function onBtnHideClicked() {
  WinJS.UI.Animation.exitContent(content2);
  content1.style.display = 'block';
  content2.style.display = 'none';
  btnShow.style.display = 'inline';
  btnNext.style.display = 'none';
  btnHide.style.display = 'none';
}
 
function onBtnShowPanelClicked() {
  panel.style.opacity = '1';
  WinJS.UI.Animation.showPanel(panel);
}
 
function onBtnHidePanelClicked() {   
  WinJS.UI.Animation.hidePanel(panel).then(function () {
    panel.style.opacity = '0';
  });    
}
11. Start the application by clicking the Debug &menuarrow; Start Debugging menu item (or by pressing F5). Note that the titles are flying to their final positions from the lower-right corner when the application starts.
12. Click the “Show content” button. Note that the paragraph text doesn’t appear immediately, but fades in and floats to its final position.
13. Click the “Next content” button. Note that the paragraph text changes to a longer text, and the controls on the page move down to provide enough screen real estate for the new content.
14. Click the “Show panel” button. Note that a narrow panel slowly flies in from the right without changing the other content on the page. You can see it in Figure 6-24.

Figure 6-24: The animations sample

c06f024.tif
Click the “Hide panel” button to fly-out the panel.
15. Click the “Hide content” button to hide the paragraph text and return the application to its start state.
How It Works
In this exercise, you created a simple Windows 8 style application that demonstrates some basic animations using the Windows 8 Animation Library.
In Step 6, you created the basic markup of the application. Note the following in the HTML:
  • An h1 and two h2 tags that render the title and the headings of the application.
  • Two p tags that contain the content that is animated when you click the “Show content,” “Next content,” and “Hide content” buttons. The first paragraph is displayed when the application starts, and it switches over to the second paragraph when you click the “Next content” button.
  • The buttons are rendered using button elements.
  • The right panel is created using a div element.
  • Most elements have an id attribute to make them uniquely accessible from JavaScript and CSS code.
In Step 8, you set the visual appearance of the elements on the page using CSS.
You used the display:none CSS declaration to completely hide elements, and the opacity:0 declaration to make elements invisible. The difference between the two is that invisible elements continue to consume screen space, whereas hidden elements are completely removed from the UI, thus giving up their space to other elements.
Note how the panel div is transformed to a full-height box and moved to the right side of the page using the position, right, top, width, and height properties. The z-index property ensures that the panel is rendered on another layer above the other UI elements.
In Step 10, you added some code that runs when the application starts.
The first line of code creates a JavaScript list with all headings (h1 and h2 elements) on the page. The second line animates these elements using the enterPage animation of the Windows 8 Animation Library. Note the second parameter of the enterPage function that sets the offset from where the headings fly into their final positions. In this case, the headings appear at 500 pixels right and 100 pixels down from their final positions when the page loads, then the enterPage animation moves them to the position defined in HTML and CSS. This offset setting is used here only for demonstration purposes. Microsoft recommends setting the offset parameter to null to create Windows 8 style animations.
The next five code lines in the application initialization code attach event-handler functions to the click event of the buttons on the page. Note that you can directly access the HTML objects on the page without calling document.getElementById by using their id defined in the HTML markup.
In Step 11, you implemented the event-handler functions that are executed when the user clicks the buttons on the UI.
You used the style.display property to show or hide the UI elements. Setting this property to 'none' hides the element. Setting this property to 'inline' or 'block' displays the inline or block elements accordingly. The style.opacity property behaves similarly. When you set it to 0, the element becomes invisible. When you set it to 1, the element becomes visible.
When you click the “Show content” button, the onBtnShowClicked function is called that starts the enterContent animation for the paragraph text, hides the “Show content” button, and displays the “Next content” button. Because the enterContent function starts the animation asynchronously, the buttons are changing while the text is still animating. The effects are simultaneous.
When you click the “Next content” button, the onBtnNextClicked function is called. This event handler starts the exitContent animation asynchronously, and uses the then function to execute additional code only after the animation is completed. After the first paragraph text is slowly faded out, the “Next content” button is hidden and the “Hide content” button is shown. Finally, the enterContent animation is started that fades in the second paragraph.
The onBtnHideClicked function is called when you click the “Hide content” button, and it uses the exitContent animation and the style.display property to restore the elements to their original state.
The onBtnShowPanelClicked and the onBtnHidePanelClicked functions are called when you click the “Show panel” and the “Hide panel” buttons accordingly. When you click the “Show panel” button, the showPanel animation starts and flies the panel in from the right of the screen. When you click the “Hide panel” button, the hidePanel animation flies the panel out from the screen. Here you can see another example of effect chaining using the then function. The panel is made invisible using the style.opacity property only after the hidePanel moved it out from the screen.

Summary

In the browser, HTML, CSS, and JavaScript have already been proven to be suitable for creating real-world applications. In the past few years, the techniques and the practices have evolved, and web developers also have become ready to implement complex solutions using mature patterns with pure HTML and JavaScript. With Windows 8, Microsoft opens the Windows developer platform to web developers by enabling them to reuse their existing knowledge and develop Windows 8 style applications. The same technologies that power all websites are now first-class citizens on the client as well.

The features and services of Windows Runtime are fully available to JavaScript applications. A specific component, the Windows Library for JavaScript (WinJS), ensures that JavaScript developers can access these features and services in a well-known and natural way, regardless of the characteristics and limitations of the language.

Additionally, this library provides helpers to common coding tasks to make the lives of developers easier. With the WinJS controls, you can quickly create Windows 8 style applications that can easily manage data using declarative or programmatic data binding. The Windows 8 Animation Library helps you to add beauty, energy, motion, and personality to your applications via device-optimized animations.

Exercises

1. In what four groups can you sort the new HTML5 elements?
2. What is the Windows Library for JavaScript (WinJS)?
3. What is data binding?
4. What are CSS media queries?
5. Why should you use the Windows 8 Animation Library instead of implementing your own animations in JavaScript?

NOTE You can find answers to the exercises in Appendix A.

What You Learned In This Chapter

TopicKey Concepts
HTML5HTML5 is the next generation of the HyperText Markup Language standard that enables you to create rich Internet applications in the browser.
Windows Library for JavaScript (WinJS)The Windows Library for JavaScript (WinJS) is a JavaScript code library that publishes system-level features and helpers for common coding patterns to simplify creating Windows 8 style applications in JavaScript.
document.getElementById and document.getElementsbyTagNameWith the document.getElementById and the document.getElementsByTagName functions, you can get references to DOM elements in JavaScript code.
addEventListenerWith the addEventListener function, you can attach a function to a DOM element to react to user actions.
Simple bindingSimple binding is a type of data binding that connects a single data value to a single UI element.
List bindingList binding is a type of data binding that connects an array of values to a complex UI element that can handle multiple values in a list or table.
WinJS.UI.ListViewListView is a WinJS control that provides the standard listing behaviors in Windows 8 style applications.
@mediaThe @media keyword introduces a CSS media query that you can use to tailor your CSS selectors to devices with specific capabilities.
Snapped modeSnapped is one of the display modes of Windows 8 style applications. In snapped mode, the application is docked to the edge of the screen in a 320-pixel-wide frame.
canvascanvas is an HTML5 element that enables you to create raster graphics with JavaScript.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset