Build a Location-Based Mobile App With HTML5 & Javascript: 3

Share this article

In the previous part of the series, I showed you the code of all the HTML pages of “Where I parked my car”. However, so far they are useless because we’ve not written the business logic behind them. In this article, we will start adding the few configurations lines of jQuery Mobile to the project, and then I’ll continue explaining some of the JavaScript files that power the application, as well as describing several Cordova APIs.

jQuery Mobile Configuration

jQuery Mobile does a lot for you just by adding it to your project without any special settings. However, there will be times when you want to modify or to take control of some default behavior. You can achieve this writing a configuration file. As stated in the first part of the series, the app has a file called jquery.mobile.config.js that, as you might guess, contains a configuration for jQuery Mobile. The most observant of you might have noticed that in the index.html file, the configuration is loaded before the library. You have to do so because when jQuery Mobile starts, it fires an event called mobileinit, and this is also the event you have to bind to override the default settings. Hence, you have to attach the handler before jQuery Mobile starts, but after the jQuery library. You can override the default configuration in two ways. The first is using the jQuery extend() method as you can see in the following example.
$(document).bind('mobileinit', function() {
  $.extend($.mobile , {
    property1: value1,
    property2: value2
    // and so on...
  });
});
The second way is to set the properties using the $.mobile object.
$(document).bind('mobileinit', function() {
  $.mobile.property1 = value1;
  $.mobile.property2 = value2;
  // and so on...
});
Explaining all the jQuery Mobile properties is outside the scope of this article, however you can study them in deep detail by reading the jQuery Mobile configuration docs. In the app configuration file, I won’t change a lot of properties. I’ll focus on changing the pages’ transition, the option to show the text when showing the page loader widget, and the theme. The full source of the file (that uses the second method to set jQuery Mobile properties) is listed below.
$(document).on(
  'mobileinit',
  function()
  {
    // Default pages' transition effect
    $.mobile.defaultPageTransition = 'slide';

    // Page Loader Widget
    $.mobile.loader.prototype.options.textVisible = true;

    // Theme
    $.mobile.page.prototype.options.theme  = 'b';
    $.mobile.page.prototype.options.headerTheme = 'b';
    $.mobile.page.prototype.options.contentTheme = 'b';
    $.mobile.page.prototype.options.footerTheme = 'b';
    $.mobile.page.prototype.options.backBtnTheme = 'b';
  }
);

The APIs

From this section on, I’ll start describing the APIs used throughout the project. Apart from the Google Maps API, the other two—that is the Geolocation API and the Web Storage API—are W3C specifications. We’ll use this APIs through the Cordova framework, however some devices may already provide an implementation of these APIs. For those devices, Cordova will use their built-in support instead of the Cordova’s implementation, but for those that don’t have storage support, the Cordova implementation has been built to remain compatible with the W3C specs.

Managing the Locations

In this section I’ll show you the class called Position, which is responsible for managing the locations. It’s aim is to create, delete, and load the locations using the Web Storage API that is composed by two areas: the Session and the Local. Cordova uses the local storage because the storage is always at app level. All the locations will be stored in an item called “positions.” Before going on, I want to highlight two facts. The first is that to store complex data (like objects and arrays) using the Web Storage API, you have to use the JSON format. So, in the Position
class methods, you’ll see the use of the JSON class and its parse() and stringify() methods. The second is that Windows Phone 7 doesn’t support the dot notation so, you must use the setItem() and getItem() methods to ensure the compatibility for all devices. This is just the first of a lot of quirks that you have to face while developing with Cordova. Since with “Where I parked my car” we’re not targeting a specific platform, you have to take into account the different support and the quirks of the Cordova API. Luckily, the first one we encountered wasn’t so hard to deal with. For the purpose of the app, we need to save the user’s and car’s latitude and longitude, but we also need the accuracy of the measurement to give the user an idea of how precise our locations are. I’ll wrap the first three data into a class called Coords. Reading coordinates isn’t very user-friendly, so to enhance the user experience, we’ll use the Google Maps API to retrieve the address of the current location. The app will also store the date and time associated with that GPS location. Remember that the app will store up to 50 locations, so if the limits is reached, the extra positions (the older ones) will be eliminated using the JavaScript slice() method. For what discussed so far, the starting point of the Position class is implemented by the following code.
function Position(position, address, datetime)
{
  var _db = window.localStorage;
  var MAX_POSITIONS = 50;

  this.getMaxPositions = function()
  {
    return MAX_POSITIONS;
  }

  this.position = position;
  this.address = address;
  this.datetime = datetime;
}

function Coords(latitude, longitude, accuracy)
{
  this.latitude = latitude;
  this.longitude = longitude;
  this.accuracy = accuracy;
}
As you may have guessed, in the JavaScript sense of the object-oriented approach, the _db property is private and MAX_POSITIONS is a constant. With the given skeleton we can’t do much, in fact, we need methods to let the application interface with the Web Storage API. These methods are
  • savePosition() to store the car’s position
  • updatePosition() to update the last position retrieved with the address if the callback to the Google Maps API succeed
  • deletePosition() to allow the user to remove a previously saved position
  • getPositions() to load all the stored locations
In all the cited methods, I’ll test if the database var (_db) is null and if it is, I’ll show an error message to the user. I test for this state because I like to try to anticipate and manage unexpected interface problems. To show the message, I’ll take advantage of the alert() method of the Cordova Notification API. Most of the supported platforms use a native dialog box, however, others (like Bada 2.X) use the well-known browser’s alert()
function’s look and feel, which is less customizable. The Cordova alert() function accepts up to four parameters:
  1. message: The string that contains the message to show
  2. alertCallback: A callback to invoke when the alert dialog is dismissed
  3. title: The title of the dialog (by default is “Alert”)
  4. buttonName: The text of the button included in the dialog (by default is “OK”)
There’s another quirk that we have to consider while developing with PhoneGap. Windows Phone 7 ignores the button name and always uses the default. And, there isn’t a built-in browser alert, so if you want to use alert('message'); you have to assign window.alert = navigator.notification.alert. For a complete list of the differences between mobile operating systems, refer to the Cordova Notification alert() documentation. If you’ve gotten this far, you deserve a prize: the full source of the described methods. You can copy and paste the code inside the Position class after the getMaxPositions() methods or before, it doesn’t matter.
this.savePosition = function(position, address)
{
  if (!_db)
  {
    console.log('The database is null. Unable to save position');
    navigator.notification.alert(
      'Unable to save position',
      function(){},
      'Error'
    );
  }

  var positions = this.getPositions();
  if (positions == null)
    positions = [];

  positions.unshift(new Position(position, address, new Date()));
  // Only the top MAX_POSITIONS results are needed
  if (positions.length > this.MAX_POSITIONS)
    positions = positions.slice(0, this.MAX_POSITIONS);

  _db.setItem('positions', JSON.stringify(positions));

  return positions;
}

this.updatePosition = function(index, position, address)
{
  if (!_db)
  {
    console.log('The database is null. Unable to update position');
    navigator.notification.alert(
      'Unable to update position',
      function(){},
      'Error'
    );
  }

  var positions = this.getPositions();
  if (positions != null && positions[index] != undefined)
  {
    positions[index].coords = position;
    positions[index].address = address;
  }

  _db.setItem('positions', JSON.stringify(positions));

  return positions;
}

this.deletePosition = function(index)
{
  if (!_db)
  {
    console.log('The database is null. Unable to delete position');
    navigator.notification.alert(
      'Unable to delete position',
      function(){},
      'Error'
    );
  }

  var positions = this.getPositions();
  if (positions != null && positions[index] != undefined)
    positions.splice(index, 1);

  _db.setItem('positions', JSON.stringify(positions));

  return positions;
}

this.getPositions = function()
{
  if (!_db)
  {
    console.log('The database is null. Unable to retrieve positions');
    navigator.notification.alert(
      'Unable to retrieve positions',
      function(){},
      'Error'
    );
  }

  var positions = JSON.parse(_db.getItem('positions'));
  if (positions == null)
    positions = [];

  return positions;
}

Conclusion

In this third part, you’ve seen how to configure “Where I parked my car” to change the pages’ transition, the option to show the text when showing the page loader widget, and the theme. You also learned how to store the car’s positions using the Web Storage API. In the next article, I’ll show you the last two JavaScript files: maps.js, and functions.js. The former contains the functions to initialize the application and some other utility functions, while the latter has the functions that use the Google Maps API to draw the map and the route to the car.

Frequently Asked Questions on Building a Location-Based Mobile App with HTML5 and JavaScript

How can I optimize my HTML5 and JavaScript mobile app for better performance?

Optimizing your mobile app for better performance involves several steps. First, minimize the use of heavy libraries and frameworks. Instead, use lightweight libraries that perform the same functions. Second, optimize your images and other media files to reduce their size without compromising quality. Third, use local storage wisely. Store only necessary data and avoid storing large files. Lastly, use efficient coding practices. Avoid unnecessary loops and computations, and use efficient algorithms and data structures.

Can I use HTML5 and JavaScript to build a mobile app for both Android and iOS?

Yes, you can use HTML5 and JavaScript to build a mobile app for both Android and iOS. This is possible through the use of hybrid mobile app frameworks like Cordova, Ionic, or React Native. These frameworks allow you to write your code once in HTML5 and JavaScript, and then compile it into native code for both Android and iOS.

How can I add geolocation features to my HTML5 and JavaScript mobile app?

Adding geolocation features to your mobile app involves using the Geolocation API provided by HTML5. This API allows you to get the geographical position of the user. You can then use this position to provide location-based services, like showing nearby places or providing directions.

What are some popular JavaScript frameworks for mobile app development?

Some popular JavaScript frameworks for mobile app development include React Native, Ionic, and Cordova. These frameworks allow you to write your code in JavaScript and then compile it into native code for Android and iOS.

How can I test my HTML5 and JavaScript mobile app?

You can test your mobile app using various tools and techniques. For unit testing, you can use tools like Jasmine or Mocha. For end-to-end testing, you can use tools like Appium or Detox. You can also use manual testing to check the user interface and user experience of your app.

How can I monetize my HTML5 and JavaScript mobile app?

There are several ways to monetize your mobile app. You can use in-app advertising, where you display ads in your app and get paid for every click or impression. You can also use in-app purchases, where you sell virtual goods or premium features within your app. Another option is to charge for the app itself, although this might discourage some users from downloading it.

How can I ensure the security of my HTML5 and JavaScript mobile app?

Ensuring the security of your mobile app involves several steps. First, use secure coding practices to prevent common vulnerabilities like SQL injection or cross-site scripting. Second, use encryption to protect sensitive data. Third, use secure APIs and libraries. Lastly, regularly update your app to fix any security issues.

How can I make my HTML5 and JavaScript mobile app accessible?

Making your mobile app accessible involves following the Web Content Accessibility Guidelines (WCAG). These guidelines provide recommendations on how to make web content more accessible to people with disabilities. For example, you should provide alternative text for images, use sufficient contrast for text, and ensure that all functionality is available through a keyboard.

How can I update my HTML5 and JavaScript mobile app after it’s been published?

Updating your mobile app after it’s been published involves making the necessary changes in your code, testing the changes to ensure they work correctly, and then publishing the updated app to the app store. You should also inform your users about the update and its benefits to encourage them to install it.

How can I handle errors in my HTML5 and JavaScript mobile app?

Handling errors in your mobile app involves using try-catch blocks to catch exceptions, using error events to handle asynchronous errors, and using error boundaries in React to catch errors in the user interface. You should also provide helpful error messages to the user and log errors for debugging purposes.

Aurelio De RosaAurelio De Rosa
View Author

I'm a (full-stack) web and app developer with more than 5 years' experience programming for the web using HTML, CSS, Sass, JavaScript, and PHP. I'm an expert of JavaScript and HTML5 APIs but my interests include web security, accessibility, performance, and SEO. I'm also a regular writer for several networks, speaker, and author of the books jQuery in Action, third edition and Instant jQuery Selectors.

jQuerymobile web tutorials
Share this article
Read Next
Get the freshest news and resources for developers, designers and digital creators in your inbox each week