Tuesday, May 15, 2012

jQuery Mobile Calculator

Click here for a PhoneGap Calculator

WORKING DEMO

Here is an easy to get your head around jQuery Mobile (JQM) project, a simple calculator. I like this project because it helps to break want-to-be web app program out of the web site mentality. The entire app consist of a single page and about 200 lines of code. Let's begin our explanation with the Kernel which is near the beginning of the file app.js.

The Kernel

The Kernel's function is to tie HTML and JavaScript files together. We map all of JQM's page events to the Kernel. First we assign the event name to the variable eventType. Then we pull the page's JavaScript file name from the psuedo-attribute, "data-rockncoder-jspage" and assign it to the variable pageName. The final lines of the Kernel call the event's handler in its page code, only if the handler exists. The long if statement simply makes sure that there is a handler before it is called. Rockncoder.App follows the Kernel. Its only function is to hook all of the page events and direct them to the Kernel.

The Page Code

Next comes the page's code in RocknCoder.Pages.calculator. We use an object literal to hold all of the pages code. At some point in the future I will be changing this code to use a function not an object literal, but I have been doing for so long like this the habit is hard to break. A better implementation would be to do something like a "Revealing Module Pattern", which would also give us the ability to hide our local variables.

In the page's code we handle three events: pageinit, pageshow, and pagehide. Any event which is not  defined is not called by the Kernel. The first event handler, pageinit, is the JQM's equivalent to jQuery's document ready event. This is the place to do any page level initialization code. Here we initialize our Android address bar hider. The second event, pageshow, is called after JQM  has rendered the page. In this handler we initialize the calculator, the poorly named RocknCoder.Display and hook all of the calculator's keys. The final event is pagehide, which we use to unhook the events. Truth be told, this event will probably never be called since  there is only one page and JQM will have no page to switch to  and therefore no need to hide the current page.

The Calculator 

The meat of the calculator is in RocknCoder.Display. I am not going to explain its function other than to say it is a very simple calculator. We could have created a more robust calculator by using the Command Pattern. Then we could have been able to have features like undo and a much cleaner separation of concerns.  But then it would not have been so light in code. 

Summary

Although this is a very simple project, it has the ability to grow. By following the example of RocknCoder.Pages.calculator, you can add other pages, just remember to add HTML markup along with JavaScript. For each use of the psuedo-attribute "data-rockncoder-jspages='xxx'" be sure to create a match JavaScript literal with the name "RocknCoder.Pages.xxx.

Next week I will turn the calculator into a PhoneGap project and show how to get it to run on iPhone, Android, and Windows Phone 7.

Complete Source Code

16 comments:

  1. I have read this post. collection of post is a nice one ..that am doing website designing company chennai india and website development company chennai india. That I will inform about your post to my friends and all the best for your future posts..

    ReplyDelete
  2. Great post Troy. I'm going through the code line by line.
    Can you explain the meaning of the first line of code in the app.js file?

    var RocknCoder = RocknCoder || {};
    The "|| {}" is confusing to me.

    ReplyDelete
  3. If I verbalize this statement, should it read "set variable RocknCoder equal to RocknCoder or {}"?

    ReplyDelete
  4. Hi Ken,
    The way I say it is: RocknCoder equals RocknCoder if set otherwise empty set. The "||" is referred to as the default operator. If the thing left of the default operator is 'falsy' then the thing on the right is used.

    ReplyDelete
  5. Thanks for the explaining it Troy.

    ReplyDelete
  6. Howdy,
    Really like what you've done here...and don't want to seem ignorant or grasping, but would it be ok to use your code in my jQueryMobile application? of course with appropriate comments in the source and acknowledgements. Thanks in advance.

    ReplyDelete
  7. Hi Rock n Coder,
    I really admire your calculator and would like to use it in a project. How hard would it be to tie the calculator to two r more text boxes depending on which one is highlighted? And how would I go about this?

    ReplyDelete
  8. Hi Troy,

    I am trying to create a keyboard to enter numbers in a input field, it works fine on the laptop, but wen I run it on the real android device, like galaxy sIII, it becomes very slow on answering the tap events.
    I noticed that the app you've created in your calculator works very well, and not slows the operation of the virtual keyboard.
    I tried to connect the click events to produce the numbers on the display, and it produce "clicks" on the android, I think that should be the reason why it makes its operation slow, every time I tap one number it has to produce the "click" before I tap another one.
    Any advice would be great appreciated.
    Regards,

    Flavio

    ReplyDelete
    Replies
    1. Hi Flavio,
      I wrote a blog post for Safari Online which deals exactly with improving the performance of jQuery Mobile. Please check it out: http://blog.safaribooksonline.com/2012/07/20/jquery-mobile-performance-improvement/
      Let me know if it helps.

      Troy

      Delete
  9. hie troy ,
    i would like to use your code as a jquery mobile application for instance if a textbox is clicked ,a popup appears showing the calculator, i am a beginner in jquery mobile and have no much idea, if u could just help showing how it can be done will be grateful ....
    Thanks

    ReplyDelete
    Replies
    1. Hi rais89,

      I am a little unclear on what you want. Do you want to put the calculator into a bigger web app and when a button is clicked, the calculator shows up?

      Delete
  10. Hi, this is really awesome and helpful information.
    It will help people. thank you so much for sharing this.
    Online English Speaking Course in India


    ReplyDelete
  11. If you want to add native keyboard support for desktop use here is the code:
    $(document).ready(function() {
    $('#displayControl').focus().keypress(function(e) {
    var action = false;
    switch(e.which) {
    case 42:
    e.preventDefault();
    RocknCoder.Display.setOperator("*");
    action = true;
    return false;
    break;
    case 47:
    e.preventDefault();
    RocknCoder.Display.setOperator("/");
    action = true;
    return false;
    break;
    case 45:
    e.preventDefault();
    RocknCoder.Display.setOperator("-");
    action = true;
    return false;
    break;
    case 43:
    e.preventDefault();
    RocknCoder.Display.setOperator("+");
    action = true;
    return false;
    break;
    case 44:
    case 46:
    e.preventDefault();
    RocknCoder.Display.enterDigit(46);
    action = true;
    return false;
    break;
    case 0:
    e.preventDefault();
    RocknCoder.Display.clearDisplay();
    return false;
    break;
    case 8:
    e.preventDefault();
    RocknCoder.Display.clearError();
    return false;
    break;
    case 13:
    case 61:
    e.preventDefault();
    RocknCoder.Display.setOperator("=");
    action = true;
    return false;
    break;
    default:
    e.preventDefault();
    if(e.which > 47 && e.which < 57){
    RocknCoder.Display.enterDigit(String.fromCharCode(e.which));
    }
    return false;
    break;
    }
    });
    });

    ReplyDelete
    Replies
    1. posted too fast heh...change [RocknCoder.Display.enterDigit(46);] to [RocknCoder.Display.enterDigit(String.fromCharCode(46));]

      also those key codes are for en-us keyboard on windows firefox(gecko) browser. they might differ in other systems. use console.log(e.which) to match yours

      Delete