Hooking into native events

Exclusive offer: get 50% off this eBook here
PhoneGap Mobile Application Development Cookbook

PhoneGap Mobile Application Development Cookbook — Save 50%

Over 40 recipes to create mobile applications using the PhoneGap API with examples and clear instructions with this book and ebook.

€20.99    €10.50
by Matt Gifford | January 2013 | Cookbooks Open Source

When developing for mobile devices, we can create feature-rich applications that harness the functionality of the native processes and systems.

The devices themselves provide us with built-in controls and user interface elements in the form of native buttons, to which we can apply methods and functions.

We can also make use of the hidden events and manage how our applications work when placed in the background on the device or alter states depending on network connectivity.

In this article by Matt Gifford, author of PhoneGap Mobile Application Development Cookbook, will introduce you to some of the native events available through the PhoneGap API, and how we can implement them into applications.

In this article, we will cover:

  • Pausing your application

  • Resuming your application

  • Displaying the status of the device battery levels

  • Making use of the native search button

  • Displaying network connection status

  • Creating a custom submenu

(For more resources related to this topic, see here.)

Pausing your application

Although we want our users to spend their time solely on our applications, they will inevitably leave our application to open another one or do something else entirely. We need to be able to detect when a user has left our application but not closed it down entirely.

How to do it...

We can use the PhoneGap API to fire off a particular event when our application is put into the background on the device:

  1. Create the initial HTML layout for the application, and include the reference to the Cordova JavaScript file in the head tag of the document.

    <!DOCTYPE HTML> <html> <head> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width;" /> <meta http-equiv="Content-type" content="text/html;> <title>Pausing an application</title> <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="cordova-2.0.0.js"></script> </head> <body> </body> </html>

  2. Before the closing head tag, create a new script tag block and add the event listener to check when the device is ready and the PhoneGap code is ready to run.

    <script type="text/javascript"> document.addEventListener("deviceready", onDeviceReady, false); </script>

  3. Create the onDeviceReady function, which will run when the event listener is fired. Inside this, we'll create a new event listener that will check for a pause event, and once received will fire the onPause method.

    function onDeviceReady() { document.addEventListener("pause", onPause, false); }

  4. Let's create the onPause method. In this example application, we'll ask the device to notify the user that the application has moved into the background by playing an audio beep. The numeric parameter specifies how many times we want the audio notification to be played — in this case, just once.

    function onPause() { navigator.notification.beep(1); }

    Developing for iOS? There is no native beep API for iOS. The PhoneGap API will play an audio file using the media API, but the developer must provide the file, named beep.wav and under 30 seconds in length, in the /www directory of the application project files. iOS will also ignore the beep count argument and will play the audio once. If developing for Windows 7 mobile, the WP7 Cordova library contains a generic beep audio file that will be used.

  5. When we run the application on the device, if you press the home button or navigate to another application, the device will play the notification audio.

How it works...

To correctly determine the flow of our lifecycle events, we first set up the deviceready event listener to ensure that the native code was properly loaded. At this point, we were then able to set the new event listener for the pause event.

As soon as the user navigated away from our application, the native code would set it into the background processes on the device and fire the pause event, at which point our listener would run the onPause method.

To find out more about the pause event, please refer to the official documentation, available here:

http://docs.phonegap.com/en/2.0.0/cordova_events_events.md.html#pause.

There's more...

In this recipe we applied the pause event in an incredibly simple manner. There is a possibility your application will want to do something specific other than sending an audio notification when the user pauses your application.

For example, you may want to save and persist any data currently in the view or in memory, such as any draft work (if dealing with form inputs) or saving responses from a remote API call.

We'll build an example that will persist data in the next recipe, as we'll be able to quantify its success when we resume the use of the application and bring it back into the foreground.

Resuming your application

Multi-tasking capabilities that are now available on mobile devices specify that the user has the ability to switch from one application to another at any time. We need to handle this possibility and ensure that we can save and restore any processes and data when the user returns to our application.

How to do it...

We can use the PhoneGap API to detect when our application is brought back into the foreground on the device. The following steps will help us to do so:

  1. Create the initial layout for the HTML and include the JavaScript references to the Cordova and the xui.js files. We will also be setting the deviceready listener once the DOM has fully loaded, so let's apply an onload attribute to the body tag.

    <!DOCTYPE HTML> <html> <head> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width;" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Resuming an application</title> <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="cordova-2.0.0.js"></script> <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="xui.js"></script> </head> <body onload="onLoad()"> </body> </html>

  2. Create a new script tag block before the closing head tag and add the deviceready event listener within the onLoad method. We'll also set two global variables, savedTime, and localStorage, the latter of which will reference the localStorage API on the device:

    <script type="text/javascript"> var savedTime; var localStorage = window.localStorage; function onLoad() { document.addEventListener("deviceready", onDeviceReady, false); } </script>

  3. Create the onDeviceReady function, within which we'll set the two event listeners to check for the pause and resume events, as follows:

    function onDeviceReady() { document.addEventListener("pause", onPause, false); document.addEventListener("resume", onResume, false); }

  4. We can now add the first of the new callback functions for the added listeners. onPause will run when a pause event has been detected. In this method, we'll create a new date variable holding the current time, and store it into the global savedTime variable we created earlier.

  5. If the user has entered something in to the text input field, we'll also take the value and set it into the localStorage API, before clearing out the input field.

    function onPause() { savedTime = new Date(); var strInput = x$('#userInput').attr('value'); if(strInput) { localStorage.setItem('saved_input', strInput); x$('#userInput').attr('value', ''); } }

  6. Define the onResume method, which will run when a resume event has been detected. In this function, we'll save a new date variable and we'll use it in conjunction with the savedTime variable created in the onPause method to generate the time difference between the two dates. We'll then create a string message to display the time details to the user.

  7. We'll then check the localStorage for the existence of an item stored using the key saved_input. If this exists, we'll extend the message string and append the saved user input value before setting the message into the DOM to display.

    function onResume() { var currentTime = new Date(); var dateDiff = currentTime.getTime() - savedTime.getTime(); var objDiff = new Object(); objDiff.days = Math.floor(dateDiff/1000/60/60/24); dateDiff -= objDiff.days*1000*60*60*24; objDiff.hours = Math.floor(dateDiff/1000/60/60); dateDiff -= objDiff.hours*1000*60*60; objDiff.minutes = Math.floor(dateDiff/1000/60); dateDiff -= objDiff.minutes*1000*60; objDiff.seconds = Math.floor(dateDiff/1000); var strMessage = '<h2>You are back!</h2>' strMessage += '<p>You left me in the background for ' strMessage += '<b>' + objDiff.days + '</b> days, ' strMessage += '<b>' + objDiff.hours + '</b> hours, ' strMessage += '<b>' + objDiff.minutes + '</b> minutes, ' strMessage += '<b>' + objDiff.seconds + '</b> seconds.</p>'; if(localStorage.getItem('saved_input')) { strMessage = strMessage + '<p>You had typed the following before you left:<br /><br />' strMessage += '"<b>' + localStorage.getItem('saved_input') + '</b>"</p>'; } x$('#message').html(strMessage); }

  8. Finally, let's add the DOM elements to the application. Create a new div element with the id attribute set to message, and an input text element with the id set to userInput.

    <body onload="onLoad()">
    <div id="message"></div>
    <input type="text" id="userInput" />
    </body>

  9. When we run the application on the device, the initial output would provide the user with an input box to enter text, should they wish to, as shown in the following screenshot:

  10. If we were to pause the application and then resume it after a period of time, the display would then update to look something like the following screenshot:

How it works...

We set up the deviceready event listener after the DOM was fully loaded, which would then run the onDeviceReady function. Within this method we then added two new event listeners to catch the pause and resume events respectively.

When the application is paused and placed into the background processes on the device, we saved the current date and time into a global variable. We also checked for the existence of any user-supplied input and if it was present we saved it using the localStorage capabilities on the device.

When the application was resumed and placed back into the foreground on the device, the onResume method was run, which obtained the time difference between the saved and current datetime values to output to the user. We also retrieved the saved user input from the localStorage if we had set it within the onPause method.

To find out more about the resume event, please refer to the official documentation, available here:

http://docs.phonegap.com/en/2.0.0/cordova_events_events.md.html#resume.

PhoneGap Mobile Application Development Cookbook Over 40 recipes to create mobile applications using the PhoneGap API with examples and clear instructions with this book and ebook.
Published: October 2012
eBook Price: €20.99
Book Price: €34.99
See more
Select your format and quantity:

Displaying the status of the device battery levels

Progressions in capabilities and processing power means we can do much more with our mobile devices including multi-tasking and background processes, this often means we end up using more battery power to fuel our applications.

How to do it...

In this recipe we will build an application to display the connection details and current power capacity of the device battery.

  1. Create the initial HTML layout for the application and include the Cordova JavaScript file. We'll also be manipulating DOM elements, so include a reference to the xui.js file within the head tag.

  2. We will be calling the onDeviceReady method to instantiate the PhoneGap functionality through an onLoad() function attached to the body tag.

    <!DOCTYPE HTML> <html> <head> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width;" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Battery State</title> <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="cordova-2.0.0.js"></script> <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="xui.js"></script> </head> <body onload="onLoad()"> </body> </html>

  3. Let's add the UI elements for the application. This will include a div element with the id attribute set to statusMessage, which will hold our returned information. We'll also build up some nested elements to create a visual representation of the device battery.

  4. We will reference the id attributes of each element using the XUI library, so we need to make sure the three attribute values are set to batteryIndicator, batteryLevel, and shade respectively:

    <h3>Battery Status</h3> <div id="statusMessage"></div> <div id="batteryIndicator"> <div id="batteryLevel"> <div id="shade" /> </div> </div>

  5. With the DOM elements inserted, let's continue to the JavaScript code. Create a script tag block before the closing head tag, and add an onLoad method, run from the body tag, which will add the event listener to check that the native PhoneGap code has been loaded and is ready for use.

    <script type="text/javascript"> function onLoad() { document.addEventListener("deviceready", onDeviceReady, false); } </script>

  6. Add the onDeviceReady method, into which we will add three new event listeners that will respond to changes with the device's battery status. Each listener has a corresponding callback method, which we will define in the next few steps.

    function onDeviceReady() { window.addEventListener("batterystatus", onBatteryStatus, false); window.addEventListener("batterylow", onBatteryLow, false); window.addEventListener("batterycritical", onBatteryCritical, false); }

  7. The first callback method is onBatteryStatus, which accepts the information object that contains properties on the device's battery. We will pass this information to a new function, setBatteryInfo.

    function onBatteryStatus(battery_info) { setBatteryInfo(battery_info); }

  8. Let's write the setBatteryInfo method, called from the status change function. We can use the level property returned from the battery_info object to set the width of the batteryLevel element. We'll then create a message with the current capacity level and whether or not the device is plugged in, which we'll set into the statusMessage element.

  9. If the battery level is below 21 percent, we'll change the background color of the battery to red, otherwise we'll set it at a healthy green.

    function setBatteryInfo(battery_info) { x$('#batteryLevel').setStyle('width', battery_info.level + '%'); var statusMessage = '<p>Percent: <span id="level">' + battery_info.level + '%</span></p>'; statusMessage = statusMessage + '<p>A/C: ' + chargingStatus(battery_info.isPlugged) + '</p>'; x$('#statusMessage').html(statusMessage); if(battery_info.level <= 20) { x$('#level').addClass('warning'); x$('#batteryLevel').setStyle('backgroundColor', '#E74A4A'); } else { x$('#batteryLevel').setStyle('backgroundColor', '#01A206'); } }

  10. The return value of the isPlugged method from the battery_info object is a Boolean value, so we'll send it to a new function to return a string representation of the connection, as shown in the following block of code:

    function chargingStatus(isPlugged) { if(isPlugged) { return 'Connected'; } return 'Disconnected'; }

  11. The batterylow event handler will run a method called onBatteryLow. Inside of this, we'll include a notification alert to inform the user. This is shown in the following code block:

    function onBatteryLow(battery_info) { navigator.notification.alert( 'Time to charge it up!', function() {}, //alert dismissed 'Low Battery', 'OK' ); }

  12. If the battery reaches critical levels, the onBatteryCritical callback method will run. Again, let's use this event to alert the user of their urgent need to charge the device.

    function onBatteryCritical(battery_info) { navigator.notification.alert( 'Seriously, plug your charger in!', function() {}, //alert dismissed 'Critical Battery', 'OK' ); }

  13. Both of our notification alerts will execute an empty function specified as the alertCallback property in the previous snippets, which will run when the alert is dismissed. For this example, we don't need to perform any extra functionality at this point, hence the empty function.

  14. Finally, include some CSS definitions to add a visual presence to our battery elements, as shown in the following code snippet:

    <style> #batteryIndicator { margin: 0 auto; width: 250px; height: 100px; border: 1px solid #ccc; background: #fff; border-radius: 10px; overflow: hidden; } #batteryLevel { height: 100%; } #shade { width: 100%; height: 15px; background: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#e5e5e5), to(#fff)); opacity: 0.2; position: relative; top: 15px; } .warning { color: #ff0000; font-weight: bold; } </style>

  15. Finally, include some CSS definitions to add a visual presence to our battery elements, as shown in the following code snippet:

  16. As soon as the device battery capacity goes below 21 percent, the UI will change to something similar to the following screenshot:

  17. In the following screenshot, the device battery levels have hit the critical value of 5 percent. As a result, we notify the user with an alert message, as shown in the following screenshot:

How it works...

Using the onDeviceReady method, we set up three new event listeners to check for the status of the device battery levels.

All three of the battery status handlers (batterystatus, batterylow, and batterycritical) return the same object with the following properties:

  • level: A Number value that defines the percentage of the battery, between 0 and 100

  • isPlugged: A Boolean value that returns a true or false value to represent if the device is connected to a charger or not

We were able to use the returned properties to update a visual representation of the device battery on screen, as well as use the level property to determine if we are below the critical threshold barrier.

Although at first glance the three events seem to do the same thing, there are important differences. The batterystatus event will detect changes in the battery capacity, and will fire its callback method with every percentage change. This allows us to keep a constant check on the status of the device battery levels. It will also fire if the device is connected or disconnected from the charger. From the isPlugged property, we can easily determine if the device is using the mains power or not.

The batterylow event will fire only when the battery has reached a specific percentage level, deemed as low by the device. The same applies to the batterycritical event, which will only fire once the battery level has reached a particular percentage.

The threshold levels for the batterylow and batterycritical events are specific to each device, so this is something to be aware of if you are hardcoding values within the application.

As a reference, Android devices typically set the low threshold to 20 percent, and the critical threshold to 5 percent.

To find out more about the batterycritical, batterylow, and batterystatus events, please refer to the official documentation, available here:

http://docs.phonegap.com/en/2.0.0/cordova_events_events.md.html#batterystatus.

There's more...

In our sample application included in this recipe, we processed a simple alert notification when the low and critical thresholds were reached.

Depending on your mobile application and what its processes are, chances are you will want to action something specific at these points. For example, you may want to save any user input values into local memory, or shutdown/pause certain aspects of the application's functionality once these thresholds have been detected. If the user is unable to charge their device, you do not want them to lose data while using your application.

Making use of the native search button

The native functionality of a mobile device search button can be overridden using the PhoneGap API, which allows developers to create custom search commands for their applications, or use the button for something else entirely different from search operations.

How to do it...

In this recipe we will create a small application that will accept user input and transfer the query, opening the device's native browser to query a search engine.

  1. Create the initial layout for the HTML, and include references to both the Cordova and XUI JavaScript libraries.

  2. We will also apply an onload attribute to the body tag to run a method once the DOM has loaded.

    <!DOCTYPE HTML> <html> <head> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width;" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Search Button</title> <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="cordova-2.0.0.js"></script> <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="xui.js"></script> </head> <body onload="onLoad()"> </body> </html>

  3. The user interface for this application is incredibly simple. Add a text input field within the body of the document, and set the id attribute of the element to criteria. We will reference this directly using XUI, as shown in the following code snippet:

    <body onload="onLoad()">
    <h2>Goog Seeker</h2>
    <input type="text" id="criteria" />
    </body>

  4. Let's now add our custom code. Create a new script tag block before the closing head tag, into which we'll define the onLoad method. This will add the event listener to fire once the PhoneGap code is ready.

    <script type="text/javascript"> function onLoad() { document.addEventListener("deviceready", onDeviceReady, false); } </script>

  5. The onDeviceReady will then add a new event listener to detect the use of the device's search button.

    function onDeviceReady() { document.addEventListener("searchbutton", onSearchPress, false); }

  6. The event listener will execute the onSearchPress method. This will obtain the value of the user-supplied input and append it to a URL string. We can then load the URL in the device browser.

    function onSearchPress() { var userInput = x$('#criteria').attr('value'); if(userInput) { var urlString = 'http://www.google.co.uk#q=' + escape(userInput); navigator.app.loadUrl(urlString); } }

  7. When we run the application on a device, the initial page layout will look something like the following screenshot:

  8. Once the user presses the search button on the device, the browser will open and run the search query, as shown in the following screenshot:

How it works...

The onDeviceReady method sets up the new event listener, which will fire when it detects the searchbutton event.

We then obtained the value from the text input feld, appended it to the URL string, and loaded that URL in the native device browser.

To find out more about the searchbutton event, please refer to the official documentation, available here:

http://docs.phonegap.com/en/2.0.0/cordova_events_events.md.html#searchbutton.

There's more...

The searchbutton event is only applicable to Android devices, but with such a prominent position on most Android phones, it really is a very useful button and event that can be used for many purposes.

Consider an application that lists contacts from the device database. Pressing the search button, you could open a dialog window to allow the user to enter search criteria to filter the contacts.

PhoneGap Mobile Application Development Cookbook Over 40 recipes to create mobile applications using the PhoneGap API with examples and clear instructions with this book and ebook.
Published: October 2012
eBook Price: €20.99
Book Price: €34.99
See more
Select your format and quantity:

Displaying network connection status

Your application may require the user to be connected to a network. This may be for partial updates, remote data transfer, or streaming. Using the PhoneGap API, we can easily detect the status or existence of any network connectivity.

How to do it...

In this recipe, we will build an application to constantly check the network connection status of our device.

  1. Create the initial HTML layout for the application. Include references to the Cordova and XUI JavaScript libraries within the head tag of the document.

  2. We will also be setting the deviceready event listener after the DOM has fully loaded, so we'll also add the onLoad() function call to the body tag.

    <!DOCTYPE HTML> <html> <head> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width;" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Network Status</title> <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="cordova-2.0.0.js"></script> <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="xui.js"></script> </head> <body onload="onLoad()"> </body> </html>

  3. Let's add the UI elements to the body of our application. Create a div block to act as a container for our statusMessage and count elements, both of which we will be referencing directly using the XUI library. We will also be inserting content into the speedMessage element, so ensure the id attribute of those three elements matches those shown as follows:

    <h3>Network Status</h3> <div id="holder"> <div id="statusMessage"></div> <div id="count"></div> </div> <div id="speedMessage"> </div>

  4. Create a new script tag block before the closing head tag and define two global variables, which we will use within the custom code. We can also now define the onLoad method, which will set the deviceready event listener.

    <script type="text/javascript"> var intCheck = 0; var currentType; function onLoad() { document.addEventListener("deviceready", onDeviceReady, false); } </script>

  5. Let's now add the onDeviceready method, called from the deviceready event listener. Within this function we will add two new event listeners to check when the device is connected or disconnected from a network. Both of these listeners will run the same callback method that is checkConnection.

  6. We will then set up an interval timer to run the same checkConnection method every second to provide us with constant updates for the connection.

    function onDeviceReady() { document.addEventListener("online", checkConnection, false); document.addEventListener("offline", checkConnection, false); var connCheck = setInterval(function() { checkConnection(); }, 1000); }

  7. The checkConnection function sets up the objConnection variable to hold a representation of the device's connection. This object returns a value in the type property, from which we are able to determine the current connection type. We'll pass that value into another function called getConnectionType, which we'll use to return a user-friendly string representation of the connection type.

  8. As this method runs every second, we want to be able to determine if the current connection type differs from the previous connection. We can do this by storing the connection type value in the currentType global variable and check if it matches the current value.

  9. Depending on the returned value of the connection type, we can optionally choose to inform the user that to get the most out of our application they should have a better connection.

  10. We will also increment an integer value, stored in the intCheck global variable, which we will use to count the number of seconds the current connection has been active for.

    function checkConnection() { var objConnection = navigator.network.connection; var connectionInfo = getConnectionType(objConnection.type); var statusMessage = '<p>' + connectionInfo.message + '</p>'; if(currentType != objConnection.type) { intCheck = 0; currentType = objConnection.type; if(connectionInfo.value <= 3) { x$('#speedMessage').html('<p>This application works better over a faster connection.</p>'); } else { x$('#speedMessage').html(''); } } intCheck = ++intCheck; x$('#statusMessage').html(statusMessage); x$('#count').html('<p>Checked ' + intCheck + ' seconds ago</p>'); }

  11. The getConnectionType method mentioned previously will return a message and value property depending on the type value sent as the parameter. The value properties have been assigned manually to allow us to control what level of connection we deem best for our application and for the experience of our users.

    function getConnectionType(type) { var connTypes = {}; connTypes[Connection.NONE] = { message: 'No network connection', value: 0 }; connTypes[Connection.UNKNOWN] = { message: 'Unknown connection', value: 1 }; connTypes[Connection.ETHERNET] = { message: 'Ethernet connection', value: 2 }; connTypes[Connection.CELL_2G] = { message: 'Cell 2G connection', value: 3 }; connTypes[Connection.CELL_3G] = { message: 'Cell 3G connection', value: 4 }; connTypes[Connection.CELL_4G] = { message: 'Cell 4G connection', value: 5 }; connTypes[Connection.WIFI] = { message: 'WiFi connection', value: 6 }; return connTypes[type]; }

  12. Finally, let's add some CSS defnitions to the bottom of our application to add some style to the UI.

    <style> div#holder { width: 250px; min-height: 60px; margin: 0 auto; position: relative; border: 1px solid #ff0080; border-radius: 10px; background: #ff0080; } div#holder p { margin: 20px auto; text-align: center; color: #ffffff; font-weight: bold; } div#speedMessage { width: 250px; margin: 0 auto; position: relative; } </style>

  13. When we run the application on our device, the output will look something like the following screenshot:

  14. If our user changes their connection method or disconnects completely, the interval timer will detect the change and update the interface accordingly, and the timer will restart. This is depicted in the following screenshot:

How it works...

We set up the onDeviceReady method to create two new event listeners to check for the online and offline events respectively. The online event will fire when the device's network connection is started, and the offline event will fire when the network connection is turned off or lost.

These events will only fire once, and so in this recipe we added in the setInterval timer function to constantly call the checkConnection method to allow us to obtain changes made to the network. The addition of this functionality helps greatly and means we can tell when a user switches from a 3G to a WiFi connection, for example. If this happens, they would not go offline, but simply change the connection type.

To find out more about the online and offline events, please refer to the official documentation, available here:

http://docs.phonegap.com/en/2.0.0/cordova_events_events.md.html#online.

There's more...

Your application may involve streaming data, remote connections or another process that requires a certain level of connectivity to a network. By constantly checking the status and type of connection, we can determine if it falls below an optimal level or a recommended type for your application. At this point, you could inform the user, or restrict access to certain remote calls or data streams to avoid latency in your application's response and possible extra financial costs incurred to the user from their mobile provider.

Creating a custom submenu

Your application may include an option for users to update or change settings, or perhaps the ability to truly exit the application gracefully, closing down all services and storing state or data.

How to do it...

In this recipe, we will create a simple application that interacts with the device's native menu button to create a sliding submenu:

  1. Create the initial layout of the HTML for our application. Include the Cordova and XUI JavaScript library references in the head of the document, and include an onLoad method call within the body tag, which will set the deviceready event listener once the DOM is fully loaded.

    <!DOCTYPE HTML> <html> <head> <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width;" /> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <title>Sub Menu</title> <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="cordova-2.0.0.js"></script> <script type="text/javascript" src='//dgdsbygo8mp3h.cloudfront.net/sites/default/files/blank.gif' data-original="xui.js"></script> </head> <body onload="onLoad()"> </body> </html>

  2. Let's now add the UI to the body of the document. Create a new button element with the id attribute set to menuToggle, and an unordered list within a div element. In this recipe, each anchor tag has a specific id attribute, which we'll use shortly to assign touch handlers to each link.

    <h2>Menu Display</h2> <button id="menuToggle">Toggle Menu</button> <div id="subMenu"> <a id="closeMenu"><span>Close Menu</span></a> <a id="hello"><span>Hello</span></a> <a id="exit"><span>Exit Application</span></a> </div>

  3. Add a new script tag block before the closing head tag in the document, and include the onLoad function which will add the deviceready event listener, as follows:

    <script type="text/javascript"> function onLoad() { document.addEventListener("deviceready", onDeviceReady, false); } </script>

  4. Create the onDeviceReady method, within which we will set a new event listener to check for the menubutton event. This will run the onMenuPress function once detected

  5. We'll also include the setMenuHandlers method, which will apply the touch handlers to the menu items.

    function onDeviceReady() { document.addEventListener("menubutton", onMenuPress, false); setMenuHandlers(); }

  6. The onMenuPress function, which is the callback method from the event listener, will handle the transition of our menu element and links. We will use XUI library to determine the current value of the subMenu element position and react accordingly to either open or close the menu.

    function onMenuPress() { var menuPosition = x$('#subMenu').getStyle('bottom'); if(menuPosition == '-100px') { x$('#subMenu').tween({bottom: '0px' }); } else { x$('#subMenu').tween({bottom: '-100px' }); } }

  7. The setMenuHandlers method will apply the touch handlers to our individual menu items. We can reference each element by id attribute and set the listener with the specific action we want it to run. To exit the application, we can call the exitApp method to gracefully close our application and not leave it running in the background on the device.

  8. The menuToggle button element and the closeMenu link item both provide the user with the ability to close the menu themselves by calling the previously created onMenuPress method.

    function setMenuHandlers() { x$('#exit').on('touchstart', function() { navigator.app.exitApp(); }); x$('#hello').on('touchend', function() { alert('Hello!'); }); x$('#closeMenu').on('touchend', function() { onMenuPress(); }); x$('#menuToggle').on('touchend', function() { onMenuPress(); }); }

  9. Finally, we will include some CSS definitions to set the menu into position and apply color styles and required attributes:

    <style> #menuToggle { width: 100%; height: 40px; position: relative; margin: 0 auto; color: #ffffff; background: #ff0080; font-size: 20px; } #subMenu { position: fixed; bottom: -100px; left: 0px; border-top: 1px solid #555; height: 100px; width: 100%; background: #e5e5e5; } #subMenu span { position: relative; margin: 0 auto; top: 40%; } #subMenu a { width: 29%; height: 100px; display: block; float: left; margin: 0 2% 0 2%; border-left: 1px solid #ccc; border-right: 1px solid #ccc; text-align: center; } </style>

  10. When we run the application on the device, the initial view will look like the following screenshot:

  11. And with the menu open, the user will be presented with our links, as shown in the following screenshot:

How it works...

The onDeviceReady method set up the new event listener to listen for the menubutton event. At this point, the onMenuPress function is run, which either opens or closes the menu depending on the current position of the subMenu element.

This is an ideal way to incorporate menu options and hidden gems of functionality within your application without overcrowding your user interface.

To create the transition of the menu, we used the tween capabilities provided by the XUI JavaScript library.

To find out more about the menubutton event, please refer to the official documentation, available here:

http://docs.phonegap.com/en/2.0.0/cordova_events_events.md.html#menubutton.

There's more...

The menubutton event provided by the PhoneGap API is not cross-device or cross-platform compatible. At present the supported device platforms are Android and BlackBerry WebWorks (OS 5.0 or higher versions).

There are other ways to include custom menus in your applications thanks to one of the many PhoneGap plugins created by the community developers and users.

The Native Menu plugin (https://github.com/mwbrooks/cordova-plugin-menu) allows you to add native toolbars, tab bars, and menus to your application, and is supported on Android, BlackBerry WebWorks, and iOS platforms.

The community and open source nature of the PhoneGap API and the Cordova product means that developers can freely extend and enhance the functionality of their applications and dig a little deeper into native processes offered by devices by creating custom plugins.

Summary

This article saw you go through events involving your application such as pausing an application, resuming a paused application, checking battery levels and displaying appropriate messages, and displaying connection statuses and customized submenus.

Resources for Article :


Further resources on this subject:


About the Author :


Matt Gifford

Matt officially began life as a developer in 2000, although he used to 'develop' simple applications using BASIC Programming on his Sinclair ZX Spectrum. After creating relational databases in VBScript and hand-coding HTML pages in text editors, the obvious route was to start developing websites using dynamic data.

He is now lead developer with Fuzzy Orange Ltd, and specializes in ColdFusion, Flex, and AIR development, and is also proud to be called an Adobe Community Professional for ColdFusion. He has spoken and presented regularly at national and international conferences and online meetings, and has written tutorials and articles for online resources and UK industry magazines.

Constantly striving to learn more and update any skill set he can, he loves to read development publications and community blogs, attend conferences, and discuss issues with other members of the development community.

A keen proponent for community resources and sharing knowledge, Matt writes and releases open-source ColdFusion applications and code samples as often as he can, and can also be seen updating resources and writing articles on his blog, http://www.mattgifford.co.uk.

Books From Packt


PhoneGap Beginner's Guide
PhoneGap Beginner's Guide

WordPress Mobile Applications with PhoneGap
WordPress Mobile Applications with PhoneGap

jQuery for Designers: Beginner’s Guide
jQuery for Designers: Beginner’s Guide

Rhomobile Beginner's Guide
Rhomobile Beginner's Guide

Android   4: New Features for Application Development
Android 4: New Features for Application Development

jQuery Mobile First Look
jQuery Mobile First Look

Mobile Web Development
Mobile Web Development

LiveCode Mobile Development Beginner's Guide
LiveCode Mobile Development Beginner's Guide


Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software