Always On, Always Connected Week 3

Single Page Applications - jQuery Mobile

jQuery Mobile is mobile web framework which enables best practices such as single page applications and brings jQuery into the mobile world.

To get started, download the "latest stable release". To use it in a PhoneGap application, at the very least you'll need to copy the "jquery.mobile-x.x.x.min.js" file into your "js" folder and the "jquery.mobile-x.x.x.min.css" into your "css" folder. You'll also need to download jQuery itself and copy the "jquery-x.x.x.min.js" file into your "js" directory.

jQuery Mobile has the concept of a page, really a content view. Multiple pages can be defined in one HTML document. Pages can be populated, either load things in dynamically through AJAX or by building the contents directly into the HTML itself. In the case of PhoneGap you'll definitely want as much of the content as possible built into the HTML itself. We'll want to link to local copies of the JavaScript and CSS in our HTML.

Here is a basic jQuery mobile page:
<!DOCTYPE html> 
<html>
	<head>
		<title>Page Title</title>
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<link rel="stylesheet" href="jquery.mobile-1.4.5.css" />
		<script src="jquery-2.1.4.js"></script>
		<script>
			// This is to get around a new security restriction in Chrome
			$(document).bind('mobileinit',function(){
				$.mobile.pushStateEnabled = false;
			});
			// It may not be needed in the end PhoneGap application
		</script> 		
		<script src="jquery.mobile-1.4.5.js"></script>
	</head>

	<body>
		Hi There!
	</body>
</html>
Here it is with multiple pages in one HTML document with the ability to navigate between them:
<!DOCTYPE html> 
<html>
	<head>
		<title>Page Title</title>
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<link rel="stylesheet" href="jquery.mobile-1.4.5.css" />
		<script src="jquery-2.1.4.js"></script>
		<script>
			// This is to get around a new security restriction in Chrome
			$(document).bind('mobileinit',function(){
				$.mobile.pushStateEnabled = false;
			});
			// It may not be needed in the end PhoneGap application
		</script> 		
		<script src="jquery.mobile-1.4.5.js"></script>
	</head>
	<body>
		<div data-role="page" id="page1">
			<div data-role="header">Page 1 Header</div>
			<div data-role="main" class="ui-content">
				Page 1 Content<br />
				<a href="#page2">Link to Page 2</a>
			</div>
			<div data-role="footer">Page 1 Footer</div>
		</div>
		<div data-role="page" id="page2">
			<div data-role="header">Page 2 Header</div>
			<div data-role="main" class="ui-content">
				Page 2 Content
				<a href="#page1">Link to Page 1</a>	
			</div>
			<div data-role="footer">Page 2 Footer</div>
		</div>
	</body>
</html> 
Instead of being a regular full screen view, a page could be dialog:
	<div data-role="page" data-dialog="true" id="page3">
	  <div data-role="header">
		<h1>Dialog Header</h1>
	  </div>

	  <div data-role="main" class="ui-content">
		<p>Hi</p>
		<a href="#page1">Go to Page 1</a>
	  </div>

	  <div data-role="footer">
		<h1>Dialog Footer</h1>
	  </div>
	</div> 
There are a bunch of transitions that you can apply to the links:
	<a href="#page1" data-transition="flip">Link to Page 1</a>	
Here is a nav bar
		<div data-role="navbar">
		  <ul>
			<li><a href="#page1">Home</a></li>
			<li><a href="#page2">Page Two</a></li>
			<li><a href="#page3">Dialog</a></li>
		  </ul>
		</div>	
Button
	<a href="#pagetwo" class="ui-btn">Go to Page Two</a>
jQuery Mobile makes it easy to add a swipe callback to an element:
<script>
	$(document).on("pagecreate","#page1",function(){
	  $("div").on("swipeleft",function(){
		alert("You swiped left!");
	  });                       
	});
</script>	
Swipe Navigation
<script>
	$(document).on("pagecreate","#page1",function(){
		$(document).on("swiperight", ".ui-content", function( event ) {
			console.log("swiperight on ui-content");
			$(":mobile-pagecontainer" ).pagecontainer("change", "#page3" );
		});  
	});
</script>	

Other Events

swipeleft, click, and more

Theming

Theme Roller

More Information:

Getting Started with JQuery Mobile
jQuery Mobile Demos
jQuery Mobile API Documentation
jQuery Mobile Tutorial
jQuery Mobile Examples
jQuery Mobile Essential Training

PhoneGap config.xml

The config.xml file controls much of the functionality of PhoneGap. Here is an example:
	<widget id="your.reverse.domain" version="0.0.1">
		<name>Hello PhoneGap</name>
		<description>
			My Cool App!
		</description>
		<author email="email@address" href="http://web.page">
			Me, Myself, and I
		</author>
		<content src="index.html" />
		<access origin="*" />
	</widget>

PhoneGap Plugins

PhoneGap itself doesn't have much of an API. In order to extend it's functionality, we have to use various plugins. This page lists the core set.

Contacts

First step is to install the plugin in our PhoneGap project:
phonegap cordova plugin add cordova-plugin-contacts
Now we can use it via JavaScript (Using JQuery Mobile). Here is an example which finds all of the contacts with the name John: (Don't forget to add <script src="cordova.js"></script>)
<script>
	$(document).on("pagecreate","#page1",function(){
		document.addEventListener("deviceready", onDeviceReady, false);
	});
	
	function onDeviceReady() {
		alert("Device Ready");
		
		var contactFindOptions = new ContactFindOptions();
		contactFindOptions.filter = "John";
		contactFindOptions.multiple = true;
		// Resulting contacts will only contain these fields
		contactFindOptions.desiredFields = [navigator.contacts.fieldType.id, navigator.contacts.fieldType.displayName, navigator.contacts.fieldType.name, navigator.contacts.fieldType.phoneNumbers];
		
		var searchFields = [navigator.contacts.fieldType.displayName, navigator.contacts.fieldType.name];
		navigator.contacts.find(searchFields, onContactsSuccess, onContactsError, contactFindOptions);
	}	
	
	
	function onContactsSuccess(contacts) {
		alert('Found ' + contacts.length + ' contacts.');
	}

	function onContactsError(contactError) {
		alert('onError!');
	}	
</script>	
Here is an example of doing something with those contacts:
function onContactsSuccess(contacts) {
    alert('Found ' + contacts.length + ' contacts.');
    
    var listviewhtml = '<ul data-role="listview">';

	for(var i = 0; i < contacts.length; i++) {
		console.log(contacts[i]);
		var contact = contacts[i];
		var phonenumber = "none";
		if (contact.phoneNumbers.length > 0) {
			phonenumber = contact.phoneNumbers[0].value;
		}
		listviewhtml += '<li><a href="tel:' + phonenumber + '">' + contacts[i].name.formatted + '</a></li>';
	}
	listviewhtml += '</ul>';
	$('#mycontacts').append(listviewhtml);
}
The above JavaScript will populate a listview in the HTML:
<ul id="mycontacts" data-role="listview" data-inset="true" data-filter="true">
	<li>Nothing here yet</li>
</ul>
Another Example: http://www.techrepublic.com/blog/software-engineer/create-cross-platform-apps-with-phonegap-and-jquery-mobile/"