10 Jan

PhoneGap + JavascriptMVC + jQuery Mobile

I started a new mobile app project and decided to go with HTML5 wrapped with PhoneGap. The reasons are many and this post isn’t about why, but how.

Before you start, here are the libraries/frameworks I am using:
jQuery Mobile – a “Touch-Optimized Web Framework for Smartphones & Tablets”
Javascript MVC – a Javascript MVC Framework (and more)
PhoneGap – “HTML5 app platform”/embedded cross platform browser

I will be posting code snippets as I go along that may be helpful to someone just starting out with a similar project.

Here is my directory structure so far:

  • blocks
    • controllers
    • views
    • blocks.js
  • pages
    • controllers
    • views
  • models
    • models.js
    • blog_post.js
  • css
  • images
  • platforms // platform projects (iOS XCode project, Android eclipse project, etc.)
  • myapp.js
  • myapp.html
  • build.xml

I also chose to go with EJS for the templating system which allows my view to look very similar to a PHP/Zend Framework view:

<%== blocks('header') %>
<div data-role="content" id="frontpageContent">
    <ul data-role="listview" data-theme="c">
        <% if (items) for(var i=0; i < items.length; i++) { %>
            <li data-icon="tcc2-arrow-right">
                <a href="#">
                    <img src="<%= items&#91;i&#93;.media.m %>"/>
                    <h3><%= items&#91;i&#93;.title %></h3>
                </a>
            </li>
        <% } %>
    </ul>
</div>
<%== blocks('footer') %>

The first piece of code that makes life a little easier on large projects is my blocks view helper. This way I can modularize and reuse:

    $.EJS.Helpers.prototype.blocks = function (blockName) {
        if (typeof MyApp.Blocks[blockName] === 'function') {
            blockInstance = new MyApp.Blocks[blockName]($('<div/>'));
            return blockInstance.view;
        }
        throw "No such block controller MyApp.Blocks." + blockName;
    }

You could also just call

<%== $.View('someview.ejs') %>

if you have no need for a controller. Block controllers look like this:

$.Controller('MyApp.Blocks.Header',
    /** @Static */
    {
        defaults: {},
        pluginName: 'header'
    },
    /** @Prototype */
    {
        init : function(){
            this.view = $.View("my_app/blocks/views/header.ejs",{});
        }
    }
); // Header controller

Now on to more substantial jQuery Mobile related code. We need jqm navigation to tie into our MVC controllers and vice versa. In other words, when we navigate to #frontpage, we want a new page injected into our dom using the frontpage controller, which in turns will render a view (frontpage.ejs, or init.ejs if you stick to the generated naming).

The answer to this problem comes straight from the jQm manual:
From myapp.js (or whatever you called your app)

steal(
    'phonegap-1.3.0.js',
    'jquery/jquery.js',
    './css/jquery.mobile.structure-1.0.min.css' // jQuery Mobile structure CSS
    )
.then(
    './css/global.css', // Our global css style and jqm theme
    'jquery/controller',
    'jquery/view/ejs'
    )
.then(
    './models/models.js', // all models
    './pages/pages.js', // all pages
    './blocks/blocks.js', // all blocks and Blocks view helper
     function () { // Init some jqm settings and fadeIn splash page
        $(document).bind("mobileinit", function(){
            $.mobile.touchOverflowEnabled = true;
            $.mobile.allowCrossDomainPages = true;
        });
    })
.then('//library/jquery.mobile-1.0.min.js') // jQuery Mobile library
.then(
    // Run the frontpage controller
    function() {
        $('#splash').fadeIn(500);
        // intercept changePage events to inject our controllers as needed (dispatch)
        $(document).bind( "pagebeforechange", function( e, data ) {
            // we only handle url changes
            if ( typeof data.toPage === "string" ) {
                // We are being asked to load a page by URL
                var u = $.mobile.path.parseUrl( data.toPage ),
                    re = /^\#([a-zA-Z]+)$/;

                if (u.hash.search(re) !== -1 ) {
                    var $page = re.exec(u.hash);
                    $page = $page[1];
                    console.log('Loading page ' + $page);
                    // We're being asked to display the items for a specific page
                    // Call our internal controller
                    if (typeof MyApp.Pages[$page] === 'function') {
                        var controller = new MyApp.Pages[$page]( $('body') );
                        controller.view.done(function (htmlOutput) {
                            $(htmlOutput).appendTo( $('body') ).page();
                            $.mobile.changePage( $(htmlOutput) );
                        });
                    }
                }
            }
        });
        setTimeout(function () {
            $.mobile.changePage('#frontpage');
        }, 500);
    });

This is of course a very early draft, but I hope it is enough to fill in the gaps between the docs of JMVC and jQm to get someone started. There is much you need to add to make this nicer. For example you could have an routes object defining each hash and params and which controller to send them to, then use that during the event above (look at jquery page params for adding hash params to jQuery Mobile).

06 Aug

Macbook battery woes

My Macbook’s battery is finally dead, which means the book shuts down immediately if I unplug it from power. I accidentally pulled on the power cable yesterday, and as a result my usually rock solid Leopard OS started showing me instability of applications, and eventually the dreaded screen of death.

Luckily, I have time machine running and backing up everything. I rebooted on the OSX install disk, ran a repair disk through the Disk Utility, then restored a couple of the Application Support folders under my user folder that I found to have been corrupted (mostly stuff I had running at the time of the crash: Firefox, Mail, VLC, iTunes, etc.)

I am glad time machine worked as advertised. My last backup was done at noon, and the crash at 2PM so I haven’t lost anything.

07 Jan

Cheap IT to start a business (Part 2)

Friends ask me all the time: how much would it cost to start a business from an IT perspective, as in get a website, get email, phone numbers, an ERP system, a CRM system, some basic automation, etc. This makes non-techies very nervous when just starting out on the cheap. Word on the street is that these things cost millions. Interestingly enough, most people don’t know that they can do most of that expensive stuff for next to nothing, and a little elbow grease.

This article is not meant as an in depth how-to but more as an example of what you can get done with a little knowledge when just starting out.

Click here if you’ve missed Part 1 of this article

Read More

10 Dec

Cheap IT to start a business (Part 1)

Friends ask me all the time: how much would it cost to start a business from an IT perspective, as in get a website, get email, phone numbers, an ERP system, a CRM system, some basic automation, etc. This makes non-techies very nervous when just starting out on the cheap. Word on the street is that these things cost millions. Interestingly enough, most people don’t know that they can do most of that expensive stuff for next to nothing, and a little elbow grease.

This article is not meant as an in depth how-to but more as an example of what you can get done with a little knowledge when just starting out.

Read More

25 Jan

Science on Track to Make us Gods

I have been seeing a trend for sometime now of humans applying their intelligence for the improvement of other species. You’re probably more than familiar with genetically tweaked fruits, insects, etc. Recently though, it seems to be more and more about us. That’s right! we are trying to improve the human condition by…(drum roll)…improving humans!

Here is my evidence that we are increasingly on the path to change our species:

  1. There is the recent viable embryos created out of a certain CEO’s cells. Creating a human being out of my own cells would allow me to potentially tweak the next generation’s attributes. Instead of having sons and daughters in the traditional sense, we might just create clones of ourselves, only “improved”. For example, say I’ve always wanted a fast metabolism, long life, and healthier teeth. It is only a matter of time (not much time) before I am able to plug- in a few parameters into a computer, and a few computational cycles (and a microwave ding) later obtain a better baby me.
  2. We are getting more and more comfortable messing with genes. In fact, we are making such fast advances that we are now able to not only understand gene functions, but we can add or remove specific genes, and even create entirely artificial genomes. To those of us who remember the old days of the computer world, when you had to make awesome looking games and demos from the ground up using x86 assembly, this is the genetic equivalent of inventing the C language. We are not yet to the point where we can create a modified human embryo with specific physical attributes (I want my clone male, buff, well endowed, and genius smart), but we are getting there in a hurry!
  3. Nature is helping us! Yes evolution is slow. Yes, mutations are almost always bad. Viruses are mostly bad for us. Yet, this 15 year old just changed her blood type and adopted a completely different immune system from a donor organ. It is only a matter of time before we discover and duplicate the processes involved in her “miracle”. When that happens, we will not only be able to receive donor organs (and limbs) from anyone, it may help us understand how to drastically improve the human body. I know a lot of women who would love to trade in some of their body parts for real better body parts. Forget silicone! Think real breast grown from your own cells!
  4. We will all be nearly immortal. Which means we will have more time to play scientists to improve the next generation. In case you haven’t noticed, the somewhat exponential growth in computer performance had all kinds of hardware limitations along the way that we promptly resolved using computers themselves. What I am trying to say here is that as we get smarter and better with each generation, so will our science, and therefore our ability to affect the next generation of humans.

Don’t be alarmed, you are already obsolete. There is no reason to panic. Your kids are already way smarter and more technologically savvy than you’ll ever be. Chalk it up to improved nutrition, or government experiments on the masses. Whatever makes you feel better about yourself. I am personally very excited to see all of this and I just hope I will live long enough to see humans control their environment by thought alone…what? already? I guess we can accomplish anything we imagine. Let’s just hope imagination can keep up.