24.March.2013
For more information about this project, more explanations and updates go to
https://github.com/raDiesle/backbone-fundamentals/blob/gh-pages/chapters/10-mobile-applications.md
as well as
https://github.com/raDiesle/backbone-fundamentals/tree/gh-pages/practicals/todo-jqm-app
which was already merged with the trunk and will be released in the book.
This project provides a bulletproof template + build process to develop an application by using jQuery mobile and backbone.js The aim is to provide it in Addy Osmanis Backbone Fundamentals
It consists of:
-
Backbone.js 0.9.2
-
extended super call (supports multiple hierarchies of inerheritance)
-
Lodash ( performance improved version of underscore + AMD support) 0.5
-
jQuery Toolkit 1.8.0
-
jQuery Mobile 1.1.1
-
Require.js (as an AMD loader) 2.0.5
-
Handlebars.js ( instead, underscore js or any other template engine can be used) 1.0.beta.6
-
Grunt.js as build tool, like ant or maven, to precompile handlebars.js templates, and r.js optimizer tasks
-
Grunt bbb a collection of tasks, containing grunt-contrib task collection
-
code structure and super-classes for clean code and easy reuse
- General
- Basic classes : Basic View [Basic Dialog] (#basicclasses_basicdialog) Validateable
- Handlebars
- Grunt
- Grunt-contrib
- Settings
- Todo
- References
Preparations:
- Checkout from git with your favourite tool or cmd. For those who are new, I would recommand usage of Eclipse Git, Webstorm or Tortoise Git
- Open your command line tool
- cd to the project folder "backbone.js-jquerymobile-boilerplate-template"
- Download and install node.js for your os system and run in your project folder:
// Installation setup, 0.4.0 grunt required npm uninstall -g grunt npm install -g grunt-cli npm install grunt --save-dev npm install -g bbb
// To install grunt-tasks e.g.: npm install grunt-release --save-dev npm install grunt-contrib --save-dev npm install grunt-contrib-connect --save-dev ...
// Run the application grunt server
// While developing to recreate handlebar templates: grunt liveload
// Manual update handlebars templates grunt handlebars
// first steps to create prod release files grunt release
###General
###Abstract classes for simple usage
For any jQuery mobile page view. (To e.g. support transparent dialogs, the page will be removed from the DOM when the same page is requested again)
- getSpecificTemplateValues() is an abstract method. The json values are used for the handlebars.js context variables.
- id is the pageID, which will automatically load the name of the template
- if you want to use your own page template ( instead of "basic_page_simple"), override getTemplateID in your class
An example usage for a simple JQM page:
ConcreteExampleView = BasicView.extend({
id: "content",
getSpecificTemplateValues : function(){
return "something"
}
});
It will render the page as dialog with or without validation. The previous page will be displayed transparent.
- Define transparentBackgroundPageElID, which is the previous pageID
- Define this.model.settings.validation.rules as validation rules. (see jQuery.Validation for more information)
- Override onSuccessfulValidation : function(){}, which will be called, per default, if the form was submitted and validation is successful.
.transparent {
background-color: orange;
zoom: 1;
filter: alpha(opacity = 50);
opacity: 0.5;
}
.ui-dialog-background {
opacity: 0.5;
display: block !important;
-webkit-transition: opacity 0.5s ease-in;
}
define([
"backbone", "modules/view/abstract/BasicDialog"],
function (Backbone, BasicDialog) {
return BasicDialog.extend({
id : "editTodoDialog",
model : new Backbone.Model.extend({
settings : {
validation : {
rules : {
title : {
"required" : true,
"min" : 5
}
}
}
},
}),
headerTitle : "Edit Todo",
transparentBackgroundPageElID : "Todos",
getSpecificTemplateValues : function () {
return this.model.toJSON();
},
onSuccessfulValidation : function () {
this.model.save({title : $("#edit_title", this.el).val()});
window.location = ""; // route to another page(close dialog)
}
});
});
Extending Validateable will use the jquery.validate plugin with jquery mobile like described here: http://www.elijahmanor.com/2011/02/jquery-mobile-form-validation.html
Pages, where validation has to be applied. The validate rules are part of the model under this property this.model.settings.validation.rules
- Define this.model.settings.validation.rules as validation rules. (see jQuery.Validation for more information)
- Override onSuccessfulValidation : function(){}, which will be called, per default, if the form was submitted and validation is successful.
label.error {
color: red;
font-size: 16px;
font-weight: normal;
line-height: 1.4;
margin-top: 0.5em;
width: 100%;
float: none;
}
define([
"backbone", "modules/view/abstract/Validateable"],
function (Backbone, Validateable) {
return Validateable.extend({
id : "editTodoDialog",
model : new Backbone.Model.extend({
settings : {
validation : {
rules : {
title : {
"required" : true,
"min" : 5
}
}
}
},
}),
headerTitle : "Edit Todo",
getSpecificTemplateValues : function () {
return this.model.toJSON();
},
onSuccessfulValidation : function () {
this.model.save({title : $("#edit_title", this.el).val()});
}
});
});
run to compile all templates found in app/templates to dist/debug/ Partials will be registered to Handlebars.partials, Templates to window.JST['templateName'] by default.
bbb handlebars or bbb watch
see jQuery Mobile documentation There are two ways to render HTML code (loaded by template) to jQuery Mobile HTML code:
- $.mobile.changePage(domEl, {}); // Methods & Utilities
- $("domNodeAccessor").trigger("create"); // Scripting pages in jQuery Mobile - Enhancing new markup section
GRUNT:
- concat - Concatenate files.
- init - Generate project scaffolding from a predefined template.
- lint - Validate files with JSHint.
- min - Minify files with UglifyJS.
- qunit - Run QUnit unit tests in a headless PhantomJS instance.
- server - Start a static web server.
- test - Run unit tests with nodeunit.
- watch - Run predefined tasks whenever watched files change.
clean
- Clear files and folders.
coffee
- Compile CoffeeScript files into JavaScript.
compress
- Compress files and folders using gzip or zip.
handlebars
- Compile handlebars templates to JST file.
jade
- Compile Jade templates to HTML.
jst
- Compile underscore templates to JST file.
less
- Compile LESS files to CSS.
mincss
- Minify CSS files.
requirejs
- Optimize RequireJS projects using r.js.
stylus
- Compile Stylus files into CSS.
To support right behavior in e.g. navigation and use default backbone.js routing, use the following properties:
$(document).bind("mobileinit", function(){
$.mobile.ajaxEnabled = false;
$.mobile.hashListeningEnabled = false;
$.mobile.pushStateEnabled = false;
$.mobile.linkBindingEnabled = false;
$.mobile.defaultPageTransition = "none";
$.mobile.page.prototype.options.degradeInputs.date = true; // optional
$.mobile.page.prototype.options.domCache = false; // optional
$.mobile.defaultDialogTransition = "none"; // optional depends on performance
});
If you want to enable transitions per device ( where you expect good performance) you can use logic per device like described here http://backbonefu.com/2012/01/jquery-mobile-and-backbone-js-the-ugly/:
var iosDevice = ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))) ? true : false;
$.extend( $.mobile , {
slideText : (iosDevice) ? "slide" : "none",
slideUpText : (iosDevice) ? "slideup" : "none",
defaultPageTransition:(iosDevice) ? "slide" : "none",
defaultDialogTransition:(iosDevice) ? "slide" : "none"
});
Backbone.history.start({ pushState: false }); is used to work properly with forward/back buttons pushState: true will only work with modern browsers( fails for some mobile browsers as well)
- Make an Addy Osmani TodoMVC application out of it. -> ongoing
- Implement good back button functionality e.g. for dialog
- add subview support with jQuery Mobile and backbone -> partly
- Extend documentation
- Write a chapter in Addy Osmani Backbone fundamentals about this project
- Add tests ( jasmine + sinon.js + + phantom.js ? + continous integration with jstestdriver and jenkins)
- Make a mobile + desktop app out of it, using common code
uses the jQuery Mobile Router plugin ( extends/manipulates the existing backbone.js routing)
The knowledge about how to run JQM with backbone is partially derived by results of several resources:
http://stackoverflow.com/questions/10904433/jquery-mobile-require-js-and-backbone
http://addyosmani.github.com/backbone-fundamentals/
http://coenraets.org/blog/2012/03/using-backbone-js-with-jquery-mobile/
https://github.com/azicchetti/jquerymobile-router
https://github.com/buildmobile/backbone.js/tree/master/js
Thanks for them !