This is the final tutorial part for developing simple PhoneGap based mobile application from the ground up. Earlier in tutorial parts one, two and three we took a closer look at what role PhoneGap hybrid mobile development framework plays in mobile development and how it works. We have created a new project and added several elements of functionality, similar to what most mobile applications out there would have – user interface, HTTP communication, data storage, native controls etc. In this final part I’m going to show you Geolocation API implementation, how to prepare and delay application splash screen and finalize everything with application icon. We’ll be working with the code from the last tutorial part (you can find at the bottom of tutorial part 3). Source code for overall finished PhoneGap application example (including today’s changes) can be found at the bottom of this post. Lets get started!
Geolocation API is there to provide your app with information on actual location of the device app is running on. In most cases its done in format of latitude and longitude. Location data is provided by mobile OS which is running on the device (it uses GPS and various network ID’s to crystallize this data).
As per PhoneGap documentation, there is no guarantee that Geolocation API will provide your app with the current location data and this is important information to consider then you are designing your app. There should always be a fallback scenario in your code in case device will not return Geolocation data.
How we are going to use the data? Well lets simply add a notification box over the recipes search field telling our app user where he currently is. Just to avoid disappointed app users who cannot buy the right ingredients in stores.. Jokes aside here is how we are going to implement it in our PhoneGap project.
navigator.geolocation.getCurrentPosition(onSuccess, onError);
Its the JavaScript API call to retrieve current mobile device position, where onSuccess and onError are the functions for handling success and error for this call. PhoneGap official documentation gives you detailed explanation. If successful this call will give us back the position object witch contains several device position related values like speed, latitude, longitude and others. We are going to use latitude and longitude to check on the name of our current location.
var latitude = position.coords.latitude; var longitude = position.coords.longitude;
We need to translate these coordinates to the actual location name and maps.googleapis will help us to do that. As we already have php back end file serving us as communication service with 3rd party APIs (tutorial part 2) we are going to add few lines of code so it makes additional API call to maps.googleapis service which will give us back the name of location based on supplied coordinates.
// Building string for request // $requeststr = "http://maps.googleapis.com/maps/api/geocode/json?"; $requeststr=$requeststr."latlng=".$latitude.",".$longitude; $requeststr=$requeststr."&sensor=true"; // CURL for communicating with web service // $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$requeststr); curl_setopt($ch, CURLOPT_VERBOSE, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); $response = curl_exec($ch); // We will do some heavy lifting on the server side // parse JSON and send back already prepared html with // only the elements we have to add to fields // $response_decoded = json_decode($response, true); // Give back location name // echo $response_decoded['results']['0']['address_components']['3']['long_name'];
Now once we have back end service in place we are going to amend the main index.js file in our project so it performs jQuery http get request to the back end providing the retrieved device coordinates. After receiving response this code will also populate dedicated <div> element for displaying geo location name. Here is the JavaScript code I have added to the file, detailed explanations follow below
// To retrieve current city name
// based on current device location we
// will use PhoneGap Geolocation API
// and some Google Map API's magic
// Handeling 2 possible outcomes - success and failature
//
navigator.geolocation.getCurrentPosition(onSuccess, onError);
function onSuccess(position) {
// Capturing values for latitude + longitude
//
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
console.log('Received current location: ' + latitude + ',' + longitude);
// Asking maps.googleapis for name of the city
//
var url = 'http://your.server.url/?latitude='+latitude+'&longitude='+longitude;
$.get(url, function(data) {
// Add results to HTML
//
$("#locationplaceholder").html("<div id='location'>Your current location is:<br /><strong>"+data+"</strong><br />Choose food wisely!</div>");
// Log received content
console.log("Location = " + data);
});
}
// onError Callback receives a PositionError object
//
function onError(error) {
console.log('Received geolocation error. code:' + error.code);
console.log('Received geolocation error. code:' + error.message);
}
Above code is already commented out (Its a good habit to spend some time to comment what your code is doing. saves time in the long run). We first retrieve coordinates through PhoneGap API, next performing http get request to selected back end server (replace this url with the one of your server containing back end php script). On successful response we update <div id="locationplaceholder"> element in the main index.html interface file. If we fail to retrieve position coordinates from the device onError function just logs error to the console. You can perform more advanced actions in this place if needed. After launching application now we can see the our current location.

Once application is launched in most cases the first initial screen your users will see will be splash screen. As developer you can enable or disable this screen in your projects. Sometimes you will need it to be displayed for a longer then default time frame. In PhoneGap projects Splash screen is shown by default so you just have to replace default image files in Resources/splash project directory.
navigator.splashscreen.hide(); navigator.splashscreen.show();
And a little trick for keeping Splash screen on a screen a little longer (you will have to set AutoHideSplashScreen option in config.xml to false)
setTimeout(function() {
navigator.splashscreen.hide();
}, 2000);
For our project I have just replaced default PhoneGap image to the Yummy Things splash screen image. I have also replaced mobile application icon (for standard and retina displays) in Resources/icons project directory. These are the icons your users will see on their mobile home screens. Application icons are one of the main criteria for users to select application from app store. Make sure it stands out. As for Yummy Things I quickly created simple icon with Yum on it. Now once install on the simulator or iOS powered device our application has custom icon and splash screen.

With this done we can call our example application done. I hope these bones can serve as a starting point for your own applications built using PhoneGap mobile app development framework. At PopularOwl I’m currently working on one PhoneGap based project which consumes data from WordPress powered eCommerce site. Its an interesting experience and I’m planning to share it with you in the one or two posts here on htmlcenter site soon. Stay tuned!
As a finishing note to these tutorial series I want to mention few things about PhoneGap project architecture and debugging.
Mobile apps developed with PhoneGap framework are not your standard web apps. Yes, they are using HTML5 markup, JavaScript and CSS for styling but the content lives mostly on users mobile device as applications have to be functional offline as well as online. This means there is no remote web server to serve your pages. And mobile device is not your friend once it comes to reproduce web server behavior. So what do we do in complex PhoneGap mobile apps? The architecture is usually to have only one entry html page and add / remove markup from it by using JavaScript. JavaScript also creates transition effects and routing management (what content gets loaded once user goes to specific pages).
Debugging PhoneGap projects is actually not so straight forward. As the project runs in webview you will not get much out of native mobile OS debugging tools. You can log events in console (I did it in our example application) but in order to insert break point, stop the code and find what values are set you will have to use some sort of remote debugging solution. Weinre can be your friend here and debug.phonegap.com had its installation running. The idea is to insert specific JavaScript code into your application which will send information to remote server and you can see it through separate web interface. Quite a painful process.
Another option is to architect your PhoneGap mobile application so it its runnable on any web browser. This way you can use browser inbuilt tools for debugging. By designing your application to run in standard web browsers I mean make its life not dependent on specific PhoneGap APIs. For example before accessing any not native JavaScript API make sure it is accessible
function showAlert {
// Are we wraped with
// PhoneGap or running
// in the browser?
//
if (navigator.notification) {
navigator.notification.alert(message, null, title, 'OK');
} else {
alert(title + ": " + message) : message);
}
}
If you want to better understand PhoneGap application design I would strongly recommend video presentation by Christophe Coenraets.
Several other useful links to keep you going. Template frameworks for PhoneGap applications (allows you to dynamically load html markup and keep it organized in separate files) – Mustache.js, Underscore.js. For front end check out Ratchet and TopCoat CSS frameworks.
Finally you can find the source code for mobile app we have created during 4 tutorial parts on GitHub. This is by no means completed application but it might (and I hope it will) give you some thoughts and push to create and publish your own PhoneGap based applications. As always comments, questions and suggestions are welcome.
Read More >
In the part one and part two of this tutorial we have discussed what PhoneGap mobile application framework is, its key components and elements. We have created a new PhoneGap mobile app project for iOS platform and started adding code for most used mobile application components. First such functionality was a communication with remote web services and 3rd party API’s through HTTP protocol by using jQuery library. Our mobile application has got a minimalistic and nice looking design created by using HTML5 markup and CSS styling.
In this part of the tutorial we will be adding data storage functionality and native application controls. Yes, native iOS controls so our PhoneGap based mobile app has a native look and feel native to its users. Such possibility to add native elements to PhoneGap hybrid mobile applications is one of the biggest strengths of this framework.
I’m going to be working with the code from the last tutorial part (you can find it on the bottom of the previous tutorial page). And the link to completed source code of today’s tutorial can be found at the end of tutorial. Lets get started.
First we are going to write a code to store last keyword that was used for search on the mobile device and retrieve it (for refilling search text box) once user launches application next time.

We have 2 main options available to us in order to store data while using PhoneGap framework. One is SQL Lite database another one is local storage / session storage.
SQL lite based storage is quite a powerful option allowing application developers to interface database with SQL language meaning that your application can perform advanced searches and various analytic on the data stored in the database. The syntax of creating and communicating with such database by using PhoneGap API is the following
var localDatabase = window.openDatabase(database_name, database_version, database_displayname, database_size);
In your code you provide database name, version, display name and size. After database is created / accessed you get back database object and do interaction with it via db.transaction() method. For more information about SLQ lite implementation in PhoneGap projects check the documentation page.
Another method of storing data is local (session) storage. Its much simpler and is usually used to keep small amounts of data between application launches. Local storage in HTML5 world is the way to store data locally within the browser filesystem. This replaces storing data in cookies as faster and more secure approach. You do use key value pairs to store the data. Example implementation in PhoneGap app would be
window.localStorage.setItem("key", "value");
Session storage is similar to the local storage but data gets cleared after each browser session (once browser stops running).
For our application we are going to use local storage option and will save the last search keyword provided by user in order to populate search field next time our application is started. This data will be kept available for us in between application launches (after app is fully stopped by user). First we have to update our callWebService() function with the code to retrieve search term and store it locally
// Storing value in the local storage
var searchTerm = $("#question").val();
window.localStorage.setItem("searchTerm", searchTerm);
var question = window.localStorage.getItem("searchTerm");
And now once we have this value stored our application can ask jQuery to update search text input field on application start.
// Getting last used search keyword and updating input text field
var lastSearch = window.localStorage.getItem("searchTerm");
$("#question").val(lastSearch);
Our application will pre populate the last search keyword used by user in the text field with id="question" to remind application user what item he / she searched for the last time they viewed this page. I’m sure you can think of many more applications for such storing user data via PhoneGap storage APIs. Note that if you don’t want to keep locally stored data after application is closed use window.sessionStorage instead. Full source code of my main index.html file after changes are made
<!DOCTYPE html>
<!--
YummyThings app
index.html
Created by Saul Zukauskas @sauliuz
PopularOwl Labs // www.popularowl.com
@16.04.2013
-->
<html>
<head>
<meta charset="utf-8" />
<meta name="format-detection" content="telephone=no" />
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
<link rel="stylesheet" type="text/css" href="css/index.css" />
<title></title>
<script type="text/javascript" src="js/cordova-2.6.0.js"></script>
<script type="text/javascript" src="js/index.js"></script>
<script type="text/javascript" src="js/jquery.js"></script>
</head>
<body>
<script type="text/javascript">
$( document ).ready(function() {
// Getting the last used search keyword
// and updating the input text field
var lastSearch = window.localStorage.getItem("searchTerm");
$("#question").val(lastSearch);
// Once share class button clicked we will
// show content class element on the screen
$(".share").click(function (e) {
$('.content').toggleClass('show');
e.preventDefault();
});
});
</script>
<script type="text/javascript" charset="utf-8">
function callWebService(){
// We don't want API call to be made everytime
// button is clicked. Only if no data loaded or
// search keyword has changed
if ($('#yummy').is(':empty') || window.localStorage.getItem("searchTerm") !== $("#question").val()){
// Adding spinner image until we will get response
$("#yummy").append("<img class='spinner' src='img/loadinfo.net.gif' />");
// Storing value in the local storage
var searchTerm = $("#question").val();
window.localStorage.setItem("searchTerm", searchTerm);
var question = window.localStorage.getItem("searchTerm");
// Log
console.log("Question value from textfield: " + question);
//create the request url
var url = "http://your.test.server.url/?q=" + question + "&requirePictures=true";
// Log
console.log("Request string: " + url);
// Call to web server
$.get(url, function(data) {
// Clear spinner
$("#yummy").empty();
// Add results to HTML
$("#yummy").html(data);
// Log received content
console.log("Received string: " + data);
}
);
} // end if
}//end of method
</script>
<div id="menu">
<input id="question" type="text"></input>
<div type="button" onclick="callWebService()" id="webservice_call">Find recipes</div>
<div id="yummy"></div>
</div>
</body>
</html>
By using PhoneGap local storage API we have started to actually interfere with the native elements of iOS (in our case this was data stored within the WebKit component). How PhoneGap does that? And how can we add some native controls like navigation bar on top of our view?
PhoneGap framework has 3 parts to it. Native core which is written in the native language for a specific mobile OS (Objective-C for iOS, Java for Android etc.). JavaScript API implementation file which exposes JavaScript functions to be used in the html files and maps these functions to a PhoneGap core. And a JavaScript code which you write in the mobile application html files (served from www directory) and which can use all the functions described in JavaScript API implementation. This is one of the key features which make PhoneGap hybrid application framework very powerful.
And the good news are – developers can extend PhoneGap core with custom plugins. This is done in the similar manner I have described above: implementing the needed functionality in the native code, creating a JavaScript file which maps native code with JavaScript functions and just using these functions in your code. And the beauty of open source is that developer community is always helpful and willing to share their knowledge. There are many of PhoneGap plugins already crated by PhoneGap and the developer community.
In our tutorial I will not make you code in Objective-C and we are going to use plugin which I wrote few weeks ago inspired by couple of other PhoneGap native iOS plugins out there. This plugin has 6 files and below are the instructions where to import them.
First 5 PhoneGap plugin files go to our projects plugins directory

Remaining NavigationBar.js file goes into our projects main js folder. You can find and download all above plugin files from the GitHub repository.
After all files are imported into the project whats left is to add JavaScript code to our main index.js file for setting up navigation bar
// Will load Cordova iOS plugin
// to get native navigation bar
var navBar = cordova.require("cordova/plugin/iOSNavigationBar");
navBar.init();
// Create Navigation Bar with style
navBar.create("BlackOpaque");
Now once we have navigation bar in place I have added about.html file and created a function to display about page once about button is clicked on the navigation bar. We have to also manage the title of nav bar based on which page is being displayed and I created JavaScript code for this as well. After all the improvements our index.js code looks like this
// We have to add event listeners to capture main events
// Cordova framework sends us.
document.addEventListener("deviceready", onDeviceReady, false);
//////////////////////////////////////////////////////////
// Functions //
//////////////////////////////////////////////////////////
function onDeviceReady() {
// Log
console.log('Received Event: deviceready');
// Navigation management
//window.sessionStorage.setItem("page", "index");
var activePage = window.sessionStorage.getItem("page");
console.log('Current page: ' + activePage);
// We have to load custom Cordova iOS plugin
// for native controls. Will be used to get custom navigation bar
var navBar = cordova.require("cordova/plugin/iOSNavigationBar");
navBar.init();
// Create Navigation Bar with style
navBar.create("BlackOpaque");
switch(activePage) {
case "index":
navBar.setTitle("Yummy Things");
break;
case "about":
navBar.setTitle("Yummy Things");
break;
default:
navBar.setTitle("Yummy Things");
}
navBar.show();
// Creating and managing
// navigation buttons
// Create right navigation button with a title
switch(activePage) {
case "index":
navBar.setupRightButton("About","",onRightNavButtonClick);
navBar.hideLeftButton();
navBar.showRightButton();
break;
case "about":
navBar.hideRightButton();
navBar.setupLeftButton("Back","",onLeftNavButtonClick);
navBar.showLeftButton();
break;
default:
navBar.setupRightButton("About","",onRightNavButtonClick);
navBar.hideLeftButton();
navBar.showRightButton();
}
// Navigation button actions
// Right button
function onRightNavButtonClick() {
// navigation management
window.sessionStorage.clear();
window.sessionStorage.setItem("page", "about");
window.location = "about.html";
console.log('Performed onRightNavButtonClick' + activePage);
}
// Left button
function onLeftNavButtonClick() {
window.sessionStorage.clear();
window.sessionStorage.setItem("page", "index");
window.location = "index.html";
// navigation management
console.log('Performed onLeftNavButtonClick');
}
}
There are additional functions in the code to handle button clicks and I’m using the session storage (remember, we just talked about it earlier) to keep the track on which page mobile application user currently is. After compiling and launching Yummy Things application in the simulator we have navigation bar and the about button in place. These are native controls, the same you get while developing mobile application natively.

With this bit done we are now closing to the end of these tutorial series with only the last part left.
You can progress to the last part of tutorial, where I’m implementing Geo location API, delayed splash screen, mobile application launch icons and talking a little bit about PhoneGap application debugging and architecture. I’m always looking for comments and suggestions, if you have any leave them in the comments under this post or get in touch directly. As always you can get most recent tutorial source code in the compressed format. Have fun!
Read More >
In the part one of these series we have checked what PhoneGap mobile application framework is, downloaded its latest version and have created our initial first project for iOS smartphone platform. I have also outlined frame for example mobile app we are going to build and the set of web APIs that we will be using to make this example application somewhat useful for its users.
In this part of the tutorial we will take a closer look to PhoneGap framework structure, its main files and will write code to consume data from the web based APIs. Lets call it slightly advanced “Hello World” example which instead of printing just simple text will display 5 yummy receipts retrieved from external web service.
We will continue working on the code of the initial project created in the part one of this tutorial. You can follow the steps we took last time, they are quite simple.
As we have much more code in this part, the all source code for today’s finished tutorial is located at the bottom of the post. Feel free to download and use it for testing. Now, lets get started.
Let’s take a look at the structure and contents of the project created by PhoneGap script. Open the project with XCode (key tool for developing iOS based mobile applications). The structure will look the same as I have pictured below, with the key files for iOS project as well as PhoneGap specific www directory and few configuration files.
For iOS apps main.m objective-c implementation file represents the main loop application is constantly running. From the contents of this file we see that AppDelegate is being referenced as a main controller. Quick view to AppDelegate.m implementation file shows us that it sets some configuration parameters for the mobile project. Cache size, window size, splash screen, default start page for view controller (project default is always index.html) and other properties. The main directory where all application files have to be placed is www and they will be served via special custom view (web view).

At this time we don’t need to touch anything in the project setup, as we are quite happy with default settings and index.html being the start view for our mobile application. And in PhoneGap world its preferable to change settings via config.xml (it lists plugins and preferences for specific project) as opposed to tweaking objective-c implementation files.
Next we take a closer look at the source of main project file index.html as this is our start view. We see standard HTML5 markup code and the most interesting portion of the code where we are importing JavaScript files.
<script type="text/javascript" src="cordova-2.6.0.js"></script> <script type="text/javascript" src="js/index.js"></script> <script type="text/javascript"> app.initialize(); </script>
We need cordova version specific .js file as well as index.js. These 2 are providing all the functionality to the project. JavaScrip file with Cordova version in the name is warping up all PhoneGap framework code written in OS native language and enables JavaScript APIs for our use. index.js file is implementing these APIs. app.initialize(); for example is the call to function created in index.js:
var app = {
// Application Constructor
initialize: function() {
this.bindEvents();
},
// Bind Event Listeners
//
// Bind any events that are required on startup. Common events are:
// 'load', 'deviceready', 'offline', and 'online'.
bindEvents: function() {
document.addEventListener('deviceready', this.onDeviceReady, false);
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicity call 'app.receivedEvent(...);'
onDeviceReady: function() {
app.receivedEvent('deviceready');
},
// Update DOM on a Received Event
receivedEvent: function(id) {
var parentElement = document.getElementById(id);
var listeningElement = parentElement.querySelector('.listening');
var receivedElement = parentElement.querySelector('.received');
listeningElement.setAttribute('style', 'display:none;');
receivedElement.setAttribute('style', 'display:block;');
console.log('Received Event: ' + id);
}
};
Above is the code from index.js and its quite self explanatory. During the initialize phase we have to bind to events and assign functions to be executed once these events fire. The full list of supported events can be found in PhoneGap documentation. At this time we only are interested in deviceready event and are going to come back to this part of code later to catch events once our mobile application will go to background state, will be retrieved from background state or will loose internet connection.
According to PhoneGap documentation deviceready event is fired once PhoneGap has fully loaded all required code, DOM and JavaScript. After this event we know that app PhoneGap JavaScript APIs are fully available to use.
As a test lets add simple alert message to our iOS application which is displayed once application is started and PhoneGap JavaScript API are ready. For this we need to make sure that config.xml has Notification plugin enabled (by default it does) and add the following code to index.js to receivedEvent section after deviceready has fired.
// Callback function for dismissed alert
function alertDismissed() {
// do something
}
navigator.notification.alert(
'DOM and JavaScrip have loaded!!', // message
alertDismissed, // callback
'YummyThings Hello World', // title
'I know' // buttonName
);
If you run your project now it will display alert once application is fully loaded and ready to function.
More about elements for notification.alert you can read in documentation section.
Now once we have some understanding about the key elements of PhoneGap based mobile application lets add functionality for consuming web API based data and for displaying received information.
Being able to communicate with web based servers and devices is now becoming the key requirement for any useful mobile application. In the part 1 of this tutorial we decided to use Yummly.com API’s for retrieving recipes based on the ingredients our mobile application users like.
Consuming data from 3rd party web services in most cases requires to obtain API credentials and authenticate your API calls by using them. Therefore its a common security practice for mobile app developers not to store such API credentials in the actual mobile application.
In our project we are going to do just that. In the simplified way for this tutorial (but before you go live with your project, make sure your server side code runs securely). I have created the following simple PHP script to represent your server side code.
<?php
// Get what's being sent to us
if ($_GET['q']) $question=$_GET['q'];
if ($_GET['requirePictures']) $rpictures=$_GET['requirePictures'];
////////////////////////////////
// API credentials /////////////
// TODO: please obtain API credentials form developer.yummly.com
$appid = "xxx";
$appkey = "xxx";
// Number of itens in response
$returnitems = 4; //will give us back 4+1=5 items
// Building string for GET request
$requeststr = "http://api.yummly.com/v1/api/recipes?";
$requeststr=$requeststr."_app_id=".$appid;
$requeststr=$requeststr."&_app_key=".$appkey;
$requeststr=$requeststr."&q=".$question;
if ($rpictures) $requeststr=$requeststr."&requirePictures=".$rpictures;
// Debug
//echo $requeststr
// CURL for communicating with web service
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$requeststr);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
$response = curl_exec($ch);
// We can do some heavy lifting on the server side
// and send back already prepared html from only the elements
// we need.
$response_decoded = json_decode($response, true);
$returnstring = "";
for ($i=0; $i<=$returnitems; $i++) {
$returnstring = $returnstring."<p><img src='".
$response_decoded['matches'][$i]['smallImageUrls']['0']."' />Recipe Name: ".
$response_decoded['matches'][$i]['recipeName'].", it has ".count($response_decoded['matches'][$i]['ingredients'])." ingridients.</p>";
}
echo $returnstring;
?>
If you are not a PHP guru, what this code does – it accepts incoming request from mobile client (with the list of ingredients – no sensitive data being sent over the network), uses received data to make a API call to 3rd party web service, parses received JSON response and returns 5 results wrapped into HTML markup code (not bad for PHP 60 liner, huh?). Feel free to copy this code to your server, or write similar functionality in the programming language you know best. The beauty of web services is that functionality is not dependent on programming language being used.
Next is our PhoneGap mobile application code. We have to make a HTTP call to our back end server, pass the values of ingredients selected by app user and receive prepared markup with number of responses. We are going to employ one of the most popular JavaScript libraries to do this work for us. I’m talking about jQuery library which is much loved by many web developers and makes great fit for hybrid mobile applications. Download the library and add it to your project by importing in index.html
<script type="text/javascript" src="js/jquery.js"></script>
The following code is added to main index.html file
<script type="text/javascript">
app.initialize();
</script>
<script type="text/javascript">
$( document ).ready(function() {
$(".share").click(function (e) {
$('.content').toggleClass('show');
e.preventDefault();
});
});
</script>
<script type="text/javascript" charset="utf-8">
function callWebService(){
// We don't want API call to be made and data refreshed
if ($('#yummy').is(':empty')){
// Adding spinner image until we will get response
$("#yummy").append("<img class='spinner' src='img/loadinfo.net.gif' />");
var question = $("#question").val();
// Log
console.log("Questions value: " + question);
//create request url
var url = "http://your.test.server.url/?q=" + question + "&requirePictures=true";
// Log
console.log("Request string: " + url);
// Call to web server
$.get(url, function(data) {
// Clear spinner
$("#yummy").empty();
// Add results to HTML
$("#yummy").html(data);
// Log received content
console.log("Received string: " + data);
}
);
} // end if
}//end of method
</script>
<div id="menu">
<input id="question" type="text"></input>
<div type="button" onclick="callWebService()" id="webservice_call">Find recipes</div>
<div id="yummy"></div>
</div>
Lets split above code into parts. First I’m using app.initialize() PhoneGap function to initialize all framework JavaScript API’s (even if in this tutorial part we are not really using them). Next I have code which displays drop down menu on the click of the button with id="webservice_call" on the click. This element will not only extend drop down menu, but once clicked will execute another function callWebService(). In it I’m preparing request string to be send to our back end server (by taking input value of text element with id="question"), displaying spinning image until we receive results for our API call and populating drop down list with received values once we get them. I’m using console.log() function in many places to print variable values to the console simply for debugging purposes.
To make our test project UI look beautiful I have reused some of the styles and markup from previous tutorials here on htmlcenter. Once compiled and run this is how our PhoneGap mobile project looks now.


We did a lot of work in this tutorial (well done! for reaching this far) and now have created PhoneGap based mobile application which can consume content from external web servers and display results within iOS view. Similar technique can be used to dynamically change larger portions of mobile application content or styles (load them remotely from your back end if there were any changes made).
This is the end of tutorial part 2. In the next part of this tutorial we are adding even more functionality: Local storage and Native Controls. I’m looking forward for any questions, comments and feedback, you can leave them in the comments area under the post or reach out to me on Twitter.
Full source code for what we have done so far can be found and downloaded here. Have fun!
Read More >
This is the first part of the tutorial. Second, Third and the last tutorial parts can be found by following the links.
After receiving good reader feedback for HTML5 widgets tutorial for iOS digital books today I’m starting with new tutorial for developing hybrid mobile applications with the help of PhoneGap framework (or Apache Cordova wrapper as some people like to call it).
The goal is to create a fully working and somewhat useful mobile application from the ground up. To make things more interesting and useful for our readers I’m planning to implement (and go into technical specs) today’s most used mobile application functions. Web services (the way for client devices to communicate with servers and each other over the World Wide Web network), Authentication (after which mobile applications can consume online resources on behalf of third parties), Geolocation, Maps and on device Storage.
I’m estimating that it will take little bit of time to get to the end of the project and to write everything in blog post format. Therefore I will split this tutorial into several parts and will publish them separately here on htmlcenter. It will make it easier to follow for everyone who is reading as well.
You are much welcome to join the discussion any time by posting comments or asking questions. There is much work ahead so lets get started!
PhoneGap was created at one of iPhoneDevCamp events by Brock Whitten and Rob Ellis and quickly got attention of good few mobile developers globally. Developers who wanted to use HTML5 and JavaScript code in their mobile projects and wanted mobile apps to still be a native mobile applications. Since then PhoneGap was acquired by Adobe who open sourced it as Apache Foundation project named Apache Cordova.
Mobile applications created with PhoneGap are called hybrid mobile apps as they are not fully native but rather are using native web view type elements within mobile application to display app resources. These applications are different from HTML5 based apps running on the web servers as JavaScript code is created for specific set of custom APIs. PhoneGap framework enables set of custom JavaScript APIs to access mobile device native functionality. The source files for mobile application are HTML markup with CSS for styling and JavaScript for interactivity and accessing native mobile functionality.
Such hybrid mobile apps allow developers to use different programming / scripting languages from OS specific one (like Objective C or Java). In this tutorial I want to show you how to create fully working mobile app for both iOS and Android platforms by using mainly the same HTML5, CSS and JavaScript code base. First we are going to create iOS version and later use the same code base for Android based application.
Don’t worry if you are quite new to hybrid mobile application development and all of this doesn’t make much sense yet. I’m sure that once you follow this tutorial further things will start to come together.
At the time of writing this tutorial PhoneGap has over 1200 registered developers in their developer directory. You can also join the developer community and discussion groups but this is not necessary in order to download the recent version of framework. Just go to the download page and get the most recent version of the framework. At the time of writing I have downloaded version 2.6.0.

Once downloaded and unzipped project has several directories in it including documents, change log and actual libraries created for all main mobile operating systems. For our purpose we will need PhoneGap library for iOS devices as the first version of our application will be developed for this mobile OS.
On the official PhoneGap website there is an extensive guide on how to implement PhoneGap library into iOS projects. Based on this guide we need to do the following steps to get started.
Create a new directory for the project. On my development machine I created
~/Documents/Mobile Development/PhoneGap/2.6.0
to keep the track of the PhoneGap version being used. Next we need to run the script from within the downloaded library to create a new XCode project. First navigate to bin directory of unzipped PhoneGap library lib/ios/bin. In the actual script you have to provide package name (unique name which in most cases is reverse url for your company or organization) and project name. Here is the command line I have executed
./create ~/Documents/Development/PhoneGap/2.6.0/YummyThings com.popularowl.phonegap.YummyThings YummyThings
and it has nicely created YummyThings XCode project. Yes, I know, yummy.. But more about this later.
XCode project file was located within newly created YummyThings app directory and after launching it through XCode IDE I have successfully compiled the code. There was one warning however
useSplashScreen is deprecated: Deprecated in Cordova 2.5. Add/Remove the SplashScreen plugin instead of setting this property
It has to do with the use of viewController.useSplashScreen iOS View Controller properties and it seams that PhoneGap wants us to use their specific plugin (hm.. I just used out of the box code). Not a big deal and we can fix this warning later.

In the mean time I have launched application in iPhone simulator and it started nicely. This means we are up and running.

Now then we have our initial iOS app project setup and running with PhoneGap it’s time to talk a little about the application we are going to develop. There is a nice site online called ProgrammableWeb. Its packed with API’s and has big list of them summarized and available to use for developer projects. After some searching I found API provided by Yummly.com folks. On Yummly web site visitors can find recipes for many yummy meals based on ingredients they like. Their API makes it easy to do this search in programmatic way. Sounds like a great fit for our YummyThings mobile application. It will give users an option to choose the ingredients they like, and get a bunch of nice recipes of yummy dishes. We will even store ingredients and recipes on the actual device so app users can view them later or share with their friends. You will need to obtain an API key from Yummly folks in order to work with their API, and there is a free plan with up to 500 API calls per day. More than enough for our sample application.
This is the end of part one. We have looked at what PhoneGap and hybrid mobile applications are, successfully created our initial PhoneGap project for iOS and tested it with XCode and iPhone simulator. Next time we are going to look through the key files in the project, implement functionality for web service communication and consuming data from Yummly APIs. I hope you are looking forward.
If you have any questions or feedback leave them in comments section under the post.
Read More >
Recently I had a chance to take a closer look at relatively new tool for creating interactive iPad tablet reading experiences called iBooks Author. It was released by Apple in January 2012 and is aimed at book authors and publishers to allow for an easy publishing of their books on Apple iBook platform. Application supports its own format .ibooks as well as .pdf and .ePub formats for exporting.
But what really caught my attention was the possibility to embed interactive elements inside actual ebooks. It can be done in the form of HTML5 widgets, with CSS styling and JavaScript support for building interactivity. As it was a good fit for one of interactive digital mobile content projects we will be crafting at PopularOwl and I went through the process of creating and adding HTML5 widget to iBook project to understand how it all comes together.
In this tutorial I’m going to walk you through the steps for building fully working HTML5 widget to be used in iBooks Author projects. This sample widget will help eBook authors to easily add social follow option to their digital books so their readers can interact from within the eBook.
Source code for finished widget project is located at the bottom of this tutorial, feel free to download and test it. The final result:

HTML5 widgets have .wdgt file format and are packaged sets of markup, style, JavaScript and configuration files. Apple recognizes .wdgt type directories as widgets on their OSX operating system and, as we will learn, on some mobile development tools as well. Simply speaking these widgets are just standard directories with additional extensions in their name. Such widget directory must contain certain files in it to work as functioning widget but more about it latter in this tutorial.
As widgets are just simple directories containing HTML, CSS, JavaScript and .plist files there are no requirements to use specific tool to create or edit them. Any text editor will do as long as it can open and edit these file types. I personally use Coda 2 but I’m sure you have your preferences.
For automated HTML5 widget creation Apple have a tool called Dashcode.
But for purposes of this tutorial we are going to create all files manually as we want to understand how widgets are build.
There are 3 required files you have to supply in order to create working HTML5 widget. Main HTML file with .html extension (no naming limitations on this one), Default.png – the image file which will be displayed to users on the eBook page (this has to be named exactly like this and is case sensitive) and Info.plist file for storing widget settings – also has to be named exactly that.
For this tutorial I’m going to use example code of HTML5 dropdown menu which is styled with simple CSS styles and has a little bit of jQuery for interactive part. It looks like this:

HTML5 widgets for iBooks have great support for JavaScript scripting language, its libraries and CSS styles (though I was not able to find exact specifications on any Apple developer sites). In my index.html I have the following markup:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1,IE=9" />
<meta name="viewport" content="user-scalable=yes, width=600" />
<script src="jquery.js" type="text/javascript"></script>
<title>DropDown</title>
<style>
body {
background: #55bed5;
font-family: 'Helvetica Neue';
font-weight: lighter;
}
ul {
margin: 0;
padding: 0;
}
li {
list-style-type: none;
margin:0;
padding: 10px 0;
}
a {text-decoration: none; color:#333;}
p {margin: 0;padding: 0; clear:none;text-shadow: 1px 1px #fff;}
#menu {
width: 260px;
background: #efefef;
margin: 30px 0px 0px 70px;
border-radius: 5px;
box-shadow: 0 10px 0 -3px rgba(0,0,0,.2),0 2px 0 rgba(0,0,0,.1);
-webkit-transform: scale(.8);
-moz-transform: scale(.8);
-ms-transform: scale(.8);
-o-transform: scale(.8);
transform: scale(.8);
-webkit-transition: all .3s ease;
-moz-transition: all .3s ease;
-ms-transition: all .3s ease;
-o-transition: all .3s ease;
transition: all .3s ease;
}
#menu:hover {
-webkit-transform: scale(1);
-moz-transform: scale(1);
-ms-transform: scale(1);
-o-transform: scale(1);
transform: scale(1);
-webkit-transition: all .3s ease;
-moz-transition: all .3s ease;
-ms-transition: all .3s ease;
-o-transition: all .3s ease;
transition: all .3s ease;
}
.share {
text-align: center;
padding: 5px;
background: #ed6b3a;
border-radius: 5px 5px 0 0;
border-bottom: 5px solid rgb(218, 109, 63);
}
.share:hover {
border-bottom: 5px solid rgb(165, 80, 45);
box-shadow:inset 0 -1px 0 rgba(255, 255, 255, .2),
inset 0 1px 0 rgba(255, 255, 255, .2);
}
.content {height: 0;overflow: hidden ;opacity:0;}
.show {
height: 253px;
opacity:1;
}
li {
box-shadow: 0 1px 0 rgba(0,0,0,.1);
position: relative;
padding: 15px;
text-align: center;
}
li img {
padding-right: 10px;
margin-right: 10px;
float: left;
border-right: 1px solid #eaeaea;
}
li:hover {background: rgba(20, 20, 20, 0.1)}
li:hover,.share:hover,.content {
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
-ms-transform: translate3d(0, 0, 0);
-o-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
-webkit-transition: all .6s ease;
-moz-transition: all .6s ease;
-ms-transition: all .6s ease;
-o-transition: all .6s ease;
transition: all .6s ease;
}
.show {
-webkit-transition: all .6s ease;
-moz-transition: all .6s ease;
-ms-transition: all .6s ease;
-o-transition: all .6s ease;
transition: all .6s ease;
}
</style>
</head>
<body>
<script type="text/javascript">
$( document ).ready(function() {
$(".share").click(function (e) {
$('.content').toggleClass('show');
e.preventDefault();
});
});
</script>
<div id="menu">
<a href="#"><div><img src="img/N3osT4l.png" alt=""></div></a>
<div>
<ul>
<a href="#"><li><img src="img/sEKPZan.png"><p>Facebook</p></li></a>
<a href="#"><li><img src="img/wefpyCe.png"><p>Twitter</p></li></a>
<a href="#"><li><img src="img/TIhzUN3.png"><p>Google+</p></li></a>
<a href="#"><li><img src="img/UpTP5kJ.png"><p>Pinterest</p></li></a>
<a href="#"><li><img src="img/IGNnYUg.png"><p>Dribbble</p></li></a>
</ul>
</div>
</div>
</body>
</html>
As you can see this is pretty simple example which requires jQuery library and several images to be present. For our purpose I have downloaded the latest version of jQuery library and packed images in to separate img directory within projects main dir. Now we have to create Info.plist file which is used for storing settings and has its own XML format. If you are new to Apple developer world I recommend you to Google and read more about this specific XML format as you are going to find it in every development project if its to do with iOS / MacOSX. Its not overall complicated. In the mean time here is the content of my Info.plist file
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>AllowNetworkAccess</key> <true/> <key>CFBundleDevelopmentRegion</key> <string>English</string> <key>CFBundleDisplayName</key> <string>DropMenu</string> <key>CFBundleIdentifier</key> <string>com.popularowl.widget.ibook</string> <key>CFBundleName</key> <string>DropMenu</string> <key>CFBundleShortVersionString</key> <string>1.0</string> <key>CFBundleVersion</key> <string>1.0</string> <key>Height</key> <string>400</string> <key>MainHTML</key> <string>index.html</string> <key>Width</key> <string>400</string> </dict> </plist>
Its quite self explanatory as each setting has a name and the corresponding value. In order to create Default.png image I took a print screen of HTML5 menu example displayed by the web browser. One note here: if you haven’t declared the widget size in your Info.plist file (we did) the dimensions of Default.png image will be used as the size for your widget. Make sure you are specifying the right height and width for your project.
Once all files are created we need to add extension .wdgt to project directory. This is done by simply renaming directory (MacOSX will ask you to confirm and you just say yes).
Whats left now is to open iBooks Author application, start the new eBook project and choose to insert widget from the top menu. Once you get dialog window there will be some pre made widgets as well as HTML option at the bottom of the list. Once selected it will give you a container within iBook where you can drag & drop your newly created widget. You should now see a preview of functioning dropdown menu. Connect your test iPad device, hit preview and welcome to interactive eBooks world.
HTML5 widgets are simple way to make digital eBooks more interactive. In my opinion the strong side is that you can reuse HTML5 and JavaScript content from other mobile or web projects you worked on with simply adopting already existing code to the screen size etc. And of course remember that eBook is not a smartphone game, so be cautious with overloading it with to much interactivity.
Source code for sample widget can be found here.
Read More >
For those of you using WordPress, GravityForms can be a real godsend. GravityForms is a premium plugin that makes it extremely simple to create forms on your website. However, there are a few features that aren’t quite built out the way they probably should be, yet.
One of those features is the ability to stop people from submitting forms with duplicate values. While this feature is extremely useful the way it’s currently implemented when it comes to duplicate entries for people’s names, email addresses, etc., it’s not overly useful when it comes to select elements, radio buttons and checkboxes. As it is currently implemented, all of the options are still available for the user to select when filling out the form, but when they submit the form, they get an error message indicating the option has already been selected.
With the use of some GravityForms filters, though, you can make things slightly more usable.
In my particular instance, I wanted a group of radio buttons to be available, and I only wanted one person to be able to select each option (the form is a registration form for a party; and the radio buttons are items that the attendees are volunteering to bring to the party with them).
I set up the form with radio buttons, checked the “Enable Values” checkbox and the “No Duplicates” checkbox for that field (along with the “Required” checkbox), gave each radio button a unique value, then saved the form. As far as setting up the form, that’s all I needed to do. The next steps have to be taken outside the scope of the form.
In my case, it’s helpful to keep all options visible on the form, but make it so that the options that have already been chosen can’t be selected. Either way, the basic steps are the same.
For my purposes, I found it simplest to implement these changes as a mu-plugin, but there’s no reason you can’t implement the same functionality using your theme’s functions.php file, or even writing your own plugin. Since this particular implementation is extremely temporary (it only needs to be in place for a week), there was no need for me to write a full-fledged plugin or to even modify my theme. You can take whichever route makes the most sense for your implementation.
To start with (since I was taking the mu-plugin route), I hooked into the plugins_loaded action to make sure GravityForms had been instantiated before I did anything. That looks like:
add_action( 'plugins_loaded', 'jwsf_gform_filters' );
function jwsf_gform_filters() {
if ( ! is_admin() )
add_filter( 'gform_field_content', 'jwsf_form_choices', 1, 5 );
}
Basically, that code just tells WordPress to wait until the plugins have been loaded, then hooks into the gform_field_content filter to filter out the choices that have already been selected.
Next, I wrote the jwsf_form_choices function that looks something like:
function jwsf_form_choices( $content, $field, $value, $lead_id, $form_id )
{
/* Check to make sure we're on the right site
Only necessary if you're using multisite
Change the "1" to the ID of your site
*/
global $blog_id;
if ( 1 !== (int) $blog_id ) return $content;
/* Check to make sure we're loading the right form
Change the "2" to the ID of the form you're modifying
*/
if ( 2 !== (int) $form_id ) return $content;
/* Check to make sure this is the field we want to filter
Change the "3" to the appropriate field ID
*/
if ( 3 !== (int) $field['id'] ) return $content;
/* Retrieve a list of the options that were already selected */
global $wpdb;
$tablename = $wpdb->prefix . 'rg_lead_detail';
/* Change the "2" to the ID of your form
Change the "3" to the ID of the field
*/
$values = $wpdb->get_col( $wpdb->prepare( "SELECT value FROM $tablename WHERE form_id=%d AND field_number=%d ORDER BY lead_id", 2, 3 ) );
/* Loop through all of the options available in this field
If that choice has already been chosen by someone else,
add a "readonly" and "disabled" attribute to the input,
and make the label strikethrough
*/
foreach ( $field['choices'] as $k => $f ) {
if ( ! in_array( $f['value'], $values ) ) continue;
$content = str_replace( array( "value='{$f['value']}'", "for='choice_{$field['id']}_$k'" ), array( "readonly disabled value='{$f['value']}'", "style='text-decoration: line-through' 'choice_{$field['id']}_$k'" ), $content );
}
/* Return the filtered content of the form field */
return $content;
}
There are a few areas in the code above where you need to make your own modifications (your blog’s ID within your multisite installation, the ID of the form as indicated by GravityForms, the ID of the field within that specific GravityForm, etc.). Also, as mentioned above, this code simply disables the radio buttons for items that have already been selected, and then adds some CSS to make the label strikethrough. If you want to actually remove the options from the form so they don’t show up at all, you’ll probably need to run a regexp or something to actually delete that portion of the content.
Read More >
Andrew Holden is co-founder and Chief Experience Officer (CXO) at Weever Apps. Andrew is a web development expert and frequently writes about mobile visitor engagement and online best practices.
HTML5 is everywhere this year! Google supports it. Facebook’s all over it. It’s clear that HTML5 is the future for mobile.
Ok, that’s cool. So what is HTML5 and what does it do for mobile?
Great question! HTML5 is the latest version of HTML – the standard for presenting and structuring content on the World Wide Web. One of the great advancements with HTML5 is that it allows websites to function like mobile apps by offering design capability that is mobile friendly, as opposed to laptop/desktop friendly. This means websites can be designed to fit mobile screens and have a user interface that is easy to control and highly functional with a touch screen. The term used for this technology is “web app”.
For practical purposes, there are two ways to implement a “web app”.
This new approach of presenting mobile content is breaking down barriers – including time, money, and the ubiquitous App Store. The doors are now being opened to individuals and small business. Big players are also gravitating to this alternative as they recognize the benefits.
Here are the facts about the mobile market: 50% of all local searches are now on mobile devices. This is largely due to smart phone ownership surpassing cell phone ownership in the US and other countries. Despite this notable adoption, most businesses don’t have any mobile solution of any kind – let alone the subsequent marketing benefits. Unfortunately, traditional app development is just too time-consuming, expensive, and technical.
So without further ado, here are five reasons why HTML5 is going to keep growing in a big way:
1 – It’s not about iPhones. It’s about ALL phones.
For all the buzz Apple iPhone generates, it only represents 25% of the market. Google Android is the market leader with 50% of the Smartphone market in North America and BlackBerry does surprisingly well with tablet sales. Web apps work for all popular touch phones and tablets – letting you to connect to every customer. That’s not just a good thing – that’s business-critical.
2 – It’s affordable.
HTML5 web apps run for about half the price and half the time to market compared to native (machine-code based) apps. Building native apps can also be a nightmare. Let me repeat that – an expensive, time-consuming, nightmare. Building one-mobile-platform (iPhone, Android, Blackberry, Windows Mobile, iPad, the list goes on…) just isn’t a workable solution for most companies. And it gets worse because…
3 – Things change. Your Business will Change.
Imagine you’re a business owner and its six months after your new machine app has launched – your business and customers have changed a little; and you need to make an update. Good luck! Start tracking down the development team, get your marketing and sales folks involved again, and get ready to pay them all again. Then, resubmit to the app store… and wait.
Web apps can reflect your organizations’ updates quickly. Like a website, changes can be implemented instantly. There’s just no comparison to a mobile solution that allows a business to be responsive to priorities and needs in real-time.
4 – Location, Location, Location.
Proximity is one of the best indicators for interest, relevance, customer purchases – you name it. Web apps have the capability to provide location-based services, like informing users with nearby points of interest and enabling users to tag content (i.e. photos and notes) to specific locations.
5 – Your Brand is Web Wide and Social. Your app should be too.
What is a web site anyway? It’s a location where your business/brand/persona lives online. Except that it’s not just that way with the modern web anymore. Brands, people and products exist across the entire web – on Twitter, Facebook, Yelp, Tumblr and hundreds (if not thousands) of other services. Today, that’s where connections are made, products and people are found, and new ideas grow.
Web apps are made to work and live with other elements of your brand on the web – allowing you to connect to your existing customers, find new ones, or just share ideas in every way possible. Web apps excel, appropriately enough, at working with other web applications.
That’s just year one folks; wait till you see what’s coming next!
Read More >
More than likely, you probably haven’t noticed, but Windows Phone 7 devices don’t fully support media queries (used mostly for responsive and adaptive designs). However, media queries can be used for designs presented on Windows Phone, you just have to know how to do it.
For the most part, I have seen designers and developers include media queries within their stylesheet(s). Windows Phone 7 will ignore media queries directly in your CSS. Instead, you have to set up separate stylesheets for each media query. For instance, rather than having the following code in your main stylesheet:
@media screen and (max-width:640px) { header { background: #f00; } footer { background: #00f; } }
You need to separate those style definitions out to a separate stylesheet. Then, use the media query within the <link> element that calls that stylesheet. That <link> element would look something like:
<link rel="stylesheet" href="style-640.css" media="screen and (640px)"/>
Then, your stylesheet would just have the following code inside of it:
header { background: #f00; } footer { background: #00f; }
There are definitely pros and cons to loading separate stylesheets for various media queries as opposed to including all of your rules within a single stylesheet. Following are some of the items you may want to consider:
If you decide that the cons outweigh the pros, you can target IE specifically, allowing all other browsers to use the comprehensive stylesheet. To accomplish this, you would simply use conditional IE comments. You can simply target any version of IE by using a simple conditional comment like:
<!--[if IE]> <link rel="stylesheet" href="style-640.css" media="screen (and max-width:640px)"/> <![endif]-->
I’ve been told (though I haven’t yet tested) that you can use conditional comments to specifically target IEMobile. That would look like:
<!--[if IEMobile]> <link rel="stylesheet" href="style-640.css" media="screen (and max-width:640px)"/> <![endif]-->
Finally, if you’d like to set something like this up in your WordPress theme, you can do so pretty easily. One of the parameters accepted by the wp_enqueue_style()/wp_register_style() functions is the “media” for the stylesheet. Most people use this simply to specify whether the stylesheet should apply to “all”, “screen”, “print”, etc.; but that’s the same place you can put in the query. That call would look something like:
wp_register_style( 'max-width-640', get_bloginfo( 'stylesheet_directory' ) . '/style-640.css', array(), '0.1', 'screen and (max-width:640px)' );
If you would then like to set that up so that it only gets called for IEMobile, if you’re using the wp_register_style() method, you can tell WordPress to wrap a stylesheet’s <link> tag within conditional comments. To do that, you would use the add_data() method for the $wp_styles object. That code would look something like:
global $wp_styles;
wp_register_style( 'max-width-640', get_bloginfo( 'stylesheet_directory' ) . '/style-640.css', array(), '0.1', 'screen and (max-width:640px)' ); $wp_styles->add_data( 'max-width-640', 'conditional', 'IEMobile' );
Read More >
The other day, I was in the process of setting up some custom post meta for an event post type. I needed to add a start date/time and an end date/time for the event as custom meta information. Once I got all of that set up, I needed to modify the loop so that it retrieved the events in order of their start date/time; but I also needed to make sure I only retrieved events that hadn’t yet ended (based on their end date/time).
In the past, this wasn’t really possible with WordPress. You could either order posts by a custom meta value, or you could limit your query to posts that had a specific custom meta value, but you couldn’t do both. Then, in version 3.1 of WordPress, the meta_query was introduced to the WP_Query class. Now, however, you can use the traditional orderby and meta_key properties to sort your posts by a specific meta value; and you can use the meta_query property to limit the posts that are returned.
In my case, wanting to sort the posts in ascending order according to the start date/time (which is stored in the MySQL datetime format of YYYY-MM-DD HH:MM:SS) and wanting to limit the posts to items that had an end date/time that had not yet occurred, I used the following properties:
array(
'orderby' => 'meta_value',
'meta_key' => '_event_start',
'order' => 'ASC',
'meta_query' => array(
array(
'key' => '_event_end',
'value' => current_time( 'mysql' ),
'compare' => '>=',
'type' => 'DATETIME',
),
),
);
If you need to sort your posts according to a numerical value, you should use meta_value_num as your orderby property instead of using meta_value. For instance, if I was storing the start and end date/times as Unix timestamps instead of MySQL datetime values, I would have needed to use meta_value_num to get them back in the correct order.
Whenever you’re working on a new WordPress theme that includes hover (mouseover) effects, especially dropdown or flyout menus, you might want to include hoverIntent. HoverIntent is a term that describes a concept through which you delay a hover action until a certain amount of time has passed, in order to make sure that the user really intended to trigger that action.
We’ve all been on websites with dropdown menus that tend to get in the way of the content, and pop open as soon as your mouse touches even a small portion of them, and we’ve most likely all been annoyed by it. The idea behind hoverIntent is to measure the speed of the mouse movement, attempting to determine whether the user actually intended to stop on the item or not. If the mouse just moves over an item with a hover effect, but doesn’t stop on it, the hover effect should not be triggered; if, however, the user’s mouse does slow down enough or stop on the item, the hover effect should be triggered.
Back in 2007, Brian Cherne submitted the first version of a jQuery plugin attempting to fix this issue. The plugin was called hoverIntent, and has become somewhat synonymous with the usability concept discussed above.
The WordPress gang was actually fairly quick to pick up on this, and began including Brian’s hoverIntent plugin in the WordPress core when WordPress 2.7 was released. That’s right, hoverIntent has been part of the WordPress core since December 2008.
However, until version 3.3 of WordPress, the hoverIntent script was only registered in WordPress from within the admin area; it wasn’t readily available (without using wp_register_script() to register it yourself) on the front-end. As of version 3.3, though, the registration of hoverIntent was moved outside of the admin area so that it is easily available throughout a WordPress site, on the front-end and back-end.
To use hoverIntent, you simply need to enqueue it by using wp_enqueue_script( 'hoverIntent' ) or even by including the handle ‘hoverIntent’ in the list of dependencies when registering your own script file in your theme or plugin.
Then, if you want to actually apply hoverIntent to an element in your theme or plugin, you simply need to call it from within your JavaScript. To use hoverIntent, you simply call jQuery( [selector] ).hoverIntent( [over-callback], [timeout], [out-callback] ).
Normally, for accessibility purposes, you should use hoverIntent as an enhancement for normal hover effects, ensuring that the hover effect doesn’t stop working altogether if JavaScript fails. Therefore, you probably want to include a default hover effect that occurs without JavaScript, then add a delay to that effect with the hoverIntent method.
To do that, though, you’ll need to use some JavaScript to determine whether or not JavaScript is active on the page. Usually, you do this by adding a CSS class to the body element that then gets removed by JavaScript.
For instance, the initial HTML for your body element might look like:
<body class="no-js">
Then, within your JavaScript file (assuming you have jQuery enabled, which is required in order to use hoverIntent), you would add a line that looks something like:
jQuery( function( $ ) {
$( 'body' ).removeClass( 'no-js' );
} );
Then, your CSS would look something like:
a:focus,
.no-js a:hover,
a.hover {
text-decoration: underline;
}
and your call to hoverIntent would look like:
$( 'a' ).hoverIntent( function() { $( this ).addClass( 'hover' ); }, 100, function() { $( this ).removeClass( 'hover' ); } );
Now, normally you wouldn’t use hoverIntent to simply add or remove an underline from a link; but the concept remains the same no matter what hover effect you’re applying.
Read More >