This post continues to answer "what is SmartJs". In this article we look at the J and the S. How is the SmartJs framework Single Page Application UI implemented with jQuery Mobile? Read on to find out...
UI Frameworks; pick one
I have tried a few frameworks for developing a mobile application UI. The the number one reason to love jQuery Mobile over things like Sencha Touch or Titanium Appcelerator, is that it allows the UI to be written in pure Html and Css. For me, other UI frameworks violate separation of concerns, when they make me compose my UI inside JavasScript files. That is why we have Html and Css, to build the UI. The especially strange feeling is when they make me use proprietary JavaScript objects to build UI's. It reminds me of a Telerik or Infragistics library kind of control I've encountered several times in the .Net world. Almost always, these would end up being trickier to integrate with when you wanted something special.
Other things I like about jQuery Mobile are:
Other things I like about jQuery Mobile are:
- It looks good
- It has a great code generator in Codiqa
- It has a great theme generator in Themeroller
- It has a rich set of widgets
- It is compatible with jQuery
- It is easy to bind to Knockout Js
- It is being actively developed and improved
- Just like everything else in SmartJs it is free, free, free
Codiqa UI; WYSIWYG Generator for jQuery Mobile
It can be daunting when you look at jQuery Mobile Html markup. There seem to be a lot of attributes that one needs to know to get the proper effects. Enter Codiqa UI to get you quickly started without having to write a single tag of that Html. If you hit the jQueryMobile homepage, there is a free demo of Codiqa where you can actually do quite a bit without ever even needing to open an account. Just drag and drop your UI elements and then customize them for your app. Then hit "Inspect Code" and copy and paste the generated source code into your app's html view file. From there it's easy to add some Knockout bindings to the Html to connect it to your ViewModels.
Bootstrapping jQuery Mobile and Phonegap
A good deal of work and research has gone into properly bootstrapping the SmartJs SPA and getting all of the libraries to work together cleanly. The startup sequence looks something like this:
In different situations the events can be received in different orders. So we need a flexible solution that works independently of timing. The SmartJs main.js file shows how this can be done.
Click here to view the SmartJs main.js bootstrap file on github.
- index.html includes Cordova directly. Cordova has its own built-in AMD implementation that registers itself as a module named "cordova".
- index.html then uses the regular RequireJs method to get to the app/main.js module
- Inside main.js we require jQuery and jQuery Mobile first
- We use jQuery to attach an event handler to document to handle the ready event. This seems to be good enough to begin using jQuery Mobile
- In the case of a mobile-targeted build configuration, we attach an event handler to the deviceready event that will be fired when Cordova has initialized. According to Phonegap documentation, a Phonegap app "shouldn't do anything" until this is received.
In different situations the events can be received in different orders. So we need a flexible solution that works independently of timing. The SmartJs main.js file shows how this can be done.
Click here to view the SmartJs main.js bootstrap file on github.
Keeping the Knockout-bound jQm Listview updated
When binding a jQuery Mobile Listview to a Knockout ViewModel, Knockout is going to come along and regenerate the Html whenever the underlying ViewModel changes. When that happens, jQueryMobile needs to be notified that the listview should be refreshed. That's because jQueryMobile does some post-processing to the normal <ul> and <li> markup of a list to turn it into a super special jQueryMobile list.
But how do we cleanly separate that concern from the ViewModel? We surely don't want to have to call a function that manually updates the View each time we update the ViewModel. Fortunately, we have the Knockout binding handler concept which is perfectly suited for the task.
Below is SmartJs's binding handler for the purpose of refreshing the jQuery Mobile Listview. To re-render other jQuery Mobile widgets after dynamically adding content, a binding handler should be created for each kind of widget, because currently jQuery Mobile's widgets each have their own "unique" way of refreshing themselves that you will need to research.
But how do we cleanly separate that concern from the ViewModel? We surely don't want to have to call a function that manually updates the View each time we update the ViewModel. Fortunately, we have the Knockout binding handler concept which is perfectly suited for the task.
Below is SmartJs's binding handler for the purpose of refreshing the jQuery Mobile Listview. To re-render other jQuery Mobile widgets after dynamically adding content, a binding handler should be created for each kind of widget, because currently jQuery Mobile's widgets each have their own "unique" way of refreshing themselves that you will need to research.