(This page intentionally left blank)
|
|
|
- Gary Hampton
- 10 years ago
- Views:
Transcription
1
2 (This page intentionally left blank)
3 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 s, 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. Figure 1: The app that you'll build in this course Intel Corporation 1-1
4 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 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 Intel Corporation.
5 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 Intel Corporation. 1-3
6 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 Intel Corporation.
7 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 Intel Corporation. 1-5
8 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 Fast Track to Intel XDK student files The following software is REQUIRED to be installed on your mobile device: Intel App Preview Available on ios, Android, and Microsoft stores Intel Corporation.
9 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 unit s content. The following icons are used throughout the guide: Concepts introduce new information. Demonstrations illustrate new concepts. Walkthroughs guide you, with the instructor s assistance, through procedures in a hands-on context. Labs let you practice new skills on your own. Summaries provide a brief synopsis of the unit s content. Reviews test how well you remember the concepts from the unit. Best Practices provide you with helpful insights and information Intel Corporation. 1-7
10 Fast Track to Intel XDK New Outlining the Course Content 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 Intel Corporation.
11 Unit 1: Introducing the Course Unit 7: Using Device Features Dialing the Phone Sending 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
12 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. The Beers List displays a list of beers that were downloaded from a REST-based web service and cached into an HTML5 WebSQL database Intel Corporation.
13 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. 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 Intel Corporation. 1-11
14 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, application, and navigation app. It also uses Google Maps to display real-time traffic conditions around your friend's location. 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 Intel Corporation.
15 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: 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, 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 Intel Corporation. 1-13
16 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 Unzip the files into your home/documents folder. End of Walkthrough Intel Corporation.
17 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 Intel Corporation. 1-15
18 (This page intentionally left blank)
19 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
20 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
21 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
22 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
23 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
24 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
25 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
26 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
27 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
28 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
29 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
30 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 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 the.apk file to yourself. 33. Open the 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
31 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
32 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
33 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
34 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
35 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=" 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
36 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
37 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
38 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
39 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
40 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 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
41 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: 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
42 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
43 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 device s 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
44 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
45 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
46 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
47 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
48 (This page intentionally left blank)
49 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
50 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
51 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
52 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
53 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
54 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
55 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
56 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
57 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
58 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
59 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
60 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
61 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 for the following files, changing the page header and footer as appropriate: beers.html drink.html 37. Click the Emulate tab. 3-13
62 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
63 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
64 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
65 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
66 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
67 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 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
68 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
69 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
70 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
71 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 Unit Topics Making External Data Requests Working with the ListView Caching Data in a Local Database Importing Data from the Contacts List 4-1
72 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
73 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=' $.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
74 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
75 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
76 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= " $.getjson(url + "?method=getbeerlist&callback=?", function(data) { me.data = data; ); 4-6
77 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: 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
78 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
79 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. method=getbeerlist&callback=? 18. Verify that your code appears similar to the following: cachebeers: function() { var me = this; var url = " $.getjson(url + "?method=getbeerlist&callback=?", function(data) { me.beers = data; console.log(data); ); 19. Save the file. 4-9
80 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
81 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
82 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
83 Dynamically Sorting an Array Working with Data 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
84 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
85 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" id="personslist" Figure 6: Adding a Search Filter 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"> </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
86 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. 3. Click the Open a Project button. 4. Select the following file: Figure 7: Output a list of Beers, grouped by country of origin. /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
87 Create the List 11. Open the Beers.html file in Design mode. Working with Data 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
88 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
89 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 window.opendatabase() WorkerUtils.openDatabase() Description Creates / opens a local database 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 string string string long function Description Database name. Will create new, empty database if the specified name does not exist. Database version. Display name Estimated size in bytes of the database size 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
90 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 1 The SQL that you wish to execute 2 Optional bind parameters 3 Optional success handler function 4 Optional error handler function 4-20
91 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 rowsaffected rows Returns the row ID of the data inserted into the database The number of rows affected by the operation 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
92 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 message A numeric error code, described below A string containing the error message, localized to the user's language The following error codes may be returned: Constant Code Description UNKNOWN_ERR 0 Transaction failed for reasons not related to the database. DATABASE_ERR 1 Operation failed due to the database, but not covered by the other error types VERSION_ERR 2 Operation failed because the database version did not match with the expected version 4-22
93 Constant Code Description Working with Data TOO_LARGE_ERR 3 The dataset returned from the database was too large QUOTA_ERR 4 Not enough disk space allocated SYNTAX_ERR 5 Failed due to a syntax error, or a mismatch on the number of bind parameters. CONTRAINT_ERR 6 Failed due to a referential integrity constraint. TIMEOUT_ERR 7 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
94 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
95 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. 3. Click the Open a Project button. 4. Select the following file: Figure 9: Store, retrieve, and output data from a local database /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
96 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 = " $.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
97 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
98 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: 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
99 Retrieving Contact Records Working with Data 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 field names to search (required) contactsuccess, // success callback function (required) contacterror, // failure callback function (optional) searchoptions // Options 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
100 Fast Track to Intel XDK New Working with Contact Data You can read the following fields for each contact record: Field Description id displayname name nickname addresses phonenumbers s ims organizations birthday note photos categories urls String. A globally unique identifier String. The name of the Contact, suitable for display to end-users Object An object containing all components of a persons name. String. A casual name to address the contact. Array. All of the contact's addresses. Array. Contact's phone numbers Array. All of the contact's addresses Array. All of the contact's instant messaging addresses Array. All of the contact's organizations Date. The contact's birthday. String. General remarks about the contact. Array. The contact's photos. Array. All of the contact's user-defined categories. 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
101 Working with Data Parsing the Contact Name The Contact Name is a javascript object containing the following properties: Field formatted familyname givenname middlename honorificprefix honorificsuffix Description String. The complete name of the contact. String. The contact's family name. String. The contact's given name. String. The contact's middle name. String. The contact's prefix (Mr. / Dr. / Mrs. / etc) 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
102 Fast Track to Intel XDK New Parsing the Contact's Addresses Each ContactAddress object has the following properties: Property pref type formatted streetaddress locality region postalcode country Description Boolean. True if the contact's preferred address. String. Indicates type of address, e.g. 'home' String. The full address, formatted for display. String. The full street address. String. The city or locality. String. The state or region. String The zip code or postal code. 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
103 Working with Data Parsing the Contact's Addresses and Phone Numbers addresses and phone numbers are stored in a ContactField objects which contains the following properties: Property type value pref Description String. The type of field, e.g. 'home','work','mobile' String. The address or phone number 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
104 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
105 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: Import Icon: ui-icon-user Icon Position: icon only id: 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
106 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
107 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, ): var fields = [ "displayname", "name", "addresses", "phonenumbers", " s" ]; 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 = null count = 0 friend = null 4-37
108 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
109 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 Address 33. After the if() block that you inserted from the prior steps, insert another conditional that evaluates whether the contact object has an s property. if (contacts[i]. s) { 4-39
110 Fast Track to Intel XDK New 34. Inside the if() block, push another object containing user's preferred address onto the friend array. if (contacts[i]. s) { friend.push( { name: " ", value: Contacts.getPreferred(contacts[i]. s).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
111 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
112 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
113 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 Modify the onimport() method to refresh the LISTVIEW after your contacts have been imported. End of Lab
114 (This page intentionally left blank)
115 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. Unit Topics Creating Forms Validating Form Input Persisting Form Data 5-1
116 Fast Track to Intel XDK New Creating Forms Intel XDK New supports the following types of form fields: Checkbox Date Number Checkbox Group Address Datetime Flip Switch Telephone Number Month Text Password URL Hidden Search Radio Slider Select Radio Group Text Area 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
117 Automatically Setting Focus Creating Input Forms 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
118 Fast Track to Intel XDK New Capturing Addresses Using <input type= > automatically adjust the user's on-screen keyboard to facilitate data entry. <form> <label for="my ">enter your address:</label> <input type=" " name="my " /> <input type="submit"> </form> As depicted in Figure 2, you can define an field by dragging an input widget onto the design canvas and then specifying as its type. Inputting Phone Numbers Figure 3: Defining an input field. 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
119 Using Select Menus Creating Input Forms 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
120 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
121 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. 3. Click the Open a Project button. 4. Select the following file: Figure 6: The data entry form that you will create during this exercise /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: ui-icon-back Icon position: icon only id: 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
122 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: (unchecked) Type: text Placeholder: First Name Name: firstname id: 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: (unchecked) Type: text Placeholder: Last Name Name: lastname id: 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: (unchecked) Type: text Placeholder: Street Address Name: address id: 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
123 Type: number Placeholder: Zip Code Name: zipcode id: zipcode Creating Input Forms 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: (unchecked) Type: Placeholder: Name: id: 25. From the Controls > Form palette, drag an Input widget and drop it directly underneath the field on the Design Canvas. 26. Configure the following properties: Label: (unchecked) Type: telephone Placeholder: Tel Name: phone id: 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: (unchecked) Options: Select a Beer Name: beerid id: 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
124 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
125 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
126 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 Jörn 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 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 The plugin validates the following patterns for correctness: Type required remote minlength Description Makes data input required. Requests a resource check the element for validity. Requires strings to be a specified minimum length rangelength Requires strings to be within a specified size range. url date dateiso number digits creditcard equalto Requires the string to be a properly formatted address. Requires the input string to be a properly formatted url. Requires the input string to be a valid date. Requires the input to be a properly formatted ISO date Requires the input to be a decimal number Makes the element require numeric values only. Validates that the creditcard number has been properly formatted. 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
127 Loading the Library Creating Input Forms 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
128 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 Addresses Require that a properly formatted address be entered into a form field by applying the following validation rules: <label class="narrow-control" for=" "></label> <input class="wide-control" placeholder="me@my address.com" type="text" name="user " id="user "> $( "#myform" ).validate({ rules: { user { required: true, true ); 5-14
129 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
130 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
131 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
132 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
133 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
134 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
135 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
136 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: " 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
137 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
138 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
139 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
140 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
141 29. Save the file. Creating Input Forms 30. Test the application. You should now be able to edit existing contact records. End of Walkthrough
142 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 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
143 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
144 (This page intentionally left blank)
145 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 Unit Topics Getting Started with Google Maps Deploying a Simple Map Programmatically Geocoding Addresses Adding Overlays and Map Markers 6-1
146 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 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
147 Using the Purchased Key Version of Google Maps Adding GEO Features 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=" 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: 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
148 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=" key=your_api_key&sensor=set_to_true_or_false"> </script> For additional licensing information, please see: 6-4
149 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=" key= &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=" &sensor=false"> </script> 6-5
150 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
151 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': ' , ', 'zoom': 15, disabledefaultui: false ; $('#map_canvas').gmap({ center: mapoptions.center, maptypeid: google.maps.maptypeid.satellite, zoom: mapoptions.zoom, disabledefaultui: mapoptions.disabledefaultui ); </script> 6-7
152 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: 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( " ", " "); $mapcontainer.gmap({ center: loc, zoom: 16, maptypeid:google.maps.maptypeid.satellite ); Figure 3: Partially rendered map. settimeout("$('#map').gmap('refresh')",500); 6-8
153 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 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
154 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 streetviewcontrol pancontrol scalecontrol maptypecontrol overviewmapcontrol Description 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). Boolean. The enabled/disabled state of the Pan control. Boolean. The initial enabled/disabled state of the Scale control. 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. Boolean. A collapsible overview map in the corner of the screen 6-10
155 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. Adding GEO Features 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 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=" 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
156 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 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 (" ", " "), 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
157 Adjust Map Rendering 25. Return to index.html in CODE mode. Adding GEO Features 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
158 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
159 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 Adding GEO Features 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
160 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
161 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
162 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: KmlLayer Layer HeatmapLayer FusionTablesLayer TrafficLayer TransitLayer WeatherLayer and CloudLayer BicyclingLayer Description Renders KML and GeoRSS elements into a Maps API V3 tile overlay. Renders geographic data using a Heatmap visualization Renders data contained in Google Fusion Tables. Renders a layer depicting traffic conditions and overlays representing traffic. Displays the public transport network of your city on the map. Allow you to add weather forecasts and cloud imagery to your map. 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
163 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 (" ", " "), 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=" 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 (" ", " "), 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
164 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: ' , ', 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 (" ", " "), 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
165 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
166 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
167 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
168 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
169 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
170 (This page intentionally left blank)
171 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 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, , and Navigation Apps Listening to the Accelerometer Listening for Push Notifications Unit Topics 7-1
172 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
173 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
174 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
175 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 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
176 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
177 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
178 Fast Track to Intel XDK New Launching the Phone, , and Navigation Apps You can execute the device's phone dialer, , and navigation apps by programmatically setting location.href to a specially encoded url link as illustrated below: // launch mail-compose location.href='mailto:[email protected]'; 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: "; 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 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 , 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
179 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( "[email protected]", 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 q 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
180 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 t The type of map to display z 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(" th 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(" th St NW 20036"); var toaddr = escape("2000 K St NW 20036"); var tpl='<a href=" 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
181 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(" th St NW 20036"); var toaddr = escape("2000 K St NW 20036"); var tpl=" 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( ' ) === -1 && document.url.indexof( ' ) === -1) { // PhoneGap application else { // Web page 7-11
182 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, , 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, , 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
183 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 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 application and sets default subject and body text when tapped. 7-13
184 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. , 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 = " {1&saddr={2,{3"; 7-14
185 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 = " 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
186 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 (and above) Android (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
187 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 ( 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
188 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
189 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
190 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
191 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
192 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 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
193 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
194 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
195 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 address. intel.xdk.notification.addpushuser( intel.xdk.device.uuid, intel.xdk.device.uuid, 'no@ .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
196 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
197 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
198 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
199 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: Click the Create Project button. 13. Enter the following information: Project Name: Friends with Beer 7-29
200 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 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
201 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
202 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 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
203 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 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
204 (This page intentionally left blank)
205 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 Unit Topics Playing Audio and Video 8-1
206 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 autoplay controls height width loop Description Boolean attribute, causes the user agent to start playing the media as soon as it is able. Boolean attribute indicating whether the author has not provided a custom controller using Javascript and would like to use the native set of controls. The height of the control, in pixels The width of the control, in pixels 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. poster "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. 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
207 Integrating Multimedia Attribute src Description 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
208 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 paused ended readystate played seeking duration starttime seekable Description Returns true if the playback is paused Returns true if playback has ended 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. Returns a TimeRanges object representing the range of the media that has been played Returns true if the user agent is currently seeking Returns the length of the media resource, in seconds Returns the earliest possible position, in seconds. Note that this might not be zero-based if the resource is being streamed in real-time. 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
209 Integrating Multimedia Read/Write Property playbackrate defaultplaybackrate volume currenttime muted Method load() pause() play() canplaytype(type) Description Returns the current playback rate Returns the default playback rate, where 1.0 is normal speed. 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. Returns the current playback position, in seconds. Can be set to seek to a specific time. Returns true if the audio is muted, false if not. Description Causes the element to reset and start selecting and loading a new media resource from scratch. Sets the paused attribute to true, loads the media resource if necessary. Sets the paused attribute to false, loads the media resource, and starts playback. 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
210 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
211 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
212 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
213 Working with Audio Integrating Multimedia 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 autoplay controls loop Description Boolean attribute, causes the user agent to start playing the media as soon as it is able. 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. 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. src "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. 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
214 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 currenttime duration muted paused Description Number. The playhead position, expressed as seconds Number. Playback time for the clip, in seconds. Boolean. Returns true if volume is muted 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 canplaythroug h progress ended play volumechange Description The media can be played, but may need to pause while downloading. Indicates that the media can be played through without pausing. 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() The end of the media was reached and playback was stopped. The media has started playing. The volume level has been adjusted. 8-10
215 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+ Chrome 31 for Android Features of the HTML5 Audio API include: Firefox 25 for Android Most desktop browsers (excluding Microsoft Internet Explorer) 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 for a detailed introduction to the html5 Web Audio API. 8-11
216 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: //player.vimeo.com/video/ Autoplay: checked Loop: 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
217 15. Enter the following Video Settings: Integrating Multimedia Webm Src: //xdktraining.com/ftxdknew/friends.webm Mp4 Src: //xdktraining.com/ftxdknew/friends.mp4 Autoplay: true Controls: true Loop: 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
218 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
219 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
220 (This page intentionally left blank)
221 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 Unit Topics Working with CSS3 on Mobile Devices Enhancing Fonts and Typography Enhancing Backgrounds Working with ThemeRoller 9-1
222 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 -webkit- -moz- -o- -ms- Description Webkit browsers (typically ios and Android) Mobile Firefox Mobile Opera 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: #c0c0c0; // fallback background-image: linear-gradient(#ffffff,#c0c0c0); background-image: -webkit-linear-gradient(#ffffff,#c0c0c0); background-image: -moz-linear-gradient(#ffffff,#c0c0c0); background-image: -o-linear-gradient(#ffffff,#c0c0c0); Consequently, most app developers typically use a 3 rd party tool to handle vendor prefixes and make CSS authoring a bit less redundant. Two of those products are Sass and LESS. 9-2
223 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 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 9-3
224 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) { #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 9-4
225 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 selector to define a font name and associated download url. You can then reference the font in subsequent style definitions as indicated { 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 text-fill-color text-stroke-color text-stroke-width Description Sets the fill color of the text. The outline color of the text. 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
226 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 as illustrated in Figure
227 Applying Transparency Theming 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
228 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
229 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
230 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 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
231 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: 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 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
232 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
233 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: -webkit-linear-gradient(gold, goldenrod); background-image: -moz-linear-gradient(gold, goldenrod); background-image: -ms-linear-gradient(gold, goldenrod); background-image: -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
234 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:# url('images/beercan.png') no-repeat; 9-14
235 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 left top left center left bottom right top right center right bottom center top center center center bottom Description 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%. x y Position the background at an absolute location, typically specified in pixels. 9-15
236 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 provide free services for converting images to base-64. Figure 11: Use 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
237 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
238 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
239 Base-64 Encode an Image 12. Open a web browser to the following url: Theming 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
240 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
241 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
242 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. Figure 14: Use ThemeRoller 4. Select the following file: 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 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
243 17. Return to Intel XDK New 18. Open index.html in Code mode. Theming 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
244 Fast Track to Intel XDK New Unit Summary Some CSS3 style properties require vendor prefixes. There are a number of 3 rd party tools that you can use to help mitigate vendor-prefix compatibility issues. CSS3 supports downloadable web fonts. Google and Adobe offer a combined 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
245 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
246 (This page intentionally left blank)
247 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 Unit Topics Creating a Production Build for Android 10-1
248 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
249 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 build- Gold, Lean, and Lean with App Game Interface. Apps that use Cordova APIs must choose Gold 10-3
250 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
251 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:
252 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:
253 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
254 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
255 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. the.apk file to yourself. 20. Open the mail client on your Android phone. 21. Open the that contains your.apk file. 22. Open the apk file on your device, install, and test it. End of Walkthrough 10-9
256 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 .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
257 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
Managing Existing Mobile Apps
Adobe Summit 2016 Lab 324: Managing Existing Mobile Apps Adobe Experience Manager Mobile 1 Table of Contents INTRODUCTION 4 GOAL 4 OBJECTIVES 4 MODULE 1 AEM INTRODUCTION 5 LESSON 1 - AEM BASICS 5 OVERVIEW
Adobe Summit 2015 Lab 712: Building Mobile Apps: A PhoneGap Enterprise Introduction for Developers
Adobe Summit 2015 Lab 712: Building Mobile Apps: A PhoneGap Enterprise Introduction for Developers 1 Table of Contents INTRODUCTION MODULE 1 AEM & PHONEGAP ENTERPRISE INTRODUCTION LESSON 1- AEM BASICS
Adobe Summit 2015 Lab 718: Managing Mobile Apps: A PhoneGap Enterprise Introduction for Marketers
Adobe Summit 2015 Lab 718: Managing Mobile Apps: A PhoneGap Enterprise Introduction for Marketers 1 INTRODUCTION GOAL OBJECTIVES MODULE 1 AEM & PHONEGAP ENTERPRISE INTRODUCTION LESSON 1- AEM BASICS OVERVIEW
JTouch Mobile Extension for Joomla! User Guide
JTouch Mobile Extension for Joomla! User Guide A Mobilization Plugin & Touch Friendly Template for Joomla! 2.5 Author: Huy Nguyen Co- Author: John Nguyen ABSTRACT The JTouch Mobile extension was developed
HYBRID APPLICATION DEVELOPMENT IN PHONEGAP USING UI TOOLKITS
HYBRID APPLICATION DEVELOPMENT IN PHONEGAP USING UI TOOLKITS RAJESH KUMAR Technical Lead, Aricent PUNEET INDER KAUR Senior Software Engineer, Aricent HYBRID APPLICATION DEVELOPMENT IN PHONEGAP USING UI
Developing Cross-platform Mobile and Web Apps
1 Developing Cross-platform Mobile and Web Apps Xiang Mao 1 and Jiannong Xin * 2 1 Department of Electrical and Computer Engineering, University of Florida 2 Institute of Food and Agricultural Sciences
place/business fetch details, 184 185 removefromfavorite () function, 189 search button handler bind, 190 191 B BlackBerry build environment
Index A addtofavorite() method, 175 177, 188 189 Android ADT Plugin for Eclipse installation, 22 24 application, GWT Build Path, 244 device info, 247 directory structure, 244, 245 Eclipse classpath, 244
CinePlay 1.1.2. User Manual
CinePlay User Manual 1 CinePlay 1.1.2 User Manual CinePlay is a professional ios video player complete with timecode overlays, markers, masking, safe areas and much more. It is ideal for dailies, portfolios,
Making Web Application using Tizen Web UI Framework. Koeun Choi
Making Web Application using Tizen Web UI Framework Koeun Choi Contents Overview Web Applications using Web UI Framework Tizen Web UI Framework Web UI Framework Launching Flow Web Winsets Making Web Application
Mobile Game and App Development the Easy Way
Mobile Game and App Development the Easy Way Developed and maintained by Pocketeers Limited (http://www.pocketeers.co.uk). For support please visit http://www.appeasymobile.com This document is protected
Republic Polytechnic School of Infocomm C308 Web Framework. Module Curriculum
Republic Polytechnic School of Infocomm C308 Web Framework Module Curriculum This document addresses the content related abilities, with reference to the module. Abilities of thinking, learning, problem
How To Use Titanium Studio
Crossplatform Programming Lecture 3 Introduction to Titanium http://dsg.ce.unipr.it/ http://dsg.ce.unipr.it/?q=node/37 [email protected] 2015 Parma Outline Introduction Installation and Configuration
Intel HTML5 Development Environment Article Using the App Dev Center
Intel HTML5 Development Environment Article Using the App Dev Center v1.06 : 06.04.2013 Legal Information INFORMATION IN THIS DOCUMENT IS PROVIDED IN CONNECTION WITH INTEL PRODUCTS. NO LICENSE, EXPRESS
Appspace 5.X Reference Guide (Digital Signage) Updated on February 9, 2015
Appspace 5.X Reference Guide (Digital Signage) Updated on February 9, 2015 1 TABLE OF CONTENTS 2 What is Appspace For Digital Signage... 4 3 Access Appspace... 4 4 Best Practices and Notes... 4 5 Appspace
Mobile App Design and Development
Mobile App Design and Development The course includes following topics: Apps Development 101 Introduction to mobile devices and administrative: Mobile devices vs. desktop devices ARM and intel architectures
Mobility Introduction Android. Duration 16 Working days Start Date 1 st Oct 2013
Mobility Introduction Android Duration 16 Working days Start Date 1 st Oct 2013 Day 1 1. Introduction to Mobility 1.1. Mobility Paradigm 1.2. Desktop to Mobile 1.3. Evolution of the Mobile 1.4. Smart phone
SYST35300 Hybrid Mobile Application Development
SYST35300 Hybrid Mobile Application Development Native, Web and Hybrid applications Hybrid Applications: Frameworks Native, Web and Hybrid Applications Mobile application development is the process by
Adobe Marketing Cloud Bloodhound for Mac 3.0
Adobe Marketing Cloud Bloodhound for Mac 3.0 Contents Adobe Bloodhound for Mac 3.x for OSX...3 Getting Started...4 Processing Rules Mapping...6 Enable SSL...7 View Hits...8 Save Hits into a Test...9 Compare
Sage CRM. 7.2 Mobile Guide
Sage CRM 7.2 Mobile Guide Copyright 2013 Sage Technologies Limited, publisher of this work. All rights reserved. No part of this documentation may be copied, photocopied, reproduced, translated, microfilmed,
SPHOL326: Designing a SharePoint 2013 Site. Hands-On Lab. Lab Manual
2013 SPHOL326: Designing a SharePoint 2013 Site Hands-On Lab Lab Manual This document is provided as-is. Information and views expressed in this document, including URL and other Internet Web site references,
Product Guide. 2013 Nintex. All rights reserved. Errors and omissions excepted.
Product Guide [email protected] www.nintex.com 2013 Nintex. All rights reserved. Errors and omissions excepted. Contents Contents... 2 Introduction... 4 1 Understanding system requirements... 5 1.1 Operating
Creating mobile layout designs in Adobe Muse
Creating mobile layout designs in Adobe Muse Using Adobe Muse, you can create site layouts for web content to be displayed on desktop, smartphones, and tablets. Using the mobile design features, you can
Elgg 1.8 Social Networking
Elgg 1.8 Social Networking Create, customize, and deploy your very networking site with Elgg own social Cash Costello PACKT PUBLISHING open source* community experience distilled - BIRMINGHAM MUMBAI Preface
HTML5 Applications Made Easy on Tizen IVI. Brian Jones / Jimmy Huang
HTML5 Applications Made Easy on Tizen IVI Brian Jones / Jimmy Huang IVI Systems Today Lots of hardware variety. Multiple operating systems Different input devices Software development requires access to
Developing Mobile Websites with Responsive Web Design and jquery Mobile
Developing Mobile Websites with Responsive Web Design and jquery Mobile Duration: 5 Days Price: CDN$2875 *Prices are subject to GST/HST Course Description: This hands-on course conveys the fundamental
Web Conferencing Version 8.3 Troubleshooting Guide
System Requirements General Requirements Web Conferencing Version 8.3 Troubleshooting Guide Listed below are the minimum requirements for participants accessing the web conferencing service. Systems which
Administering Jive for Outlook
Administering Jive for Outlook TOC 2 Contents Administering Jive for Outlook...3 System Requirements...3 Installing the Plugin... 3 Installing the Plugin... 3 Client Installation... 4 Resetting the Binaries...4
Operational Decision Manager Worklight Integration
Copyright IBM Corporation 2013 All rights reserved IBM Operational Decision Manager V8.5 Lab exercise Operational Decision Manager Worklight Integration Integrate dynamic business rules into a Worklight
Tutorial: Building a Dojo Application using IBM Rational Application Developer Loan Payment Calculator
Tutorial: Building a Dojo Application using IBM Rational Application Developer Loan Payment Calculator Written by: Chris Jaun ([email protected]) Sudha Piddaparti ([email protected]) Objective In this
Mobility with Eye-Fi Scanning Guide
Mobility with Eye-Fi Scanning Guide Scan and Transfer Images Wirelessly with Eye-Fi This document is to be used in addition to the scanner s user guide located on the installation disc. The instructions
Sage CRM. Sage CRM 7.3 Mobile Guide
Sage CRM Sage CRM 7.3 Mobile Guide Copyright 2014 Sage Technologies Limited, publisher of this work. All rights reserved. No part of this documentation may be copied, photocopied, reproduced, translated,
Seagate Business Storage 8-bay Rackmount NAS Reviewer s Guide
Seagate Business Storage 8-bay Rackmount NAS Reviewer s Guide Seagate Business Storage 8-bay Rackmount NAS Reviewer s Guide/page 2 Purpose of this guide Experience the most common use cases for the product,
QUICK FEATURE GUIDE OF SNAPPII'S ULTRAFAST CODELESS PLATFORM
QUICK FEATURE GUIDE OF SNAPPII'S ULTRAFAST CODELESS PLATFORM (* Click on the screenshots to enlarge) TABLE OF CONTENTS 1. Visually Develop Mobile Applications 2. Build Apps for Any Android or ios Device
Mobile application testing is a process by which application software developed for hand held mobile devices is tested for its functionality,
Mobile Testing Mobile application testing is a process by which application software developed for hand held mobile devices is tested for its functionality, usability and consistency. A mobile application
USER GUIDE MANTRA WEB EXTRACTOR. www.altiliagroup.com
USER GUIDE MANTRA WEB EXTRACTOR www.altiliagroup.com Page 1 of 57 MANTRA WEB EXTRACTOR USER GUIDE TABLE OF CONTENTS CONVENTIONS... 2 CHAPTER 2 BASICS... 6 CHAPTER 3 - WORKSPACE... 7 Menu bar 7 Toolbar
Developing and deploying mobile apps
Developing and deploying mobile apps 1 Overview HTML5: write once, run anywhere for developing mobile applications 2 Native app alternative Android -- Java ios -- Objective-C Windows Mobile -- MS tools
Citrix EdgeSight for Load Testing User s Guide. Citrix EdgeSight for Load Testing 3.8
Citrix EdgeSight for Load Testing User s Guide Citrix EdgeSight for Load Testing 3.8 Copyright Use of the product documented in this guide is subject to your prior acceptance of the End User License Agreement.
DroboAccess User Manual
DroboAccess User Manual Release 8.2 The DroboAccess developers June 02, 2016 CONTENTS 1 DroboAccess 8.2 User Manual Introduction 1 2 Configuration of DroboAccess 8.2 3 2.1 Users, passwords and share management................................
Getting Started Guide. January 19, 2014
Getting Started Guide January 19, 2014 User Guide Chapters 1. Scheduling Meetings Configuring Meeting Details Advanced Options Invitation Email, received by the Participants Invitation Email, sent to the
MAGENTO THEME SHOE STORE
MAGENTO THEME SHOE STORE Developer: BSEtec Email: [email protected] Website: www.bsetec.com Facebook Profile: License: GPLv3 or later License URL: http://www.gnu.org/licenses/gpl-3.0-standalone.html 1
unisys ClearPath eportal Developer 6.1 Unisys Multi-Device App Developer s Guide March 2015 8230 0898 001
unisys ClearPath eportal Developer 6.1 Unisys Multi-Device App Developer s Guide March 2015 8230 0898 001 NO WARRANTIES OF ANY NATURE ARE EXTENDED BY THIS DOCUMENT. Any product or related information described
NotePad No More: - A Personal Survey of HTML5 Developer Toolsets. Stewart Christie - Tizen and HTML5 Community Manager.
NotePad No More: - A Personal Survey of HTML5 Developer Toolsets Stewart Christie - Tizen and HTML5 Community Manager @intel_stewart HTML5 Developer Conference Oct 2013 Editor Wars. Mat says: January 22,
Quick Start Guide Mobile Entrée 4
Table of Contents Table of Contents... 1 Installation... 2 Obtaining the Installer... 2 Installation Using the Installer... 2 Site Configuration... 2 Feature Activation... 2 Definition of a Mobile Application
Introduction to Tizen SDK 2.0.0 Alpha. Taiho Choi Samsung Electronics
Introduction to Tizen SDK 2.0.0 Alpha Taiho Choi Samsung Electronics Contents Web technologies of Tizen Components of SDK 2.0.0 Alpha Hello world! Debugging apps Summary 1 Web technologies on Tizen Web
How To Test Your Web Site On Wapt On A Pc Or Mac Or Mac (Or Mac) On A Mac Or Ipad Or Ipa (Or Ipa) On Pc Or Ipam (Or Pc Or Pc) On An Ip
Load testing with WAPT: Quick Start Guide This document describes step by step how to create a simple typical test for a web application, execute it and interpret the results. A brief insight is provided
Firefox for Android. Reviewer s Guide. Contact us: [email protected]
Reviewer s Guide Contact us: [email protected] Table of Contents About Mozilla Firefox 1 Move at the Speed of the Web 2 Get Started 3 Mobile Browsing Upgrade 4 Get Up and Go 6 Customize On the Go 7 Privacy
DreamFactory & Modus Create Case Study
DreamFactory & Modus Create Case Study By Michael Schwartz Modus Create April 1, 2013 Introduction DreamFactory partnered with Modus Create to port and enhance an existing address book application created
Intro to Web Development
Intro to Web Development For this assignment you will be using the KompoZer program because it free to use, and we wanted to keep the costs of this course down. You may be familiar with other webpage editing
Quick Start Guide. Installation and Setup
Quick Start Guide Installation and Setup Introduction Velaro s live help and survey management system provides an exciting new way to engage your customers and website visitors. While adding any new technology
WP Popup Magic User Guide
WP Popup Magic User Guide Plugin version 2.6+ Prepared by Scott Bernadot WP Popup Magic User Guide Page 1 Introduction Thank you so much for your purchase! We're excited to present you with the most magical
Using the Jive for ios App
Using the Jive for ios App TOC 2 Contents App Overview...3 System Requirements... 4 Release Notes...5 Which Version Am I Using?... 6 Connecting to Your Community... 11 Getting Started...12 Using Your Inbox...13
SuperOffice Pocket CRM
SuperOffice Pocket CRM Version 7.5 Installation Guide Page 1 Table of Contents Introduction... 3 Prerequisites... 3 Scenarios... 3 Recommended small scenario... 3 About this version... 4 Deployment planning...
Getting Started Guide
Getting Started Guide User Guide Chapters 1. Scheduling Meetings Configuring Meeting Details Advanced Options Invitation Email, received by the Participants Invitation Email, sent to the Moderator (scheduler)
Website Builder Documentation
Website Builder Documentation Main Dashboard page In the main dashboard page you can see and manager all of your projects. Filter Bar In the filter bar at the top you can filter and search your projects
Designing for the Mobile Web Lesson 3: HTML5 Web Apps
Designing for the Mobile Web Lesson 3: HTML5 Web Apps Michael Slater, CEO Andrew DesChenes, Dir. Services [email protected] 888.670.6793 www.webvanta.com Welcome! Four sessions 1: The Mobile
IBM BPM V8.5 Standard Consistent Document Managment
IBM Software An IBM Proof of Technology IBM BPM V8.5 Standard Consistent Document Managment Lab Exercises Version 1.0 Author: Sebastian Carbajales An IBM Proof of Technology Catalog Number Copyright IBM
Getting Started Guide. November 25, 2013
Getting Started Guide November 25, 2013 Getting Started Guide Chapters 1. Scheduling Meetings Configuring Meeting Details Advanced Options Invitation Email, received by the Participants Invitation Email,
Your First App Store Submission
Your First App Store Submission Contents About Your First App Store Submission 4 At a Glance 5 Enroll in the Program 5 Provision Devices 5 Create an App Record in itunes Connect 5 Submit the App 6 Solve
Getting Started Guide
Getting Started Guide Table of Contents OggChat Overview... 3 Getting Started Basic Setup... 3 Dashboard... 4 Creating an Operator... 5 Connecting OggChat to your Google Account... 6 Creating a Chat Widget...
Cloud Administration Guide for Service Cloud. August 2015 E65820-01
Cloud Administration Guide for Service Cloud August 2015 E65820-01 Table of Contents Introduction 4 How does Policy Automation work with Oracle Service Cloud? 4 For Customers 4 For Employees 4 Prerequisites
How To Convert A Lead In Sugarcrm
Attract. Convert. Retain. Lead Management in SugarCRM Written by: Josh Sweeney and Matthew Poer www.atcoresystems.com Atcore Systems, LLC 2010 All rights reserved. No part of this publication may be reproduced
Develop a Native App (ios and Android) for a Drupal Website without Learning Objective-C or Java. Drupaldelphia 2014 By Joe Roberts
Develop a Native App (ios and Android) for a Drupal Website without Learning Objective-C or Java Drupaldelphia 2014 By Joe Roberts Agenda What is DrupalGap and PhoneGap? How to setup your Drupal website
Mobile Web Design with HTML5, CSS3, JavaScript and JQuery Mobile Training BSP-2256 Length: 5 days Price: $ 2,895.00
Course Page - Page 1 of 12 Mobile Web Design with HTML5, CSS3, JavaScript and JQuery Mobile Training BSP-2256 Length: 5 days Price: $ 2,895.00 Course Description Responsive Mobile Web Development is more
An Informational User Guide for: Web Conferencing
Allows You to: Manage your audio conference online using easy point and click conference commands Show slide presentations and graphics to meeting participants Show your desktop to meeting participants
How To Use Senior Systems Cloud Services
Senior Systems Cloud Services In this guide... Senior Systems Cloud Services 1 Cloud Services User Guide 2 Working In Your Cloud Environment 3 Cloud Profile Management Tool 6 How To Save Files 8 How To
Grapevine Mail User Guide
Grapevine Mail User Guide Table of Contents Accessing Grapevine Mail...2 How to access the Mail portal... 2 How to login... 2 Grapevine Mail user guide... 5 Copying your contacts to the new Grapevine Mail
GeoInt 2015 Watson Workshop
GeoInt 2015 Watson Workshop Bluemix Building a Watson Question & Answer Service Hands-on Lab The lab is divided into three parts Part A: Getting started what you need and what you will be building Estimated
GoToWebinar. User Guide. 7414 Hollister Avenue Goleta CA 93117. http://support.citrixonline.com. 2013 Citrix Online, LLC. All rights reserved.
GoToWebinar User Guide 7414 Hollister Avenue Goleta CA 93117 http://support.citrixonline.com 2013 Citrix Online, LLC. All rights reserved. Contents Get Started with Your Account... 1 Log In... 1 Download
Visualizing a Neo4j Graph Database with KeyLines
Visualizing a Neo4j Graph Database with KeyLines Introduction 2! What is a graph database? 2! What is Neo4j? 2! Why visualize Neo4j? 3! Visualization Architecture 4! Benefits of the KeyLines/Neo4j architecture
5.1 Features 1.877.204.6679. [email protected] Denver CO 80202
1.877.204.6679 www.fourwindsinteractive.com 3012 Huron Street [email protected] Denver CO 80202 5.1 Features Copyright 2014 Four Winds Interactive LLC. All rights reserved. All documentation
Amcrest 960H DVR Quick Start Guide
Amcrest 960H DVR Quick Start Guide Welcome Thank you for purchasing our Amcrest 960H DVR! This quick start guide will help you become familiar with our DVR in a very short time. Before installation and
ITP 101 Project 3 - Dreamweaver
ITP 101 Project 3 - Dreamweaver Project Objectives You will also learn how to make a website outlining your company s products, location, and contact info. Project Details USC provides its students with
Advanced Web Development SCOPE OF WEB DEVELOPMENT INDUSTRY
Advanced Web Development Duration: 6 Months SCOPE OF WEB DEVELOPMENT INDUSTRY Web development jobs have taken thе hot seat when it comes to career opportunities and positions as a Web developer, as every
Seagate NAS OS 4 Reviewers Guide: NAS / NAS Pro / Business Storage Rackmounts
Seagate NAS OS 4 Reviewers Guide: NAS / NAS Pro / Business Storage Rackmounts Seagate NAS OS 4 Reviewers Guide 2 Purpose of this guide Experience the most common use cases for the product, learn about
ORACLE BUSINESS INTELLIGENCE WORKSHOP
ORACLE BUSINESS INTELLIGENCE WORKSHOP Integration of Oracle BI Publisher with Oracle Business Intelligence Enterprise Edition Purpose This tutorial mainly covers how Oracle BI Publisher is integrated with
Intel HTML5 Development Environment. Tutorial Building an Apple ios* Application Binary
Intel HTML5 Development Environment Tutorial Building an Apple ios* Application Binary V1.02 : 08.08.2013 Legal Information INFORMATION IN THIS DOCUMENT IS PROVIDED IN CONNECTION WITH INTEL PRODUCTS. NO
Site Configuration Mobile Entrée 4
Table of Contents Table of Contents... 1 SharePoint Content Installed by ME... 3 Mobile Entrée Base Feature... 3 Mobile PerformancePoint Application Feature... 3 Mobile Entrée My Sites Feature... 3 Site
dotmailer for Salesforce Installation Guide Winter 2015 Version 2.30.1
for Salesforce Installation Guide Winter 2015 Version 2.30.1 Page 1 CONTENTS 1 Introduction 2 Browser support 2 Self-Installation Steps 2 Checks 3 Package Download and Installation 4 Users for Email Automation
Bridging the Gap: from a Web App to a Mobile Device App
Bridging the Gap: from a Web App to a Mobile Device App or, so how does this PhoneGap* stuff work? *Other names and brands may be claimed as the property of others. 1 Users Want Mobile Apps, Not Mobile
Salesforce Customer Portal Implementation Guide
Salesforce Customer Portal Implementation Guide Salesforce, Winter 16 @salesforcedocs Last updated: December 10, 2015 Copyright 2000 2015 salesforce.com, inc. All rights reserved. Salesforce is a registered
Generate Android App
Generate Android App This paper describes how someone with no programming experience can generate an Android application in minutes without writing any code. The application, also called an APK file can
Mobile App Framework For any Website
Mobile App Framework For any Website Presenting the most advanced and affordable way to create a native mobile app for any website The project of developing a Mobile App is structured and the scope of
Using the Push Notifications Extension Part 1: Certificates and Setup
// tutorial Using the Push Notifications Extension Part 1: Certificates and Setup Version 1.0 This tutorial is the second part of our tutorials covering setting up and running the Push Notifications Native
Novell Filr. Mobile Client
Novell Filr Mobile Client 0 Table of Contents Quick Start 3 Supported Mobile Devices 3 Supported Languages 4 File Viewing Support 4 FILES THAT CANNOT BE VIEWED IN THE FILR APP 4 FILES THAT GIVE A WARNING
ADMINISTRATOR GUIDE VERSION
ADMINISTRATOR GUIDE VERSION 4.0 2014 Copyright 2008 2014. All rights reserved. No part of this document may be reproduced or transmitted in any form or by any means electronic or mechanical, for any purpose
Adobe Dreamweaver CC 14 Tutorial
Adobe Dreamweaver CC 14 Tutorial GETTING STARTED This tutorial focuses on the basic steps involved in creating an attractive, functional website. In using this tutorial you will learn to design a site
J j enterpririse. Oracle Application Express 3. Develop Native Oracle database-centric web applications quickly and easily with Oracle APEX
Oracle Application Express 3 The Essentials and More Develop Native Oracle database-centric web applications quickly and easily with Oracle APEX Arie Geller Matthew Lyon J j enterpririse PUBLISHING BIRMINGHAM
Issues of Hybrid Mobile Application Development with PhoneGap: a Case Study of Insurance Mobile Application
DATABASES AND INFORMATION SYSTEMS H.-M. Haav, A. Kalja and T. Robal (Eds.) Proc. of the 11th International Baltic Conference, Baltic DB&IS 2014 TUT Press, 2014 215 Issues of Hybrid Mobile Application Development
UP L18 Enhanced MDM and Updated Email Protection Hands-On Lab
UP L18 Enhanced MDM and Updated Email Protection Hands-On Lab Description The Symantec App Center platform continues to expand it s offering with new enhanced support for native agent based device management
INTERMEDIATE ANDROID DEVELOPMENT Course Syllabus
6111 E. Skelly Drive P. O. Box 477200 Tulsa, OK 74147-7200 INTERMEDIATE ANDROID DEVELOPMENT Course Syllabus Course Number: APD-0248 OHLAP Credit: No OCAS Code: None Course Length: 120 Hours Career Cluster:
Startup Guide. Version 2.3.9
Startup Guide Version 2.3.9 Installation and initial setup Your welcome email included a link to download the ORBTR plugin. Save the software to your hard drive and log into the admin panel of your WordPress
DiskPulse DISK CHANGE MONITOR
DiskPulse DISK CHANGE MONITOR User Manual Version 7.9 Oct 2015 www.diskpulse.com [email protected] 1 1 DiskPulse Overview...3 2 DiskPulse Product Versions...5 3 Using Desktop Product Version...6 3.1 Product
WebSphere Business Monitor V6.2 Business space dashboards
Copyright IBM Corporation 2009 All rights reserved IBM WEBSPHERE BUSINESS MONITOR 6.2 LAB EXERCISE WebSphere Business Monitor V6.2 What this exercise is about... 2 Lab requirements... 2 What you should
!!!!!!!! Startup Guide. Version 2.7
Startup Guide Version 2.7 Installation and initial setup Your welcome email included a link to download the ORBTR plugin. Save the software to your hard drive and log into the admin panel of your WordPress
Sage CRM. Sage CRM 2016 R1 Mobile Guide
Sage CRM Sage CRM 2016 R1 Mobile Guide Contents Chapter 1: Introduction to Sage CRM Mobile Solutions 1 Chapter 2: Setting up Sage CRM Mobile Apps 2 Prerequisites for Sage CRM mobile apps 3 Enabling users
MASTERTAG DEVELOPER GUIDE
MASTERTAG DEVELOPER GUIDE TABLE OF CONTENTS 1 Introduction... 4 1.1 What is the zanox MasterTag?... 4 1.2 What is the zanox page type?... 4 2 Create a MasterTag application in the zanox Application Store...
Citrix Virtual Classroom. Deliver file sharing and synchronization services using Citrix ShareFile. Self-paced exercise guide
Deliver file sharing and synchronization services using Citrix ShareFile Self-paced exercise guide Table of Contents Table of Contents... 2 Overview... 3 Exercise 1: Setting up a ShareFile Account... 6
Developing ASP.NET MVC 4 Web Applications MOC 20486
Developing ASP.NET MVC 4 Web Applications MOC 20486 Course Outline Module 1: Exploring ASP.NET MVC 4 The goal of this module is to outline to the students the components of the Microsoft Web Technologies
