Build a Currency Converter with jQuery Mobile and Cordova: Constructing The Interface

Web & App Developer
This entry is part 2 of 6 in the series Build a Currency Converter with jQuery Mobile and Cordova

Build a Currency Converter with jQuery Mobile and Cordova

In the introductory article of this series, I showed the requirements of the soon-to-be-built “Currency Converter” app and the technologies involved. I also built out a file structure and outlined each component of the app and its purpose. In this article, we’ll delve deeper into the layout and functionality of our app, and I’ll show you the source of both the two HTML pages and the CSS file that govern our app’s interface.

The Homepage

By default, the interface loads the pages differently from the first initial page load using AJAX; That’s why we have to include all the JavaScript and CSS files. As I pointed out in the first article, the app we’re developing is very simple; the entry point is index.html, and it’s also the only page that the user will really interact with. It contains the form the user will use to convert money from one currency to another. The form will have the field to write the monetery amount, the currency to convert from, and the currency to convert into.

I’ll use the new HTML5 tags where possible, and the amount field is ideal to use the new <input type="number">. Apart from the new input type, I’ll take advantage of the min by setting it to zero, because we won’t be converting negative amounts of currency. I’ll also use the attribute pattern and set it with the value range [0-9]* . As a result, when the user puts “focus” on this field (by touching it), the numbers keyboard will be shown instead of the alphabetical one. You can see this specific part of code that creates this streamlined functionality below:

<input type="number" id="from-value" name="from-value" pattern="[0-9]*" value="0" min="0" max="999999999999999" />

The remaining two fields are implemented using the classic <select> tag. They will be filled dynamically using a JavaScript function that I’ll describe in the next parts of the series.

For the output of the currency calculation, I used the new <output> element. This has a very interesting attribute (at least for me), called for, which allows you to specify what elements are involved in the calculation to obtain the result you have. Thus, I specify the id of the amount, the “from” currency and the “to” currency fields, as you can see in the following snippet.

<output id="result" name="result" for="from-currency-value from-currency-type to-currency-type">0</output>

The last interesting twist is the layout grid system that I applied to style the reset and the submit buttons. By default, the framework styles the buttons to take all the space and not allowing to have other elements on the same line. However, I wanted those two buttons to be on the same horizontal line and to divide the total width. To build this two-column layout in jQuery Mobile, you must create a wrapper having class ui-grid-a, and then apply to its children the class ui-block-a for the first column and ui-block-b for the second. Consider the following example:

<div class="ui-grid-a">
  <div class="ui-block-a">
    <input id="reset-button" type="reset" value="Reset" data-icon="delete" data-theme="c" />
  </div>
  <div class="ui-block-b">
    <input id="submit-button" type="submit" value="Convert" data-icon="check" />
  </div>
</div>

Now, you’re probably wondering why I added two additional containers. The reason is that since an <input> field is wrapped with other elements by jQuery Mobile to add aesthetic enhancements (which take up space), so if the buttons take up 50% of the width each, the added width from the styling forces the buttons onto different lines, as you can see in the following screenshot.

Buttons wrong alingment

Now that you know all the main elements of the page, it’s time to show you the page’s whole code.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Currency converter</title>
    <link rel="stylesheet" href="css/jquery.mobile-1.2.0.min.css" type="text/css" media="all" />
    <link rel="stylesheet" href="css/style.css" type="text/css" media="all" />
    <script src="js/jquery-1.8.3.min.js"></script>
    <script src="js/jquery.mobile.config.js"></script>
    <script src="js/jquery.mobile-1.2.0.min.js"></script>
    <script src="cordova.js"></script>
    <script src="js/jquery.auderoTextChanger.min.js"></script>
    <script src="js/translation.js"></script>
    <script src="js/currency.js"></script>
    <script src="js/settings.js"></script>
    <script src="js/functions.js"></script>
    <script>
      $(document).on('pagebeforecreate orientationchange', updateIcons);
      $(document).one('deviceready', initApplication);
    </script>
  </head>
  <body>
    <div id="home-page" data-role="page">
      <header data-role="header">
        <h1>Currency converter</h1>
        <a href="#" id="update-button" data-icon="refresh" data-iconpos="notext" class="ui-btn-right">Update data</a>
      </header>
      <div data-role="content">
        <p id="app-description">
          Currency Converter is a simple app that helps you convert from a currency to another. You can
          update the exchange rates every time you want so you'll have always an up-to-date conversion.
        </p>
        <label id="last-update-label">Last update rates:</label>
        <span id="last-update"></span>
        <form id="form-converter" name="form-converter" action="#">
          <h2 id="convert-title">Convert</h2>
          <div data-role="fieldcontain">
            <label for="from-value" id="from-value-label">Value:</label>
            <input type="number" id="from-value" name="from-value" pattern="[0-9]*" value="0" min="0" max="999999999999999" />
          </div>
          <div data-role="fieldcontain">
            <label for="from-type" id="from-type-label">From Currency:</label>
            <select id="from-type">
            </select>
          </div>
          <div data-role="fieldcontain">
            <label for="to-type" id="to-type-label">To Currency:</label>
            <select id="to-type">
            </select>
          </div>

          <h2 id="result-title">Result</h2>
          <output id="result" name="result" for="from-value from-type to-type">0</output>

          <div class="ui-grid-a">
            <div class="ui-block-a">
              <input id="reset-button" type="reset" value="Reset" data-icon="delete" data-theme="c" />
            </div>
            <div class="ui-block-b">
              <input id="submit-button" type="submit" value="Convert" data-icon="check" />
            </div>
          </div>
        </form>
      </div>
      <footer data-role="footer">
        <h3 id="copyright-title">Created by Aurelio De Rosa</h3>
        <a id="credits-button" href="aurelio.html" data-icon="info" data-iconpos="notext" data-prefetch="prefetch" data-transition="flip" class="ui-btn-right">Credits</a>
      </footer>
    </div>
  </body>
</html>

In addition to what I’ve already outlined for the header and the footer, I’ve used the new HTML5 <header> and <footer> tags instead of generic <div> tags. Each of those two elements has a link inside: the header’s link will execute the currencies rate update, while the footer’s will simply take the user to the credits page (aurelio.html), which is nothing special but a spam page about…well, me.

Additionally, the link inside the <header>, as well as the one inside the <footer>, uses the attribute data-iconpos="notext". This tells to jQuery Mobile to hide the link’s text, because on small screens it could require too space. However, as you can see at line 19, I attached a handler, called updateIcons(), to the pagebeforecreate and the orientationchange events. This function will programmatically test the screen’s width, and if a larger enough screen is found, the attribute will be removed and the element’s text will be displayed.

The last thing you should know about this page is the use of a handler, initApplication(), for the deviceready event, which is fired when Cordova is fully loaded. It’s the function that will set up the application, but its functionality will be illustrated in the next parts of this article series.

The Credits Page

Although the page aurelio.html is very simple, there are a couple of facts worth mentioning. The first is the use of two new HTML5 tags: <figure>, and <article>. Of course, explaining HTML5 is beyond the scope of this series, so I’ll give you a very brief summary. The <figure> element represents a unit of content, optionally with a caption, that is self-contained. The caption described is provided using the element <figcaption>. Regarding the <article> element, it represents a component of a page that consists of a self-contained composition in a document, page, application, or site. The second fact to highlight is the use of the attribute target="_blank" applied to all the links of the contact listings on the page. It will be used to attach a handler to all those links; the how and the why will be explained in the next article of this series.

The full source of the credits page is below.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Aurelio De Rosa</title>
  </head>
  <body>
    <div id="aurelio-page" data-role="page">
      <header data-role="header">
        <a href="#" data-icon="back" data-iconpos="notext" data-rel="back" title="Go back">Back</a>
        <h1>Aurelio De Rosa</h1>
      </header>
      <div id="content" data-role="content">
        <div class="person">
          <figure class="photo">
            <img src="images/aurelio-de-rosa.png" alt="Photo of Aurelio De Rosa" />
            <figcaption>Aurelio De Rosa</figcaption>
          </figure>
          <article>
            <p>
              I'm an Italian web and app developer who have a bachelor degree in Computer Science and more than
              5 years' experience programming for the web using HTML5, CSS3, JavaScript, and PHP. I mainly use the
              LAMP stack and frameworks like jQuery, jQuery Mobile, Cordova (PhoneGap), and Zend Framework.
              My interests also include web security, web accessibility, SEO, and WordPress.
            </p>
            <p>
              Currently I'm self-employed working with the cited technologies, and I'm also a regular contributor to the
              SitePoint network, where I write articles about the topics I usually work with and more. The articles can
              be found on the following websites of the network:
              <a href="http://www.sitepoint.com/author/aderosa/" target="_blank">BuildMobile.com</a>,
              <a href="http://www.sitepoint.com/author/aderosa/" target="_blank">PHPMaster.com</a>,
              <a href="http://www.sitepoint.com/author/aderosa/" target="_blank">JSPro.com</a> and
              <a href="http://www.sitepoint.com/author/aderosa/" target="_blank">SitePoint.com</a>.
            </p>
          </article>
          <article>
            <h2>Contacts</h2>
            <ul data-role="listview" data-inset="true">
              <li>
                <a href="http://www.audero.it" target="_blank">
                  <img src="images/website-icon.png" alt="Website icon" />
                  Visit my website: www.audero.it
                </a>
              </li>
              <li>
                <a href="mailto:aurelioderosa@gmail.com" target="_blank">
                  <img src="images/email-icon.png" alt="Email icon" />
                  Drop me an email: aurelioderosa@gmail.com
                </a>
              </li>
              <li>
                <a href="mailto:a.derosa@audero.it" target="_blank">
                  <img src="images/email-icon.png" alt="Email icon" />
                  Drop me an email (alternative address): a.derosa@audero.it
                </a>
              </li>
              <li>
                <a href="https://twitter.com/AurelioDeRosa" target="_blank">
                  <img src="images/twitter-icon.png" alt="Twitter icon" />
                  Follow me on Twitter (@AurelioDeRosa)
                </a>
              </li>
              <li>
                <a href="http://it.linkedin.com/in/aurelioderosa/en" target="_blank">
                  <img src="images/linkedin-icon.png" alt="LinkedIn icon" />
                  View my profile on LinkedIn
                </a>
              </li>
              <li>
                <a href="https://bitbucket.org/AurelioDeRosa" target="_blank">
                  <img src="images/bitbucket-icon.png" alt="BitBucket icon" />
                  Visit my repository on BitBucket (AurelioDeRosa)
                </a>
              </li>
            </ul>
          </article>
        </div>
      </div>
    </div>
  </body>
</html>

Style Tuning

By default, jQuery Mobile will truncate long titles inside the <header> and the <footer>, adding an ellipsis at the end of the truncated text. However, this method also applies to other kind of elements like buttons. I don’t like this behavior very much, so in the very short stylesheet, called style.css, which I mentioned in the previous article, I changed it by applying the rule white-space: normal !important;. Apart from that, I just centered my photo in the credits page and applied some styles to the result of the calculation.

The source of the stylesheet is the following:

.ui-header .ui-title,
.ui-footer .ui-title,
.ui-btn-inner *
{
   white-space: normal !important;
}

.photo
{
   text-align: center;
}

#result-title
{
   margin-bottom: 0.2em
}

#result
{
   display: block;
   font-size: 1.5em;
   text-align: center;
}

Conclusion

In this second part of the series, I described the two essential HTML pages and outlined the key points of each. Although the app is very small, the markup is semantic and rich thanks to the use of several new HTML5 tags and attributes. Apart from these elements, the most important feature is probably the jQuery Mobile layout grid system that allows you to create responsive and equally-spaced multi-column layouts. Due to the fact that the business logic isn’t yet complete, the files aren’t very useful at the moment. Additionally, if you try to wrap them using Cordova, as soon as you visit one of the external links in aurelio.html, and then go back using the back button, you’ll see that the credit page will lose the framework’s style enhancements, as well as any custom styles applied. This issue will be discussed in the next articles of the series, where I’ll show you the solution to these problems, and I’ll also describe some of the JavaScript files that power the “Currency Converter” app.

Build a Currency Converter with jQuery Mobile and Cordova

<< Build a Currency Converter with jQuery Mobile and Cordova: IntroductionBuild a Currency Converter with jQuery Mobile and Cordova: JavaScript and User Settings >>

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • Ari

    Hi Aurelio:

    Thanks for another interesting and educational series!

    Ummm… I cannot find some of the fields you referred to when you used the HTML5 element. For example, I do not see any of the 3 IDs that the “for” attribute refers to.

    Did I something?

  • http://www.audero.it/ Aurelio De Rosa

    The 3 ids referer to the two select boxes and the input box. There was I typo in the for attribute.