I really like creating small applications. You learn new things, can leverage cutting edge practices and libraries, and you attain that gratification after completing a project very quickly!

I noticed that many of the mini-apps I create are calculator related, so I launched HyperCalc.com as a "farm" for my silly little apps.

Most recently, I decided to create a web hosting calculator. It's more of a worksheet than a calculator, but I had to stick with the "calculator-ish" theme. I wanted this thing to be completely mobile friendly, so I decided to let jQuery Mobile do it's magic. From there, my hope was to turn it into a PhoneGap application for release on iOS and Android.

I was, for the most part, happy with the end result, but I don't feel that the implementation is as good as it could be. Here's what I took away from the experience:

  1. Don't try to make JavaScript more than it is
    Don't use JavaScript to create an application that primarily deals with data. My app became littered with if/elseif/else blocks, arrays and data objects. What should have been setup in two or three relational database tables ended up being stored in native JavaScript data types. Not only did it greatly increase the code size, but it made querying the data very difficult.

    Since my goal was to release this as a PhoneGap application as well, I thought using JavaScript alone would be a good approach. I should have instead made AJAX calls to a server-side language, which would pull data appropriately from a MySQL database. This would have easily translated to a PhoneGap app as well.

  2. Avoid jQuery Mobile for non-mobile applications.
    jQuery Mobile should not be used to for anything other than mobile sites or applications. I originally used jQuery Mobile to provide the interface for the desktop version of this app and found it to be a bit "clunky". Almost every action provided by jQM was slow to respond.

    In other apps, I had used a more basic paging technique, which involved using jQuery load() to bring in page content without refreshing the page, and nothing more. These apps responded far more quickly for the user. I'm not sure if jQuery Mobile has too much going on behind the scenes or what, but I was a little disappointed. 

  3. Keep a watchful eye on UI enhancements
    Since the calculator results were extremely relevant at any point in time within the app "flow", I decided to fix their position on the right side of the page, just a bit from the top.

    What I didn't notice right away is that when the length of the results became longer than the height of the browser viewport, it was impossible to view them. When using fixed positioning, it's important that the element being positioned is not taller than the browser viewport.

    To make sure the element was not applied fixed positioning when it became taller than the viewport, I had to use JavaScript to detect the height of the element with each change:


    $(window).scroll(function() {
        if ($(window).scrollTop() > 150 && $('#results').height() < ($('body').height() - 50)) {
        else {

    .sidebar-results.snapTop { position: fixed; right: -2%; top: 10px; }

    Essentially, the jQuery is selectively adding or removing the snapTop CSS class as the results element becomes taller or shorter.

  4. Reset your CSS
    And finally, always apply a set of CSS reset rules at the beginning of your CSS file. This technique ensures that all of your styling will be displayed consistently across browsers.

    Different browsers have different default styles for elements. For example, IE might default <p> tags to a line-height of 1.25em, while FireFox defaults them to 1.5em. That is not a confirmed rule, just an example.

    By resetting the styles, you are forced to do the extra work of recreating many of the default styles. For instance, the <b> tag may need to be recreated with:

    b { font-weight: bold; }

    But, this technique really helps to avoid much of the CSS debugging that is typically required for cross-browser consistency.


Leave a Reply

Your email address will not be published. Required fields are marked *