Build a Currency Converter with jQuery Mobile and Cordova: 3

Share this article

In the second part of the series, I showed you the code of the two HTML pages and the custom CSS file of our “Currency Converter” app. In this article, I’ll show you the jQuery Mobile custom configuration and some of the JavaScript files that implement the business logic. While describing the JavaScript files, I’ll also demonstrate the Cordova APIs in detail.

jQuery Mobile Custom Configuration

jQuery Mobile has a default configuration that is usually good enough for most of the projects with basic requirements. However, you may still need to set up some specific custom rules to fit your app’s requirements. As I said in the first part of the series when I presented the list of the files that make up our app, we have a file called jquery.mobile.config.js, which is exactly where we would specify a configuration. In this section, I’ll show you what options I’ll change.

(Please note that when you create a file like this, you must include it before the library files itself. In fact, when jQuery Mobile starts, it fires an event called mobileinit, which is used to override the default settings.)

You have two different ways to specify the settings, but I’ll use the method that changes the properties of the $.mobile object. I’ll change just some of them, but if you need an overview of all of the jQuery Mobile properties, you can read the jQuery Mobile configuration docs. Our file will change the options concerning the page loader widget, the theme, and those that allow cross-domain requests. The settings to allow cross-domain requests are the most interesting ones and well worth a discussion.

As you learned in the app requirements, “Currency Converter” will make a call to the European Central Bank RSS feed to update the currencies rates, so we need to be able to do HTTP requests to an external source. When you use the Cordova framework in conjunction with jQuery Mobile, to be able to make cross-domain requests, you need to set one property in the config.xml file of for first framework (Cordova) and two properties for the second (jQuery Mobile).

The jQuery Mobile properties to change are $.support.cors and $.mobile.allowCrossDomainPages. The first is a boolean that you need to set to true in order to tell the browser to support cross-domain requests. The project also has links to external pages (in the credits page) so, we must also set the $.mobile.allowCrossDomainPages property to true. In fact, when jQuery Mobile tries to load an external page, the request runs through the $.mobile.loadPage() method, which will only allow cross-domain requests if the cited property is set to true. By default, its value is false, because, according to the documentation, the framework tracks what page is being viewed within the browser’s location hash, so it is possible for a cross-site scripting (XSS) attack to occur if the XSS code in question can manipulate the hash and set it to a cross-domain URL of its choice. This option must be set before the requests are made, and the documentation suggests putting it into the initial configuration. We’ll act accordingly.

Now that you know the meaning of these options, you’re ready to see the full source of jquery.mobile.config.js.

$(document).on(
  'mobileinit',
  function()
  {
    // Page Loader Widget
    $.mobile.loader.prototype.options.text = 'Loading...';
    $.mobile.loader.prototype.options.textVisible = true;

    // Bypass Access-Control-Allow-Origin
    $.support.cors = true;
    $.mobile.allowCrossDomainPages = 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 Translation Class

Recalling the project’s requirements, you’ll remember that “Currency Converter” is a multi-language app. Since its most important part is index.html, I’ll create translations for that page and ignore translations for aurelio.html. I think that having the credits solely in English is adequate.

To store the strings of the different languages within the translation.js file, I used an object calling the variable Translation. This object has as many properties as the spoken languages that you want support. So, since we’ll translate it into Italian, French, and Spanish, we’ll have three properties whose values are objects containing the strings. To simplify the translation process, these objects have the id of the elements that will be translated as their property names, and the string to change as their values. To understand how Translation is made, it’s enough to see one language, so I’ll show you just the Italian, but you’ll find the others will be supported within the app repository.

var Translation = {
  'it': {
    'app-description': 'Currency Converter è una semplice applicazione che ti aiuta a convertire da una valuta ad un'altra. È anche possibile aggiornare i tassi di cambio ogni volta che si desidera così da avere sempre dei tassi di conversione aggiornati.',
    'convert-title': 'Converti',
    'from-value-label': 'Valore:',
    'from-type-label': 'Da Valuta:',
    'to-type-label': 'A Valuta:',
    'result-title': 'Risultato',
    'copyright-title': 'Creata da Aurelio De Rosa',
    'credits-button': 'Crediti',
    'update-button': 'Aggiorna dati',
    'submit-button': 'Converti',
    'reset-button': 'Azzera dati',
    'last-update-label': 'Ultimo aggiornamento cambi:'
  }
  // other languages here
}

The User Settings

In the introductory article of this series, I stated:

The app will save the last currency used for a conversion, so at the next start of the application, the user will find their last-used currency. In addition, the date and time of the last update will be stored too, so that the user knows how recent (or old) his conversion rates are.

Thus, we need to manage and store these data. To achieve this goal, we’ll use the Cordova Storage API, which is built on the top of the Web Storage API and Cordova. For the devices that have built-in support, it uses the native implementation instead of its own, which is compatible with the W3C specs.

In this section, I’m going to describe the file called settings.js that contains the class called Settings. Let’s take a closer look at this file.

As you already know, this class has three public properties: lastUpdate, fromCurrency, and toCurrency. It also has two private ones: _db and _tableName. The aim of the first three properties should be self-evident so I’ll skip their explanation. _db is a reference to the window.localStorage property that will be used to call the Web Storage API’s method to store and retrieve the data from the browser (or, in the case of our hybrid app, from the device). Keep in mind that this API doesn’t use real tables like a DBMS does. Instead, it has a set of properties whose values are a basic type (like a string or a number) or a JSON-encoded object. Having said that, it should be clear that _tableName isn’t a property having as its value a string containing the name of a real table, but rather the name of the property where we’ll store the JSON-encoded object containing the user settings.

The following code shows what I’ve explained so far.

function Settings(lastUpdate, fromCurrency, toCurrency)
{
  var _db = window.localStorage;
  var _tableName = 'settings';

  this.lastUpdate = lastUpdate;
  this.fromCurrency = fromCurrency;
  this.toCurrency = toCurrency;
}

Now, we need two methods: one to store the data, and one to retrieve them. In another one of my astonishingly-creative moments, I named these methods save() and load() respectively. These methods do nothing but wrap the call the getItem() and setItem() methods, as you can see by looking at their code below.

this.save = function()
{
  _db.setItem(_tableName, JSON.stringify(this));
}

this.load = function()
{
  return JSON.parse(_db.getItem(_tableName));
}

Some of you who have have already used the Web Storage API might wonder why I used setItem() and getItem() instead of using the dot notation. The reason is that Windows Phone 7 doesn’t support the latter, so to ensure the compatibility across all the operating systems, we’ve got to use the former.

This class has another method to discuss that is more of a utility than a must-have method. It’s called getSettings() and it’s a static method. When you use load(), the retrieved object isn’t an instance of the Settings class but of the Object equivalent. Now, suppose that you want to change the current user’s settings based on the ones you stored. In this case, it’s a lot easier to have a Settings instance, so that you can modify the properties and then call the save() method directly. For this reason, I created getSettings(), which calls load() and then converts the result into a Settings instance. The source of this utility is the following:

Settings.getSettings = function()
{
  var settings = new Settings().load();
  return (settings === null) ?
     {} :
     new Settings(
       settings.lastUpdate,
       settings.fromCurrency,
       settings.toCurrency
     );
}

Conclusion

In this third article of the series, I described the custom configuration of “Currency Converter” and the importance of the options to allow cross-domain requests. Additionally, I showed the class used to translate the application and the class used to save the user settings. In the next part of the series, I’ll illustrate the other two remaining JavaScript files: functions.js (which has the functions to retrieve the rates, update the currencies select boxes, and initialize the application), and currency.js, the file that contains the class to store, load, sort, and convert the retrieved currencies.

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.

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