Where Is My Car - Web App and PhoneGap compatible App

The source code for this sample can be found here: https://github.com/gomobile/sample-where-is-my-car.

A unique feature of the Where Is My Car application is that it is a single source code set that can be deployed as a web app hosted in a browser or as a device app bundled with the Apache Cordova* API (earlier versions were known as the PhoneGap* API) where it runs as a native first class application.

Functionally the app is very simple. Immediately after parking your car, you ask the app to remember your current location (where your car is parked).

Later, when you have finished your errands and need to locate your car, the app can be re-opened to search for the last remembered location.

The Files

Before diving into the details of this app, look at its files. There are two that will standout as unusual: phonegap.js and fauxgap.js.

The phonegap.js file included in the project is a stub file. It insures that the deviceready event is called when delivered as a web app as well as when deployed as a device app (an Apache Cordova* (PhoneGap) app). You can use this stub phonegap.js file in other projects to help unify ready event handling between web app deployments and device app deployments. There is no harm bundling it with projects you package using the Intel® HTML5 Development Environment tools; when you submit your application for build through the Adobe* PhoneGap Build* service any phonegap.js file included in the project is overwritten by the build service. However, if you choose to build a hybrd HTML5 device application directly using the PhoneGap library and the respective target SDK and tools, you will need to replace this stub file with the appropriate phonegap.js file.

The fauxgap.js file is another stub file. It provides a dummy implementation of the entire Apache Cordova* API. Depending upon what you are working on, you may or may not find this file useful. If you wish to use it, modify your <script src="phonegap.js"></script> declaration to point to fauxgap.js.  It will not conflict with the Ripple Emulator.  However, it absolutely should not be bundled when you build your device app. So remember to replace the line that includes fauxgap.js if you do choose to use it.

The Techniques

This sample project uses several different techniques you might want to use in your own app development.

The Pages

There are two GUI pages: the starting page and the search page. These pages are simply implemented as different div blocks in the same HTML document. One div has its CSS display feature set to none. A toggle_panes JavaScript function is used to ensure that only one of the divs is visible at any given time.

THE HTML:

<body>
  <div id="startpage">
   ...
   </div>
   <div id="findpage">
   ...
  </div>
</body>

THE CSS:

#findpage{ display:none; }

THE JAVASCRIPT:

function toggle_panes(show_find)
{
    var page = byId("startpage");
    page.style.display = show_find ? "none" : "block";
    page = byId("findpage");
    page.style.display = show_find ? "block" : "none";
}

The Styles

The buttons and the header use CSS3 gradients to get their effects. They were intentionally modeled to look like Apple iOS* controls.  You'll find the styling for a basic .header and .button CSS class in the ios_styles.css file inside the css directory of the project.

The Layout

This app intentionally uses a very simple layout. Almost every element is simply inserted into the HTML after its neighbor, with no width set in its CSS style. This will place all block level elements into a vertical column. (Block elements are <div> and <p>; whereas Inline elements, like <span> and <label>, will wrap). This also has the effect that the elements are all full browser viewport width regardless of the browser they are presented in or the orientation of the view presented by the mobile device (landscape or portrait). Exceptions to this rule are the back button and the user and car icons. Margins style rules are used to space out elements, and padding is used when their default bounding box needs to be extended away from the element a bit. Lastly, 0px margins are applied to both the <html> and <body> tags in the CSS so there will not be a gap between the header and the viewport border.

Meta

Because the page contents support liquid layout (i.e. it adjusts to any viewport width) the viewport meta identifier is simpler. There is no need to prescribe a specific starting width.

<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0" />

For more information about viewport meta, see https://developer.mozilla.org/en-US/docs/Mobile/Viewport_meta_tag.

Additionally, if you are planning that your web app can be added to the home screen of an Apple iPhone*, there are additional meta values you can set to tell the Apple Safari mobile browser if the page should be viewed full screen and what icon to place on the home screen. The following code snippet provides that function, more information about this technique can be found on the Apple developer site.

<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<!-- icon and startup screen -->
<link rel="apple-touch-icon" href="images/small-car-icon.png"/>

The Startup

A web app will typically have initialization routines that should fire when the DOM is loaded. Commonly, this is done using the jQuery $(document).ready( ... ) method, or with something like <body onload="...."> . But if your app uses any Apache Cordova* (PhoneGap) API's, then the DOM loading event will fire too early. Cordova API routines can only be called after the deviceready event fires. But deviceready only fires when your app has been compiled by PhoneGap Build (or a similar service); this even never fires in a regular web application, even when viewed in a mobile browser.

This means that if you want to write an app that can be both a web application as well as built by PhoneGap Build you have to negotiate two different initialization strategies (two competing ready events). The best solution we've found, so far, is the use of a dummy phonegap.js file. This file is included with this sample project.

This dummy phonegap.js file ensures that deviceready is always called. It will be called when the DOM loads for a regular web application, or it will be called by Cordova when the device ready function has completed.

So, within your web app, you use the dummy phonegap.js file and listen for the deviceready event instead of $(document).ready(...) or other typical startup entry points.

/* To keep things simple, we want exactly one initialization routine.
* our fake phonegap.js that we are using in this project will fire
* the PhoneGap deviceready event when the page loads.
*/
function onDeviceReady()
{
  .... //init code goes here
}
document.addEventListener("deviceready", onDeviceReady, false);

Cordova or Web App

If you wish to release your app as both a Cordova application and as a regular HTML5 web app, there may be times when you need to disambiguate the runtime environment. In other words, you need to ask the question: is this code running under Cordova on a mobile device or in a browser?

The simplest way to detect this is to simply look for the device  global variable. When Cordova is present, window.device will be initialized and device will be a usable global variable.  For example:

//is this PhoneGap or web app? 
if(typeof device !== "undefined")
{
   //PHONEGAP/CORDOVA IS PRESENT
}
else
{
  //WEB APP. PHONEGAP/CORDOVA IS NOT PRESENT.
}

Devices Tested:

  • Apple iPhone* OS 4.2.1
  • Apple iPad* 2, OS 5.1.1
  • Samsung Galaxy Player* 5.0,
For more complete information about compiler optimizations, see our Optimization Notice.

Comments


Just a comment on PhoneGap vs

Just a comment on PhoneGap vs Cordova:
PhoneGap is the original name of the project it was made by Nitobi
Cordova is the new name of the Open source project since Abode Bought Nitobi
PhoneGap is now a Commercial Distribution of the project owned by Adobe and used as the basis of Adobe PhoneGap Builds System
Regards,
Paul