Вы находитесь на странице: 1из 257

(This page intentionally left blank)

Unit 1:
Unit 1: Introducing the Course

About the Course


Fast Track to Intel XDK New is designed to
teach experienced web developers and
designers how to design, implement, and
package web applications for mobile devices.
The course is task-based, with you learning by
performing a series of hands-on tasks. Over the
next four hours you will create a web
application named Friends with Beer that
enables users to create a themed contact
manager that uses many mobile-specific
features such as calculating geoposition, video
playback, push notifications, phone dialing,
sending emails, and more!
Along with covering the basics of the Intel
XDK New, the course focuses on best practices
and design, stressing the importance of
usability, optimization, and maintainability of
cross-device compatible applications.
Lab instructions are designed for Windows or
OS/X users who have an Android phone.

2013 Intel Corporation

Figure 1: The app


that you'll build in this
course.

1-1

Fast Track to Intel XDK New

Introducing Intel XDK New


Intel XDK NEW, enables you to easily create, test, and package crossdevice compatible HTML5-based mobile apps. Intel XDK New runs on
Windows 7,8, OS/X and Ubuntu Linux desktops. It seamlessly integrates
many best-of-breed mobile web development technologies into an easy-touse, integrated development environment.

Figure 2: The Intel XDK New GUI

Choose a Framework
You can develop your apps using popular HTML5 mobile
frameworks including

1-2

Bootstrap a popular front-end framework for faster


and easier web development.

jQuery Mobile the write less, do more library for


rapidly coding mobile apps.

Intel's App Framework - an open source HTML5 UI


framework

Topcoat a fast-performing CSS framework from Adobe that includes


icons, fonts, and themed components for mobile devices.

2013 Intel Corporation.

Unit 1: Introducing the Course

Develop visually, code fast and furiously


Intel XDK NEW integrates an easy-to-use, drag & drop app designer
with Brackets, a highly-regarded, open-source editor with syntax helpers
and auto-completion.

Figure 3: The integrated Brackets code editor.

Emulate popular devices


Use the built-in Apache Ripple device emulator to simulate your app
running on multiple devices, from different geographic locations, varying
bandwidth conditions, and changing orientations. Use the integrated
Google Chrome Dev Tools to troubleshoot runtime issues.

Figure 4: Using the built-in device emulator.

2013 Intel Corporation.

1-3

Fast Track to Intel XDK New

Trust, But Verify


By loading Intel App Preview onto your mobile devices, you'll be able to
easily:

Run your app on physical devices without rebuilding

Debug your app while it's running on the device, using the integrated
weinre remote debugger.

Conduct performance profiling

Check out demo apps.

Intel App Preview is available for iOS, Android, and Windows Phone.

Figure 5: Test your app on physical devices with Intel App Preview

1-4

2013 Intel Corporation.

Unit 1: Introducing the Course

Package for App Stores


After you've completed your testing, use Intel XDK's integrated Apache
Cordova framework to build native apps for all the popular mobile
platforms.

Integrate native features and add cloud support


The Intel XDK API that includes features not currently available in
Cordova, including:

Facebook login API

Android multi-touch

Oauth support

Enhanced audio

Accelerated canvas

In addition, you can quickly add cloud-based features from appMobi to


such as push notification support, user management, e-commerce, and
cloud hosting.

2013 Intel Corporation.

1-5

Fast Track to Intel XDK New

Reviewing the Course Objectives


After completing this course, you should be able to:

Develop web and native apps for mobile devices

Visually design and implement a graphical user interface.

Create input forms that read and submit data to/from an application
server

Request JSON data from an application server

Integrate mapping, geolocation, and push notifications into a mobile


app.

Deploy audio and video assets

Theme your application to meet branding standards

Test and package your app to run natively on Android and iPhone
devices.

Reviewing the Course Prerequisites


The knowledge prerequisites for this course are:

Prior experience with HTML 5

A casual understanding of CSS

Intermediate JavaScript coding skills and, in particular, familiarity with


JavaScript Object Notation

Required Software
The following software is REQUIRED to be installed on your computer:

Intel XDK
http://xdk-software.intel.com/

Fast Track to Intel XDK student files


http://www.xdktraining.com/student.zip

The following software is REQUIRED to be installed on your mobile


device:

1-6

Intel App Preview


Available on iOS, Android, and Microsoft stores.
2013 Intel Corporation.

Unit 1: Introducing the Course

Reviewing the Course Format


This course is divided into ten units, each of which presents new
information and contains demonstrations, walkthroughs, and a lab. At the
end of each unit, you will find a summary and a short review to test your
knowledge of the units content.
The following icons are used throughout the guide:
Concepts introduce new information.

Demonstrations illustrate new concepts.

Walkthroughs guide you, with the instructors assistance, through


procedures in a hands-on context.

Labs let you practice new skills on your own.

Summaries provide a brief synopsis of the units content.

Reviews test how well you remember the concepts from the unit.

Best Practices provide you with helpful insights and information.

2013 Intel Corporation.

1-7

Fast Track to Intel XDK New

Outlining the Course Content

1-8

Unit 1: Introducing the Course

Unit 2: Getting Started


Introducing the Intel XDK New
Reviewing the features and benefits of HTML5 / CSS3
Using Debugging Techniques
Getting Help

Unit 3: Designing Views


Defining Pages
Using Layout Controls
Linking to Pages
Adding text and images

Unit 4: Working with Data


Using jQuery to make data requests via AJAX
Outputting structured data into a List
Reading Data from the Contact's list
Storing data on the Device with WebSQL

Unit 5: Implementing Forms


Using the Forms Widgets
Implementing Data Validation
Saving Form Data

Unit 6: Implementing GEO Features


Geocoding Addresses
Acquiring the Device Position
Calculating Distance to Targets
Visualizing Data on a Map

2013 Intel Corporation.

Unit 1: Introducing the Course

Unit 7: Using Device Features


Dialing the Phone
Sending Email
Launching Turn By Turn Directions
Using the Accelerometer
Handling Push Notifications

Unit 8: Handing Multimedia


Understanding the features and capabilities of HTML5
Playing Audio
Playing Video

Unit 9: Theming your App


Using CSS3 Features and Capabilities
Applying CSS3 Backgrounds
Using ThemeRoller to theme your UI components

Unit 10: Going Native


Creating Production Web Builds
Creating Native Builds for iOS
Exercise: Packaging a Native iOS Build

2013 Intel Corporation.

1-9

Fast Track to Intel XDK New

Demonstration 1-1: Viewing the Applications


Observe as your instructor introduces the applications that you will be
building during the exercises:
You will build the Friends with Beer mobile application during your
instructor-led walkthroughs in the following order:

About Friends with Beer (Home Page)

Beer List

Friends with Beer Contact List

Friends with Beer Contact Data Entry Form

Friends with Beer Contact Detail

Friends with Beer Video

Reviewing the Application Intro Screens

The Friends with Beer Home Page


contains simple html markup. It's
designed to help you get comfortable
using the Intel XDK visual designer.

1 - 10

2013 Intel Corporation.

The Beers List displays a list of


beers that were downloaded from a
REST-based web service and
cached into an HTML5 WebSQL
database.

Unit 1: Introducing the Course

The Contact List is driven from data


stored in a WebSQL database. Clicking
on the button in the top-left corner
enables you to import data from your
phone's native contacts app. Users can
actually shake the device to select a
friend at random.

2013 Intel Corporation.

The Contact form enables you to


edit information about your
contacts. It also converts their
street address to a lat/lng position
on-the-fly and has client-side data
validation.

1 - 11

Fast Track to Intel XDK New

Reviewing the Application Using Device Features

The Friends with Beer Detail Page


enables the user to activate the device's
phone dialer, email application, and
navigation app. It also uses Google
Maps to display real-time traffic
conditions around your friend's
location.

1 - 12

2013 Intel Corporation.

The Video page displays a


streaming video from Vimeo and
an mp4 from a web server so that
the user will never have to feel like
they're drinking alone.

Unit 1: Introducing the Course

Walkthrough 1-1: Installing the Courseware


In this lab, you will perform the following tasks:

Install Intel XDK New on your desktop

Install Intel App Preview on your mobile device

Download and install the course files

Steps
Download and Install Intel XDK

1. Open a web browser to the following URL:


http://xdk-software.intel.com/
2. Click the Download Intel XDK New button.
OS/X Users:

3. Open the downloaded .dmg file


4. Double-click on the .pkg file
5. Complete the steps in the installation wizard.
6. Select Go > Applications and verify that XDK New is present.
Microsoft Windows 7+ Users:

7. Open the downloaded .exe file


8. Complete the steps in the installation wizard
9. Verify that Intel XDK New appears in your Start menu.
Log into Intel XDK

10. Launch Intel XDK New


11. Click on Need to sign up for an Account?
12. Fill out the form, entering your name, email address, password, and
country. Note the following:
Passwords must be between 8-15 characters in length
Passwords must contain at least one alpha character
Passwords may not contain non-English characters
Passwords must contain at least one number
Passwords must contain at least one special character (!@#$%)
13. Check the Terms and Conditions checkbox.
14. Sign up for the newsletters.
2013 Intel Corporation.

1 - 13

Fast Track to Intel XDK New

15. Click the Submit button.


16. Enter your username and password.
17. Turn on the checkbox labeled Keep me logged in on this computer.
18. Click Submit.
Install Intel App Preview on your Mobile Device

19. Configure your mobile device to be on the same wireless network as


your computer.
20. Open Google Play on your Android phone.
21. Search for Intel App Preview
22. Tap on Intel App Preview
23. Tap on the Install button.
24. Tap the Accept button.
25. When the installation process as completed, tap the open button.
26. Sign into the app using the Intel XDK credentials that you created
earlier in this exercise.
Download and Unzip the Exercise Files

27. Download the exercise files from


http://www.xdktraining.com/exercises.zip
28. Unzip the files into your home/documents folder.
End of Walkthrough --

1 - 14

2013 Intel Corporation.

Unit 1: Introducing the Course

Unit Summary

The course is presented through a combination of lectures and handson exercises.

The course has been designed assuming that you already understand
HTML, CSS, and some Javascript.

The course consists of 10 units that cover the essentials of developing


mobile apps with Intel XDK New.

The course focuses on developing web and native applications for


mobile devices.

You will build a web application to keep track of your friends with
beer.

2013 Intel Corporation.

1 - 15

(This page intentionally left blank)

Unit 2:
Getting Started with Intel XDK New

Unit Objectives
After completing this unit, you should be able to:

Understand the features and capabilities of Intel XDK New

Use the visual designer to create a Hello World page in your app.

Use the code editor to add JavaScript to your app.

Test your app on the simulator and your mobile device.

Package your app as a native application for distribution on App stores.

Introducing Intel XDK New


Debugging Your Apps
Getting Help

Unit Topics

2-1
2013 Intel Corporation.

Fast Track to Intel XDK New

Introducing Intel XDK New


The Intel XDK NEW development system is for those developers who
wish to use their HTML5 expertise to build hybrid HTML5 apps for
mobile devices (e.g., phones and tablets) and other platforms that host
HTML5 web apps (such as a Google Chrome* extension or a mobile web
site).

Going with an HTML 5 Solution


Developers and corporate IT increasingly turn to HTML5 as a solution to
meet the critical, time-sensitive demands of their organizations.
Developing mobile apps with HTML5 offers several key advantages over
native app development:

Native apps are developed to run on a single device platform whereas


HTML5 apps use the same codebase to run on multiple devices and
operating systems.

Native apps are typically distributed via app stores, however, HTML5
apps can also be deployed as mobile web sites that run in a user's
mobile web browser.

HTML5 apps use open-source technologies.

Native OS apps can get lost among the hundreds of thousands of


apps in app stores. Mobile web apps are crawlable by search engines.

Mobile web apps are instantly updatable on a web server.

Instead of having to learn Java or Objective-C, web developers can


leverage their existing skill sets to rapidly create mobile apps.

HTML5-based apps tend to be less affected by changes in the mobile


operating system.

Navigating the Tooling Quagmire


Historically, one of the biggest challenges faced by mobile web app
developers has been dealing with the lack of a truly integrated development
environment. Most developers spend their days toggling between an html
design tools, a javascript code editor, a CSS editor, web browser,
debugger, command-line build utilities, FTP, mobile simulators, and more.
Intel XDK NEW is the first truly integrated development environment that
application consists of a set of best-of-breed tools that help you code,
debug, test and build mobile web apps and hybrid HTML5 apps for
multiple target platforms.

2-2
2013 Intel Corporation.

Getting Started with Intel XDK New

Reviewing the Intel XDK New Interface


Intel XDK New is organized around the sequence that HTML app
developers follow when they create and package an application:
1. Develop
Use the visual designer to prototype your graphical user interface and
handle user interactions by hand-coding javascript with the built-in
Brackets editor.
2. Emulate
Validate that your application looks and functions properly across
multiple screen resolutions, under varying bandwidth conditions, and
from different geographic locations by using the embedded Apache
Ripple emulator. Debug application errors with the integrated Google
debugger.
3. Test
Verify that your app performs as expected by running from Intel's App
Preview container. Debug the app and chart its performance as it runs
on your device by using the embedded weinre remote debugger.
4. Build
Package the app for distribution via app stores or the web using the
integrated Apache Cordova toolkit. Test device-specific features.
5. Services
Integrate cloud-based services into your app from appMobi, including
push-notifications, e-commerce, live updates, in-app purchasing, and
hosting.

2-3
2013 Intel Corporation.

Fast Track to Intel XDK New

Designing Apps
As depicted in Figure 1, Develop mode enables you to visually prototype
the look and feel of your application.

Figure 1: Develop / Design View

The Project Selector enables you to load pre-existing projects or


create new projects into the Intel XDK GUI.

Your app's views appear in the Project Files panel.

While in Design view, you can drag and drop components from the
UI Controls Palette onto the Design Canvas.

UI controls that you've dropped onto the Design Canvas may be


configured by changing settings in the Property Editor.

The Product Version indicator alerts you as to the release version


of the XDK that is currently in use.

2-4
2013 Intel Corporation.

Getting Started with Intel XDK New

Developing Apps
As depicted in Figure 2, toggling to Code view enables you to modify the
code generated by the visual designer, as well as edit javascript and css
application assets. Code hints appear as you type.

Figure 2: Using the integrated Brackets editor to hand-code your app

Running Your App in an Emulator


As illustrated in Figure 3, clicking on the Emulate tab runs your app in the
Apache Ripple emulator.

Figure 3: Simulate your app running on multiple devices.

The emulator enables you to simulate your app running on multiple devices
under varying environmental conditions:
2-5
2013 Intel Corporation.

Fast Track to Intel XDK New

The Devices panel allows you to simulate your app running on a


variety of popular devices including the iPad, iPhone, Google Nexus,
Microsoft Surface Pro, Motorola Droid 2, Nokia Lumina 920,
Samsung Galaxy S, and Samsung Galaxy tab.

The Information panel provides


you with metrics regarding your
selected device, including OS,
screen resolution, pixel density, and
the http user agent that's transmitted
on each request.

The Accelerometer panel enables


you to simulate moving the device
along its x, y, and z axis. This is
vital for testing movement-based
controls. You can also have it
virtually shake the device.

The Live Update Service panel


simulates your app receiving an
update service request from
appMobi.

The Device & Network Settings


panel enables you to simulate
Figure 4: Testing accelerometerdifferent degrees of network
based controls.
throughput (from WiFi to no
connection), as well as toggle locales from English to French or
German.

The Geo Location panel allows you to simulate how your app would
behave if it were running from different physical locations. You can
also configure heading, speed, altitude, GPS accuracy, and GPS
timeout. You can even have it replay a route that was saved to a GPS
Exchange Format (GPX) file.

The PushMobi panel allows you to inspect how your application


would behave if it received a push-notification message.

2-6
2013 Intel Corporation.

Getting Started with Intel XDK New

Testing your app on a device


The Test module, depicted in Figure 5, enables you to easily upload your
application to a testing server. You can then launch it on any device that's
running the Intel App Preview mobile application.

Figure 5: Upload your app and test it on devices using Intel App Preview

You'll typically test apps on physical devices


by completing the following steps:
1. In Intel XDK New, click on the Test tab.
2. Click on the Push Files button
3. Open Intel App Preview on your mobile
device.
4. Tap on the Server Apps tab.
5. Tap on the camera icon, located in the
top-right corner of the app.
6. Scan the QR code in the XDK with your
phone's camera.
Once the QR code has been scanned, the app
will be automatically downloaded and
executed.
You can debug the app as it's running on yourFigure 6: Intel App Preview
device by using the built-in weinre remote
debugger.
2-7
2013 Intel Corporation.

Fast Track to Intel XDK New

Generating Production Builds


The Build tab, as depicted in Figure 7, uploads your app to a cordovabased build server, packaging your code as a native app for distribution
across popular app stores or for distribution within your enterprise. Options
include:

iOS Ad-Hoc
Distribution

Windows 8 Store

iOS App Store

Android

Windows Phone 8

Tizen

Amazon

Nook

Figure 7: Intel XDK uses Apache Cordova to convert your web app into
native apps for all popular platforms.

2-8
2013 Intel Corporation.

Getting Started with Intel XDK New

As illustrated by Figure 8, some vendors will require you to upload


distribution certificates and/or supply authentication credentials.

Figure 8: Uploading certificates and a provisioning profile for an iOS App


Store production build

You can also have XDK New create a distribution package for deployment
across the following web platforms:

WebApp
Enables you to post your code on a local or remote web server, or host
in AppMobi. (Your code may be downloaded as a .zip file)

Chrome
Packages your app for distribution in the Google Chrome store.

Facebook
Packages your app for distribution via the Facebook social network.

2-9
2013 Intel Corporation.

Fast Track to Intel XDK New

Using Cloud Services


As illustrated by Figure 9, Intel XDK New features tight integration with
appMobi cloud services.

Figure 9: Using the appMobi hosting service

While you are not obligated to use appMobi, it is a convenient resource for
providing the following application support resources:

HostMobi can host your app in a PHP, .NET, or Node.js server


environment. Edge-cached hosting delivers the best performance for
on-the-go web apps, and hostMobi provides that through our
partnership with Amazon's Elastic Computing Cloud, (which now
spans the entire globe).

Live Update enables you to notify users that a new version of your
app is available. You have the option to push app updates immediately
instead of waiting for your users to upgrade at their leisure.

Storeview is a cloud-based reporting service that aggregates detailed


app analytics from the most popular app stores and displays them in an
interactive dashboard.

Pushmobi enables you to send push notifications to your subscribers.


You can target messages to a particular user target users based on
search filters.

1Touch is an in-app purchase (IAP) cloud service, that allows you to


interface with various app stores using a single line of javascript.
1Touch takes away the pain of integrating with the various app stores
and payment providers. With a single function call you can sell in-app
items on IOS, Android, Windows8, Windows8 Phone, Facebook and
the Chrome Store.

2 - 10
2013 Intel Corporation.

Getting Started with Intel XDK New

Walkthrough 2-1: Getting Started


In this lab, you will perform the following tasks:

Log into Intel XDK

Create a new project

Design a hello world page

Test your app in the emulator

Package your app for distribution

Install your app on your Android device

Steps
Create a New Project

1. Launch Intel XDK New


2. Click on the Start a New Project button
3. Click on Start with App Designer
4. Enter a project name of MyHelloWorld
5. Click the Create button.
6. Click the No Thanks button.
7. Click the Let's Go! button.
8. In the left panel, click on index.html. The Select a Framework dialog
box will appear.
9. Click on the jQuery Mobile radio button.
10. Click on the Select button.
Design a Page

11. From the Controls panel, drag a Header and drop it onto the design
canvas.
12. In the Header Settings panel, turn on the checkbox adjacent to the Title
property and enter the following title:
Friends with Beer

13. Turn on the Fixed checkbox.


14. From the Controls > Media panel, drag a Text control and drop it
underneath the Header on the Design canvas.

2 - 11
2013 Intel Corporation.

Fast Track to Intel XDK New

15. In the Text Settings panel, change the text to the following:
Welcome to Friends with Beer!

Display your page in the Emulator

16. Click on the Emulate tab.


17. In the Devices panel, select Google Nexus 4.
18. In the Devices panel, toggle the orientation of the emulated device by
clicking on the landscape orientation button.
19. In the Device & Network Settings panel, note that you can emulate
different network lag conditions.
Run Your App on Your Mobile Device

20. Click on the Test tab.


21. Click the Sync button.
22. Open Intel App Preview on your mobile device.
23. Tap the Server Apps button.
24. Tap the Camera button located in the top right corner of the GUI.
25. Scan the QR code on your desktop.
26. Tap OK. Your app should launch.
Build your App for Native Distribution

27. Return to XDK New on your desktop.


28. Click the Build tab.
29. Click the Android Build button.
30. Click the Build App Now button.
31. Click the Download Build button and save the generated .apk file to
your desktop.
32. Email the .apk file to yourself.
33. Open the email on your Android phone.
34. Tap on the .apk file attachment.
35. Click on the Install button.
36. Click Open. Your app should open.
Congratulations. You've just built a native mobile app!

2 - 12
2013 Intel Corporation.

Getting Started with Intel XDK New

Debugging Your Apps


As you develop your apps, you'll inadvertently insert bugs into your
program which will need to be eradicated as quickly and efficiently as
possible. Most of your bugs will likely appear when you run your app in
the emulator. Others may not show up until you run the app on a physical
device. Fortunately, XDK New has both of these scenarios covered.

Debugging in the Emulator


Intel XDK New
features an integrated
Chromium developer
that you can invoke by
clicking the debugger
button from Emulate
mode, as depicted in
Figure 10.
The debugger enables
you to inspect the
DOM of your
Figure 10: Activating the Debugger
application, review all
HTTP requests, read the contents of cookies and HTML5 local storage, and
can even provide hints as to how to optimize your application's
performance.
Most importantly, it enables you to set breakpoints and step through your
code interactively while monitoring the contents of variables.

Figure 11: The integrated Chromium debugger.

2 - 13
2013 Intel Corporation.

Fast Track to Intel XDK New

The debugger is partitioned into the following seven segments:

Label

Description

Elements

Enables you to click on any area in your browser and


inspect its markup. It also displays all the CSS applied to
the element and allows you to selectively enable, disable,
and modify individual styles.

Resources

Enables you to review the contents of HTML5 local


database (SqlLite), HTML5 Local Storage, HTML5 Session
Storage, HTTP cookies, and the HTML5 Application
Cache.

Network

Displays all HTTP communications. This is particularly


useful for troubleshooting AJAX requests. Displays both
data transmitted via the HTTP header to the server as well
as the content returned from the server.

Sources

Displays all of the JavaScript files that were loaded into the
browser as part of the request. You can set breakpoints and
step through your code one line at a time. You can also
define watch expressions to keep an eye on the contents of
your variables.

Timeline

Displays the time to download files from the server, the


time to execute scripts, and the time to render the output.
Use the timeline to develop insights into where your
bottlenecks might be in your code as well as benchmark
your changes.

Profiles

Similar to the timeline, the Profiles panel captures the


execution of your application and then displays the
percentage of CPU utilization that was required to execute
specific methods or handle events. You can also profile the
performance of your CSS to see how long selector matching
took and take a heap snapshot to understand memory
distribution among your page's Javascript objects and
related DOM nodes.

Audits

Evaluates the performance of your application and provides


helpful optimization tips.

Console

Displays error messages as well as the output from


executing console.log() statements. You can also execute
javascript code interactively in this view.

2 - 14
2013 Intel Corporation.

Getting Started with Intel XDK New

Programmatically Setting Breakpoints


You can set programmatic breakpoints by inserting the following command
into your JavaScript:
debugger;

If the Chromium debugger is active when this statement is encountered,


execution of your app will pause and your script will appear in the Sources
section as depicted in Figure 12).

Figure 12: Active breakpoint

As depicted in Figure
13, you can use the
debugger controls to
interactively step
through your code.
You can also set watch
expressions in order to
view how your code
changes the contents of
your variables.

Figure 13: Using the debugger's step controls

2 - 15
2013 Intel Corporation.

Fast Track to Intel XDK New

Outputting Variables to the Debugger Console


Use the console.log() command to dump the contents of Javascript
variables to the Chromium debugger console as illustrated below:
<script type="application/javascript">
function init() {
$('#debugBtn').bind('click', function(e) {
debugger;
for (var i=0; i<5; i++) {
console.log(i);
}
});
}
</script>

Figure 14: Variables that are output via console.log appear in the Chromium
debugger Console view

Programmatically Interacting with Your Application


The Chromium debugger can do far more than just report errors and output
the results of console.log() statements. You can actually use it to interact
with your application in real-time, use it to experiment with invoking
javascript api methods, and change the contents of variables on-the-fly.
As depicted in figure 15, you can even fire events on application elements
and see the result in the emulator!

Figure 15: Invoking application methods from the Chromium console view.

2 - 16
2013 Intel Corporation.

Getting Started with Intel XDK New

Debugging on the Device


If your application invokes methods from the Cordova API, or uses device
features that are not natively supported by Javascript, you may find
yourself in a situation when it's most effective to troubleshoot the app when
it's actually running on a physical device.
Using a desktop debugger to inspect an app running on a device is a
process called remote debugging. Remote debugging is supported by the
Intel XDK via the weinre remote debugger.

Figure 16: Add the <script> from the Test tab onto all html pages that you
need to remotely debug.

For remote debugging to work properly, you must:


1. Embed the following code into your HTML files:
<script
src="http://debug-software.intel.com/target/target-scriptmin.js#{unique identifer}"></script>

Where {unique identifier} is indicated on the Intel XDK New Test


panel.
2. Launch the app on the device via App Preview.
3. Click on the Begin Debugging on Device button in the Intel XDK New
Test panel.

2 - 17
2013 Intel Corporation.

Fast Track to Intel XDK New

As depicted in figure 17, after you click the Begin Debugging on Device
button, the weinre extension for the Chromium browser appears, enabling
you to troubleshoot your app as it's runs on your device. The debugger
functions nearly identically to the one that you used in the Emulate panel.

Figure 17: Invoking the weinre remote debugger.

In a manner similar to the Chromium debugger, you can inspect the


browser's DOM, review network traffic, review runtime errors, and even
interact directly with the app through the debugger's Console view.

Figure 18: Using the weinre remote debugger.

2 - 18
2013 Intel Corporation.

Getting Started with Intel XDK New

Walkthrough 2-2: Debugging your Applications


In this lab, you will perform the following tasks:

Use Javascript's debugger; and console.log() methods to aid you in


your debugging efforts.

Use the Chromium debugger to step through your code on an emulated


device.

Use the weinre debugger to step through code in your app running on a
physical device.

Steps
Open a Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk2_2/walk2_2.xdk

5. Click the open button.


Add JavaScript Debugging Statements

6. Click on the Develop tab.


7. In the project's file browser, click on the index.html file.
8. Click on the CODE button.
9. On line 32, insert the following statement to establish a programmatic
breakpoint:
debugger;

10. After the code that you inserted from the prior step, insert a for loop
that loops from 0 to 4:
for (var i=0; i<5; i++) {
}

11. Inside the for loop, insert a statement that outputs the value of the
variable i to the debugging console:
console.log(i);

12. Select File > Save from the code editor's menu.

2 - 19
2013 Intel Corporation.

Fast Track to Intel XDK New


Inspect the app in the Emulator

13. Click on the Emulate tab


14. Click on the Debug button
15. Click on the Debug Me button within the app running in the emulator.
The sources panel of the debugger should activate.
16. Click on the [+] button in the Watch Expressions title bar.
17. Enter i as the expression and press [Enter]
18. Click the debugger's Step Over button to advance the program
execution through the for loop. Notice how the value for the variable I
changes in the Watch panel.
19. Mouse-over the variable i, located in the console.log() statement.
Hovering your mouse over the variable should display its value.
20. Open the Scope Variables panel and review the contents of the
variables that are present.
21. Click the Resume Script Execution button to allow your scripts to run
to completion.
22. Click on the debugger's Console tab. You should see the results from
executing your console.log() statement.
Use the Remote Debugger

23. In the Intel XDK New, click on the Test tab.


24. Scroll down the page to the On Device Debugging section.
25. Copy the script tag displayed at the bottom of the page to your
clipboard.
26. Click on the Develop tab.
27. Open the index.html file in Code view.
28. Paste the <script> tag just above the </head> tag.
29. From the code editing menu bar, select File > Save.
30. Click the Test tab.
31. Click on the Push Files button.
32. Run Intel App Preview on your mobile device.
33. Tap on the Camera button and scan the QR code from the Test tab.
34. On your mobile device, tap OK to launch the app.
35. In the Intel XDK Test tab, click on the Begin Debugging on Device
button.
36. Click on the hyperlinked target reference.
37. In the weinre debugger, click on the Console button.
38. In the app running on your mobile device, tap the Debug Me button.

2 - 20
2013 Intel Corporation.

Getting Started with Intel XDK New

39. Note that the console output from your mobile app running on your
device appears in the weinre remote debugger console view.
40. Click on the End Debugging Button to end your remote debugging
session.
End of Walkthrough --

2 - 21
2013 Intel Corporation.

Fast Track to Intel XDK New

Getting Help
Intel XDK New ships with online documentation and sample applications,
and has community support resources available as well. As illustrated by
Figure 19, help features are available by clicking on the yellow question
mark button.

Figure 19: Accessing help resources.

Using the XDK Documentation


Selecting the Visit the Help Page link opens your web browser to the Intel
Developer Zone at http://software.intel.com/en-us/html5/articles/xdkdocs.
From here, you can get quick access to Intel's App Framework docs, the
Apache Cordova API docs, jQuery API, and Google Chrome Dev Tools
docs

Figure 20: The Intel XDK New Help Page

2 - 22
2013 Intel Corporation.

Getting Started with Intel XDK New

Perhaps the most relevant documentation for this course is the Intel XDK
API documentation, which contains information about available javaScript
methods in the intel.xdk namespace. You can access these resources
directly from:
http://www.html5dev-software.intel.com/documentation/jsAPI/index.html
Figure 21: Documation for the intel.xdk javascript package

This package documents methods that enable you to access the following
resources:

Mobile device physical resources, including the camera and


accelerometer

Facebook API support

Supporting multitouch on Android devices

oAuth authentication methods

Interacting with the accelerated Canvas App Game interface plugin

2 - 23
2013 Intel Corporation.

Fast Track to Intel XDK New

Using the Forums


The Intel XDK New developer forum, depicted in Figure 22, is a great
resource for interfacing with other developers and the Intel XDK
development team. Post your technical support questions here and receive
quick responses from other developers as well as members of Intel's XDK
New development team.

Figure 22: The Intel XDK New developer forum.

2 - 24
2013 Intel Corporation.

Getting Started with Intel XDK New

Reviewing the Sample Applications


As depicted in Figure 23, Intel XDK New ships with 14 separate sample
applications that aptly demonstrate how to use commonly requested mobile
app features. Documentation for each example, accessed by pressing the
document button, highlights the specific API calls that were critical in
producing the desired outcome.

Figure 23: Opening a sample application

The examples include the following:


Name

Description

Rolling Can

Captures a devices accelerometer data and animates an


HTML element using CSS transformations.

Flood Puzzle

A simple puzzle game implemented as a Single Page


App that illustrates how to use Javascript to modify CSS
styles based on user interactions.

Springboard

A jQuery-Mobile based application that demonstrates


custom styling techniques which adapt to various screen
sizes and rotations, and achieve a different look and feel
than JQM defaults.

Buttons

A basic example of that reads the touchStart and


touchEnd JavaScript events in order to provide a
responsive visual cue to the user that a button is being
pressed.

2 - 25
2013 Intel Corporation.

Fast Track to Intel XDK New

Name

Description

App
Framework

A simple app that demonstrates how to use various Intel


App Framework UI components.

Geolocation

Plots the user's geolocation on a Google Map, updating


every five seconds.

Tab Nav

A multi-page JQM scaffold using tab-based navigation. It


demonstrates how to create a custom options menu
widget that maintains state across page transitions and
how to dynamically inject widgets into the DOM.

RPN
Calculator

A themable stack-based calculator that uses different


color schemes, styles, and button animations.

Basic Hybrid
App

Demonstrates how to use the intel.xdk library to access


native device features.

Hello World

The classic. You know it, you love it.

PhoneGap
Audio

Uses a Cordova media object to record and playback


audio.

Towers of
Hanoi

Uses CSS and jQuery to animate solving the classic


Towers of Hanoi puzzle.

Counting
Beads

A simple HTML5-based game that teaches young


children how to count up to 50.

IQM List
View

A JQM-based app that uses the Rotten Tomatoes API to


create a paginated list of DVD rentals. It demonstrates
how to populate a list view with live data and
dynamically generate pages.

2 - 26
2013 Intel Corporation.

Getting Started with Intel XDK New

Walkthrough 2-3: Using a Starter App


In this lab, you will perform the following tasks:

Review the Tab Nav sample application

The Friends with Beer application that you're going to create uses a similar
navigational structure. You'll review and learn how to apply the techniques
used to create this app later in the course.

Steps
Create a New Project from a Sample

1. Open Intel XDK New


2. Click on the word Projects in the top left corner of the GUI.
3. Click the Start a New Project button.
4. Click on the Work with a Demo tab.
5. Click on the IQM Tab Nav app.
6. Click Next.
7. Enter the following information:

Name your project: walk2_3


Project Location: /path/to/ftIntelXdkNew/walk/walk2_3

8. Click the Create button.


9. Click No Thanks
10. Click Let's Go
Review the App

11. Click on the Emulate tab and review how the application runs onscreen. Note the tab-based navigation that's docked to the bottom of the
screen.
12. Click on the Develop tab.
13. Click on the index.html file.
14. Review the structure of the HTML. Note that each page is represented
by a set of logical pages, set off by a <div> tag with data-role=page.
15. Review the structure of the tab bar which manifests from the
<div data-role=footer> markup.
16. Open the file app/tabbedImages.js and review the code. Note that jQM
pages fire an event named pageshow when they appear to a user.
End of Walkthrough --

2 - 27
2013 Intel Corporation.

Fast Track to Intel XDK New

Unit Summary

Designing and developing applications for handheld devices is a


completely different process than writing for desktop browsers

Intel XDK New is an integrated development environment for creating


mobile applications built on web standards HTML 5, JavaScript, and
CSS3.

Intel XDK New integrates many best-of-breed HTML5 development


tools including the following:

MobiOne WYSIWYG visual interface designer


Brackets code editor
Google Chromium Debugger
Apache Ripple Emulator
Intel App Preview mobile app launcher
weinre remote debugger
Apache Cordova native app packager
appMobi cloud services

You can develop your application using a variety of Javascript


frameworks including jQuery Mobile, TopCoat, Bootstrap, and Intel's
App Framework.

Intel's App Framework API extends Apache Cordova features.

The Chromium debugger and weinre remote debugger provide you


powerful troubleshooting capabilities and optimization tips.

Intel XDK New ships with over a dozen sample apps that demonstrate
frequently requested mobile application features.

2 - 28
2013 Intel Corporation.

Getting Started with Intel XDK New

Unit Review
1. Do you need to install any software other than Intel XDK New in order
to develop, test, build, and deploy a mobile app?

2. What are some advantages to developing a mobile app using web


standards instead of using Objective-C or Java?

3. Which physical device features can you test with the Emulator?

4. You must develop mobile apps using Intel's App Framework


(true/false)

5. List two programmatic techniques for inspecting the contents of a


javascript variable.

2 - 29
2013 Intel Corporation.

(This page intentionally left blank)

Unit 3:
Page Layout

Unit Objectives
After completing this unit, you should be able to:

Define logical pages in your application

Use layout controls to position elements on a page

Implement your app's navigational controls

Enable animated transitions between pages

Add text and image content to your application

Defining Pages
Adding Content

Unit Topics

3-1
2013 Intel Corporation.

Fast Track to Intel XDK New

Defining Pages
jQuery mobile uses a combination of HTML tags and HTML5 custom data
properties to implement a page-based architecture for layout. An HTML
file may contain either a single page widget, or multiple page widgets.
Pages are typically indicated by <div> tags with a data-role property equal
to page. Most jQuery Mobile pages, therefore use the the following
structure:
<div data-role="page" id="page1">
<!-- fixed page header -->
<-- page body -->
<!-- fixed page footer -->
</div>

Note: The Intel XDK New visual wysiwyg designer does not support
defining multiple pages within a single .html file.
You'll typically define pages with the following attributes:
Attribute

Description

data-dom-cache

Determines whether to keep the page in the


DOM when the user navigates away from it.

data-theme

Sets the theme that will be used to render the


page.

In most transactional-based apps, you'll also need to write an event handler


that executes when a page is instantiated in the DOM. Typically your event
handler will download .JSON data from a REST-based webservice or
static .JSON file and use it to populate the contents of the page.
The structure of your page creation event listener will resemble the
following:
$("#page1").on("pagecreate", function( event, ui ) {
// page initialization logic goes here.
});

3-2
2013 Intel Corporation.

Page Layout

Adding New Pages in Intel XDK


You can add new pages to
your app by right/cmdclicking in the files panel as
indicated in figure 1.

Figure 1: Adding new files to your project

As indicated by Figure 2, you''ll be prompted to select a mobile Javascript


framework for each new .html file that you add to your project.

Figure 2: You must select a framework for each html file.

3-3
2013 Intel Corporation.

Fast Track to Intel XDK New

Defining Page Headers


The page header typically displays a page title and can display up to two
buttons which are aligned to the left and right of the title, respectively.
Headers are usually placed in a fixed position at either the top or bottom of
a page.
The title text is normally an H1 heading element but it's possible to use any
heading level (H1-H6) to allow for semantic flexibility.
The basic syntax for implementing a header or resembles the following:
<div data-role="page" id="page1">
<div data-role="header" data-position="fixed">
<h1>Friends with Beer</h1>
</div>
<-- page body goes here -->
<div data-role="footer" data-position="fixed">
<!-- footer goes here -->
</div>
</div>

Adding Buttons to Headers


The header container automatically sets the first child link to the left button
slot and the second child link in the right as depicted by the following
example:
<div data-role="header">
<a href="#" data-icon="delete">Cancel</a>
<h1>Edit Contact</h1>
<a href="#" data-icon="check">Save</a>
</div>

You can also set button position by applying the ui-btn-right and ui-btn-left
style classes. This is particularly useful if you need to place a single button
on the right of a header as illustrated by the following example:
<div data-role="header">
<h1>Edit Contact</h1>
<a id="btnSave"
data-icon="check"
class="ui-btn-right">Save</a>
</div>

3-4
2013 Intel Corporation.

Page Layout

Adding Back Buttons


Jquery Mobile will
automatically add a back
button on a header if the
following conditions exist:

The page must have the


data-add-back-btn=true
property.

Using the data-rel=back


property on an anchor.

The data-rel=back property


causes the default href action to
Figure 3: Automatic back button support
be ignored in favor of
mimicking the browser's back
button behavior, going back one history entry.
<div data-role="page"
id="editForm"
data-add-back-btn="true">
<div data-role="header"
data-position="fixed">
<a data-rel="back"
data-role="button"
data-icon="back">Back</a>
<h1>Edit Friend Info</h1>
<button
id="btnSaveFriend"
data-icon="save"
class="ui-btn-right">Save</a>
</div>
</div>

3-5
2013 Intel Corporation.

Fast Track to Intel XDK New

Defining Navigation Bars with the NavBar widget


The NavBar widget enables you to place a navigation bar containing up to
five buttons, within a header or footer by using the following syntax:

Figure 4: Implementing a Nav Bar


<div data-role="footer">
<div data-role="navbar">
<ul>
<li><a href="#">About</a></li>
<li><a href="#">Contacts</a></li>
<li><a href="#">Beers</a></li>
<li><a href="#">Drink!</a></li>
</ul>
</div>
</div>

Buttons are automatically sized to occupy the available width/height of


their container.

3-6
2013 Intel Corporation.

Page Layout

Setting the Default Button State


To set an item to be active by default, add class="ui-btn-active" to
the corresponding anchor. Add a class of ui-state-persist to make the
jQuery automatically restore the active state each time the page is shown.
For instance, a nav bar on the index.html page should resemble the
following:
<div data-role="footer">
<div data-role="navbar">
<ul>
<li><a
href="index.html"

class="ui-btn-active ui-state-persist"

>About</a>
</li>
<li><a href="contacts.html">Contacts</a></li>
<li><a href="beers.html">Beers</a></li>
<li><a href="drink.html">Drink!</a></li>
</ul>
</div>
</div>

Adding Page Transitions


Add the data-transition property to each anchor tag in order to apply
a transition animation when a user taps on a navbar button.
<div data-role="footer">
<div data-role="navbar">
<ul>
<li><a
href="index.html"

class="ui-btn-active ui-state-persist"
>About</a>
</li>
<li><a href="contacts.html"

data-transition="slide">Contacts</a></li>

<li><a href="beers.html"

data-transition="fade">Beers</a></li>
<li><a href="drink.html"

data-transition="none">Drink!</a></li>

</ul>
</div>
</div>

Supported transitions include the following:

fade

turn

slide

pop

flow

slideup

flip

slidefade

slidedown

none

3-7
2013 Intel Corporation.

Fast Track to Intel XDK New

Defining Navigation Bars with the Button Group Widget


The ControlGroup widget groups
buttons together so that they look
similar to a navigation component.
The effect is generated by
applying a
data-role=controlgroup property
to a <div> tag that wraps a series
of anchor-based buttons as
Figure 5: Control Group Buttons
illustrated by the following code
snippet:
<div data-role="controlgroup">
<a href="#" data-role="button">Click Me!</a>
<a href="#" data-role="button">No, Click me!</a>
<a href="#" data-role="button">Always click me!</a>
</div>

You can set the buttons to display horizontally by adding the datatype=horizontal attribute to the controlgroup container as illustrated
below:

Figure 6: A horizontally aligned button group.


<div data-role="controlgroup" data-type="horizontal">
<a href="#" data-role="button">Click Me!</a>
<a href="#" data-role="button">No, Click me!</a>
<a href="#" data-role="button">Always click me!</a>
</div>

Other configuration properties for the controlgroup widget include:


Property

Description

data-corners

Boolean. Sets whether to draw the controlgroup with


rounded corners. Defaults to true.

data-mini

Boolean. Controls whether to display more compact


buttons that use less space. Defaults to false.

3-8
2013 Intel Corporation.

Page Layout

Defining Buttons
Buttons are coded with standard HTML anchor and input elements, then
enhanced by jQuery Mobile to make them more attractive and useable on a
mobile device. You'll typically use anchor links to define navigation
buttons, reserving input or button elements for form submission.
As previously described, the basic syntax for defining a button is the
following:
<a href="index.html" data-role="button">Home</a>

You can add icons to buttons by applying the data-icon property to the
anchor tag as illustrated below:
<a
href="index.html"
data-role="button"
data-icon="home">Home</a>

The complete set of bundled icons is illustrated in Figure 7:

Figure 7: jQuery Mobile Icons

Icons may be positioned at the top, left, bottom, or right of the button's text
by setting the data-iconpos property:
<a
href="index.html"
data-role="button"
data-icon="home"
data-icon-pos="top">Home</a>

You can change the button's theme, causing it to display with either a light
background and dark text or a dark background and light text by applying
the data-theme property:
<a
href="index.html"
data-role="button"
data-theme="b"
>Home</a>
3-9
2013 Intel Corporation.

Fast Track to Intel XDK New

Creating Button Groups with the WYSIWYG Designer


As depicted in Figure 8, you can drag a controlgroup widget to the center
of a footer, and then style each button individually through the properties
panel.

Figure 8: Using the controlgroup widget and styling buttons in the


WYSIWYG designer

Navigating Between HTML Files


jQuery Mobile automatically ''hijacks standard links and form
submissions, converting them into an AJAX requests.
Whenever a link is clicked or a form is submitted, that event is
automatically intercepted by the AJAX nav system. An AJAX request
based on the href or form action is issued instead of reloading the page.
While the framework waits for the AJAX response, a loader overlay is
displayed.
When the requested page loads, jQuery Mobile parses the document for an
element with the data-role="page" attribute and inserts that code into the
DOM of the original page. Any widgets in the incoming page are enhanced
to apply all the styles and behavior. The title of the incoming page is noted
and the home page is updated when the new page is transitioned into
view.
NOTE: The rest of the incoming page is discarded so any scripts,
stylesheets or other information will not be included.

3 - 10
2013 Intel Corporation.

Page Layout

Walkthrough 3-1: Designing Pages


In this lab, you will perform the following tasks:

Define your application pages

Implement a basic header and footer

Implement the app's basic navigational structure

Figure 9: During this lab, you'll Implement tab-style navigation and create
placeholder pages.

Steps
Open a Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk3_1/walk3_1.xdk

5. Click the open button.


Design the Page Footer

6. Open the index.html file in Design view.


7. Drag a FOOTER control from the Controls-Layout panel and drop it
onto the design canvas.
8. Drag a BUTTON GROUP control from the Controls-Form panel and
drop it onto the center of the footer.
9. Click on the first button on the left in the control group.

3 - 11
2013 Intel Corporation.

Fast Track to Intel XDK New

10. In the Button Settings panel, configure the following properties:

Label : Home
Theme: (b) dark
Icon: home
Icon position: top

11. Click on the button adjacent to the Home button and configure the
following properties:

Label : Friends
Icon: user
Icon position: top

12. Click on the button adjacent to the Friends button and configure the
following properties:

Label : Beers
Icon: heart
Icon position: top

13. Drag an additional button from the Controls > Form panel and drop it
to the far right of the controlgroup in the footer.
14. Configure the following properties:

Label : Drink!
Icon: video
Icon position: top

15. Go to Code view and add the following attributes to the Home
button:

href : index.html
data-transition: slide

16. Add the following attributes to the Friends button:

href: friends.html
data-transition: slide

17. Add the following attributes to the Beers button:

href: beers.html
data-transition: slide

18. Add the following attributes to the Drink button:

href: drink.html
data-transition: fade

19. Save the file.

3 - 12
2013 Intel Corporation.

Page Layout

20. Click on the Emulate tab. The footer should appear similar to Figure
10 .

Figure 10: The completed page footer.


Create the Contacts, Beers, and Drink! Placeholders

21. Return to Develop mode.


22. In the Files panel, right/cmd-click on index.html and select New File.
23. Enter the following file name:
friends.html

24. When prompted, select the jQuery Mobile framework and click
Select.
25. Return to the index.html file
26. Enter Code View
27. Copy the contents of the entire page to your clipboard
28. Return to friends.html
29. Enter Code view
30. Paste the contents of your clipboard into the friends.html file.
31. Cut the following code to your clipboard and paste it into the anchor
tag that points to contacts.html:
data-theme="b"

32. Return to Design mode.


33. Click on the page header.
34. In the Header Settings panel, change the title to the following:
Friends

35. Save the file.


36. Repeat steps 21-35 for the following files, changing the page header
and footer as appropriate:

beers.html
drink.html

37. Click the Emulate tab.

3 - 13
2013 Intel Corporation.

Fast Track to Intel XDK New

38. Confirm that you can navigate between the pages by clicking/tapping
on the footer's navigation bar.
End of Walkthrough

3 - 14
2013 Intel Corporation.

Page Layout

Adding Content
You'll typically implement the page content area as a <div> tag with the
attribute data-role="content", placing it between the page header and
footer as illustrated below:
<div data-role="page" id="page1">
<div data-role="header" data-position="fixed">
<h1>Friends with Beer</h1>
</div>
<div data-role="content">
Hello World
</div>
<div data-role="footer" data-position="fixed">
<!-- footer goes here -->
</div>
</div>

As illustrated in Figure 11, the Intel XDK New WYWIWYG designer


enables you to quickly lay out your content into a series of columns and
rows by dragging and dropping the Column and Row widgets onto the
design canvas.

Figure 11: Drag and dropping rows and columns into the content area

Note that as you drag widgets from the Controls pallette, valid drop targets
become highlighted with a cyan colored background in the design canvas.
When you hover over a valid drop target, its color changes to orange.

3 - 15
2013 Intel Corporation.

Fast Track to Intel XDK New

The designer generates a series of styled <div> elements, as illustrated by


the following code snippet:
<div class="upage-content">
<div class="grid grid-pad urow uib_row_1 row-height-1"
data-uib="layout/row">
<div class="col uib_col_4 col-0_6-12"
data-uib="layout/col">
<div class="widget-container content-area vertical-col">
<div class="widget uib_w_3 d-margins"
data-uib="media/text">
<div class="widget-container left-receptacle"/>
<div class="widget-container right-receptacle"/>
<div>
<p>Column 1</p>
</div>
</div>
<span class="uib_shim"></span>
</div>
</div>
<div class="col uib_col_5 col-0_6-12"
data-uib="layout/col">
<div class="widget-container content-area vertical-col">
<div class="widget uib_w_4 d-margins"
data-uib="media/text">
<div class="widget-container left-receptacle" />
<div class="widget-container right-receptacle"/>
<div>
<p>Column 2</p>
</div>
</div>
<span class="uib_shim"/>
</div>
</div>
<span class="uib_shim"></span>
</div>
<div class="grid grid-pad urow uib_row_2 row-height-2"
data-uib="layout/row">
<div class="col uib_col_6 col-0_12-12"
data-uib="layout/col">
<div class="widget-container content-area vertical-col">
<div class="widget uib_w_5 d-margins"
data-uib="media/text">
<div class="widget-container left-receptacle"/>
<div class="widget-container right-receptacle" />
<div>
<p>This row spans both columns</p>
</div>
</div>
<span class="uib_shim"></span>
</div>
</div>
<span class="uib_shim"></span>
</div>
</div>

3 - 16
2013 Intel Corporation.

Page Layout

Adding Text
As depicted in Figure 12, you can add text to page by dragging and
dropping the Text widget from the Controls-Media panel and dropping it
onto the design canvas.

Figure 12: Adding text to an app page.

The Text Settings panel enables you to perform the following functions:

Replace the Lorum ipsum placeholder text

Set the id property of the generated <div> element.

Set display and visibility properties

Define CSS Styles for text and margins

Create define media queries that apply styles based on screen


resolution (covered in unit 9)

3 - 17
2013 Intel Corporation.

Fast Track to Intel XDK New

Applying Typographic Styles


As illustrated in Figure 13, the
WYSIWYG interface enables you to
define typographic styles for your page
elements. Configurable options include:

Font Size

Font Style

Font Weight

Color

Font Family

Text Decoration

Text Align

Line Height

Figure 13: Defining typographic


styles

Style classes that are defined for one element can be applied to other
elements in the WYSIWYG designer.
You'll learn how to extend these styling capabilities via Code View in unit
9.

Adding Images
The IMG widget enables you to add
jpg, png, or gif images to your
content. As depicted in Figure 14,
any images that have been placed in
your project's folder structure may be
selected from the drop-down list in
the IMG Settings panel. You can also
configure Alt text (to meet section
508 accessibility requirements), edit
a visible caption, and set the
generated elements DOM identifier.
Figure 14: Configuring an IMG
widget

3 - 18
2013 Intel Corporation.

Page Layout

Walkthrough 3-2: Adding Content


In this lab, you will perform the following
tasks:

Add text content to the home page.

Define typographic styles.

Add an image to the home page.

Steps
Open a Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the topleft corner of the GUI.
3. Click the Open a Project button.

Figure 15: Your goal

4. Select the following file:


/ftIntelXdkNew/walk/walk3_2/walk3_2.xdk

5. Click the open button.


Add Text

6. From the Controls > Media panel, drag a Text widget and drop it onto
the design canvas, placing it between the header and footer.
7. Open walk3_2/resources/homepagetext.txt in Code view.
8. Copy the contents of the first paragraph of homepagetext.txt to your
clipboard.
9. Open index.html in Design view.
10. In the Design canvas, click on the Text widget.
11. In the Text Settings panel, paste the contents of your clipboard into the
Text field.
Define Typographic Styles

12. In the Text Settings panel, click on the Text button and select New...
13. Enter a style class name of homepage
14. Enter the following properties:

Font-Size:
Font-Family:
Line-Height:

0.9em
sans-serif
normal
3 - 19
2013 Intel Corporation.

Fast Track to Intel XDK New


Add an Image

15. From the Controls > Media panel, drag an IMG widget and drop it
underneath the Text block on the Design Canvas.
16. Configure the following IMG settings:

Src: Resources/Beer.jpg
Alt: Beer: The cause and solution to all of our problems

Add a Second Text Widget

17. From the Controls > Media panel, drag a Text widget and drop it onto
the design canvas, placing it directly underneath the image.
18. Open walk3_2/resources/homepagetext.txt in Code view.
19. Starting with the second paragraph, copy the contents of
homepagetext.txt to your clipboard.
20. Open index.html in Design view.
21. In the Design canvas, click on the Text widget.
22. In the Text Settings panel, paste the contents of your clipboard into the
Text field.
Apply the homepagetext Text Style

23. In the Text Settings > Styles panel, click on the Text menu and select
homepagetext as illustrated below:

24. Save the file


25. Click the Emulate button. Your app should appear similar to Figure 15
on the previous page.
End of Walkthrough --

3 - 20
2013 Intel Corporation.

Page Layout

Unit Summary

jQuery mobile uses a combination of HTML tags and HTML5 custom


data properties to implement a page-based architecture for layout.

jQuery mobile behaviors are typically defined by adding custom data


properties to html elements.

When pages are created in the mobile browser's DOM, the


pagecreate event is fired.

Every html page in your app must be linked to a mobile JavaScript


framework.

Page headers and footers can be docked into a fixed position.

JQM can automatically add a back button on a header.

Use the ButtonGroup widget to easily add navigation to your apps.

JQM supports slide and fade transitions between pages.

Buttons may be styled with icons and themes.

The Intel XDK App Designer enables you to lay out your pages using a
rows/column metaphor.

Style classes that are defined for an element can be applied to other
elements within your app.

The App Designer will automatically locate all images that have been
placed within your project folder.

3 - 21
2013 Intel Corporation.

Fast Track to Intel XDK New

Unit Review
1. Pages do not need to be linked to a mobile javascript framework
(true/false)

2. You cannot define custom icons for your buttons (true/false)

3. An HTML file may only contain a single page view (true/false)

4. The App Designer generates HTML table markup to ensure


compatibility with the broadest range of browsers (true/false)

5. How can you impement a page transition animation?

3 - 22
2013 Intel Corporation.

Unit 4:
Working with Data

Unit Objectives
After completing this unit, you should be able to:

Use jQuery Mobile to make asynchronous data requests

Output structured data into a ListView

Transfer data read from an application server into an HTML5 Local


SQL Database

Read data from the device's Contacts list

Making External Data Requests


Working with the ListView
Caching Data in a Local Database
Importing Data from the Contacts List

Unit Topics

4-1
2013 Intel Corporation.

Fast Track to Intel XDK New

Making External Data Requests


Jquery mobile supports making two different types of data requests from a
web browser:

Use the $.ajax() method to read and post external data using
Javascript's native XmlHttpRequest() method.

Use the $.getJSON() method to read structured data in JavaScript


Object Notation format (JSON) from a remote domain by dynamically
injecting a <script> tag into your application's DOM.

Making AJAX Data Requests from JQM


You can make AJAX requests to a server using the $.ajax() method
illustrated below. $.ajax() should be used whenever you need to retrieve
external data that's not in JSON format or if you need to POST data to a
server.
$.ajax({
url: 'myservice.cfc?method=getdata',
type: 'GET',
dataType: 'json',
error : function (){ alert('there was an error'); },
success: function (data) {
console.log(data);
// debugger;
}
});

Note the following:

The callback to the success or error handler is executed


asynchronously.

The success handler receives the data as a javascript object. You do not
need to use the eval() method or an equivalent to parse the JSON into a
native JavaScript object.

Use the console.log() method to output results to your debugger.


Alternately, you can use the debugger; command to set a programmatic
breakpoint.

Web apps will not be able to make cross-domain requests unless the
remote host supports cross-origin resource sharing (CORS)

Cordova-based apps will need to whitelist all external domains


(covered in unit 10).

4-2
2013 Intel Corporation.

Working with Data

Making JSONP Requests from JQM


You can make cross-domain JSON-P requests from jQuery using the
$getJSON method illustrated below:
var url='http://someurl/someAppServerService.php?';
$.getJSON(url + 'method=somemethod&callback=?',
function(data) {
console.log(data);
}
);

Note that the ? Used in the callback url is replaced at runtime by a jQuery
with a randomly generated set of numbers. JSONP GET requests
therefore typically resemble the following:

Figure 1: A typical JSONP Request.

Use $.getJSON() whenever you need to retrieve JSON data from a remote
domain that does not support CORS.

4-3
2013 Intel Corporation.

Fast Track to Intel XDK New

Deferring Data Requests Until Page Activation


One of the challenges that you will have with building larger, more
complicated JQM apps is minimizing the amount of memory that your app
consumes. One strategy for managing memory is to not load data until it is
absolutely needed. For instance, if a data request is required to populate a
list view, you might want to defer making the request until such time as the
page is requested by the user.
The typical pattern to trigger the execution of code on page visibility is the
following:
$(document).bind('pageinit', function() {
$(document).on( "pagechange", function(event,page) {
switch(page.toPage[0].id) {
case 'page1' :
// initialize page 1
break;
case 'page2' :
// initialize page 2
break;
};
});
});

In the preceding code snippet, the pageinit event is triggered once the
index.html page has completed loading in the browser. In jQuery Mobile,
listening for pageinit event should be used in lieu of document.onready().
The pagechange event is triggered whenever an anchor tag is activated by
a user, causing jQM to intercept the request and load the requested html
page. You can parse the second argument returned to the pagechange event
handler to determine the id property contained within the div tag
containing the data-role=page attribute as illustrated below:
<div class="upage" data-role="page" id="page1">

4-4
2013 Intel Corporation.

Working with Data

Developing Javascript Classes to Encapsulate Event Handlers


As your application grows in size, you may find it useful to bundle all of a
page's event listeners into a single Javascript object. This approach has
several benefits:

Encapsulation

Protected variable scoping

Code Reuse

The general approach to implement this coding style is to define a global


javascript object in your index.html file for each page of your app. For
example, you might define a Javascript object container for your beerspage related subroutines as illustrated by the following:
var BeersPage = {
};

Inside of the JavaScript object, you'll place all of the page's dynamic
properties and methods:
var BeersPage = {
initialized: false,
init: function() {
this.initialized = true;
}
}

Note that in the preceding case, the init() method refers to the initialized
variable using the this scope as both the init() method and the initialized
property are both members of the same object.
You could then invoke the init() method for beersPage through the
following syntax:
BeersPage.init();

You will use this development methodology throughout this course.

4-5
2013 Intel Corporation.

Fast Track to Intel XDK New

Caching Data In a Local Variable


From a performance perspective, HTTP transactions from mobile devices
are very costly. You can reduce external calls by caching data in memory,
html5 local storage, or html5 local database.
It's relatively straightforward to extend our class system in order to persist
remote data in a local variable. In the following code, we've extended the
Beers class described on the prior page by adding an additional property
named data. Once the JSON-P data has been successfully read from the
server, it's placed into the data property where it can be referred for the
duration that the app remains running. A strategically placed if() condition
prevents the remote data from being fetched more than once.
var Beers = {
initialized: false,
data : null,
init: function() {
var me = this; // use closure to retain scope
if (me.data === null && !me.initialized) {
me.initialized = true;
var url= "http://xdktraining.com/ftxdknew/data/beer.cfc";
$.getJSON(url + "?method=getBeerList&callback=?",
function(data) {
me.data = data;
}
);
}
}
}

4-6
2013 Intel Corporation.

Working with Data

Walkthrough 4-1: Making External Data Requests


In this walkthrough, you will start developing the Beer List feature of the
application.

Make a local data request to retrieve a list of Beers that's encoded in


JSON format.

Display the results from the transaction in the debugger.

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk4_1/walk4_1.xdk

Define a pageinit Event Listener

5. Open the following URL and review the output:


http://xdktraining.com/ftxdknew/data/beer.cfc?
method=getBeerList

6. Open the index.html file in Code view.


7. Immediately prior to the closing <head> tag, insert a Javascript block:
<script type=text/javascript>
</script>

8. Inside the <script>, listen for the pageinit event to be triggered by the
index page:
Your code should appear similar to the following:
<script type="text/javascript">
$(document).bind('pageinit', function() {
});
</script>

4-7
2013 Intel Corporation.

Fast Track to Intel XDK New

9. Inside the event handler function, define a variable named page that
retrieves the file name of the current url. Your code should resemble
the following:
var page = event.target.baseURI.split('/');
page = page[page.length - 1];

10. After the code that you inserted from the prior step, check for the
existence of the global variable App.initialized. If the variable has bot
been defined, set it equal to true and call a method named App.init()
which you will define later in this exercise.
$(document).bind('pageinit', function(event,obj) {
var page = event.target.baseURI.split('/');
page = page[page.length - 1];
if (!App.initialized) {
App.initialized = true;
App.init();
}
}

11. After the code that you inserted from the prior step, insert a switch/case
statement that evaluates the contents of the page variable and checks it
against each of your application's pages.
switch (page) {
case 'index.html' :
break;
case 'beers.html' :
break;
case 'friends.html' :
break;
case 'drink.html' :
break;
}

Create the App Class and Get the Data

12. Where indicated by the comment, define an object named App with
the following properties:

initialized: false
beers: null

13. Verify that your code appears as follows:


var App = {
initialized: false,
beers: null
}

4-8
2013 Intel Corporation.

Working with Data


Retrieve and Cache the Data

14. Define two method for the App object named init() and cacheBeers().
var App = {
initialized: false,
beers: null,
init: function() {
},
cacheBeers: function() {
}
}

15. Invoke the cacheBeers() method from the init() method as illustrated
below:
var App = {
initialized: false,
beers: null,
init: function() {
this.cacheBeers();
},
cacheBeers: function() {
}
}

Make a JSON-P Request

16. Inside the cacheBeers method, define a local variable named me that
points to the Beers class and set the initialized property to true.
var me = this;

17. Immediately after the code that you inserted from the prior step, make
a JSON-P request to the following URL, placing the result in the Beers
class data property and dumping its results to the debugging console.
http://xdktraining.com/ftxdknew/data/beer.cfc?
method=getBeerList&callback=?

18. Verify that your code appears similar to the following:


cacheBeers: function() {
var me = this;
var url = "http://xdktraining.com/ftxdknew/data/beer.cfc";
$.getJSON(url + "?method=getBeerList&callback=?",
function(data) {
me.beers = data;
console.log(data);
}
);
}

19. Save the file.

4-9
2013 Intel Corporation.

Fast Track to Intel XDK New

20. Click on the Emulate tab.


21. Open the debugger. You should see the array output from the data
request as illustrated in Figure 2:

Figure 2: Inspecting the results of the JSON-P request.

22. Type the following code in the debugger's console view to output the
list of Beers:
App.beers

--End of Walkthrough--

4 - 10
2013 Intel Corporation.

Working with Data

Working with the ListView


Use the ListView widget, depicted in Figure 3, to display the contents of
either unordered or ordered lists.
Add a data-role=listview property to a
<ul> or <ol> entity in order to instantiate
a ListView:
<ul data-role="listview">
<li><h3>Aaron</h3></li>
<li><h3>Adam</h3></li>
<li><h3>Alexander</h3></li>
</ul>

Figure 3: A simple listview

Grouping Lists
You can create grouped lists as illustrated in Figure 4 by applying the
data-autodividers="true" property to the <ul> entity as illustrated below.
Note the following:

Grouped items must be placed in alphabetical order.

By default, the group name will be the uppercased first character of the
item's text.

<ul
data-role="listview"
data-autodividers="true">
<li><h3>Drucker, Aidan</h3></li>
<li><h3>Drucker, Dylan</h3></li>
<li><h3>Drucker, Steve</h3></li>
<li><h3>Gallerizzo, David</h3>
</li>
</ul>

Figure 4: Using autodividers

4 - 11
2013 Intel Corporation.

Fast Track to Intel XDK New

Defining Custom Group Names


The following code snippets illustrate
how to define custom group names by
completing the following steps:

Add a custom data attribute to your


<li> entities that define the group
name.

Define an autodividersSelector
method that dynamically returns the
group name based on list item
properties.

Programmatically refresh the list

Markup:

Figure 5: Defining custom group


names

<ul data-role="listview" id="personsList">


<li data-lastname="Drucker"><h3>Drucker, Aidan</h3></li>
<li data-lastname="Drucker"><h3>Drucker, Dylan</h3></li>
<li data-lastname="Drucker"><h3>Drucker, Steve</h3></li>
<li data-lastname="Watts"><h3>Watts, David</h3></li>
<li data-lastname="Watts"><h3>Watts, Tiberius</h3></li>
</ul>

Script:
$("#personsList").listview({
autodividers: true,
autodividersSelector: function(li) {
return li.attr("data-lastname");
}
});
$("#personsList").listview("refresh");

Dynamically Populating a List from JSON


In most use cases you'll need to dynamically construct a list from data that
was returned from an AJAX or JSON-P call. In order to pull this off, you'll
usually need to perform the following tasks:

Dynamically sort the array returned from the AJAX/JSON-P call.

Construct a template for generating list item markup.

Generating html markup for each item and append to the ListView.

Refresh the ListView.

4 - 12
2013 Intel Corporation.

Working with Data

Dynamically Sorting an Array


Use Javascript's array.sort() method to sort an array of objects so that it
may be grouped correctly into a list.
Passing a function as an argument to the sort() method enables you to sort
based on two or more fields typically the field that you're grouping on,
and the label for each list item. In this context, Javascript automatically
passes in two objects to your custom function. The function, in turn, must
return the following:

-1 if a < b

0 if a == b

1 if b > a

The following code snippet illustrates an ascending alphabetical sort for a


group-based sort.
data.sort(function(a,b) {
if(a.groupfield == b.groupfield) {
return (a.label < b.label) ? -1 :(a.label > b.label) ? 1:0;
} else {
return (a.groupfield < b.groupfield) ? -1 : 1;
}
});

Constructing a Template
Using templates improves code readability while reducing syntax errors
that inevitably result from performing complex multi-variable string
concatenation with the + operator.
While, jQuery 1.x no longer supports built-in template methods, but you
can easily add a substitute by extending JavaScript's String class as
illustrated by the following snippet:
String.prototype.format = function () {
var args = arguments;
return this.replace(
/\{(\d+)\}/g,
function (m, n) { return args[n]; }
);
};

This String.format() method enables you to easily perform dynamic string


replacement of placeholders through the following invocation:
var template = "The rain in {0} falls mostly on the {1}";
template.format("Spain","plain");
// output: The rain in Spain falls mostly on the plain

4 - 13
2013 Intel Corporation.

Fast Track to Intel XDK New

Dynamically Generating List Items


The problem with using the aforementioned syntax, however, is that
creating a multi-line template remains somewhat error-prone since you
can't insert line breaks within a Javascript string. Sharing the template
across multiple applications would also be problematic.
The solution is to break the template out into a separate script as illustrated
below:
<script type="text/template" id="tplListItem">
<li data-value="{0}">
<h3>{1}</h3>
</li>
</script>

You can then convert the contents of the script to an HTML string using
jQuery's html() method:
var itemTemplate = $("#tplListItem").html();

Now that you've got your template in place, you can easily loop through
your dataset, appending markup to your list. Note that once you have
completed adding list items, you must programmatically refresh the list as
illustrated by the following example:
var list = $('ul#personsList');
list.empty(); // remove all items
for (var i=0; i< data.length; i++) {
var item = data[i];
var str = itemTemplate.format(item.id, item.name);
list.append(str);
}
// redraw the list absolutely REQUIRED!!!
list.listview("refresh");

4 - 14
2013 Intel Corporation.

Working with Data

Adding a Search Filter


Adding the data-filter="true" property
to a list causes the jQuery Mobile
framework to prepend a search box that
filters out list items that don't contain
the text that the user types into the box.
The input's placeholder text defaults to
"Filter items..."
<ul
data-role="listview"
Figure 6: Adding a Search Filter
id="personsList"
data-filter="true" >
<li data-lastname="Drucker"><h3>Drucker, Aidan</h3></li>
<li data-lastname="Drucker"><h3>Drucker, Dylan</h3></li>
<li data-lastname="Drucker"><h3>Drucker, Steve</h3></li>
<li data-lastname="Watts"><h3>Watts, David</h3></li>
<li data-lastname="Watts"><h3>Watts, Tiberius</h3></li>
</ul>

Displaying Counts and Carats in a List


The framework includes text formatting
conventions for common list patterns like
header/descriptions, secondary
information and counts through semantic
HTML markup.

To add a count indicator to the right


of the list item, wrap the number in an
element with a class of ui-li-count

To add a carat indicator, insert the following into each list item:

<span
class="ui-icon ui-icon-arrow-r ui-icon-shadow">&nbsp;</span>

Listening for a Tap Event


Listen for tap events on list items by using the bind() method as illustrated
below:
$('#personsList > li').bind('tap', function(e) {
var targetValue = this.getAttribute('data-lastname');
alert("You selected the " + targetValue + " family");
});

4 - 15
2013 Intel Corporation.

Fast Track to Intel XDK New

Walkthrough 4-2: Dynamically


Generating Lists
In this walkthrough, you will enhance your
application by outputting the data that you
retrieved in the previous walkthrough into a
ListView.

Generate a list view

Sort an array of records

Output records into a grouped list

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the
top-left corner of the GUI.

Figure 7: Output a list of


Beers, grouped by country of
origin.

3. Click the Open a Project button.


4. Select the following file:
/ftIntelXdkNew/walk/walk4_2/walk4_2.xdk

Sort the Dataset

5. Where indicated by the comment, sort the dataset.


Group on the country field
Sort by the name field
6. Your code should appear similar to the following:
data.sort(function(a,b) {
if(a.country == b.country) {
return (a.name < b.name) ? -1 : (a.name > b.name) ? 1 : 0;
} else {
return (a.country < b.country) ? -1 : 1;
}
});

7. Save the file and run the app in the emulator.


8. Open the debugger's console view.
9. Inspect the results from the console.log(). You should see that the data
retrieved from the getJSON() method has been sorted by country name
and beer name.
10. Click on the Develop tab.

4 - 16
2013 Intel Corporation.

Working with Data


Create the List

11. Open the Beers.html file in Design mode.


12. From the Controls > Widgets panel, drag a ListView widget and drop it
onto the design canvas between the page's header and footer.
13. In the ListView Settings panel, turn on the following checkboxes:

Filter
Auto Dividers
id

14. Enter the following id for the ListView:


beerslist

15. Save the file and test the application in the emulator. The list should
appear.
Define a List Item Template

16. Where indicated by the comment, define a template for the list items
that you need to dynamically instantiate. Assign an id property to the
template of tplBeerItem The output from the template needs to
contain markup similar to the following:
<li data-value="1" country="United States">
<h3>Samuel Adams Boston Lager</h3>
<span class="ui-li-count">0</span>
</li>

17. Verify that your code appears similar to the following:


<script type="text/template" id="tplBeerItem">
<li data-value="{0}" country="{1}">
<h3>{2}</h3>
<span class="ui-li-count">{3}</span>
</li>
</script>

Populate the List

18. Return to Develop mode.


19. Open index.html in Code view.
20. Inside the populateList() method, define a variable named list that
points to the ListView component.
var list = $('#beerslist > ul');

21. Clear the default list items from the list. Your code should appear
similar to the following:
list.empty();

22. After the code that you inserted from the prior step, define a variable
named beerTemplate that points to the html in the tplBeerItem element.
var beerTemplate = $("#tplBeerItem").html();

4 - 17
2013 Intel Corporation.

Fast Track to Intel XDK New

23. After the code that you inserted from the prior step, loop through the
data retrieved from the JSON-P transaction. Your code should appear
similar to the following:
for (var i=0; i<App.beers.length; i++) {
var item = App.beers[i];
}

24. Inside the for-loop, use the String.format() method to generate a


dynamic list item and then append the result to the list.
for (var i=0; i<App.beers.length; i++) {
var item = App.beers[i];
list.append(beerTemplate.format(
item.id, item.country, item.name, 0));
}

25. After the for-loop, insert code to refresh the list.


list.listview("refresh");

26. Save the file and test the application in the emulator. You will need to
test the app by launching the index.html file and then clicking on the
Beers button in the footer. Note that the dividers are not displaying
correctly.
Configure Custom AutoDividers

27. Return to Develop mode.


28. Open index.html in code view.
29. In the populateList() method, immediately after the variable
declaration of the variable list , define a custom autodivider selector
that is generated from the value of the country attribute from each list
item. Your code should appear similar to the following:
list.listview({
autodividers: true,
autodividersSelector: function ( li ) {
return li.attr('country');
}
});

30. Save the file and re-test in the emulator. Your list dividers should now
contain the names of the countries from where the beers were made.

End of Walkthrough --

4 - 18
2013 Intel Corporation.

Working with Data

Caching Data in a Local Database


The HTML 5 specification defines database-agnostic SQL for accessing
local databases. Most mobile browsers have implemented SqlLite, enabling
you to use define database tables to store and retrieve structured data.
The amount of space allocated for local databases is configurable through
the browser. You can allocate up to 5MB per app without needing to
prompt the user to allocate more space.

Creating / Opening a Local Database


The following access methods are supported for opening a database
connection:
Method

Description

window.openDatabase()

Creates / opens a local database

WorkerUtils.openDatabase()

Creates / opens a local database using


web workers (threads)

WorkerUtils.openDatabaseSync() Synchronizes database information

Each of the aforementioned methods require the following arguments


(listed in order). Items in bold are required:
Type

Description

string

Database name. Will create new, empty database if the


specified name does not exist.

string

Database version.

string

Display name

long

Estimated size in bytes of the database size

function

A callback to be invoked if the database has not yet


been created. The callback function, in turn, must
invoke the changeVersion() function to set the version
id for the database. If a callback is not specified, the
database will be created and version set to the value
specified by the second argument. Note that
changeVersion() is not implemented in all browsers.

4 - 19
2013 Intel Corporation.

Fast Track to Intel XDK New

The following example illustrates the creation of a local database


containing a single table:
<script>
Cart = {
db : null,
dbOpen : function() {
this.db = openDatabase('cart',
'1.0',
'Cafe Townsend Shopping Cart',
5*1024*1024
);
this.db.transaction(function(tx) {
tx.executeSql('CREATE TABLE IF NOT EXISTS cart(id
INTEGER PRIMARY KEY ASC, desc TEXT, qty INT, unitprice NUM)',
[], this.onSuccess, this.onError);
});
},
onError : function(tx, e) {alert("Error: " + e.message);}
onSuccess : function(e) {alert("Success"); }
}
</script>
<body onload="Cart.dbOpen()">

Performing Database Transactions


You can perform database transactions using the transaction() method of
your web database to define a transaction and then using the executeSql()
method of a transaction to process your queries.
The executeSql() method accepts four arguments, listed in order:
Arg

Description

The SQL that you wish to execute

Optional bind parameters

Optional success handler function

Optional error handler function

4 - 20
2013 Intel Corporation.

Working with Data

The following example illustrates using a combination of hardcoded and


bind parameters, represented by question marks, to insert data into the cart
table:
Cart.db.transaction(function(tx) {
var desc = "Roasted Tomato Soup";
var qty = "5";
var unitprice = "4.5";
tx.executeSql('INSERT INTO cart (id, desc, qty, unitprice)
VALUES (1,?,?,?)',
[desc,qty,unitprice],
function() {alert('success')},
function() {alert('failed')});
});

Similarly, an update statement might resemble the following:


Cart.db.transaction(function(tx) {
var desc = "Steak";
tx.executeSql('update cart set qty = qty + 1
where desc = ?', [desc]);
});

Delete statements may be handled in a similar fashion:


Cart.db.transaction(function(tx) {
var id = 1
tx.executeSql('delete from cart where id=
});

?', [id]);

Retrieving Data from the Database


The executeSql() method passes a SQLResultSet object into its success
callback function.
SQLResultSet has the following read-only attributes:

Attribute

Description

insertId

Returns the row ID of the data inserted into


the database

rowsAffected

The number of rows affected by the operation

rows

A SQLResultSetRowList object. representing


the rows returned, in the order returned by the
database. If no rows were returned, it will be
empty (zero-length).

4 - 21
2013 Intel Corporation.

Fast Track to Intel XDK New

The SQLResultSetRowList object contains a readonly attribute - length


which contains the number of rows returned. It also contains a getter
method named item(). Passing a row number to the item() method returns a
structure representing the row's column data.
The following example illustrates the process of retrieving and looping
through a SQLResultSetRowList object:
function getData(db) {
db.transaction(function(tx) {
tx.executeSql(
'SELECT * FROM cart',
[],
function (tx, results) {
var len = results.rows.length;
for (var i = 0; i < len; i++)
{
alert(results.rows.item(i).desc);
}
});
})
}

Handling Database Errors


When an error occurs, either a SQLError or a SQLException object is
passed to your handler. Both objects have similar structures, containing the
following attributes:
Attribute

Description

code

A numeric error code, described below

message

A string containing the error message, localized to


the user's language

The following error codes may be returned:

Constant

Code

Description

UNKNOWN_ERR

Transaction failed for reasons not related


to the database.

DATABASE_ERR

Operation failed due to the database, but


not covered by the other error types

VERSION_ERR

Operation failed because the database


version did not match with the expected
version

4 - 22
2013 Intel Corporation.

Working with Data

Constant

Code

Description

TOO_LARGE_ERR

The dataset returned from the database


was too large

QUOTA_ERR

Not enough disk space allocated

SYNTAX_ERR

Failed due to a syntax error, or a


mismatch on the number of bind
parameters.

CONTRAINT_ERR

Failed due to a referential integrity


constraint.

TIMEOUT_ERR

Could not establish a transaction lock in a


reasonable amount of time

The following code snippet illustrates handling a database exception:


db.transaction(function(tx) {
var desc = "Roasted Tomato Soup";
var qty = "5";
var unitprice = "4.5";
tx.executeSql(
''.concat('INSERT INTO cart (id, desc, qty, unitprice)',
' VALUES (1,?,?,?)'
),
[desc,qty,unitprice],
function() {
alert('success');
},
function(tx,e) {
alert('Error code: ' + e.code + ':' + e.message);
}
);
});

4 - 23
2013 Intel Corporation.

Fast Track to Intel XDK New

Manually Verifying Database Transactions


You can manually validate that your data has been manipulated in the local
database by opening the Chromium debugger, clicking on the Resources
tab, and inspecting the contents of the Web SQL assets as indicated in
figure 8.

Figure 8: Reviewing the contents of a WebSQL table.

4 - 24
2013 Intel Corporation.

Working with Data

Walkthrough 4-3: Working with


WebSQL
In this walkthrough, you will refactor your
application by caching the list of beers that
you retrieved in the previous walkthrough
into a webSQL database.

Generate a WebSQL database

Review code that inserts, updates, and


deletes from a WebSQL Database

Select data from a WebSQL table and


output it to a ListView

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the
top-left corner of the GUI.

Figure 9: Store, retrieve, and


output data from a local
database

3. Click the Open a Project button.


4. Select the following file:
/ftIntelXdkNew/walk/walk4_3/walk4_3.xdk

Review the WebSQL Database API

5. Open walk4-3/js/localdb.js. Review the code. This JavaScript class


defines a singleton that will handle all basic SQL operations within
your application. Note that this library could be easily repurposed for
use in other applications.

The init() method defines two local database tables - beer which
will hold a cached list of beers and friend which will store
extended contact information for your friends.
The runQuery() method executes the structured query language
(SQL) code that you pass into it, passing the results to a callback
function.
The writeRecord() method performs insert and update operations
on the specified table.
The importTable() method copies an array of objects into the
specified database table.

4 - 25
2013 Intel Corporation.

Fast Track to Intel XDK New

Cache data in WebSQL

6. Open walk4-3/index.html in Code View


7. Inside the getJSON callback function, invoke the
FriendsWithBeerDB.importTable() method to transfer the json data
into the Beer table.
var App = {
cacheBeers : function() {
var url = "http://xdktraining.com/ftxdknew/data/beer.cfc";
$.getJSON(url + "?method=getBeerList&callback=?",
function(data) {
FriendsWithBeerDB.importTable('beer',data);
}
);
}
};

8. Save the file.


9. Open the emulator.
10. Open the debugger and click on the Resources panel.
11. Open Web SQL > Friends with Beer.
12. Click on the Beer table. You should see data in the panel.
Retrieve Data from WebSQL and Output to a ListView

13. Return to the index.html in Code view.


14. Review the refactored Beers class.
15. Where indicated by the comment, call the
FriendsWithBeerDB.runQuery() method to execute the SQL
statement defined on the previous line. Your code should appear
similar to the following:
FriendsWithBeerDB.runQuery(sql, function(records) {
});

16. Inside the SQL callback function, loop through the data returned from
the sql transaction:
FriendsWithBeerDB.runQuery(sql, function(records) {
for (var i=0; i<records.length; i++) {
}
});

4 - 26
2013 Intel Corporation.

Working with Data

17. Inside the for-loop, append dynamically generated list items to the
ListView. Your code should appear as follows:
FriendsWithBeerDB.runQuery(sql, function(records) {
for (var i=0; i<records.length; i++) {
var item = records[i];
list.append(
beerTemplate.format(
item.id,
item.country,
item.name,
item.thecount
)
);
}
});

18. Immediately after the for-loop, refresh the list.


list.listview("refresh");

19. Save the file and test the app in the emulator. You should see the full
list of beers appear on the Beers tab.

End of Walkthrough

4 - 27
2013 Intel Corporation.

Fast Track to Intel XDK New

Importing Data from the Contacts List


Intel XDK New supports Apache Cordova, which acts as a bridge that
enables you to use Javascript to access native device resources. One of
those resources is the device's contacts list.
Since contact information is generally considered to be private and
personal, your app's privacy policy should discuss how your app uses this
data and whether it will be shared with other parties. You should also
strongly consider providing a just-in-time notice prior to your app
accessing or using contact data (if the device operating system doesn't do
so already).
The Cordova API enables you to both read and write to the device's
Contacts list.
Full documentation on this API is at the following URL:
http://cordova.apache.org/docs/en/2.9.0/cordova_contacts_contacts.md.htm
l#Contacts

Loading the Cordova Library


You'll need to load the Cordova javascript library, cordova.js, in order to
access Cordova's Contacts List API.
The cordova.js file is dynamically injected into the root of your application
during the BUILD process. All you need to do is add the following element
to the top of your index.html file's <head> section:
<script type="text/javascript" src="cordova.js"></script>

Handling Time-Intensive Asynchronous Operations


Retrieving contacts can be a time-intensive operation, depending on the
speed of the device and the number of contacts that the user has stored.
When dealing with asynchronous operations, it is often useful to provide
the user with feedback that they should wait for a function to complete
before proceeding. Jquery's Loader widget works well in these scenarios.
Instantiate the loader using the following syntax:
$.mobile.loading( 'show', {
text: "Please Wait",
textVisible: true,
theme: "a",
textonly: false,
html: ""
});

Use the following syntax to hide the loader:


$.mobile.loading( "hide" );
4 - 28
2013 Intel Corporation.

Working with Data

Retrieving Contact Records


Contacts.find() queries the device contacts database asynchronously and
returns an array of Contact objects which are passed to a callback function.
The basic syntax is:
navigator.contacts.find(
contactFields, //array of
contactSuccess, // success
contactError,
// failure
searchOptions
// Options
);

field names to search (required)


callback function (required)
callback function (optional)
to filter contacts (optional)

Note the following:

Only the fields specified in the contactFields parameter will be


returned as properties of the Contact objects that are passed to the
contactSuccess callback function.

A contactFields value of ["*"] will return all contact fields.

A zero-length contactFields parameter is invalid and will result in a


ContactError.INVALID_ARGUMENT_ERROR.

The following example returns contacts named Steve:


var options = new ContactFindOptions();
options.filter="Steve";
var fields = ["displayName", "name"];
navigator.contacts.find(
fields,
function(contacts) {
alert(contacts.length + " records found!");
for (var i=0; i<contacts.length; i++) {
alert("Display Name = " + contacts[i].displayName);
}
},
function(err) {
alert("Import Failed");
},
options
);

4 - 29
2013 Intel Corporation.

Fast Track to Intel XDK New

Working with Contact Data


You can read the following fields for each contact record:

Field

Description

id

String. A globally unique identifier

displayName

String. The name of the Contact, suitable for display


to end-users

name

Object An object containing all components of a


persons name.

nickname

String. A casual name to address the contact.

addresses

Array. All of the contact's addresses.

phoneNumbers

Array. Contact's phone numbers

emails

Array. All of the contact's email addresses

ims

Array. All of the contact's instant messaging addresses

organizations Array. All of the contact's organizations


birthday

Date. The contact's birthday.

note

String. General remarks about the contact.

photos

Array. The contact's photos.

categories

Array. All of the contact's user-defined categories.

urls

Array. An array of web url's associated with the


contact.

You would use the following syntax to output a contact's display name to
an alert box:
onSuccess: function(contacts) {
for (var i=0; i<contacts.length; i++) {
window.alert(contacts[i].displayName);
}
}

4 - 30
2013 Intel Corporation.

Working with Data

Parsing the Contact Name


The Contact Name is a javascript object containing the following
properties:
Field

Description

formatted

String. The complete name of the contact.

familyName

String. The contact's family name.

givenName

String. The contact's given name.

middleName

String. The contact's middle name.

honorificPrefix String. The contact's prefix (Mr. / Dr. / Mrs. / etc)


honorificSuffix String. The contact's suffix, e.g. Esq, DDS, MD

To output a contact's first name followed by their last name, you would use
the following syntax:
onSuccess: function(contacts) {
for (var i=0; i<contacts.length; i++) {
window.alert(
''.concat(
contacts[i].name.givenName,
' ',
contacts[i].name.familyName
)
)
}
}

4 - 31
2013 Intel Corporation.

Fast Track to Intel XDK New

Parsing the Contact's Addresses


Each ContactAddress object has the following properties:
Property

Description

pref

Boolean. True if the contact's preferred address.

type

String. Indicates type of address, e.g. 'home'

formatted

String. The full address, formatted for display.

streetAddress

String. The full street address.

locality

String. The city or locality.

region

String. The state or region.

postalCode

String The zip code or postal code.

country

String. The country name.

To determine the preferred address, you'll need to loop through the


contact's addresses array as illustrated by the following snippet:
onSuccess: function(contacts) {
for (var i=0; i<contacts.length; i++) {
var address = "";
for (var j=0; j<contacts[i].addresses.length; j++) {
if (contacts[i].addresses[j].pref) {
address = contacts[i].addresses[j];
break;
}
}
alert(address.formatted);
}
}

4 - 32
2013 Intel Corporation.

Working with Data

Parsing the Contact's Email Addresses and Phone Numbers


Email addresses and phone numbers are stored in a ContactField objects
which contains the following properties:
Property

Description

type

String. The type of field, e.g. 'home','work','mobile'

value

String. The email address or phone number

pref

Boolean. If true, represents the preferred value.

The following example illustrates how to retrieve the preferred phone


number:
onSuccess: function(contacts) {
for (var i=0; i<contacts.length; i++) {
var phone = "";
for (var j=0; j<contacts[i].phoneNumbers.length; j++) {
if (contacts[i].phoneNumbers[j].pref) {
phone = contacts[i].phoneNumbers[j].value;
break;
}
}
alert(phone);
}
}

4 - 33
2013 Intel Corporation.

Fast Track to Intel XDK New

Testing Contact Features


Accessing the Contact's list is a device-specific feature. You will not be
able to access this functionality through either the emulator or Intel App
Preview. You can only test your code by creating a native build.
Also, note that in the Details configuration tab of the Build panel, you'll
need to turn on the option labeled This App Accesses the User's Contacts
as illustrated in Figure 10.

Figure 10: Including the Contacts library in your native build.

4 - 34
2013 Intel Corporation.

Working with Data

Walkthrough 4-4: Loading Contacts


In this walkthrough, you will add a button to the Friends screen that
enables a user to import their device's contacts into the Friends with Beer
app.

Access device contacts

Transfer contact data into a WebSQL table

Use the weinre debugger to verify your work

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk4_4/walk4_4.xdk

Add the Import Button

5. Open Contacts.html in Design View


6. From the Controls > Form palette, drag a Button widget and drop it on
the left edge of the Friends header.
7. Configure the following Button properties:

Label:
Icon:
Icon Position:
id:

Import
ui-icon-user
icon only
btnImportContacts

Load the Cordova API

8. Open index.html in Code View


9. Where indicated by the comment, insert a <script> tag to load the file
cordova.js
Review the Contacts Object

10. Where indicated by the comment, review the Contacts object and its
method's associated comments.

4 - 35
2013 Intel Corporation.

Fast Track to Intel XDK New

11. Inside the Contacts init() method, define an event listener for the tap
event on the btnImportContacts button.
init: function() {
$("#btnImportContacts").bind("tap", function(e) {
}
}

12. Inside the tap event handler, insert an if-else block that determines
whether the navigator.contacts object exists.
If navigator.contacts does not exist, display an alert() message that
informs the user that the feature is not available.
init: function() {
this.initialized = true;
$("#btnImportContacts").bind("tap", function(e) {
if (navigator.contacts) {
} else {
alert("Function not available");
}
}
}

13. Inside the if-block, insert a window.prompt() that asks the user for the
name of the contact that they want to import. If the user enters a
response, pass it along to the importContacts method of the Contacts
object.
init: function() {
this.initialized = true;
$("#btnImportContacts").bind("tap", function(e) {
if (navigator.contacts) {
var friendName = window.prompt(
"Enter your friend's name",
""
);
if (friendName != null) {
Contacts.importContacts(friendName);
}
} else {
alert("Function not available");
}
}
}

14. Save the file and test in the Emulator. You should see a Function not
available message when attempting to import contacts from the
emulator.

4 - 36
2013 Intel Corporation.

Working with Data


Search for Contacts

15. Return to Develop mode.


16. Inside the importContacts function, display a Please Wait message
to the user.
$.mobile.loading( 'show', {
text: "Please Wait",
textVisible: true,
theme: "a",
textonly: false,
html: ""
});

17. After the code that you inserted in the prior step, define a local variable
named options that is a new ContactFindOptions object.
var options = new ContactFindOptions();

18. Set the filter property of the options object to the value of the
argument that was passed into the function.
options.filter=friendName;

19. Set the multiple property of the options object to retrieve multiple
contact records.
options.multiple = true;

20. Define a local variable named fields that contains an array of strings
for the contact information that you need to retrieve (name, address,
phone, email):
var fields = [
"displayName",
"name",
"addresses",
"phoneNumbers",
"emails"
];

21. Invoke the navigator.contacts.find() method as illustrated below:


navigator.contacts.find(fields,
this.onImport,
this.onImportError,
options);

Define the Contact's Search Success Handler

22. Inside the onImport method, hide the Please Wait message.
$.mobile.loading( "hide" );

23. After the code that you inserted in the prior step, define the following
local variables:
address = null
phone = null
email = null
count = 0
friend = null
4 - 37
2013 Intel Corporation.

Fast Track to Intel XDK New

24. After the code that you inserted in the prior step, insert a for-loop to
iterate through the contacts data returned to the function.
for (var i=0; i<contacts.length; i++) {
}

25. Inside the for-loop, insert an if() block that checks if the contact's given
name is not undefined.
if (contacts[i].name.givenName != undefined) {
}

26. Inside the for-loop, increment the count variable by 1.


if (contacts[i].name.givenName != undefined) {
count++;
}

Retrieve the Contact's Name

27. After the code that you inserted from the prior step, set the variable
friend equal to an array containing two objects with two properties
name and value.

In the first object, the name should be equal to firstName and the
value property should equal the contact's given name.
In the second object, the name should be equal to lastName and
the value property should equal the contact's family name.

for (var i=0; i<contacts.length; i++) {


if (contacts[i].name.givenName != undefined) {
count++;
var friend = [
{
name: "firstName",
value: contacts[i].name.givenName
},
{
name: "lastName",
value: contacts[i].name.familyName
}
];
}
}

Capture the Primary Contact Address

28. After the code that you inserted in the prior step, insert a conditional
that checks for the existence of a contact's address.
if (contacts[i].addresses) {
}

4 - 38
2013 Intel Corporation.

Working with Data

29. Inside the if() block, set the address variable equal to the result from
calling the Contacts.getPreferred() method, passing in the contact's
addresses.
if (contacts[i].addresses) {
address = Contacts.getPreferred(contacts[i].addresses);
}

30. Immediately after the code that you inserted in the prior step, add the
resulting street address and zipcode to the friends array as indicated
below:
if (contacts[i].addresses) {
address = Contacts.getPreferred(contacts[i].addresses);
friend.push(
{ name: "address", value: address.streetAddress}
);
friend.push(
{ name: "zipcode", value: address.postalCode}
);
}

Get the Contact's Primary Phone Number

31. After the contact's IF block, insert another conditional that evaluates
whether or not any phone numbers exist for the contact.
if (contacts[i].phoneNumbers) {
}

32. Inside the if() block, push another object onto the friend array that
contains the contact's preferred phone number.
if (contacts[i].phoneNumbers) {
friend.push(
{
name: "phone",
value:
Contacts.getPreferred(contacts[i].phoneNumbers).value});
}
)
}

Get the Contact's Preferred Email Address

33. After the if() block that you inserted from the prior steps, insert another
conditional that evaluates whether the contact object has an emails
property.
if (contacts[i].emails) {
}

4 - 39
2013 Intel Corporation.

Fast Track to Intel XDK New

34. Inside the if() block, push another object containing user's preferred
email address onto the friend array.
if (contacts[i].emails) {
friend.push(
{
name: "email",
value: Contacts.getPreferred(contacts[i].emails).value});
}
)
}

Save the Friend Object to the Database

35. Immediately after the last if() block, write the data from the friend
object to your WebSQL database.
FriendsWithBeerDB.writeRecord('friend',null, friend);

36. Immediately outside the for-loop in the onImport() method, output the
value from the count variable to the user in an alert box.
alert(count + " Contacts Imported");

Test your Work on Your Device

37. Save the file.


38. Click on the Test tab.
39. Click the Push Files button.
40. Open Intel App Preview on your phone.
41. Click the Camera icon and focus the camera on the QR code.
42. Click OK.
43. Click the Friends button.
44. Click the Import Contacts button.
45. Enter the first or last name of one of your friends who are in your
device's Contacts list.
46. Tap OK.
47. Return to Intel XDK New
48. Click Begin Debugging on Device.
49. Click on the Target hyperlink
50. Click on the Resources tab.
51. Open the FriendsWithBeer database and confirm that data is present in
the Friend table.
End of Walkthrough --

4 - 40
2013 Intel Corporation.

Working with Data

Unit Summary

jQuery Mobile enables you to make external data requests to remote


services using either AJAX or JSON-P protocols.

All data requests are handled asynchronously.

Verify that data was retrieved correctly by outputting the server


response to the debugger using console.log()

Web apps will not be able to make cross-domain requests unless the
remote host supports cross-origin resource sharing (CORS)

Most data requests should be deferred until they are specifically


requested by the user.

Compartmentalize your code by attaching properties and methods to


Javascript objects.

Remote data can be cached in browser memory or persisted in html5


localStorage or WebSQL databases.

Use the ListView widget to output lists of data.

You can listen for tap events on list items and then programmatically
retrieve properties associated with the item that was tapped.

The Cordova API gives you access to hardware resources, including


the Contacts list.

Most Cordova API functionality must be tested on physical devices


and may not function properly in the emulator.

4 - 41
2013 Intel Corporation.

Fast Track to Intel XDK New

Unit Review
1. AJAX requests can only be made to the same domain that a web app is
hosted on (true/false).

2. JSON-P requests cannot read XML data (true/false)

3. You can POST data via JSON-P (true/false).

4. The ListView search filter can only search for data that's visible to the
user.

5. String.format() is a native Javascript method (true/false)?

6. Why do data requests typically require that you supply a callback


function?

7. Which hardware resources can only be accessed via the Cordova API?

4 - 42
2013 Intel Corporation.

Working with Data

Lab 4: Working with Lists and WebSQL


During this lab you will read data from your WebSQL database and display
it in a dynamically populated list view.

Objectives
After completing this lab, you should be able to:

Read data from a WebSQL database

Dynamically construct a list view

Steps
1. Open /lab/lab4/lab4.xdk
2. Open contacts.html
3. Drag a LISTVIEW widget onto the design canvas and configure its
properties.
4. Return to index.html
5. Modify the Contact's displayList() method to output data from the
WebSQL table into the LISTVIEW that you defined from step 3.
6. Modify the onImport() method to refresh the LISTVIEW after your
contacts have been imported.

End of Lab --

4 - 43
2013 Intel Corporation.

(This page intentionally left blank)

Unit 5:
Creating Input Forms

Unit Objectives
After completing this unit, you should be able to:

Create a data entry form

Pre-fill form fields with data

Populate a <select> control with data from a webservice

Validate data input

Transmit form data to an application server

Save form data to a WebSQL database.

Creating Forms
Validating Form Input
Persisting Form Data

Unit Topics

5-1
2013 Intel Corporation.

Fast Track to Intel XDK New

Creating Forms
Intel XDK New supports the following types of form fields:

Checkbox

Date

Number

Checkbox Group

Email Address

Datetime

Flip Switch

Telephone Number

Text

Password

URL

Hidden

Search

Radio

Slider

Select

Radio Group

Text Area

Month

Working with Text Fields


HTML5 extends the standard textfield from HTML 4.01 by adding the
following easily deployed features:

Automatically set focus

Specify placeholder text

Validate that data was input in a specific format

Figure 1: Configuring Text Fields with Intel XDK New

Some of these capabilities are directly supported by the Intel XDK New
GUI as depicted in Figure 1. Others you will need to add using code view.
5-2
2013 Intel Corporation.

Creating Input Forms

Automatically Setting Focus


The HTML 5 autofocus attribute enables you to set focus to a specific form
field as soon as the form is rendered in your browser. In HTML 4 this
could only be accomplished by using JavaScript's focus() method.
The following example sets focus to a text field:
<form>
<label for="myfield">
This field will automatically have cursor focus:
</label>
<input type="text" name="myfield" autofocus />
</form>

Specifying Placeholder Text


Placeholder text helps you make your forms more intuitive and usable by
allowing for descriptive text to be placed inside of a text field via the
placeholder attribute. Once the field has focus or has a value, the
placeholder text is removed.
<form>
<label for="lastname">Enter your last name:</label>
<input type="text"
name="lastname"
placeholder="Last Name" />
</form>

As depicted in Figure 2, the placeholder is frequently used in lieu of a label


in order to conserve space. You can quickly implement this feature by
turning on the placeholder checkbox in the XDK New interface.

Figure 2: Placeholders help you conserve space.

5-3
2013 Intel Corporation.

Fast Track to Intel XDK New

Capturing Email Addresses


Using <input type=email> automatically adjust the user's on-screen
keyboard to facilitate data entry.
<form>
<label for="myemail">Enter your e-mail address:</label>
<input type="email" name="myemail"
placeholder="me@mycompany.com" />
<input type="submit">
</form>

As depicted in Figure 2, you can define an email field by dragging an input


widget onto the design canvas and then specifying email as its type.

Figure 3: Defining an email input field.

Inputting Phone Numbers


Use <input type=tel> to enable a user to
easily enter a telephone number. Mobile browsers
automatically present the user with a phone keypad
to facilitate input into this field type.
<form>
<input
type="tel"
name="phone"
placeholder="Tel" />
<input type="submit">
</form>

Figure 4: The tel field


in iOS
5-4
2013 Intel Corporation.

Creating Input Forms

Using Select Menus


The select menu hides the default html
<select> control and replaces it with a
custom-styled select button that matches
the look and feel of the jQuery Mobile
framework. The select menu is fully
accessible to people with disabilities.
When pressed, select menu options will
render using the native format of the
device. When a value is selected and the
menu closes, the custom button's text is
updated to match the selected value.
The syntax generating a jQuery Select
Menu is the same as generating a standard
HTML <select> control:
<select name="beerid"
id="beerid">
Figure 5: A jQM Select Menu.
<option value="1">Amstel</option>
<option value="2">Budweiser</option>
<option value="3">Chimay Rouge</option>
<option value="4">Corona Extra</option>
</select>

Adding a Placeholder Option


You'll typically want to include a "null" option in your select element to
force a user to choose an option. Placeholder options are automatically
hidden by jQM in the overlay menu, thereby ensuring that only valid
choices are presented to the user. Placeholders are recognized as:

An option with no value attribute or an empty value attribute

An option with no text node

An option with a data-placeholder="true" attribute.

The following example illustrates using a placeholder:


<select name="beerid" id="beerid">
<option>Select a Beer</option>
<option value="1">Amstel</option>
<option value="2">Budweiser</option>
<option value="3">Chimay Rouge</option>
<option value="4">Corona Extra</option>
</select>

5-5
2013 Intel Corporation.

Fast Track to Intel XDK New

Dynamically Adding Options to a Select Menu


Adding dynamic options to a Select menu is quite similar to adding
dynamic rows to a ListView widget. As illustrated by the following code
snippet, use jQuery's append() method to attach dynamically created
<option> elements to a <select> control and then invoke the widget's
refresh() method to have those changes appear on-screen.
var beers = [
{
label: "Amstel Light",
value: 1
},
{
label: "Corona Extra",
value: 2
}
];
var MySelect = $("select#beerid");
var tpl = '<option value="{0}">{1}</option>';
// remove all items
MySelect.empty();
// add placeholder
MySelect.append(tpl.format('','Please Select'));
// add data items
for (var i=0; i<beers.length; i++) {
MySelect.append(tpl.format(
ships[i].value,
ships[i].label
));
}
// important: refresh the list!!!
MySelect.selectmenu("refresh", true);

5-6
2013 Intel Corporation.

Creating Input Forms

Walkthrough 5-1: Designing a Form


In this walkthrough, you will start developing a
data input form to enable the user to edit their
contacts and link their contacts to a specific
brand of beer.

Design a form

Dynamically populate a <select> list

Implement a Back button

Respond to button taps

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the topleft corner of the GUI.

Figure 6: The data entry


form that you will create
during this exercise

3. Click the Open a Project button.


4. Select the following file:
/ftIntelXdkNew/walk/walk5_1/walk5_1.xdk

Define the Header Buttons

5. Open the contactform.html file in Design mode.


6. From the Controls > Form palette, drag a button widget and drop it on
the left edge of the page header.
7. Configure the following properties:

Icon:
Icon position:
id:

ui-icon-back
icon only
btnBack

8. Go to Code mode.
9. Locate the anchor tag that was generated for the back button and add
the following attribute:
data-rel="back"

10. Return to Design mode.


11. From the Controls > Form palette, drag a button widget and drop it on
the right edge of the page header.

5-7
2013 Intel Corporation.

Fast Track to Intel XDK New

12. Configure the following properties:

Icon:
ui-icon-check
Icon Position: Icon only
id:
btnSave

Define the Form

13. From the Controls > Layout panel, drag a Row widget and drop it
onto the center of the design canvas.
14. Configure the following property:

is Form: checked

Define the Contact Fields

15. From the Controls > Form palette, drag an Input widget and drop it
onto the Row widget in the Design Canvas.
16. Configure the following properties:

Label:
Type:
Placeholder:
Name:
id:

(unchecked)
text
First Name
firstName
firstName

17. From the Controls > Form palette, drag an Input widget and drop it
directly underneath the First Name field on the Design Canvas.
18. Configure the following properties:

Label:
Type:
Placeholder:
Name:
id:

(unchecked)
text
Last Name
lastName
lastName

19. From the Controls > Form palette, drag an Input widget and drop it
directly underneath the Last Name field on the Design Canvas.
20. Configure the following properties:

Label:
Type:
Placeholder:
Name:
id:

(unchecked)
text
Street Address
address
address

21. From the Controls > Form palette, drag an Input widget and drop it
directly underneath the Address field on the Design Canvas.
22. Configure the following properties:

Label:

(unchecked)

5-8
2013 Intel Corporation.

Creating Input Forms

Type:
Placeholder:
Name:
id:

number
Zip Code
zipcode
zipcode

23. From the Controls > Form palette, drag an Input widget and drop it
directly underneath the Zip Code field on the Design Canvas.
24. Configure the following properties:

Label:
Type:
Placeholder:
Name:
id:

(unchecked)
email
you@you.com
email
email

25. From the Controls > Form palette, drag an Input widget and drop it
directly underneath the email field on the Design Canvas.
26. Configure the following properties:

Label:
Type:
Placeholder:
Name:
id:

(unchecked)
telephone
Tel
phone
phone

Create a Dynamically Populated Select List

27. From the Controls > Form palette, drag a Select widget and drop it
directly underneath the telephone field on the Design Canvas.
28. Configure the following properties:

Label:
Options:
Name:
id:

(unchecked)
Select a Beer
beerId
beerId

29. Save the file


30. Open index.html in Code mode.
31. Where indicated by the comment, define a JavaScript object named
ContactForm.
var ContactForm = { };

32. Define the following property on the ContactForm object:


friendId: null;

33. Add the following methods to the ContactForm object:

init
populateBeerField

34. Review your code to ensure that it appears similar to the following:
5-9
2013 Intel Corporation.

Fast Track to Intel XDK New

var ContactForm = {
friendId: null,
init: function() {
},
populateBeerField : function() {
}
};

35. Inside the initialize() method, call the populateBeerField method.


var ContactForm = {
init: function() {
this.populateBeerField();
},
populateBeerField : function() {
}
};

36. Inside the populateBeerField() method, define a local variable named


beerField that points to the beerid select widget in the form. Your code
should appear similar to the following:
var beerField = $("select#beerId");

37. After the code that you inserted from the prior step, insert a for-loop
that loops through the beer data that's cached in the variable App.beers.
populateBeerField : function() {
var beerField = $("select#beerId");
for (var i=0; i< App.beers.length; i++) {
}
}

38. Inside the for-loop, insert code that dynamically outputs the data from
App.beers as <option> elements inside of the select widget.
populateBeerField : function() {
var beerField = $("select#beerId");
for (var i=0; i< App.beers.length; i++) {
beerField.append(
'<option value="{0}">{1}</option>'.format(
App.beers[i].id,
App.beers[i].name
)
);
}
}

39. After the for-loop, insert a statement to refresh the display of the select
widget.
beerField.selectmenu("refresh", true);

40. Save the file.


Add a Add Contact button to the Contacts List

41. Open the contacts.html page in Design mode.

5 - 10
2013 Intel Corporation.

Creating Input Forms

42. From the Controls > Form palette, drag a button widget and drop it on
the right edge of the page header.
43. Configure the following properties:

Icon:
ui-icon-plus
Icon Position: Icon only
id:
btnAdd

44. Go to Code mode and locate the generated markup for the button.
45. Add the following attributes to the anchor tag that wraps the add
button:

href=contactform.html
data-transition=flip

46. Save the file.


47. Return to index.html in Code mode.
48. In the Contacts object, at the end of the init() method, bind a tap event
handler to the Add Contact button.
$("#btnAdd").bind("tap", function(e) {
});

49. Inside the button tap callback function, set the friendId property in the
ContactForm object to null.
$("#btnAdd").bind("tap", function(e) {
ContactForm.friendId = null;
});

50. Save the file and test in the emulator.


End of Walkthrough --

5 - 11
2013 Intel Corporation.

Fast Track to Intel XDK New

Validating Form Input


Unfortunately, mobile browsers do not support the native form field
validation properties that are stipulated as part of the HTML5 specification.
You can adapt the jQuery Validation Plugin, however, to easily ensure that
users are entering data in the format that you intended.
The jQuery Validation Plugin is maintained by Jrn Zaefferer, a member
of thejQuery team, lead developer on the jQuery UI team and maintainer of
QUnit. It was started back in the early days of jQuery in 2006, and updated
and improved since then.
The plugin comes bundled with a useful set of validation methods,
including URL and email validation, while providing an API to write your
own methods. All bundled methods come with default error messages in
english and translations into 37 other languages.
It's free to use under an MIT license and hosted at
http://jqueryvalidation.org/
The plugin validates the following patterns for correctness:
Type

Description

required

Makes data input required.

remote

Requests a resource check the element for validity.

minlength

Requires strings to be a specified minimum length

rangelength Requires strings to be within a specified size range.


email

Requires the string to be a properly formatted email


address.

url

Requires the input string to be a properly formatted url.

date

Requires the input string to be a valid date.

dateISO

Requires the input to be a properly formatted ISO date

number

Requires the input to be a decimal number

digits

Makes the element require numeric values only.

creditcard

Validates that the creditcard number has been properly


formatted.

equalTo

Requires the input data in one field be identical to the


input data in another field.

It also comes with extensions to validate other data types as well, including
US phone numbers.
5 - 12
2013 Intel Corporation.

Creating Input Forms

Loading the Library


You can load the jQuery Validation Library (jquery.validate.js) by simply
inserting a <script> tag into your document's <head> section:
<head>
...
<script type="text/javascript"
src="js/jquery.min.js"></script>
<script type="text/javascript"
src="jqm/jquery.mobile-min.js"></script>
<script type="text/javascript"
src="js/jquery.validate.js"></script>
</head>

Adding Validation Rules to Form Fields


You can add validation rules to fields by invoking the form.validate()
method which requires a javascript object that defines rules, behaviors, and
other options.
Typical validate() invocations appear as follows:
$( "#myform" ).validate({
submitHandler: function(form) {
$(form).ajaxSubmit();
},
invalidHandler: function(event,validator) {
var errors = validator.numberOfInvalids();
alert("Invalid data in " + errors + " fields");
},
rules: {
lastName: {
required: true
}
},
messages: {
lastName: "Please enter you family name"
}
});

In the preceding snippet, note the following:

The submitHandler is invoked when the the user presses the form's
submit button and all form fields pass validation.

The invalidHandler is called when the form is submitted when the


user presses the form's submit button but not all fields have passed
validation.

The rules object defines data validation rules on form fields. In this
case, lastName is the id of a text field.

The messages object enables you to define custom validation error


messages.

5 - 13
2013 Intel Corporation.

Fast Track to Intel XDK New

Requiring Data Input


You can require data input on a field by adding the required attribute to any
<input> field as illustrated below:
<label class="narrow-control" for="lastName"></label>
<input class="wide-control"
placeholder="Last Name"
type="text"
name="lastName"
id="lastName"
required >

You can also attach the required validation rule to a field by invoking a
form's validate() method (injected by the plugin):
$( "#myform" ).validate({
rules: {
lastName: {
required: true
}
}
});

Validating Email Addresses


Require that a properly formatted email address be entered into a form field
by applying the following validation rules:
<label class="narrow-control" for="email"></label>
<input class="wide-control"
placeholder="me@myemailaddress.com"
type="text"
name="useremail"
id="userEmail">
$( "#myform" ).validate({
rules: {
userEmail: {
required: true,
email: true
}
}
});

5 - 14
2013 Intel Corporation.

Creating Input Forms

Validating String Length


You can set validation on string field length by using the rangelength
validator as illustrated below:
<label class="narrow-control" for="lastName"></label>
<input class="wide-control"
placeholder="Last Name"
type="text"
name="lastName"
id="lastName">
$( "#myform" ).validate({
rules: {
lastName: {
required: true,
rangelength: [2,20]
}
}
});

Validating Numeric Input


Require that input data may only contain characters in the range of 0-9 by
applying the digits rule as noted below:
<label class="narrow-control" for="zip"></label>
<input class="wide-control"
placeholder="zip code"
type="text"
name="zipcode"
id="zipcode">
$( "#myform" ).validate({
rules: {
zipcode: {
required: true,
digits: true
}
}
});

Programmatically Execute Validation Rules


You can invoke form field validating programmatically by invoking the
validator.form() method as illustrated below.
var validator = $("form#contactform").validate();
validator.form();

5 - 15
2013 Intel Corporation.

Fast Track to Intel XDK New

Configuring Validation Message Placement and Theming


By default, error validation messages are injected into the form field's
<label> element. You can modify this behavior on a field-level basis by
specifying an errorPlacement method. The following example moves the
validation method into a parent <div> for a <select> element with an id of
beerid:
var form = $("form#contactform");
form.validate({
errorPlacement: function(error, element) {
if (element.attr("name") === "beerid") {
error.insertAfter($(element).parent());
} else {
error.insertAfter(element);
}
}
});

As illustrated in the following snippet, you can style the error message by
defining a css class on the label.error selector.
label.error {
float: left;
color: red;
padding-top: .5em;
vertical-align: top;
font-weight:bold
}

5 - 16
2013 Intel Corporation.

Creating Input Forms

Walkthrough 5-2: Implementing Form Validation


In this walkthrough you will add data input
validation rules to the contact form.

Load the jQuery Validation plugin.

Define validation rules for form fields

Customize the display of error messages

Programmatically trigger form validation

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk5_2/walk5_2.xdk

Add an ID Property to Your Form

5. Open the contactform.html file in Code view.


6. Add the following attribute to the <form> element:
id="contactform"

Define the Validation Rules

7. Open the index.html file in Code mode.


8. On line 34, insert a <script> tag to load the jQuery Validation library.
<script type="text/javascript"
src="js/jquery.validate.js"></script>

9. Inside the ContactForm object, underneath the populateBeerField


method, define a function named initValidation.
10. Inside the initValidation method, define a local variable named form
that points to the form that you defined in the prior walkthrough.
var form = $("form#contactform");

5 - 17
2013 Intel Corporation.

Fast Track to Intel XDK New

11. After the code that you inserted in the prior step, invoke form.validate
and configure the following rules:

Data input for the lastName field is required


Data input for the lastName field must have between 2 and 20
characters
Data input on the firstName field is required
Data input on the address field is required
Data input for the zipcode field may only be digits

12. Review your code to ensure it appears similar to the following:


initValidation: function() {
var form = $("form#contactform");
form.validate({
rules: {
lastName: {
required: true,
rangelength: [2,20]
},
firstName: {
required: true
},
address: {
required: true
},
zipcode: {
required: true,
digits: true
}
}
});
}

13. Inside the init() method of the ContactForm object, invoke the
initValidation() method.
var ContactForm = {
init: function() {
this.populateBeerField();
this.initValidation();
},
populateBeerField: function() {
// omitted for brevity
},
initValidation: function() {
// omitted for brevity
}
}

5 - 18
2013 Intel Corporation.

Creating Input Forms


Programmatically Validate the Form

14. Define an additional method of the ContactForm class named


submitForm()
15. Inside the submitForm() method, execute the validation rules that you
defined in step 9 and output the number of errors to an alert box. Your
code should appear similar to the following:
submitForm: function() {
var validator = $("form#contactform").validate();
validator.form();
alert(validator.numberOfInvalids());
}

16. Save the file


Link the Save button to the submitForm Method

17. Open contactform.html in Design mode.


18. Click on the button to the right of the Friends with Beer header and
configure the following property:

id: btnSave

19. Save the file.


20. Return to index.html in Code view.
21. Inside the init() method of the ContactForm object, define a tap event
handler for the save button that invokes the submitForm method. Your
code should appear similar to the following:
init: function() {
this.initialized=true;
this.populateBeerField();
this.initValidation();
var me = this;
$("#btnSave").bind("tap", function(e) {
me.submitForm();
});
}

22. Save the file and test the app in the emulator. Clicking the save button
should trigger the display of the error validation messages.
Theme the Error Messages

23. Return to index.html in Code mode.


24. Add the following style definition to the <style> block on line 14.
label.error {
float: left;
color: red;
padding-top: .5em;
vertical-align: top;
font-weight:bold
}

5 - 19
2013 Intel Corporation.

Fast Track to Intel XDK New

25. Save the file and re-test the app in the emulator. You should see that
your error messages are now formatted.
End of Walkthrough --

5 - 20
2013 Intel Corporation.

Creating Input Forms

Persisting Form Data


Transactional CRUD interfaces require that you support four major
functions:

Create new records

Read and display records

Update pre-existing records

Delete records

In order to update pre-existing records, you'll typically need to populate a


form with data, allow the user to edit the record, and then post it back to
the server.

Dynamically Setting Form Field Values


To programmatically set the value of an input field, invoke the field's .val()
method as illustrated below:
$("#firstName").val("Steve");

To programmatically set the value of other types of JQM form controls,


you must first manipulate the native control and then use the widget's
refresh method to synchronize the enhanced control with its native html
counterpart as illustrated by the following examples:
// updating checkboxes
var myCheckbox = $("input[type='checkbox']#check1")
myCheckbox.prop("checked",true).checkboxradio("refresh");
// updating radio buttons
var myRB = $("input[type='radio']#rb1")
myRB.prop("checked",true).checkboxradio("refresh");
// select controls
var myselect = $("select#beerid");
myselect.selectedIndex = 1;
myselect.selectmenu("refresh");

Dynamically Getting All Form Field Values


The form.serializeArray() method creates a JavaScript array of objects
consisting of your form field names and their associated input values.
var formData =

$("form#contactform").serializeArray();

5 - 21
2013 Intel Corporation.

Fast Track to Intel XDK New

Posting Data to an Application Server


In jQuery Mobile, form submissions are automatically handled using Ajax
whenever possible, resulting in a smooth transition between the form and
the result page. If left unspecified, a form's method will default to get and
its action will default to the current page's relative path
($.mobile.path.get())
Note that forms accept attributes for transitions just like anchors, so you
can attach a data-transition="pop" and datadirection="reverse".
If you do not want a page transition to occur or simply want more control
over the submission process, you'll need to invoke the $.ajax() method as
illustrated by the following example:
submitForm: function() {
var form = $("form#contactform");
var validator = form.validate();
validator.form();
if (validator.numberOfInvalids() == 0) {
$.ajax({
type: "POST",
url: "http://www.xdktraining.com/savecontact.cfm",
data: form.serialize(),
success: function(data) {
alert("Record Saved");
},
error: function(XMLHttpRequest, textStatus, err){
var msg = ''.concat(
'status:', XMLHttpRequest.status, '\n',
'status text: ', XMLHttpRequest.statusText
);
alert(msg);
}
});
}
}

Note the following from the preceding example:

Call the form.serialize() method to retrieve all form field values and
serialize them into a single encoded string for posting to the app server.

You should always include a failure handler in your AJAX transactions

5 - 22
2013 Intel Corporation.

Creating Input Forms

Walkthrough 5-3: Inserting and Updating Records


In this walkthrough you will add data
input validation rules to the contact
form.

Insert contact records into the


WebSQL database

Set the values of form fields

Update contact records in the


WebSQL database

Programmatically load pages

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk5_3/walk5_3.xdk

Add Disabled Lat/Lng Fields to the Form

5. Open contactform.html in Design mode.


6. Drag an Input widget from the Controls > Form palette and drop it
directly underneath the beers select box on the design canvas.
7. Configure the following properties:

Label: Lat (unchecked)


Placeholder: Latitude
Name: lat
id: lat

8. Drag an Input widget from the Controls > Form palette and drop it
directly underneath the beers select box on the design canvas.
9. Configure the following properties:

Label: Lng (unchecked)


Placeholder: Longitude
Name: lng
id: lng

10. Go to code mode and add a disabled property to the lat and lng fields.
5 - 23
2013 Intel Corporation.

Fast Track to Intel XDK New


Create a New Record

11. Open the index.html file in Code mode.


12. Refactor the ContactForm.submitForm() method as indicated below:
submitForm: function() {
var form = $("form#contactform");
var validator = form.validate();
validator.form();
if (validator.numberOfInvalids() == 0) {
} else {
alert("Invalid data input");
}
}

13. Inside the if() block, use the form.serializeArray() method to serialize
all of the form fields into a local variable named fields.
var fields = form.serializeArray();

14. Immediately after the code that you inserted in the last step, append the
values of the disabled lat and lng fields to the fields array.
fields[fields.length] = {
name: 'lat',
value: $('#lat').val()
};
fields[fields.length] = {
name: 'lng',
value: $('#lng').val()
};

15. Immediately after the code that you inserted in the last step, invoke the
FriendsWithBeerDB.writeRecord() method to transfer the data from
the fields variable into your webSQL database.
FriendsWithBeerDB.writeRecord(
'friend',
this.friendId,
fields,
function() {
}
);

16. Inside the writeRecord() callback function, use the alert() method to
output a message to the user and then reload the contacts.html page.

5 - 24
2013 Intel Corporation.

Creating Input Forms

17. Review your submitForm() method to ensure that it appears similar to


the following:
if (validator.numberOfInvalids() == 0) {
var fields = form.serializeArray();
fields[fields.length] = {
name: 'lat',
value: $('#lat').val()
};
fields[fields.length] = {
name: 'lng',
value: $('#lng').val()
};
FriendsWithBeerDB.writeRecord(
'friend',
this.friendId,
fields,
function() {
alert("Record Saved");
$.mobile.changePage('friends.html');
}
);
}
}

18. Save the file and test the application in the emulator. You should now
be able to create new contact records!
Attach a tap event listener to the List Items in the
Friends List

19. In the FriendsList.displayList() method, where indicated by the


comment, attach a tap event listener to the list items.
$('#friendsList > li').bind('tap', function(e) {
});

20. Inside the event handler, retrieve the numeric identifier in the list item
and transfer its value to the ContactForm.friendId property.
$('#friendsList > li').bind('tap', function(e) {
ContactForm.friendId = this.getAttribute('data-value');
});

21. Immediately after the code that you inserted in the prior step,
programmatically change the page to contactform.html
$('#friendsList li').bind('tap', function(e) {
var ContactForm.friendId = this.getAttribute(
'data-value');
$.mobile.changePage('contactform.html');
});

22. Save the file and test in the emulator. Clicking on an item in the
Friends list should now transfer control to the data entry form.
Load Data Into the Form

23. Add a new method named loadRecord to the ContactForm object.


5 - 25
2013 Intel Corporation.

Fast Track to Intel XDK New

24. Inside the loadRecord() method, define an if() block that evaluates
whether the value of the ContactForm.friendId property is null.
loadRecord: function() {
if (this.friendId != null) {
}
}

25. Inside the if() block, invoke the FriendsWithBeerDB.runQuery()


method to retrieve the record from the WebSQL friends table where the
friendId is equal to the friendId stored in the ContactForm object.
loadRecord: function() {
if (this.friendId != null) {
var sql = "select * from friend where id = {0}";
sql.format(this.friendId);
FriendsWithBeerDB.runQuery(sql, function(records) {
});
}
}

26. Inside the runQuery callback function, loop through the properties of
the first record that was returned from the database query, transferring
the values from the query result into the form.
loadRecord: function() {
if (this.friendId != null) {
var sql = "select * from friend where id = {0}";
sql.format(this.friendId);
FriendsWithBeerDB.runQuery(sql, function(records) {
var rec = records[0];
for (var i in rec) {
$("#" + i).val(rec[i]);
}
});
}
}

27. Immediately after the for-loop that you entered in the prior step, refresh
the beerId select menu.
$("#beerId").selectmenu("refresh", true);

Invoke the loadRecord() method

28. Inside the ContactForm.init() method, invoke the


ContactForm.loadRecord() method.
init: function() {
this.initialized=true;
this.populateBeerField();
this.initValidation();
this.loadRecord();
var me = this;
$("#btnSave").bind("tap", function(e) {
me.submitForm();
});
}
5 - 26
2013 Intel Corporation.

Creating Input Forms

29. Save the file.


30. Test the application. You should now be able to edit existing contact
records.
End of Walkthrough --

5 - 27
2013 Intel Corporation.

Fast Track to Intel XDK New

Unit Summary

Intel XDK New and jQuery Mobile support all HTML5 form element
types.

jQuery Mobile replaces standard checkbox, radio button, and select


field controls with controls that have been optimized for a mobile
device.

Native HTML5 form field validation is not supported by most mobile


browsers.

You can easily adapt the jQuery Validation Plugin to work with jQuery
mobile.

The jQuery Validation Plugin supports validating basic patterns


including email address, required data input, string length, numeric
input, and more.

You can persist data in memory, transmit form information to an


application server, or store it in WebSQL or HTML5 localStorage.

5 - 28
2013 Intel Corporation.

Creating Input Forms

Unit Review
1. The name and id properties of an input field should always be identical
(true/false)

2. Which method do you invoke in order to get the value of a form field?

3. Which method do you invoke in order to set the value of a form field?

4. You must call the refresh method of a text input field after changing its
value (true/false)

5. Which method can you invoke to easily combine the values from all of
your form fields in order to transmit them to a server?

6. What are the relative advantages/disadvantages to storing information


locally in WebSQL instead of posting it to an application server?

7. Describe how to populate a <select> control with options that are read
dynamically from an application server.

5 - 29
2013 Intel Corporation.

(This page intentionally left blank)

Unit 6:
Adding GEO Features

Unit Objectives
After completing this unit, you should be able to:

Load the Google API

Instantiate a map

Programmatically geocode an address from data input by the user

Programmatically center a map and understand the basic Google map


configuration options

Add overlays to a map

Getting Started with Google Maps


Deploying a Simple Map
Programmatically Geocoding Addresses
Adding Overlays and Map Markers

Unit Topics

6-1
2013 Intel Corporation.

Fast Track to Intel XDK New

Getting Started with Google Maps


The Google Maps Javascript API is a free service that lets you embed
Google Maps in your own web pages. Version 3 of the API was
specifically designed to support mobile devices as well as traditional
desktop browser applications. It includes a number of utilities for
manipulating maps and adding content to the map through a variety of
collateral services.
To facilitate the integration of Google Maps into a jQM-based app, use the
Google Maps v3 plug-in for jQuery and jQM, available at
http://code.google.com/p/jquery-ui-map/.

Working with the Google Maps Javascript API


The Google Maps Javascript API V3 now comes in three different
versions. All versions support the same features, however, they are limited
in the number of requests that they will process during a 24-hour period.
In the current model each of these API versions is limited to a number of
Page Views a day and a max number of queries per second (QPS). Google
considers a Page View to be an instance of the Maps Javascript API
being loaded in the browser or a single request for a static map. It is
important to note that the API contains many different web services and
that making request to those collateral services (e.g. the Google Geocoding
service) will also count against your Page View limit.
Page View Limitations for the Google Maps Javascript API V3 are as
follows:
1. The Free Version Limited to 1000 Page Views a day per
individual IP address, across all services
2. Purchased Key Version Users of the API can purchase an
overall daily Page View quota, that is not limited by IP address
3. Google Maps for Business API 100,000 Page Views a day per
each different service all different API services:

Directions API

Distance Matrix API

Elevation API

Geocoding API

Places API

Regardless of whether you use the free or paid-for versions of the API you
will be limited to a maximum of 10 queries per second per API. You can
purchase more bandwidth on an as-needed basis.

6-2
2013 Intel Corporation.

Adding GEO Features

Using the Purchased Key Version of Google Maps


The free version of Google Maps v3 enables you to load the API using the
following syntax:
<!--- load maps API --->
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?
sensor=SET_TO_TRUE_OR_FALSE">
</script>

However, if you wish to track map usage or you need a larger number of
daily Page Views then utilizing the Purchased Key Version. API keys are
tied to both your Google account and the domain name from where your
application will be hosted. The process to obtain an API key can be found
at the following URL:
https://developers.google.com/maps/documentation/javascript/tutorial#api_
key
As noted in the instructions, you are allowed to use the key from any
domain, but it is strongly encouraged to restrict the usage from the
domain(s) you manage.
Your Purchased Key license comes with the following restrictions:
1. 25,000 per Page View per day limit on map loads.
2. The Maps API does not include advertising.
3. Your service must be freely accessible to end users. Read terms of use
for details governing this.
4. You may not alter or obscure the logos or attribution on the map.
5. Maps should not be used to display illegal activity or reveal personal
information

6-3
2013 Intel Corporation.

Fast Track to Intel XDK New

Working with the Purchased Key Version of Google Maps


When you sign up for a paid API key, you'll be prompted to register a new
Project ID. This allows multiple Google services to be tied to a single
project/API key for tracking purposes.

Figure 1: Registering a Google Map project

After registering you'll be presented with the following screen which


contains your API key.

Figure 2: Generating the Google Maps API Key

Take the API key and inject it into the script tag that loads the maps API as
illustrated below:
<!--- load maps API --->
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?
key=YOUR_API_KEY&sensor=SET_TO_TRUE_OR_FALSE">
</script>

For additional licensing information, please see:


https://developers.google.com/maps/documentation/javascript/usage
6-4
2013 Intel Corporation.

Adding GEO Features

Deploying a Simple Map


Deploy a Google map in your app by completing the following steps:

Load the Maps JavaScript library

Load the plug-in for jQuery and JQM

Position your map on a page

Place a marker on your map that identifies a location

Loading the Google Maps API


The following is a simple example of loading the Google Maps Javascript
API V3:
<!--- load maps API --->
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?
key=3474828372366&sensor=FALSE">
</script>

As explained previously, Google Maps Javascript API V3 now allows you


to implement a mapping solution without requiring an API key. If you are
using an API Key is it important to note the following:

If Maps services are restricted to a specific set of domains, and the


load request if performed from a domain that is NOT in that set,
you will receive errors upon calling any function from the library.

You must specific true or false for the sensor URL parameter,
depending on if the device has Geospatial System (GS) capabilities
or not. You should set this to TRUE for mobile apps..

For cases where you are using the Free Version of the Google Maps
Javascript API V3, the following call would suffice for most solutions:
<!--- load maps API --->
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?
&sensor=FALSE">
</script>

6-5
2013 Intel Corporation.

Fast Track to Intel XDK New

Loading the Google Maps V3 plugin for jQuery and JQM


The Google Maps V3 plug-in for jQuery and JQM is a very flexible, highly
customizable, lightweight (3.2kB or 3.9kB for the full) library One of its
best features is that you can populate a map from microformats, RDFa or
micro-data on your site, which can be used as a fallback if a user doesn't
have Javascript enabled.
The plug-in is well-documented and acts as an abstraction library for the
most commonly used functionality available from Google Maps. The
jQuery Google Maps plug-in documentation integrates links to Google
Maps Javascript V3 APIs, classes and methods, shortening the learning
curve for including Google Maps in a mobile web app.
The Google Maps V3 plug-in for jQuery and JQM comes with a variety of
libraries, in both full source and minified versions. Depending on your
implementation you may use one or more of these:

jquery.ui.map.js Main library file

jquery.ui.map.extensions.js Used with Geocoding

jquery.ui.map.microdata.js Used for microdata


implementations

jquery.ui.map.microformat.js Used with microformats

jquery.ui.map.overlays.js Used with shapes and KML

jquery.ui.map.rdfa.js Used with RDFa data

jquery.ui.map.services.js Used with Directions and Street view

Each of these libraries has an associated minified version for you to work
with. When implementing for JQM you will use a special minified version
of the main library file jquery.ui.map.full.min.js.
To handle the most basic of map implementations your to implement the
plug-in will look like the following:
<!--- Google Maps / JQuery Plugin --->
<script type="text/javascript"
src="ui/jquery.ui.map.full.min.js">
</script>

6-6
2013 Intel Corporation.

Adding GEO Features

Placing your map on a page


You can instantiate a map into any HTML element that has a unique
identifier (typically a <div>). The map will conform to the defined size of
the container. A typical map container would resemble the following:
<div id="map_canvas"></div>

In order to style the map you will either provide in-line styles for the
<div> tag or provide some parameters for the div to constrain the size. In
this example, you could include a <style> block at the top of the file, or
place the style within a CSS file. The entry for the ID 'map_canvas' could
look like this:
<style type="text/css">
html { height: 100% }
body { height: 100%; margin: 0; padding: 0 }
#map_canvas { width: 100%; height: 380px }
</style>

When implementing for mobile you will want pay particular attention to
the map canvas parameters. Depending on how the styles have been
implemented with the application you may have to push the map into a
fixed height.
Instantiating a map with the JQM Google Maps plugin typically requires
you to call a constructor named gmap() as illustrated below. Note the use
of #map_canvas which is used to point the map to our map_canvas
<div> and the use of the mapOptions variable to set some basic
parameters for the map,.
<!-- loading a Google Map using jQuery -->
<script type="text/javascript">
var mapOptions = {
'center': '38.986000000, -76.940131000',
'zoom': 15,
disableDefaultUI: false
};
$('#map_canvas').gmap({
center: mapOptions.center,
mapTypeId: google.maps.MapTypeId.SATELLITE,
zoom: mapOptions.zoom,
disableDefaultUI: mapOptions.disableDefaultUI
});
</script>

6-7
2013 Intel Corporation.

Fast Track to Intel XDK New

Setting Options for your Map


The Google Maps Javascript API Map class supports over 30 different
configuration properties, generally referred to as MapOptions. A full
listing can be found here:
https://developers.google.com/maps/documentation/javascript/reference#M
apOptions
At a minimum, the following options must be included when instantiating
a new Map object:

zoom (type int) max zoom value is 19

mapTypeId indicates the type of map to display

center center point on the map, in


Latitude/Longitude

Refreshing the Map


In some user-cases, as illustrated by Figure 3, your
map may only partially instantiate. To handle this
glitch, invoke the gmap refresh() method after a brief
delay to allow the map to initialize.
var loc = new google.maps.LatLng(
"38.908696", "-77.036527");
$mapContainer.gmap({
center: loc,
Figure 3: Partially
zoom: 16,
mapTypeId:google.maps.MapTypeId.SATELLITE rendered map.
});
setTimeout("$('#map').gmap('refresh')",500);

6-8
2013 Intel Corporation.

Adding GEO Features

Geocoding a starting position


One of the most important MapOptions is the the center option. This
option gives the map its starting center latitude and longitude coordinates.
You can manually geocode a starting address by going to http://geocoder.us

Figure 4: Manually convert street addresses to lat/lng positions

Using Different Map Types


One of the main features of Google Maps are the different map types. In
the example below we used a MapOption called MapTypeID to name of
the map type displayed. These are defined in the Google API
documentation as follows:

ROADMAP (Default) - displays the normal, default 2D tiles of


Google Maps.

SATELLITE - displays photographic tiles.

HYBRID - displays a mix of photographic tiles and a tile layer for


prominent features (roads, city names).

TERRAIN - displays physical relief tiles for displaying elevation and


water features (mountains, rivers, etc.).

The value of the map type is case sensitive and coincides with the different
map types you can choose from the standard maps UI.
<!-- Instantiating a map using the Satellite Map type -->
$('#map_canvas').gmap({
'center': mapOptions.center,
'mapTypeId': google.maps.MapTypeId.SATELLITE,
'zoom': mapOptions.zoom,
'disableDefaultUI': mapOptions.disableDefaultUI
});
6-9
2013 Intel Corporation.

Fast Track to Intel XDK New

Customizing the look/feel of a map


Another set of commonly used MapOptions are the controls. Google Maps
allows you to customize the various controls within your maps. In our
example on the previous page we set the disableDefaultUI option to false.
This enables the zoom, map type, and street view controls by default.
Other supported controls, which allow you more granularity, include the
following:
Property

Description

streetViewControl

Boolean. The initial enabled/disabled state of the


Street View control. This control is part of the
default UI, and should be set to false when
displaying a map type on which the Street View
road overlay should not appear (e.g. a non-Earth
map type).

panControl

Boolean. The enabled/disabled state of the Pan


control.

scaleControl

Boolean. The initial enabled/disabled state of the


Scale control.

mapTypeControl

Boolean. Buttons that let the user toggle between


map types (such as Map and Satellite). There are
several levels of sub options for controlling the
position and style if the map type controls that can
be defined here.

overviewMapControl Boolean. A collapsible overview map in the corner


of the screen

6 - 10
2013 Intel Corporation.

Adding GEO Features

Walkthrough 6-1: Getting Started with Maps


In this walkthrough you will manually geocode
an address and center a map on that location
using the JQM Plug-in and Google Maps
Javascript API V3.

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the topleft corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk6_1/walk6_1.xdk

Manually Geocode a Location

5. Open a web browser to http://geocoder.us


6. Enter your address and click search.
7. Note the latitude and longitude of your address.
Load Google Maps and the Google JQM Maps Plugin

8. Open index.html in code view.


9. Where indicated by the comment, insert the script declarations to
initialize the Google Maps Javacript API V3 library. Your code should
resemble the following:
<script type="text/javascript"
src="http://maps.googleapis.com/maps/api/js?
sensor=true></script>

10. After the code that you inserted in the prior step, add a <script> tag
that loads the jQuery Google Map plugin.
<script type="text/javascript"
src="js/jquery.ui.map.js"></script>

Reserve a Space for the Map

11. Open contactdetail.html in Design mode.


12. From the Controls > Layout palette, drag a ROW widget and drop it
onto the middle of the Design Canvas

6 - 11
2013 Intel Corporation.

Fast Track to Intel XDK New

13. From the Controls > Layout palette, drag a ROW widget and drop it
directly underneath the row that you inserted in the prior step.
14. Go to Code view.
15. Locate the markup that was generated for the second row widget and
add an id property with a value of map as illustrated below:
<div class="grid grid-pad urow uib_row_2 row-height-2"
data-uib="layout/row"
id="map">

16. Save the file.


Render the Map

17. Open index.html in code view. Note that a ContactDetail object has
been defined for you.
18. Inside the ContactDetail object, define an init() method.
19. Inside the init() method, define a local variable named $mapContainer
that points to the map row that you defined in step 15.
var $mapContainer = $("#map");

20. After the code that you inserted in the previous step, use the gmap()
method to instantiate a map that's centered on the lat/lng position that
you noted from step 7.
21. Review your code to ensure that it appears similar to the following:
var ContactDetail = {
friendId: null,
gMap: null,
init: function() {
var $mapContainer = $("#map");
this.gMap = $mapContainer.gmap({
center: new google.maps.LatLng ("38.908696",
"-77.036527"),
zoom: 16
});
}
}

22. Save the file.


Invoke the ContactDetail Page

23. In the Contacts.displayList() method, modify the tap event listener for
the friendsList list items to load the contactDetail.html page. Your code
should appear as follows:
$('#friendsList li').bind('tap', function(e) {
ContactForm.friendId = this.getAttribute('data-value');
ContactDetail.friendId = ContactForm.friendId;
$.mobile.changePage('contactdetail.html');
});

24. Save the file and test. Tapping on a list item should display a small
sliver map on the ContactDetail page.

6 - 12
2013 Intel Corporation.

Adding GEO Features


Adjust Map Rendering

25. Return to index.html in CODE mode.


26. At the bottom of the ContactDetail.init() method, use jQuery to set the
height of the map to be the height of the document body minus 300
pixels (to account for the header, footer, and top row).
$mapContainer.height ($("body").height() - 200);

27. Save the file and test in the Emulator. You should see a larger map,
however that still doesn't quite render correctly.
28. Return to index.html in CODE mode.
29. At the bottom of the ContactDetail.init() method, insert a setTimeout()
method that refreshes the map after 500 milliseconds.
setTimeout("$('#map').gmap('refresh')",500);

30. Save the file and test the application in the emulator.
End of Walkthrough --

6 - 13
2013 Intel Corporation.

Fast Track to Intel XDK New

Programmatically Geocoding Addresses


In order to plot a position on a map, you must know its geocode, or
latitude/longitude. You can programmatically determine the geocode of an
address by using the geocode() method of the google.maps.Geocoder
object. Note the following:

The use of the geocode() method is restricted daily based on your


Google Maps API license levels.

For best results, store geocodes of specific locations in your


database. Note that Google's license terms specifically forbid
storing positions generated by Google's geocoder in a database.

When calling the geocode() method, you must specify a callback


function that will receive the calculated coordinates

The geocode() method is called asynchronously. As such you will


not be able to pass variables out of the callback function. If you
need to pass the coded data out you will need to chain your
functions together.

The latitude/longitude is returned within a geometry structure


within a results array. You can access the information by calling
the lat() and lng() methods..

In the following example illustrates Geocoding and address and storing the
resulting lat/long into a variable. The map is then centered on the specified
position.
<!-- get lat and lng of address -->
var geocoder = new google.maps.Geocoder();
geocoder.geocode(
{
address : '1600 Pennsylvania Ave Washington DC'
},
function(results, status) {
var location;
if(status != google.maps.GeocoderStatus.OK) {
alert("Address not found");
} else {
location = results[0].geometry.location;
}
$('#map_canvas').gmap({
center: location,
zoom: 15,
disableDefaultUI: false
});
});

6 - 14
2013 Intel Corporation.

Adding GEO Features

Walkthrough 6-2: Geocoding Addresses


In this walkthrough you will programmatically
geocode your contact's address.

Define disabled input fields

Attach event listeners to form fields

Geocode a street address

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk6_2/walk6_2.xdk

Add Buttons to the ContactDetail Page

5. Open contactdetail.html in Design mode.


6. Add a back button to the page header by dragging a Button widget
from the Controls > Forms panel and dropping it on the leftmost
position of the header toolbar.
7. Configure the following Button properties:
Label: Back (unchecked)
Icon: ui-icon-back (checked)
Icon Position: icon only
8. Go into code view and add the following property to the Back
button:
data-rel="back"

9. Return to Design mode.


10. Add an Edit button to the page header by dragging a Button widget
from the Controls > Forms panel and dropping it on the right-most
position of the header toolbar.
11. Configure the following Button properties:

Label: Edit (unchecked)


Icon: ui-icon-edit (checked)
Icon Position: icon only

6 - 15
2013 Intel Corporation.

Fast Track to Intel XDK New


Geocode the Address

12. Go to code view and add the following property to the edit button's
anchor tag:

href=contactform.html

13. Save the file and test the application in your emulator.
Geocode the Address

14. Open index.html in Code mode.


15. Add a method to the ContactForm object named geoCode.
16. Inside the geoCode function, create a variable named geocoder that
instantiates the Google Maps Geocoder object.
var geocoder = new google.maps.Geocoder();

17. Directly under the code that you inserted from the prior step, call the
geocoder.Geocode method, passing it the address and zip code that the
user entered in the form.
geoCode: function() {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
address : $('#address').val() + " " + $('#zipcode').val()
}, function(results,status) {
});
}

18. Inside the geocoder callback function, insert code to populate the lat
and lng text fields with the resulting geocode data. If the geocding
failed, set the values of the lat and lng field to the empty string. Your
code should appear similar to the following:
geoCode: function() {
var geocoder = new google.maps.Geocoder();
geocoder.geocode({
address : $('#address').val() + " " + $('#zipcode').val()
}, function(results,status) {
if(status != google.maps.GeocoderStatus.OK) {
alert("Address not found");
$("#lat").val('');
$("#lng").val('');
} else {
$("#lat").val(results[0].geometry.location.lat());
$("#lng").val(results[0].geometry.location.lng());
}
});
}

6 - 16
2013 Intel Corporation.

Adding GEO Features


Attach Event Listeners to the Address and ZipCode
Fields

19. At the bottom of the ContactForm.init() method, create event listeners


for the change event on the address and zipcode fields that fire the
geocode method.
$("#address").bind("change", this.geoCode);
$("#zipcode").bind("change", this.geoCode);

20. Save the file and test the app in the Emulator. Editing a contact record
should cause the address to be geocoded with the results getting placed
into the lat/lng input fields.
-- End of Walkthrough --

6 - 17
2013 Intel Corporation.

Fast Track to Intel XDK New

Adding Overlays and Map Markers


Overlays are map objects that indicate points, lines, areas, or objects which
are tied to specific lat/lng coordinates. There are a number of canned
overlays, such as the Google Maps Traffic Layer, that you can easily add to
your map. Map markers, identifying specific positions on your map, are a
form of custom overlay.

Using Overlays
Google Maps enables you to add transparency layers to your map that
visualize the following datasets:
Layer

Description

KmlLayer

Renders KML and GeoRSS elements into a Maps


API V3 tile overlay.

HeatmapLayer

Renders geographic data using a Heatmap


visualization

FusionTablesLayer

Renders data contained in Google Fusion Tables.

TrafficLayer

Renders a layer depicting traffic conditions and


overlays representing traffic.

TransitLayer

Displays the public transport network of your city


on the map.

WeatherLayer and
CloudLayer

Allow you to add weather forecasts and cloud


imagery to your map.

BicyclingLayer

Renders a layer of bike paths and/or bicyclespecific overlays into a common layer. This layer is
returned by default within the DirectionsRenderer
when requesting directions of travel mode
BICYCLING.

PanoramioLayer

Adds photos from Panoramio as a layer.

DemographicsLayer Renders United States demographic information as


a layer, and is available to Google Maps API for
Business customers only. It is contained within the
visualizationlibrary.

6 - 18
2013 Intel Corporation.

Adding GEO Features

Displaying the Current Traffic Conditions


Instantiate the traffic layer using the google.maps.TrafficLayer()
constructor. In order to apply it to a map, you must call the setMap()
method of the resulting object.
The following code snippet illustrates how to add traffic map overlay to a
Google Map. Note that the use of the callback method which receives a
pointer to the google map instance created by the jQuery Maps plugin.
var $mapContainer = $("#map");
$mapContainer.gmap({
center: new google.maps.LatLng ("38.908696", "-77.036527"),
zoom: 16,
callback: function(map) {
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
}
});

Displaying the Panoramio Layer


Loading the Panoramio layer requires you to modify the url of the <script>
tag that loads the Google Maps API as illustrated by the following
example:
<script
src="https://maps.googleapis.com/maps/api/js?
v=3.exp&sensor=true&libraries=panoramio">
</script>

With the Panoramio version of the Google Maps API loaded, it becomes a
simple matter to instantiate the map with local photos:
var $mapContainer = $("#map");
$mapContainer.gmap({
center: new google.maps.LatLng ("38.908696", "-77.036527"),
zoom: 16,
callback: function(map) {
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
var pl = new google.maps.panoramio.PanoramioLayer();
pl.setMap(map);
}
});

6 - 19
2013 Intel Corporation.

Fast Track to Intel XDK New

Adding Map Markers


Markers identify points on a map and inherit from the same base class as
overlays. They are assigned a position on a map, and can be assigned a
number of properties, including tooltips and custom icons for display.
Using the Google Maps plug-in for jQuery and JQM you can add a marker
to an existing map with the following block of code:
$('#map_canvas').gmap('addMarker', {
position: '42.345573,-71.098326',
bounds: false
});

Note the following:

The position attribute determines where the marker should be placed


on the map.

The bounds attribute identifies whether or not you want the map to
automatically zoom in on the marker when the marker is instantiated.

Adding a Marker to the Center of the Map


In most use-cases, you'll want to place a maker on the map to identify the
center point. As illustrated by the following code snippet, you can easily
implement this in the callback handler that executes during the map
instantiation process.
var $mapContainer = $("#map");
$mapContainer.gmap({
center: new google.maps.LatLng ("38.908696", "-77.036527"),
zoom: 16,
callback: function(map) {
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
var pl = new google.maps.panoramio.PanoramioLayer();
pl.setMap(map);
this.addMarker({
position: map.getCenter()
})
}
});

6 - 20
2013 Intel Corporation.

Adding GEO Features

Walkthrough 6-3: Defining Markers


In this walkthrough you will change your
map instantiation to center the map on your
friend's location and display a map marker.

Retrieve data from a WebSQL database

Center the map on a lat/lng position that


was saved to a WebSQL database

Add a marker to the map

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the
top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk6_3/walk6_3.xdk

Retrieve and Cache Contact Information from WebSQL

5. Add the following properties to the ContactDetail object:


contactData
mapCenter
6. Inside the init() method, define a local variable named me and set it
equal to the ContactData object.
var me = this;

7. At the end of the init() method, use WebSQL to retrieve the


information for the friend whose primary key value is stored in the
ContactDetail.friendId property.
FriendsWithBeerDB.runQuery(
"select * from friend where id = " + this.friendId,
function(records) {
}
);

8. Inside the WebSQL callback function, set the


ContactDetail.contactData property equal to the record that was
returned from the sql query.
me.contactData = records[0];

6 - 21
2013 Intel Corporation.

Fast Track to Intel XDK New

9. After the code that you inserted in the prior walkthrough, set the
ContactDetail.mapCenter property equal to the a Google LatLng object
that's set to the lat/lng position retrieved from the database query.
me.mapCenter = new google.maps.LatLng (
records[0].lat, records[0].lng
);

10. Invoke the initMap() method from the WebSQL function callback.
Center the Map and Add Overlays

11. Inside the ContactDetail.initMap() method, configure the map instance


to center on ContactDetail.mapCenter.
this.gMap = $mapContainer.gmap({
center: this.mapCenter,
zoom: 16
});

12. Inside the $mapContainer.gmap() configuration object, add a callback


method.
this.gMap = $mapContainer.gmap({
center: this.mapCenter,
zoom: 16,
callback: function(map) {
}
});

13. Inside the callback function, instantiate the traffic and panoramio
layers and apply them to the map.
this.gMap = $mapContainer.gmap({
center: this.mapCenter,
zoom: 16,
callback: function(map) {
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
var panoramioLayer = new
google.maps.panoramio.PanoramioLayer();
panoramioLayer.setMap(map);
}
});

6 - 22
2013 Intel Corporation.

Adding GEO Features


Add a Marker to the Map

14. At the bottom of the map instance callback function, add a map marker
to the center of the map.
this.gMap = $mapContainer.gmap({
center: this.mapCenter,
zoom: 16,
callback: function(map) {
me.map = map;
var trafficLayer = new google.maps.TrafficLayer();
trafficLayer.setMap(map);
var panoramioLayer = new
google.maps.panoramio.PanoramioLayer();
panoramioLayer.setMap(map);
this.addMarker({
position: map.getCenter()
});
}
});

15. Save the file and test in the emulator using a friend record that has
been successfully geocoded.

-- End of Walkthrough --

6 - 23
2013 Intel Corporation.

Fast Track to Intel XDK New

Unit Summary

There are multiple licensing options for the Google Maps Javascript
API V3, including a paid for subscription model

Use the JavaScript loader to dynamically load Google API's at runtime

To facilitate using Google Maps with jQuery and JQM you can use the
Google Maps V3 plugin for jQuery and jQuery Mobile

Use the google.maps.Map() object to instantiate maps on your pages in


basic Javascript

Use $(#map_canvas).gmap() to instantiate maps using the plugin for


jQuery mobile

Use jQuery to loop through a returned dataset to programmatically


populate a map overlay components.

Create map markers using the google.maps.Marker() or addMarker()


and assign them to overlays

6 - 24
2013 Intel Corporation.

Adding GEO Features

Unit Review
1. What do you need to get started using the Google Maps API?

2. Describe the process for placing a map on a web page

3. Describe the steps for geocoding an address

4. What are the types of overlays that you can place on a Google Map?

5. You cannot configure the look of a map marker? (true/false)

6 - 25
2013 Intel Corporation.

(This page intentionally left blank)

Unit 7:
Using Device Features

Unit Objectives
After completing this unit, you should be able to:

Retrieving the device's current location

Programmatically activate the phone dialer

Launch the device's email client with the subject, body, and to: fields
pre-filled

Prompt the user to launch the device's built-in navigation app

Create an event listener for the accelerometer so that an action is


performed when the user shakes their device.

Listen for push notifications

Retrieving the Device's Current Location


Launching the Phone, Email, and Navigation Apps
Listening to the Accelerometer
Listening for Push Notifications

Unit Topics

7-1
2013 Intel Corporation.

Fast Track to Intel XDK New

Retrieving the Device's Current Location


Use the navigator.geolocation class to retrieve the user's current position
from its GPS sensor.

Getting the Latitude and Longitude


As illustrated by the following code sample, determining a device's
position is an asynchronous event due to the latency associated with
locating the proper satellites from which to calculate a "fix". When the
position of the device has been calculated, the callback handler will be
executed.
Note that you should always provide an error handler as this feature may
fail if the user moves to a location where line-of-sight to the satellites and a
wifi connection are both unavailable.
navigator.geolocation.getCurrentPosition(
function(position) {
var pos = new google.maps.LatLng(
position.coords.latitude,
position.coords.longitude);
},
function (error) {
var msg = "";
switch(error.code) {
case error.PERMISSION_DENIED:
msg="User denied the request for Geolocation."
break;
case error.POSITION_UNAVAILABLE:
msg="Position is unavailable."
break;
case error.TIMEOUT:
msg="The GPS request timed out";
break;
case error.UNKNOWN_ERROR:
msg = "An unknown error occurred getting your position"
break;
}
alert(msg);
}
);

7-2
2013 Intel Corporation.

Using Device Features

Retrieving Additional Information from the GPS Sensor


In addition to the latitude and longitude, most device browsers will also
return the following information as properties of the position.coords object.
Property

Description

accuracy

The accuracy of the position

altitude

The altitude (in meters) above sea level

altitudeAccuracy The accuracy of the altitude query


heading

The user's heading, specified in degrees clockwise from


North

speed

The speed (in meters per second)

timestamp

The date/time of the last successful request

Calculating Distance to Target


You can calculate the distance between two points by using either the
Haversine formula or the Spherical Law of Cosines. The following
function represents a JavaScript implementation of the Haversine formula:
var calcDistance = function(lat1,lng1,lat2,lng2) {
var
var
var
var
var

R = 3959; // use 3959 for miles or 6371 for km


dLat = (lat2-lat1) * Math.PI / 180 ;
dLon = (lng2-lng1)* Math.PI / 180;
lat1 = lat1 * Math.PI / 180;
lat2 = lat2 * Math.PI / 180;

var a = Math.sin(dLat/2) * Math.sin(dLat/2) +


Math.sin(dLon/2) * Math.sin(dLon/2) * Math.cos(lat1) *
Math.cos(lat2);
var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
return R * c;
}

7-3
2013 Intel Corporation.

Fast Track to Intel XDK New

Enabling Permissions to Access the GPS Sensor


As illustrated in Figure 1, you will need to turn on permissions to the GPS
sensor prior to producing a native build. Android apps that attempt to
access the gps sensor without the proper permissions will fail silently.

Figure 1: Configuring GeoLocation Permission

7-4
2013 Intel Corporation.

Using Device Features

Walkthrough 7-1: Getting the Device Location


In this walkthrough you will get the device's
current position and calculate the distance
between the device and your selected friend.

Implement a multi-column layout

Format WebSQL data using a Template

Get the device's current position

Calculate range to target

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the topFigure 2: Output contact
left corner of the GUI.
3. Click the Open a Project button.

info and distance to


target.

4. Select the following file:


/ftIntelXdkNew/walk/walk7_1/walk7_1.xdk

Modify the Contact Detail Layout

5. Open contactdetail.html in Design mode.


6. From the Controls > Layout palette, drag a
Column widget and drop it to the left of
the top row of page layout.
7. Drag the left column's right-divider to the
right until your layout appears similar to
Figure 3.
8. Go to Code View

Figure 3: ContactDetail
page layout

9. Add an id=contactdetails property to the column that you just added.


Your code should resemble the following:
<div class="col uib_col_4 col-0_6-12" data-uib="layout/col">
<div class="widget-container content-area vertical-col"
id="contactdetails">
<span class="uib_shim"></span>
</div>
</div>

10. Save the file

7-5
2013 Intel Corporation.

Fast Track to Intel XDK New

Output Contact Information

11. Open index.html in Code view.


12. Where indicated by the comment, define a template that contains
placeholders for the contact's first name ({0}), last name ({1}), address
({2}), and favorite beer ({3}) as well as a <span> tag from where the
distance will be output.
<script type="text/template" id="tplContact">
<div class="contactname">{0} {1}</div>
<div class="contactaddress">{2}</div>
<div class="contactdistance">{3} is only <span
id="distancetofriend"></span> away!</div>
</script>

13. Define a method in the ContactDetail object named outputDetails().


14. Inside the outputDetails() method, define a local variable named
tplContact that contains the html from the template that you defined
from step 12.
var tplContact = $("#tplContact").html();

15. After the code that you added in the prior step, define a local variable
named html that processes the contact's information through the
template.
var html = tplContact.format(
this.contactData.firstName,
this.contactData.lastName,
this.contactData.address,
this.contactData.beername
);

16. After the code that you inserted in the prior step, output the contents of
the html variable to the #contactdetails <div> element.
$("#contactdetails").html(html);

17. Where indicated by the comment, invoke the


ContactDetail.outputDetails() method.
18. Save the file and test in the emulator. Tapping on a contact name
should now display the contact's name, address, and favorite beer in an
area positioned immediately above the map.
Get the Device's Current Position

19. Return to index.html in Code mode.


20. Add an additional method named outputDistance() to the
ContactDetail object.
21. Inside the outputDistance() method, define a variable named me that
points to the current scope.
var me = this;

7-6
2013 Intel Corporation.

Using Device Features

22. Invoke the navigator.geolocation.getCurrentPosition() method,


defining success and error callback functions. Your code should
appear similar to the following:
navigator.geolocation.getCurrentPosition(
function(position) {
},
function(error) {
}
);

23. Inside the success callback function, convert the device's latitude and
longitude coordinates to a google maps lat/lng object and store the
resulting object into the ContactDetail.currentPosition property.
navigator.geolocation.getCurrentPosition(
function(position) {
me.currentPosition =
new google.maps.LatLng(
position.coords.latitude,
position.coords.longitude
);
},
function(error) {
}
);

24. After the code that you inserted in the prior step, define a local variable
named miles that contains the calculated distance between the device
and the selected friend.
Note: The calcDistance function is defined on line 102 of index.html
var miles = calcDistance(
me.mapCenter.lat(),
me.mapCenter.lng(),
position.coords.latitude,
position.coords.longitude
);

25. Immediately after the code that you inserted in the prior step, output
the value from miles into the <span id=contactdistance> element.
$("#distancetofriend").html(miles + " miles ");

26. Inside the error function callback, output an alert() that indicates that
an error occurred in retrieving the device's coordinates.
27. Where indicated by the comment inside of the ContactDetail.init()
method, invoke the outputDistance function.
28. Save the file and test. Tapping on a contact should now display the
distance between the device and the contact's address as illustrated by
the screenshot in Figure 2.
End of Walkthrough -7-7
2013 Intel Corporation.

Fast Track to Intel XDK New

Launching the Phone, Email, and Navigation Apps


You can execute the device's phone dialer, email, and navigation apps by
programmatically setting location.href to a specially encoded url link as
illustrated below:
// launch mail-compose
location.href='mailto:sdrucker@figleaf.com';

Activating the Phone Dialer


Use the tel URL scheme to launch the device's phone dialer and initiate
dialing of the specified phone number. Whether or not the user is prompted
to dial or the dialing occurs automatically is dependent on the type of
mobile operating system being used.
The javascript syntax to activate the native Phone app is:
location.href="tel:555-555-5555";

Note that the iOS browser will automatically try to detect and hyperlink
strings that match a phone number pattern. You can disable this behavior
by adding the following meta tag to your html:
<meta name = "format-detection" content = "telephone=no">

Activating the Email Client


Use the mailto: url scheme to launch the mail app's compose feature and
programmatically fill the following fields:

Syntax

Description

mailto:

Receipient or recipients (comma-separated list)

&cc=

The carbon copy recipients (comma-separated list)

&bcc=

The blind carbon copy recipients (comma-separated list)

&subject

The subject of the email, url encoded using JavaScript's


escape() method.

&body=

The body of the message (including line breaks), url


encoded using Javascript's escape() method.

7-8
2013 Intel Corporation.

Using Device Features

To launch the mail client, dynamically assemble the url and


programmatically click it as illustrated by the following code snippet:
var mailLink = "mailto:{0}?subject={1}&body={2}";
mailLink = mailLink.format(
"sdrucker@figleaf.com",
escape("Can I come over now?"),
escape("Hey good buddy, can I come over?")
);
location.href = mailLink;

Branching your code for Turn-by-Turn Directions


The techniques for launching turn-by-turn directions in iOS and Android
vary significantly, therefore you'll need to branch your code by inspecting
the contents of the navigator.userAgent property as illustrated below:
if( /Android/i.test(navigator.userAgent) ) {
// android-specific code
} else if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
// ios specific code
}

Activating the Navigation App on iOS


On iOS, the maps URL scheme can open the native Apple maps app to
show geographical locations as well as generate driving directions between
two points.
On iOS, maps links are specified using a special maps:// uri as illustrated
by the following snippet:
<a href="maps://?daddr=2000 K St 20036&saddr=santa clara,
CA">Directions</a>

You can pass the following parameters to the maps.apple.com url:


Argument

Description

This parameter is treated as if it had been typed into the


query box by the user in the Maps app

near

Locates a position near the specified target

ll

The latitude and longitude (comma-separated) for the


center point of the map.

7-9
2013 Intel Corporation.

Fast Track to Intel XDK New

Argument

Description

sll

The latitude and longitude (comma-separated) from where


a business search should be performed.

spn

The approximate latitude and longitude span

The type of map to display

Zoom level

saddr

The source address from which to generate driving


directions

daddr

The destination address from which to generate driving


directions.

The following snippet illustrates how to generate a link that, when pressed,
would launch an iOS device's maps app with turn-by-turn directions:
var fromAddr = escape("1400 16th St NW 20036");
var toAddr = escape("2000 K St NW 20036");
var tpl='<a href="maps://?daddr={0}&saddr={1}">Click Me</a>'
location.href = tpl.format(fromAddr,toAddr);

Activating the Navigation App for Android Web Apps


Opening the navigation app on Android can be a little tricky since the
Android webview, which is used to drive native-apps functions slightly
differently than the native Android browser when it's running in standalone
mode.
If running your code as a web app, the browser will respond similarly to
the technique previously described for iOS devices you simply need to
specify the url for maps.google.com as illustrated below:
var fromAddr = escape("1400 16th St NW 20036");
var toAddr = escape("2000 K St NW 20036");
var tpl='<a href="http://maps.google.com/maps?
daddr={0}&saddr={1}">Click Me</a>'
location.href = tpl.format(fromAddr,toAddr);

You can also open the native Google Maps app by using the geo: uri. As
illustrated by the following use case, you can pass a latitude and longitude
as a comma-delimited list. The z argument indicates zoom level on a scale
of 1-23 where 1 is the whole earth and 23 is is the highest zoom level.
<a href="geo://?
saddr=20.544,34.34&daddr=20.866,45.345">Navigate!</a>

7 - 10
2013 Intel Corporation.

Using Device Features

Unfortunately, the Android WebView that is used to run your app in


native mode does not recognize that a maps.google.com url or the geo:
uri should be opened in an external app.

Launching Google Maps in the Cordova InAppBrowser


An alternative to launching the native Google
Maps app on the device is to launch the
maps.google.com web app inside of a
Cordova InAppBrowser.
The InAppBrowser is a web browser that
displays when you invoke the window.open()
method as illustrated below:
var fromAddr =
escape("1400 16th St NW 20036");
var toAddr =
escape("2000 K St NW 20036");
var tpl="http://maps.google.com/maps?
daddr={0}&saddr={1}";
var loc =
tpl.format(fromAddr,toAddr);

Figure 4: The Cordova


InAppBrowser

var ref = window.open(loc, '_blank', 'location=yes');

Activating the Navigation App for Native Android Apps


Another alternative is to use a Cordova plugin that enables you to launch
and Android intent. An intent is an abstract description of an operation to
be performed which can include launching an activity. In native Android
parlance, an activity is an app.

Detecting Native vs Web


if (document.URL.indexOf( 'http://' ) === -1 &&
document.URL.indexOf( 'https://' ) === -1) {
// PhoneGap application
} else {
// Web page
}

7 - 11
2013 Intel Corporation.

Fast Track to Intel XDK New

Walkthrough 7-2: Invoking External Apps


In this walkthrough you will enhance the
contactdetail view by adding buttons that
enable the user to telephone, email, or get turnby-turn directions to their friend with beer.

Add buttons to a UI

Create a function to programmatically


click a dynamic link

Use special urls to invoke external apps

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the topleft corner of the GUI.
Figure 5: Add buttons to
3. Click the Open a Project button.

dial, email, and navigate

4. Select the following file:


/ftIntelXdkNew/walk/walk7_2/walk7_2.xdk

Add buttons to the UI

5. Open contactdetail.html in Design mode.


6. From the Controls > Form panel, drag a BUTTON widget and drop it
on the top row, right-column of the page body in the canvas.
7. Configure the following Button properties:

Mini: checked
Icon: ui-icon-phone
Icon Position: Icon only
Id: btnPhone

8. From the Controls > Form panel, drag a BUTTON widget and drop it
onto the design canvas, directly underneath the btnPhone button.
9. Configure the following Button properties:

Mini: checked
Icon: ui-icon-mail
Icon Position: Icon Only
Id: btnMail

10. From the Controls > Form panel, drag a BUTTON widget and drop it
onto the design canvas, directly underneath the btnMail button.
7 - 12
2013 Intel Corporation.

Using Device Features

11. Configure the following Button properties:

Mini: checked
Icon: ui-icon-navigation
Icon Position: Icon Only
Id: btnNav

12. Save the file


Create an Event Listener for the Telephone Button

13. Inside the ContactDetail object, define a method named


configureButtons().
14. In the ContactDetail.init() method, invoke the
ContactDetail.configureButtons() function directly underneath the
outputDetails() invocation.
me.outputDetails();
me.configureButtons();
me.outputDistance();

15. Inside the ConfigureButtons() method, bind a tap event listener to the
btnPhone button so that it launches the user's phone application and
dials their friend's phone number when tapped.
16. Verify that your code appears similar to the following:
$("#btnPhone").bind("tap", function(e) {
var ph = ContactDetail.contactData.phone;
if (ph != "") {
var telLink = "tel:" + ph;
location.href=telLink;
} else {
alert("Phone Number Not Available");
}
});

17. Save the file.


18. Click on the Test tab.
19. Click the Push Files button
20. Launch Intel App Preview on your device, scan the QR code, and test
your app.
Create an Event Listener for the Email Button

21. Return to index.html in Code mode.


22. Underneath the code that you added in step 14, bind a tap event listener
to the btnMail button so that it launches the user's email application
and sets default subject and body text when tapped.

7 - 13
2013 Intel Corporation.

Fast Track to Intel XDK New

23. Verify that your code appears similar to the following:


$("#btnMail").bind("tap", function(e) {
var mailLink = "mailto:{0}?subject={1}&body={2}";
mailLink = mailLink.format(
ContactDetail.contactData.email,
escape("Can I come over now?"),
escape("Need to chat about something big!")
);
location.href = mailLink;
});

24. Launch Intel App Preview on your device, scan the QR code, and test
your app.
Create an Event Listener for the Nav Button

25. After the code that you inserted from step 22, bind a tap event listener
to the #btnNav button. Your code should appear similar to the
following:
$("#btnNav").bind("tap", function(e) {
});

26. Inside the event handler function, insert an if-elseif-else block that
determines whether the user is using an Android device or an iOS
device. If the device is not iOS or Android, output an alert message.
Your code should appear similar to the following:
$("#btnNav").bind("tap", function(e) {
if (/Android/i.test(navigator.userAgent)) {
} else if (/iPhone|iPad|iPod/i.test(navigator.userAgent)) {
} else {
alert('Device not supported');
return;
}
});

27. Inside the if() block for Android, define a local variable named
mapsUrl and set it equal to the google maps url with GET parameters
named daddr and saddr that point to lat/lng placeholders.
if (/Android/i.test(navigator.userAgent)) {
var mapsUrl = "http://maps.google.com/maps?daddr={0},
{1}&saddr={2},{3}";
}

7 - 14
2013 Intel Corporation.

Using Device Features

28. After the code that you inserted in the prior step, replace the
placeholders with the lat/lng coordinates of the contactData and
currentPosition properties of the ContactDetail object.
mapsUrl = mapsUrl.format(
ContactDetail.contactData.lat,
ContactDetail.contactData.lng,
ContactDetail.currentPosition.lat(),
ContactDetail.currentPosition.lng()
);

29. After the code that you inserted from the prior step, launch the url in an
inAppBrowser.
window.open(mapsUrl, '_blank', 'location=yes');

30. Inside the if() block for iOS, define a local variable named mapsUrl
and set it equal to the Apple maps url with GET parameters named
daddr and saddr that point to lat/lng placeholders.
if (/Android/i.test(navigator.userAgent)) {
var mapsUrl = "http://maps.google.com/maps";
} else if (/iPhone|iPad|iPod/i.test(navigator.userAgent)){
var mapsUrl = "maps://?daddr={0},{1}&saddr={2},{3}";
} else {
/* omitted for brevity */
}

31. After the code that you inserted in the prior step, replace the
placeholders with the lat/lng coordinates of the contactData and
currentPosition properties of the ContactDetail object.
mapsUrl = mapsUrl.format(
ContactDetail.contactData.lat,
ContactDetail.contactData.lng,
ContactDetail.currentPosition.lat(),
ContactDetail.currentPosition.lng()
);

32. After the code that you inserted in the prior step, launch the url by
setting the location.href property as illustrated below:
location.href = mapsUrl;

33. Save the file.


34. Click on the Test tab.
35. Click on Push Files.
36. Launch Intel App Preview on your device and test the app.
End of Walkthrough --

7 - 15
2013 Intel Corporation.

Fast Track to Intel XDK New

Listening to the Accelerometer


You can access a device's accelerometer through either JavaScript's
DeviceMotion API or, alternatively, via Cordova's Accelerometer support.
The DeviceMotion API enables you to listen for changes in the device's
orientation as well as changes in movement.
Browsers that currently support the DeviceMotion API include:

iOS Safari 4.2.1 (and above)

Android 4.0.3 (default browser)

Firefox for Android

Opera Mobile (Android)

FirefoxOS Devices

BlackBerry PlayBook 2.0

Detecting Changes to Device Orientation


Before using the DeviceOrientation API, verify that the
DeviceOrientationEvent is supported by your browser as illustrated in the
following snippet:
if

(window.DeviceOrientationEvent) {
// insert coolness here

} else {
alert("Aw, Snap! Can't determine device orientation");
}

You can subsequently add an event listener that is triggered whenever the
user's device changes orientation along different axes. In the following
example, the event handler simply outputs the orientation of the device to
the debugging console.
window.addEventListener('deviceorientation', function(e) {
var out = "alpha: {0}, beta: {1}, gamma: {2}";
console.log(out.format(
e.alpha,
e.beta,
e.gamma
));
});

Note the following:

alpha is the direction that the device is facing.

beta is the angle that the device is tilted from front-to-back.

gamma is the angle that the device is tilted left-to-right.

7 - 16
2013 Intel Corporation.

Using Device Features

Detecting Changes in Device Motion


Listen to the DeviceMotionEvent to poll for the rotation and acceleration
of the device.
Since support for this API varies, you should always verify that the event is
available by including the following code snippet:
if (window.DeviceMotionEvent) {
// bring the awesome here
} else {
alert("Aw, Snap! No shake gesture for you!");
}

Attach your event handler to the devicemotion event as illustrated below:


window.addEventListener('devicemotion', function(e) {
// get refresh interval:
// e.interval
//
//
//
//

acceleration info:
e.acceleration.x
e.acceleration.y
e.acceleration.z

//
//
//
//

acceleration info including gravity:


e.accelerationIncludingGravity.x
e.accelerationIncludingGravity.y
e.accelerationIncludingGravity.z

//
//
//
//

rotation rate
e.rotationRate.alpha
e.rotationRate.beta
e.rotationRate.gamma

}, false);

Using the Shake.js Library


The Shake.js library, developed by Alex Gibson (http://alxgbsn.co.uk/) and
available under an MIT license, gives you a high-level event that's fired
when the user shakes their device. You can set up the event listener by
simply loading his shake.js script and then listen for a shake event as
illustrated by the following snippet:
window.addEventListener('shake', shakeEventDidOccur, false);

7 - 17
2013 Intel Corporation.

Fast Track to Intel XDK New

Walkthrough 7-3: Listening for a Shake


In this walkthrough you will use the shake.js library to capture a shake
gesture and display information about a randomly selected friend.

Load the shake.js library

Review the devicemotion api

Configure an event listener

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk7_3/walk7_3.xdk

5. Open index.html in Code View.


6. Review the getRandomFriend() and handleAppShake() methods of
the App object.
Listen for a Shake Gesture

7. Where indicated by the comment, insert a <script> tag to load the


js/shake/shake.js file.
8. Open the js/shake/shake.js file and review its contents. Note that it uses
the DeviceMotion API.
9. Return to index.html in Code mode.
10. Inside the App.init() method, where indicated by the comment, listen
for a shake event. When triggered, invoke the App.handleshake()
method.
window.addEventListener(
'shake',
App.handleAppShake,
false
);

11. Save the file.

7 - 18
2013 Intel Corporation.

Using Device Features


Test Your Work

12. Test the app using Intel App Preview.


Note: this feature cannot be tested on the emulator at the current time
13. Run the app and shake your phone (be careful not to drop it!). Note
that shaking the phone selects a random friend and displays his/her
detail information.
End of Walkthrough --

7 - 19
2013 Intel Corporation.

Fast Track to Intel XDK New

Listening for Push Notifications


Push notifications transfer messages through a constantly open IP
connection to mobile devices. Notifications may include badges, sounds or
custom text alerts. They can play a vital role in increasing user
engagement.
Each mobile operating system vendor has a gateway from which
notifications are transmitted. You can build your own front-end to these
gateways or use a 3rd party push notification vendor. Typically these
vendors offer GUI and web-service based API's that enable you to target
specific groups of users based on metadata collected by your apps, their
current geographic position, username, and more.

Figure 6: Sending messages to devices from PushMobi

Vendors include, but are not limited to:

AppMobi Cloud Services (PushMobi)

Urban Airship

PushWoosh

Mixpanel

This course details how to receive push notifications from the PushMobi
service to Android devices.

7 - 20
2013 Intel Corporation.

Using Device Features

Registering your App to Receive Notifications


The first step to enabling push notifications is to enable push notification
support for each mobile platform via the BUILD tab in the Intel XDK.
Clicking on the PUSH tab, as illustrated by Figure 7, presents you with an
OS-specific form. Before you can proceed, you'll need to register your app
with the Google Cloud Messaging Service.

Figure 7: Configuring Push notification services for Android

7 - 21
2013 Intel Corporation.

Fast Track to Intel XDK New

Registering with the Google Cloud Messaging Service


In order to enable GCM for your app, you'll need to register your project in
the Google Cloud Console at http://cloud.google.com.

Figure 8: Enabling Google Cloud Messaging

After registering your project, you'll need to click on the APIs & Auth tab
and enable Google Cloud Messaging for Android as illustrated in Figure 8.

Registering the PushMobi App as the Client


Rather counter-intuitively, what you need to register in the next step of the
process is not your android app, but actually a web application since it's
actually the PushMobi service that will be communicating with the GCM
to send messages and PushMobi is a web-based application.

Figure 9: Registering the PushMobi front-end for Friends with Beer

7 - 22
2013 Intel Corporation.

Using Device Features

Getting the Necessary Credentials


In order to configure PushMobi to be able to communicate properly with
GCM, you'll need to retrieve two identifiers from the Google Cloud
Console:

The Web Application's Browser Key

The Project's Identifier

You can retrieve the first item by opening the Browser Key section of your
APIs Web Application detail page as illustrated by Figure 10.

Figure 10: Getting the Browser Key

Once you've copied the browser key to your clipboard, you must paste it
into the Api Key (5d) field in the Intel XDK Build > Push screen as
illustrated in figure 7.

7 - 23
2013 Intel Corporation.

Fast Track to Intel XDK New

The second piece of information the project's identifier, you can get by
clicking on your project's Overview tab as illustrated by figure 11. You'll
need to copy the Project Number and paste it into the Project Id (5C) field
as illustrated in Figure 7.

Figure 11: Getting the Project's ID

Using the intel.xdk.notification API


After you've configured the PushMobi service to communicate with the
Google Cloud Messenger gateway, you can add code to your app to listen
for push notifications and handle them when the occur.
The PushMobi client-side API registers a user (or device) with the push
service and listens for incoming messages. The code is largely boilerplate
and can be easily copied into an app.
Essentially, the process is broken into three steps:
1. Check to see if the user/device is registered with the service
2. Register the user/device if necessary
3. Listen for notifications and handle them when they occur.

Checking Device and User Registration


Invoke the intel.xdk.notification.checkPushUser() method to
determine if a user account has been registered with the PushMobi service.
The general syntax is:
intel.xdk.notification.checkPushUser(
username,
password
);

Note that if your app does not require authentication, you can simply
substitute the device's unique identifer (UUID) for both the username and
password as illustrated below:
intel.xdk.notification.checkPushUser(
intel.xdk.device.uuid,
intel.xdk.device.uuid
);

7 - 24
2013 Intel Corporation.

Using Device Features

When the checkPushUser() method has completed, it will fire an event


named intel.xdk.notification.push.enable and pass in an event
object where you can inspect the result and register the user, if necessary:
var notifications = {
didAdd : false,
register: function(event) {
if(event.success === false) {
if (notifications.didAdd === false) {
notifications.didAdd = true;
intel.xdk.notification.alert(
"Doing addPushUser now...",
"My Message",
"OK"
);
//Try adding the user now - sending unique user id,
//password, and email address.
intel.xdk.notification.addPushUser(
intel.xdk.device.uuid,
intel.xdk.device.uuid,
'no@email.com'
);
//This will fire the push.enable event again,
//so that is why we use didAdd to make sure
//we dont add the user twice if this fails for any reason.
return;
}
intel.xdk.notification.alert(
"Notifications Failed: " + event.message,
"My Message",
"OK"
);
return;
}
var msg = event.message || 'success';
intel.xdk.notification.alert(
"Notifications Enabled: " + msg,
"My Message",
"OK"
);
}
// register event listener
document.addEventListener(
"intel.xdk.notification.push.enable",
notifications.register,
false
);

7 - 25
2013 Intel Corporation.

Fast Track to Intel XDK New

Listening for Notifications


After the user's account has been registered, the receiving of push
notifications will trigger the
intel.xdk.notification.push.receive event. You can code this
handler any way that you wish, although typically you'll use the following
methods to read, parse, and delete messages:

intel.xdk.notification.getNotificationList()
Returns an array of strings that correspond to the identifiers for
received messages.

intel.xdk.notification.getNotificationData(notification id)
Returns an object containing the properties of the specified notification
Object property names include: msg and data.

intel.xdk.notification.deletePushNotifications(notification id)
Deletes the specified notification

A typical notification handler resembles the following snippet:


var notifications = {
receivedPush: function() {
var N = intel.xdk.notification;
var myNotifications=N.getNotificationList();
// It may contain more than one message, so loop!
var len=myNotifications.length;
if(len > 0) {
for(i=0; i < len; i++) {
//Get message id
msgObj=N.getNotificationData(myNotifications[i]);
if(typeof msgObj == "object" &&
msgObj.id == myNotifications[i]){
// Display the message now.
// You can do this however you like // it doesn't have to be an alert.
N.alert(msgObj.msg + "\n" + msgObj.data + "\n" +
msgObj.userkey, "pushMobi Message","OK");
// Always mark the messages as read and delete them.
// If you dont, your users will see them repeated
N.deletePushNotifications(msgObj.id);
return;
}
} // for
} // if()
} // function
} // class
// listen for event
document.addEventListener(
"intel.xdk.notification.push.receive",
notifications.receivedPush,
false);
7 - 26
2013 Intel Corporation.

Using Device Features

Testing in the Emulator


You can verify your event handlers and view the result of your push
notification handling by running your app in the Emulator as depicted in
Figure 12. Typing a message into the PUSHMOBI SERVICE panel
simulates the firing of an intel.xdk.notification.push.receive
event.

Figure 12: Sending a test message in the emulator.

7 - 27
2013 Intel Corporation.

Fast Track to Intel XDK New

Testing on a Device
Test your app on a physical device by going through the application build
process, install the app on your device, and then access the PushMobi
service under the XDK Services tab as illustrated in figure 13.

Figure 13: Sending a message via PushMobi

Devices that have properly registered themselves with the PushMobi


service should appear under the User Management tab. Note that the
PushMobi console allows you to target individual users by name, device
platform, or custom filter.

7 - 28
2013 Intel Corporation.

Using Device Features

Walkthrough 7-4: Handling Push Notifications


During this walkthrough you will configure
PushMobi to send messages through the Google
Cloud Messaging Service. You will then add code
to your application to register the device and
handle push notifications. You'll test your work in
the Emulator and on a physical device.

Register a Push Notification App with Google

Configure PushMobi to communicate with


GCM

Listen for push messages to your app

Steps
Figure 14: Handling
Push Notifications

Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk7_4/walk7_4.xdk

Configure the Server Push Service

5. Click on the Build Tab


6. Click on Build > Android
7. Click Upload Code
8. Click on the Push tab
9. Click on the radio button labeled Configure this app for push
messaging
10. Click OK.
Configure Google Cloud Messaging (GCM)

11. Open a web browser to the following URL:


http://cloud.google.com/console

12. Click the Create Project button.


13. Enter the following information:

Project Name: Friends with Beer

7 - 29
2013 Intel Corporation.

Fast Track to Intel XDK New

14. Click the Create button.


Proceed through the SMS verification process

15. Click on API's & Auth


16. Turn the Google Cloud Messaging for Android to ON.
17. Click on Registered apps
18. Click on the Register App button and enter the following information:

Name: Friends with Beer


Platform: Web Application

19. Click the Register button.


20. Click on Browser Key
21. Copy the API Key to your clipboard
22. Paste the API Key into the Intel XDK API Key field (5d)
23. Click on Projects
24. Click on Friends with Beer
25. Copy the Project Number to your clipboard
26. Paste the project number into the Intel XDK Project ID field.
27. Click Go to Next Step.
Listen for Push Notification Events

28. Click on the Develop tab.


29. Open index.html in Code mode.
30. Carefully review the Notifications object, its properties, and its
methods that start on line 709.
31. Where indicated by the comment in the onDeviceReady() handler, add
an event listener for the intel.xdk.notification.push.enable event that
invokes the notifications.register event.
var onDeviceReady=function(){
//hide splash screen
intel.xdk.device.hideSplashScreen();
document.addEventListener(
"intel.xdk.notification.push.enable",
notifications.register,
false
);
};

7 - 30
2013 Intel Corporation.

Using Device Features

32. Immediately after the code that you inserted in the prior step, add an
event listener that invokes the notifications.receivedpush method
when an intel.xdk.notification.push.receive event is fired.
var onDeviceReady=function(){
//hide splash screen
intel.xdk.device.hideSplashScreen();
document.addEventListener(
"intel.xdk.notification.push.enable",
notifications.register,
false
);
document.addEventListener(
"intel.xdk.notification.push.receive",
notifications.receivedPush,
false
);
};

33. Immediately after the code that you inserted in the prior step, check to
see if the device is registered with the PushMobi service. Your code
should appear as follows:
var onDeviceReady=function(){
//hide splash screen
intel.xdk.device.hideSplashScreen();
document.addEventListener(
"intel.xdk.notification.push.enable",
notifications.register,
false
);
document.addEventListener(
"intel.xdk.notification.push.receive",
notifications.receivedPush,
false
);
intel.xdk.notification.checkPushUser(
intel.xdk.device.uuid,
intel.xdk.device.uuid
);
};

34. Save the file.


Test the Service in the Emulator

35. Click on the Emulate Tab


36. Send a test message from the PUSHMOBI SERVICE panel.
End of Walkthrough --

7 - 31
2013 Intel Corporation.

Fast Track to Intel XDK New

Unit Summary

You can retrieve a device's current position by using either the Cordova
API or the build-in navigator.geolocation.getCurrentPosition() method.

You can activate the phone dialer and email client by calling special
URI's.

Support for launching the built-in navigation app varies between


platforms and delivery systems

Use the accelerometer to handle changes in orientation to the device.

The devicemotion api enables you to detect changes in how the device
is being handled including shake gestures.

Implement push notifications to enhance user engagement.

You can create your own push notification messaging front-end or


choose from a variety of third-party services.

Intel XDK New directly supports the PushMobi front-end for sending
push notifications.

You will need to configure PushMobi for each of the platforms that
you intend to support (iOS, Android, Windows Mobile)

7 - 32
2013 Intel Corporation.

Using Device Features

Unit Review
1. You must use the Cordova API to access the device's accelerometer
(true/false)?

2. Describe the process for activating the device's phone dialer and
default email application.

3. Which method do you call to get the device's current position?

4. Why should you always include an error callback function when


attempting to get the device's current position?

5. Intel XDK apps can only receive push notifications from the PushMobi
service (true/false)

7 - 33
2013 Intel Corporation.

(This page intentionally left blank)

Unit 8:
Integrating Multimedia

Unit Objectives
After completing this unit, you should be able to:

Add audio to your applications

Integrate video from different sources into your app

Use JavaScript to implement custom player controls for your media

Playing Audio and Video

Unit Topics

8-1
2013 Intel Corporation.

Fast Track to Intel XDK New

Playing Audio and Video


Intel XDK New has design-time widgets for deploying native HTML5
audio and video players. It also has widgets for embedding YouTube videos
and Vimeo presentations within your app.
The goal of the HTML 5 audio/video specification was to natively support
data formats that are royalty-free, have good data compression while not be
cpu-intensive to decode, and a hardware decoder. It states that browsers
should support Theora video and Vorbis audio, as well as the Ogg container
for a placeholder, since these codecs are not affected by any known patents.
Syntactically, the playback of audio and video is handled through the
<video> , <audio>, and <source> commands.

Adding HTML5 Video


You can insert browser-based video into your web page using the <video>
tag. The following attributes are supported:
Attribute

Description

autoplay

Boolean attribute, causes the user agent to start playing


the media as soon as it is able.

controls

Boolean attribute indicating whether the author has not


provided a custom controller using Javascript and would
like to use the native set of controls.

height

The height of the control, in pixels

width

The width of the control, in pixels

loop

Boolean attribute indicating whether the media should


continue playing from the start of the file once it has
reached its end.

preload

"none" indicates to the browser that that the author


will probably not need the media resource.

"metadata" hints to the browser that the author will


probably not need the media resource but that prefetching the resource metadata (dimensions, first
frame, duration) is worthwhile.

"auto" hints to the browser that the author expects the


video to be played and therefore it should
optimistically cache the resource.

poster

Gives the address of an image file that the user agent can
show while no video data is available. The attribute, if
present, must contain a valid non-empty URL potentially
surrounded by spaces. The image is supposed to be a
representative frame from the video.

8-2
2013 Intel Corporation.

Integrating Multimedia

Attribute

Description

src

The URL of the media asset. May be overridden by the


use of the <source> element.

The following example illustrates a simple invocation of the <video> tag:


<video
width="320"
height="240"
controls="true"
src="video1.ogg"
preload="auto"
poster="titleframe.jpg">
Get a real browser, yo.
</video>

Reviewing supported file formats


Support for video formats varies, with most vendors supporting either the
WebM or MP4 formats. Ironically, support for Ogg as stipulated in the
HTML5 specification, is only included in the mobile Opera and Firefox
browsers.

Browser

WebM

MP4

Android

Yes

Partial

iOS

No

Yes

Blackberry

No

Yes

IE Mobile

No

Yes

Opera Mobile

No

Yes

Chrome Android

Yes

Yes

Firefox Android

Yes

Partial

In order to support all mobile browsers, you'll therefore need to support


both WebM and MP4 formats by using the <source> element as illustrated
below:
<video

width="320"
height="240"
controls="true">

<source src="video1.webm" type="video/webm" />


<source src="video1.mp4" type="video/mp4" />
</video>
8-3
2013 Intel Corporation.

Fast Track to Intel XDK New

Inserting Video with Intel XDK New


As illustrated in Figure 1, Intel
XDK New has a Video widget
that enables you to drag and drop
a video into your app.
Supported config properties
include:

Webm Source File

Mp4 Source File

Autoplay

Controls

Loop

Preload

Video Caption

Figure 1: Intel XDK New Video Widget


Settings

Building your own controls


The HTML5 media element supports the following properties and methods
from which you could build a custom playback controls:
Read Only
Property

Description

paused

Returns true if the playback is paused

ended

Returns true if playback has ended

readyState

Describes whether the video is ready to be


played and/or enough of the video has been
preloaded for it to play without intermediate
pauses.

played

Returns a TimeRanges object representing the


range of the media that has been played

seeking

Returns true if the user agent is currently seeking

duration

Returns the length of the media resource, in


seconds

startTime

Returns the earliest possible position, in seconds.


Note that this might not be zero-based if the
resource is being streamed in real-time.

seekable

Returns a TimeRanges object that represents the


ranges of the media resource to which it is
possible for the user agent to seek.

8-4
2013 Intel Corporation.

Integrating Multimedia

Read/Write
Property

Description

playbackRate

Returns the current playback rate

defaultPlaybackRate

Returns the default playback rate, where 1.0 is


normal speed.

volume

Retuns the current playback volume, in a range


of 0.0 to 1.0 where 0.0 is the quietest and 1.0 is
the loudest.

currentTime

Returns the current playback position, in


seconds. Can be set to seek to a specific time.

muted

Returns true if the audio is muted, false if not.

Method

Description

load()

Causes the element to reset and start selecting


and loading a new media resource from scratch.

pause()

Sets the paused attribute to true, loads the media


resource if necessary.

play()

Sets the paused attribute to false, loads the media


resource, and starts playback.

canPlayType(type)

Returns the empty string (a negative response),


"maybe", or "probably" if the user agent
determines that it can play media resources of
the given type.

The following Media events are also available:

ondurationchange

onplaying

onemptied

onseeked

onerror

onseeking

onloadedmetadata

onstalled

onloadstart

onsuspend

onpause

ontimeupdate

onplay

onvolumechange

onwaiting

8-5
2013 Intel Corporation.

Fast Track to Intel XDK New

Using these properties and methods, you could create your own
playback/pause button as illustrated by the following snippet:
<head>
<script language="javascript">
enablebuttons = function() {
document.getElementById('playbutton').disabled =
false;
}
playpause = function() {
var objMedia = document.getElementById('mymedia');
var objButton = document.getElementById('playbutton');
if (objMedia.paused) {
objMedia.play();
objButton.value="Pause";
} else {
objMedia.pause();
objButton.value="Play";
}
}
</script>
</head>
<body>
<video
width="320"
height="240"
controls="false"
onCanPlayThrough="enableButtons()"
id="mymedia">
<source src="video1.webm" type="video/webm" />
<source src="video1.mp4" type="video/mp4" />
</video>
<input type="button"
value="Play"
onClick="playpause()"
id="playbutton">
...
</body>

8-6
2013 Intel Corporation.

Integrating Multimedia

Playing Videos from YouTube


You can play YouTube videos from your app by inserting a video's embed
code into your app. The embed code uses an <iframe> and, as illustrated in
Figure 2, the url is located within the Share-Embed block underneath each
video.

Figure 2: Retrieving a YouTube video embed url

8-7
2013 Intel Corporation.

Fast Track to Intel XDK New

Intel XDK New includes a design-time video widget that will insert the
<iframe> code for you you simply need to enter the embed URL into the
YouTube Settings panel as illustrated in figure 3.

Figure 3: Configuring a YouTube video

Embedding Content from Vimeo


Vimeo is a video-sharing website similar in nature to YouTube. Unlike
YouTube, however, it does not play advertisements before, during, or after
your videos. Vimeo has a significant following among the creative and
business communities and is directly supported by Intel XDK New.
You can embed Vimeo videos into your app by using the same <iframe>
technique that had been previously described for embedding YouTube
videos. As illustrated in Figure 4, you can copy the URL to your clipboard
by clicking on a video's Share button and then paste it into the XDK New
Vimeo widget Settings panel.

Figure 4: Getting an embed URL from Vimeo

8-8
2013 Intel Corporation.

Integrating Multimedia

Working with Audio


The <audio> tag functions similarly to the <video> tag in that it enables
you to play a media file without requiring the use of a browser plug-in and
is typically used in mobile apps to play songs and podcasts.
Audio support in mobile browsers remains problematic for use in games.
Timing issues, lags, lack of pre-loading, inability to play multiple clips
simultaneously, and general bugginess make it unsuitable for playing short
sound-effect clips with precision timing. In the near future, the recently
introduced HTML5 Audio API may provide some relief for html5 mobile
game developers.
Supported attributes of the <audio> element include the following:
Attribute

Description

autoplay

Boolean attribute, causes the user agent to start playing


the media as soon as it is able.

controls

Boolean attribute indicating whether the author has not


provided a custom controller using Javascript and would
like to use the native set of controls.
Note that Android devices do not have native audio
controls.

loop

Boolean attribute indicating whether the media should


continue playing from the start of the file once it has
reached its end.

preload

"none" indicates to the browser that that the author


will probably not need the media resource.

"metadata" hints to the browser that the author will


probably not need the media resource but that prefetching the resource metadata (dimensions, first
frame, duration) is worthwhile.

"auto" hints to the browser that the author expects the


video to be played and therefore it should
optimistically cache the resource.

Note: preload is not supported on most mobile browsers.


src

The URL of the media asset. Use the <source> element


to specify alternative file formats for broader user agent
compatibility.

As illustrated below, you should include both mp3 and Ogg Vorbis files in
order to support the broadest range of devices.
<audio
controls="false"
onCanPlayThrough="enableButtons()"
id="mymedia">
<source src="audiofile.mp3" type="audio/mpeg" />
<source src="audiofile.ogg" type="audio/ogg" />
</audio>
8-9
2013 Intel Corporation.

Fast Track to Intel XDK New

Using <audio> Properties


The <audio> element exposes a number of runtime properties that help you
determine the clip's current state:
Property

Description

currentTime

Number. The playhead position, expressed as seconds

duration

Number. Playback time for the clip, in seconds.

muted

Boolean. Returns true if volume is muted

paused

Boolean. Returns true if media is paused.

volume

Float. Volume level, between 0 and 1.

Listening for <audio> Events


You can listen on the following events which are thrown by an Audio
object.

Event
canplay

Description
The media can be played, but may need to pause while
downloading.

canplaythroug Indicates that the media can be played through without


h
pausing.
progress

Fires to indicate progress at downloading the media file.


Typically fires every 250 ms but can be unreliable on
mobile devices. For better granularity, call a method
using window.setInterval()

ended

The end of the media was reached and playback was


stopped.

play

The media has started playing.

volumechange The volume level has been adjusted.

8 - 10
2013 Intel Corporation.

Integrating Multimedia

Futures: Using the HTML5 Audio API


As previously discussed, manipulation of audio in Javascript is quite
limited. A new HTML5 Audio API is under development, however, support
remains limited to the following browsers:

iOS Safari 6.0+

Firefox 25 for Android

Chrome 31 for Android

Most desktop browsers


(excluding Microsoft Internet
Explorer)

Features of the HTML5 Audio API include:

An AudioContext class for

managing and playing all sounds.

Support for playing multiple


sound sources simultaneously.

Loading sounds via the


XMLHTTPRequest object with
audio decoding methods.

Scheduling precise sound


playback for games.

Cross-fading between sounds

Applying filter effects.

The following code snippet illustrates how you could use the HTML5
Audio API to load a sound file.
var musicBuffer = null;
// Fix up prefixing
window.AudioContext = window.AudioContext ||
window.webkitAudioContext;
var context = new AudioContext();
function loadSound(url) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.responseType = 'arraybuffer';
// Decode asynchronously
request.onload = function() {
context.decodeAudioData(
request.response,
function(buffer) {
musicBuffer = buffer;
},
function (err) {
alert("Could not decode audio file");
}
);
}
request.send();
}
loadSound('100BottlesOfBeerOntheWall.mp3');

Note: See http://www.html5rocks.com/en/tutorials/webaudio/intro/ for a


detailed introduction to the html5 Web Audio API.
8 - 11
2013 Intel Corporation.

Fast Track to Intel XDK New

Walkthrough 8-1: Playing Videos


In this walkthrough you will add streaming video playback from Vimeo to
your application as well as use the native html5 <video> element

Integrate video from Vimeo

Use the HTML5 <video> element to play an MP4 file.

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk8_1/walk8_1.xdk

Integrate Video from Vimeo

5. Open drink.html in Design mode.


6. From the Controls > Media panel, drag a Vimeo widget and drop it
onto the center of the Design Canvas.
7. Configure the following Vimeo Settings:

Src:
Autoplay:
Loop:

//player.vimeo.com/video/9608723
checked
checked

8. Click on the TEST tab.


9. Click the Push Files button
10. Test your application on a device using Intel App Preview. You should
be able to play the Vimeo video by tapping on the Drink! tab of the
app.
Integrate WebM/MP4 Video

11. Return to the drink.html file in Intel XDK New's Design mode.
12. Right-click/Cmd-click on the Vimeo video and select Delete.
13. Right-click/Cmd-click on the Column object and select Delete.
14. From the Controls > Media panel, drag a Video widget and drop it onto
the center of the Design Canvas.

8 - 12
2013 Intel Corporation.

Integrating Multimedia

15. Enter the following Video Settings:

Webm Src:
Mp4 Src:
Autoplay:
Controls:
Loop:

//xdktraining.com/ftxdknew/friends.webm
//xdktraining.com/ftxdknew/friends.mp4
true
true
true

16. Save the file.


17. Click on the TEST tab.
18. Click the Push Files button
19. Test your application on a device using Intel App Preview. You should
be able to play the Vimeo video by tapping on the Drink! tab of the
app.
End of Walkthrough --

8 - 13
2013 Intel Corporation.

Fast Track to Intel XDK New

Unit Summary

You can play audio and video without the user of a plug-in

The HTML5 <audio> and <video> elements have API methods that
you can use to design custom player controls.

You should support both WebM and MP4 video formats to ensure the
highest degree of compatibility.

Intel XDK New has design-time widgets for HTML5 video as well as
playing assets hosted on YouTube.com and Vimeo.com

The <audio> element is not well-suited for playing sound effects in


games.

The HTML5 Audio API contains a very robust set of methods for
handling audio, however, it is not currently supported by the native
Android browser.

8 - 14
2013 Intel Corporation.

Integrating Multimedia

Unit Review
1. What is the purpose of the <video> element's poster property?

2. What video file formats are natively supported by iOS and Android?

3. You cannot programmatically determine where the playhead is at


while a video or audio clip is playing (true/false).

4. The Android browser will automatically output playback controls for


<audio> instances (true/false).

8 - 15
2013 Intel Corporation.

(This page intentionally left blank)

Unit 9:
Theming

Unit Objectives
After completing this unit, you should be able to:

Understand how to work with vendor prefixes

Add web fonts to your application

Enhance your app's typography

Apply background gradients and images

Use ThemeRoller to visually prototype a application widgets

Working with CSS3 on Mobile Devices


Enhancing Fonts and Typography
Enhancing Backgrounds
Working with ThemeRoller

Unit Topics

9-1
2013 Intel Corporation.

Fast Track to Intel XDK New

Working with CSS3 on Mobile Devices


Generally speaking, most advanced features of CSS3 are well-supported by
mobile browsers. CSS3 adds support for many important functions that are
critical for simulating native app behavior and minimizing the use of
hacks that were typically graphics intensive and led to slower download
times and increased memory requirements. Key features include:

Rounded borders

Transparency

Downloadable Fonts

Better text overflow handling

Enhanced Typography

Shadowing

Background sizing and


positioning

CSS-based Keyframe Animation

Handling Vendor Prefixes


Vendor prefixes in CSS generally denote a CSS property that is unique to a
specific browser or may not have been officially ratified by the W3C.
Typical vendor prefixes that you'll encounter in mobile development
include:
Prefix

Description

-webkit-

Webkit browsers (typically iOS and Android)

-moz-

Mobile Firefox

-o-

Mobile Opera

-ms-

Mobile IE

As illustrated by the following snippet, these vendor prefixes can make


supporting CSS files somewhat laborious as the same declaration must be
repeated multiple times in order to achieve full cross-platform
compatibility:
.box_gradient {
background-color:
background-image:
background-image:
background-image:
background-image:
}

#c0c0c0; // fallback
linear-gradient(#ffffff,#c0c0c0);
-webkit-linear-gradient(#ffffff,#c0c0c0);
-moz-linear-gradient(#ffffff,#c0c0c0);
-o-linear-gradient(#ffffff,#c0c0c0);

Consequently, most app developers typically use a 3rd party tool to handle
vendor prefixes and make CSS authoring a bit less redundant. Two of those
products are Sass and LESS.
9-2
2013 Intel Corporation.

Theming

About Sass
Sass (Syntactically Awesome Stylesheets) is an extension of CSS that a
allows you to use variables, nested rules, inline imports, with a fully CSScompatible syntax. Sass helps keep large stylesheets well-organized, and
get small stylesheets up and running quickly, particularly with the help of
the Compass style library.

Sass is essentially a stylesheet compiler. You author .scss files (Sassy CSS)
which are then converted into production-ready CSS files by a commandline utility.
Vendor prefixes in Sass are handled through a mechanism called mixins
which are analogous to javascript functions. However, whereas a
JavaScript function typically returns result data based on a set of
parameters, a Sass mixin generates css styles based on passed-in data.
For instance, the following declaration in Sass:
.myCustomClass {
@include border-radius(5px);
}

Generates this CSS output:


.myCustomClass{
-webkit-border-radius:5px;
-moz-border-radius:5px;
-ms-border-radius:5px;
-o-border-radius:5px;
border-radius:5px
}

More information about Sass is available from www.sass-lang.com.

9-3
2013 Intel Corporation.

Fast Track to Intel XDK New

About LESS
LESS is similar to Sass it's a dynamic stylesheet language that's designed
to make CSS authoring more robust and easier to maintain. Less is
actually used behind-the-scenes by Intel XDK New to manage app styles.

LESS also supports the concept of mixins as illustrated by the following


snippet:
.rounded-corners (@radius: 5px) {
-webkit-border-radius: @radius;
-moz-border-radius: @radius;
-ms-border-radius: @radius;
-o-border-radius: @radius;
border-radius: @radius;
}
#header {
.rounded-corners;
}
#footer {
.rounded-corners(10px);
}

Generated CSS code:


#header {
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
}
#footer {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
-ms-border-radius: 10px;
-o-border-radius: 10px;
border-radius: 10px;
}

You can find out more about LESS at http://lesscss.org

9-4
2013 Intel Corporation.

Theming

Enhancing Fonts and Typography


Intel iOS webkit browsers supports a large number of fonts, however, very
few of these are also supported by Android's native browser. To ensure that
your applications uses the same font across a wide variety of devices you
should leverage CSS3's support for downloadable fonts.
Google Web Fonts contains over 600 free, open-source fonts that have
been optimized for the web. Adobe Edge Web Fonts contains another 502
fonts. The most difficult part of implementing web fonts is making a
decision about which fonts to use in your apps!

Downloading a Font
CSS3 capable browsers can download fonts and use them to format your
text. Use the @font-face selector to define a font name and associated
download url. You can then reference the font in subsequent style
definitions as indicated below:
@font-face {
font-family: 'Droid Sans';
src: url(fonts/Droid_Sans.ttf);
}
h1{
font-family: 'Droid Sans';
}

Customizing Text Stroke and Fill Color


CSS3 supports the following font-related attributes:
Property

Description

text-fill-color

Sets the fill color of the text.

text-stroke-color

The outline color of the text.

text-stroke-width

The thickness of the stroke line.

The following snippet illustrates how to use these properties:


<style>
h1 {
text-fill-color: green;
text-stroke-color: orange;
text-stroke-width: 2px;
font-family: arial;
font-size: 40px;
}
</style>
<h1>This is a test</h1>
9-5
2013 Intel Corporation.

Fast Track to Intel XDK New

Adding Text Shadows


The CSS3 text-shadow property enables you to cast a shadow behind your
text as indicated below:
<style>
p {
font-family:arial;
font-size: 30px;
text-shadow:2px 2px 5px #000;
}
</style>
<p>This is a demonstration of text shadows</p>

As illustrated below, text-shadow takes


four arguments:
1. Right shadow offset
2. Vertical (down) shadow offset
3. Blur radius
4. Shadow color

You can visually prototype text-shadow and box-shadow effects by visiting


http://css3gen.com/text-shadow/ as illustrated in Figure 5.

9-6
2013 Intel Corporation.

Theming

Applying Transparency
CSS 3 allows you to
declare colors as Red,
Green, Blue, and Alpha
transparency. Alpha
transparency is
specified as a numeric value between zero (fully transparent) and one
(opaque). Note that you should also specify a fallback color to use for
browsers that do not support RGBA
<style>
p {
font-family:arial;
font-size: 30px;
color: rgba(255,255,255,0.4);
text-align: center;
padding-top: 30px;
}
#appetizer {
background:url(../images/appetizer.jpg);
width: 475px;
height: 102px
}
</style>
<div id="appetizer"><p>This is a watermark</p></div>

Creating an Inset-Text Effect


Combine color, text-shadow, and rgba transparency to create an insetteffect as illustrated by the following snippet:
h1 {
color: #3a1515 !important;
text-shadow: 0px 1px rgba(255, 255, 255, 0.3) !important!;
}

9-7
2013 Intel Corporation.

Fast Track to Intel XDK New

Using Ellipsis for Text Overflow


CSS 3 enables you to automatically terminate text with ellipsis if the
content is too large to fit within its parent container.
<style>
#test {
width: 100px;
height: 40px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
</style>
<div id="test">
Lorum Ipsum and more pseudo-latin ridiculousness
</div>

Implementing Newspaper-Style Columns


With CSS3 it is now relatively straightforward to implement multiple
columns of wrapped text using the column-count and column-gap
properties. This technique can be particularly useful when developing apps
for tablets.
<style>
#myarticle{
column-count: 2;
column-gap: 10px;
/* Column-count not implemented yet */
-moz-column-count: 2;
-webkit-column-count: 2;
/* Column-gap not implemented yet */
-moz-column-gap: 22px;
-webkit-column-gap: 22px;
}
</style>
<div id="myarticle">
<p>Lorem Ipsum...and more latin nonsense</p>
</div>

9-8
2013 Intel Corporation.

Theming

Using Google Fonts


As illustrated in Figure 7, Google Fonts has a filter panel in its left column
that enables you to search for fonts based on font type (serif, sans-serif,
display, and handwriting) as well as thickness, slant, and width.
Studies have shown that, on mobile devices, sans-serif and display fonts
are more readable than serif fonts.

After you select a font, the Google Fonts interface generates the <link>
element and font-family css declarations that you'll use to invoke the font
from within your app. It also displays an estimate impact on page load
time.

9-9
2013 Intel Corporation.

Fast Track to Intel XDK New

Using Adobe Edge Fonts


Adobe Edge Web Fonts gives you access to a vast web font library made
possible by contributions from Adobe, Google, and designers around the
world. The fonts are served by Typekit which is a subscription-based
library of hosted, high-quality fonts that was acquired by Adobe in 2011.

The interface for


selecting fonts from
Adobe Edge is not too
dissimilar from
Google Fonts. One
minor difference is
that while Google
uses a <link> tag to
download your
selected fonts, Adobe
Edge uses a <script>
tag as illustrated by
Figure 9.
Figure 9: Load your selected font by including a
<script> tag generated by Adobe Edge Fonts

9 - 10
2013 Intel Corporation.

Theming

Walkthrough 9-1: Applying Typography


In this walkthrough you will replace the
default font with a Google web Font.

Select a web font from Google Fonts

Set the custom default font for text in


your application

Apply an insert effect to the page


headers

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the
top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk9_1/walk9_1.xdk

Select a Google Font

5. Open a web browser to Google Fonts at:


http://www.google.com/fonts

6. Type the following font name into the text field:


Rambla

7. Click the Quick Use button.


8. In section 1 (Choose the styles you want), select Bold 700
9. Copy the <link> tag from section 3 to your clipboard and note the fontfamily declaration in section 4.
Deploy the Rambla Font

10. Return to Intel XDK New and open index.html in Code view
11. At the top of the file, where indicated by the comment, paste the
<link> tag from your clipboard.

9 - 11
2013 Intel Corporation.

Fast Track to Intel XDK New

12. In the <style> block near the top of the file, add a body and paragraph
tag selector that specifies Rambla as the font-family and bold as the
font-weight.
body, p {
font-family: 'Rambla', sans-serif;
font-weight: bold;
}

13. Save the file and test in the Emulator.


Customize the Page Header Font

14. Return to Code mode in the index.html file.


15. Directly underneath the style that you added in step 12, define a class
named ui-title that increases the font-size for the header text and gives
it an inset effect. Your code should appear similar to the following:
.ui-title {
font-size: 1.5em !important;
color: #000000 !important;
text-shadow: 0px 1px rgba(255, 255, 255, 0.3) !important;
}

16. Save the file and test in the emulator.


End of Walkthrough --

9 - 12
2013 Intel Corporation.

Theming

Enhancing Backgrounds
You can enhance the backgrounds of images in CSS3 by specifiying
background gradients and background images for html elements. If you
plan to use background images, consider base-64 encoding them into your
spreadsheet for improved performance.

Applying a Background Gradient


CSS3 gradients enable you to display smooth transitions between two or
more specified colors. Using gradients offer several advantages over
background images:

Gradients reduce download times and bandwidth usage.

Gradients automatically adjust to running in different screen


resolutions.

Gradients retain their integrity zooms in or out of an area.

As illustrated by the following snippet, gradient definitions are typically


applied through the background-image css property and require the use of
vendor-prefixes. The simplest syntax simply deals with direction of the
transformation (linear, top-bottom), with a color that's specified for the stop
at 0% (the top of the affected area) and a color that's the stop at 100% (the
bottom of the affected area).
body {
background-image:
background-image:
background-image:
background-image:
}

-webkit-linear-gradient(gold, goldenrod);
-moz-linear-gradient(gold, goldenrod);
-ms-linear-gradient(gold, goldenrod);
-o-linear-gradient(gold, goldenrod);

An example of a gradient that transitions from red to white to blue using


color stops is illustrated below:

<style>
body {
background-image: -webkit-gradient(
linear, left top, left bottom,
color-stop(0%,#ffffff),
color-stop(50%,#f20e0e),
color-stop(100%,#3e21ff)
);
// other vendor prefixes omitted for brevity
}
</style>
9 - 13
2013 Intel Corporation.

Fast Track to Intel XDK New

Most designers choose to create gradients visually, and many use the
Ultimate CSS Gradient generator depicted in Figure 10.

Applying a Background Image


CSS3 enables you to scale and position a background image two
attributes that are critical for supporting an application that needs to
responds properly to varying screen resolutions.
The basic CSS syntax for specifying a background image is the following:
body {
background: #000000; // black background color
background-image:url('images/beercan.png');
background-repeat: no-repeat;
}

Alternately, you can set all background properties in a single statement:


body {
background:#000000 url('images/beercan.png') no-repeat;
}

9 - 14
2013 Intel Corporation.

Theming

Specifying a background size


Use the background-size property to scale an image to either a
specified pixel size or a percentage of the content area.
You can also specify background-size: cover; which scales the
background image to completely cover the background area, while
mantaining the background image's aspect ratio. Using this option may
result in some parts of the background image being hidden.
Specifying background-size: contain; scales the image such that
both the width and the height of the image fit within the content area.
However, this may result in the background not being fully covered by the
image.
// scale the background image to cover the body
body
{
background:url(beercan.gif);
background-size: cover;
background-repeat:no-repeat;
}

Specifying background-position
Use the background-position property to set the starting position of a
background image.
Valid settings include the following:

Value

Description

left top
left center
left bottom
right top
right center
right bottom
center top
center center
center bottom

Positions the background image to a relative location


within its container.

x% y%

Positions the background image to a location specified


as a percentage value along the x/y axis. The right
bottom corner is 100% 100%.

xy

Position the background at an absolute location,


typically specified in pixels.
9 - 15
2013 Intel Corporation.

Fast Track to Intel XDK New

Base-64 Encoding a Background Image


Base-64 encoding enables you to take a binary image file and encode it as a
text string that can be included as part of a stylesheet. Encoding images
directly into a stylesheet gives you better startup performance since it
eliminates the need for the browser to make separate http requests for each
image. A drawback, however, is that the process usually increases the
image's data size by approximately 30%.
Websites like www.base64-image.de provide free services for converting
images to base-64.

Figure 11: Use www.base64-image.de to encode your images.

Images encoded into a stylesheet typically appear as follows (note that the
image data has been truncated for brevity):
.body {
background-image: url('data:image/png;base64,iVBORw==');
background-size: cover;
background-repeat: no-repeat;
}

9 - 16
2013 Intel Corporation.

Theming

Combining Multiple Background Images


CSS3 enables you to specify multiple background images that are stacked
on top of each other as transparency layers.
The following examples illustrate the effect of combining a background
images with a radial gradient to produce a glossy-wood effect:

.ui-header-fixed {
background-image: url('resources/headerbackground.png')
}

.ui-header-fixed {
background-image: -webkit-linear-gradient(#9f5628,#5d2f17);
}

.ui-header-fixed {
background-image: url('resources/headerbackground.png'),
-webkit-linear-gradient(#9f5628, #5d2f17) !important;
}

Specifying Background Images


To specify a background image for all pages in your app, attach a
background-image property to the .ui-page class as illustrated below:
.ui-page {
background-image: url('resources/background.png') !
important;
background-size: cover !important;
background-repeat:no-repeat !important;
}

To specify a background image for page headers, attach a backgroundimage property to the .ui-header-fixed class as illustrated in the previous
section.

9 - 17
2013 Intel Corporation.

Fast Track to Intel XDK New

Walkthrough 9-2: Applying Backgrounds


In this walkthrough you will theme the
header, footer, and body of the app by
applying CSS3 techniques.

Apply a base-64 encoded background


image to the body of the pages.

Apply a background gradient and image


to the header and footer.

Tweak the style of the control bar


buttons.

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the
top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:

Figure 12: Apply backgrounds


to the header, body, and footer.

/ftIntelXdkNew/walk/walk9_2/walk9_2.xdk

Create a New Stylesheet

5. In the project file listing, right-click on the css folder and select New
File.
6. Rename the new file to custom.css
7. Open the index.html file in code view
8. Where indicated by the comment, insert a <link> element to load the
custom.css file.
Apply a Background to your Pages

9. Open custom.css
10. Define a style class named .ui-page that sets the following properties:

background-image: url('../resources/background.png');
background-size: cover;

11. Save the file and test in the emulator. You should see that there's now
beer in the background in each page of your app.

9 - 18
2013 Intel Corporation.

Theming
Base-64 Encode an Image

12. Open a web browser to the following url:


www.base64-image.de

13. Click the Upload Image button.


14. Upload the following file:
/ftxdknew/walk/walk9-2/resources/background.png

15. Click the encode image button.


16. Copy the background-image property from the CSS Background Image
block onto your clipboard.
17. Return to the custom.css file.
18. Paste the contents of your clipboard into the file, replacing the existing
background-image statement.
19. Save the file and test the app in the emulator. You should see that the
background image still appears in the app.
Theme the Application Header and Footer

20. Return to the custom.css file in your editor.


21. At the beginning of the file, Insert a new class selector named
.ui-header-fixed that has the following property:
background-image:
url('../resources/headerbackground.png'), -webkit-lineargradient( #9f5628, #5d2f17) !important;

22. Add another class selector to the definition that you inserted in the
prior step named .ui-footer-fixed. Your code should appear as follows:
.ui-header-fixed, .ui-footer-fixed {
background-image: url('../resources/headerbackground.png'),
-webkit-linear-gradient( #9f5628, #5d2f17) !important;
}

23. Save the file and test in the emulator. Your header and footer should
now have a glossy-wood background.
Format the Control Bar

24. Return to the custom.css file.


25. At the top of the file insert the following definition to make the button
backgrounds transparent and set the button label style:
.ui-controlgroup-controls .ui-btn {
background: transparent;
color: #000000 !important;
text-shadow: 0px 1px rgba(255, 255, 255, 0.3) !important;
border-color: transparent;
}

26. Save the file and test. Note that the selected button style class remains
inconsistent with the rest of the footer.
9 - 19
2013 Intel Corporation.

Fast Track to Intel XDK New

27. Return to the custom.css file.


28. At the top of the file insert the following definition to make the
selected button style consistent with the rest of the control bar:
.ui-btn.ui-btn-b {
background: transparent !important;
border-color: transparent !important;
color: #DAA520 !important;
text-shadow: 0px 1px rgba(100, 100, 100, 0.3) !
important;
}

29. Save the file and test. Your output should appear similar to figure 9.
Note that the list views in the Friends and Beers list still need to be
themed.
End of Walkthrough --

9 - 20
2013 Intel Corporation.

Theming

Working with ThemeRoller


ThemeRoller for jQuery Mobile is a visual theme designer that enables you
to easily style jQM UI widgets. ThemeRoller also incorporates
complementary color swatches from Adobe Kuler which can assist you in
selecting complementary colors for your app.
A jQuery Mobile theme contains global settings for items such as font and
corner radius as well as up to to 26 "swatches" lettered from A-Z, each
with a unique color scheme that can be mixed and matched in your app.
Each swatch sets the colors, textures and font settings for the primary
elements: toolbar, content block and button. Buttons have 3 interaction
states: normal, hover, pressed.

Getting Started with ThemeRoller


The ThemeRoller interface has 3 major zones: the left column contains the
inspector panel, along the top is the QuickSwatch/Kuler bar, and below this
is the preview window.

Figure 13: jQuery Mobile ThemeRoller

Use the Inspector panel to set global theme settings on the first tab and
tweak the individual style options for each swatch.

When you drag and drop a color from the QuickSwatch panel onto an
element in the preview panel, ThemeRoller automatically calculates
text color and shadow, borders, gradients and button states. The sliders
make it easy to adjust the lightness and saturation of the colors. Use
the Adobe Kuler Swatches to load complementary color palettes from
Adobe's popular color palette sharing site.

The Preview panel shows a sample of common jQuery Mobile


widgets that live update each time you make a change to the theme so
you can quickly test and tweak the theme.
9 - 21
2013 Intel Corporation.

Fast Track to Intel XDK New

Walkthrough 9-3: Using ThemeRoller


In this walkthrough you will create a custom
stylesheet for your application using jQuery
Mobile ThemeRoller.

Use Adobe Kuler to select complementary


colors for your UI controls

Use ThemeRoller to generate a CSS file

Deploy the custom CSS in your app

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the topleft corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:

Figure 14: Use ThemeRoller


to change the colors of your
JQM widgets

/ftIntelXdkNew/walk/walk9_3/walk9_3.xdk

Theme JQM Components with ThemeRoller

5. Open a browser to http://www.jquerymobile.com/themeroller/


6. Click on the Get Rolling button.
7. Click on the Adobe Kuler swatches link
8. Choose Search Colors from the Adobe Kuler select list.
9. Enter the following search criteria into the Adobe Kuler search box:
beer

10. Click the search button.


11. Drag and drop colors from the various beer color schemes onto the
components in the A swatch.
12. Click the Download button.
13. Enter a theme name of FWB
14. Click the Download Zip button.
Deploy the CSS File

15. Open the zip file


16. Extract the themes/fwb.css file to the /walk9_3/css folder.

9 - 22
2013 Intel Corporation.

Theming

17. Return to Intel XDK New


18. Open index.html in Code mode.
19. Immediately preceeding the <link> tag to custom.css, insert a <link>
tag that points to the css/fwb.css file.
20. Test your app in the emulator. Note that the list of beers and friends are
now themed.

End of Walkthrough --

9 - 23
2013 Intel Corporation.

Fast Track to Intel XDK New

Unit Summary

Some CSS3 style properties require vendor prefixes.

There are a number of 3rd party tools that you can use to help mitigate
vendor-prefix compatibility issues.

CSS3 supports downloadable web fonts.

Google and Adobe offer a combined 1000+ fonts freely available for
download.

You can combine text-shadow and transparancy effects to output an


inset-text effect.

CSS3 enables you to combine background images and gradients to


produce exciting effects.

Base-64 encode your application's images in order to reduce the


number of http requests that must be made and improve app
performance.

You can theme your app by overriding jQuery Mobile CSS classes and
by generating a CSS file from ThemeRoller.

9 - 24
2013 Intel Corporation.

Theming

Unit Review
1. What are the benefits and drawbacks to using base-64 encoding?

2. List three tools that you can use to either visually prototype CSS3
styles or mitigate vendor prefix issues.

3. What are the relative advantages/disadvantages to using ThemeRoller?

4. Which style class can you override to set a background image for all of
the pages in your app?

9 - 25
2013 Intel Corporation.

(This page intentionally left blank)

Unit 10:
Going into Production

Unit Objectives
After completing this unit, you should be able to:

Configure run permissions on an app

Lock the application into a specific device orientation

Implement a custom icon and splash screen

Create a production build for Android

Install a .apk file on your device

Creating a Production Build for Android

Unit Topics

10 - 1
2013 Intel Corporation.

Fast Track to Intel XDK New

Creating a Production Build for Android


You've made it to the finish line! Your app, from all appearances, works
great in the simulator and on Intel App Preview. Now you're ready to create
a production build and test it across multiple physical devices and versions
of Android. After you've completed device testing, you can upload it to
Google Play, the Amazon AppStore, or simply post it to a web server for
download.
Your first step is to click on the Build tab in Intel XDK New as illustrated
in figure 1.

Figure 1: The Overview tab

For Android builds, the overview tab will indicate that your app is ready to
be packaged into a production-ready .apk file. However, while this is
technically a true statement, there are a number of settings that you will
want to modify before you proceed with packaging.

The Details panel allows you to set your application title, version,
permissions, orientation, and codebase.

The Assets panel enables you to configure your application's startup


orientation as well as launch icon and startup screens.

The Plugins panel gives you the ability to upload Cordova plugins for
use in your app.

The Credentials tab lets you enter credentials for working with the
Facebook APIs.

The Push tab configures your app for Push Notification support from
the Google Cloud Messaging Service and PushMobi.

10 - 2
2013 Intel Corporation.

Going into Production

Configuring Build Details


Configure the following information on the Details tab:

Figure 2: Configuring Build Details

Application Name
The name of the application that is displayed to the user when it's
installed on the device.

Application Version ID
The version number of the app (typically 1.0 for your initial release).

Application Permissions
The device resources that your app uses. Note that if your app tries to
access a resource for which it has not been granted permission, it will
usually fail silently.

Device Configuration
Choose the devices that you'll support. You must select Phone+Tablet
for Android builds.

Operating System
This will default to Android 4.2 with backwards compatibility to
Android 2.3

Code Base
There are three options that impact the size (in bytes) of your buildGold, Lean, and Lean with App Game Interface. Apps that use
Cordova APIs must choose Gold

10 - 3
2013 Intel Corporation.

Fast Track to Intel XDK New

Configuring Application Assets


The Assets tab, depicted in Figure 3, enables you to add a custom
application icon and splash screens. You can also set the device's initial
start-up orientation.

Figure 3: Define a custom icon and splash screen

Note the following:

The Android Launch Icon must be a 96x96 PNG file

The splash screen for phones must be a 720w x1280h PNG, JPG, or
JFIF.

The tablet splash screen must be a 1600w x 2560h PNG, JPG, or JFIF

During the build process, the launch icon and splash screens will be
automatically resized, while maintaining the same aspect ratio, to support
different device screen resolutions.

10 - 4
2013 Intel Corporation.

Going into Production

Locking the Screen Orientation


You can lock rotation using the intel.xdk bridge library by invoking the
following methods:

Use the intel.xdk.device.setRotateOrientation(str) method to the


preferred orientation (landscape or portrait)

Use the intel.xdk.device.setAutoRotate(bool) method to lock the


orientation.

The following code snippet locks an application into a portrait orientation:


<script type="text/javascript">
intel.xdk.device.setRotateOrientation("portrait");
intel.xdk.device.setAutoRotate(false);
</script>

Adding App Plugins


The plugins tab, as illustrated in Figure 4, enables you to create and upload
cordova API extensions.

Figure 4: Adding Cordova Plugins

Full documentation and examples for writing, packaging, and uploading


plugins is located at the following URL:
http://intel.ly/1dpj1B0

10 - 5
2013 Intel Corporation.

Fast Track to Intel XDK New

Entering App Credentials


As depicted in Figure 5, the App Credentials panel is where you must enter
additional credentials if your app makes use of the Intel XDK native
application Facebook integration.

Figure 5: Adding Facebook Credentials

More information about Facebook integration is located at the following


URL:
http://intel.ly/J5ek5O

10 - 6
2013 Intel Corporation.

Going into Production

Configuring Push Notifications


As described in unit 7, you will need to add information into the Push
notifications panel, in order to receive push notifications from Intel's
PushMobi service.

Figure 6: Configuring PushMobi support

10 - 7
2013 Intel Corporation.

Fast Track to Intel XDK New

Walkthrough 10-1: Packaging an App


In this walkthrough you will create a production app for Android devices.

Lock the application device orientation

Configure application permissions

Upload a custom icon and splash page

Steps
Open the Project

1. Open Intel XDK New


2. Click on the word PROJECTS in the top-left corner of the GUI.
3. Click the Open a Project button.
4. Select the following file:
/ftIntelXdkNew/walk/walk10_1/walk10_1.xdk

Set a Fixed Portrait Orientation

5. Open index.html in Code view.


6. At the top of the onDeviceReady() function, lock the orientation of the
app into portrait mode.
intel.xdk.device.setRotateOrientation("portrait");
intel.xdk.device.setAutoRotate(false);

7. Save the file.


Configure Android Permissions

8. Click on the Build tab


9. Click on the Android Build button.
10. Click the Upload Code button.
11. Click on Details and configure the following properties:

Application Title: FriendswithBeer


Application Version Name: 1.0
This app uses geolocation: Yes
This app accesses the user's contacts: Yes

10 - 8
2013 Intel Corporation.

Going into Production


Upload an Icon and Splash Page

12. Click the browse button adjacent to the Android Launch Icon field.
13. Select the walk10_1/resources/icon.png file.
14. Click the browse button adjacent to the Phone Splash Screen field.
15. Select the walk10_1/resources/splash.png file.
Create a Build

16. Click on the Overview tab.


17. Click the Build App Now button.
18. Click the Download Build button and save the file to your computer.
Test the Build

19. Email the .apk file to yourself.


20. Open the mail client on your Android phone.
21. Open the email that contains your .apk file.
22. Open the apk file on your device, install, and test it.

End of Walkthrough

10 - 9
2013 Intel Corporation.

Fast Track to Intel XDK New

Unit Summary

Accessing some hardware functions require that you grant permissions


to your app.

Application icons and startup images are automatically resized during


the build process in order to support multiple device resolutions.

Use the intel.xdk.device methods to lock the application into using a


specific orientation.

Facebook and Push notification support require that you enter


additional credentials during the build process.

You can email .apk files to your users or post them to a web server.
App distribution does not require uploading your app to Google Play.

Always test your app on a physical device prior to uploading it to an


app store.

10 - 10
2013 Intel Corporation.

Going into Production

Unit Review
1. Which device resource permissions can be set within the Build
process?

2. What is a plugin and why would you need one?

3. App icons and splash screens are automatically scaled in order to


account for varying device resolutions.

4. Describe the process for installing an .apk file on a physical device.

10 - 11
2013 Intel Corporation.

Вам также может понравиться