A template to use jquerymobile with backbone.js and handlebars.js
JavaScript
Latest commit 63e8f9d Mar 29, 2013 @raDiesle fix 0.4.0 configurations

readme.md

Current Status

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.

Backbone and jquerymobile JQM Boilerplate code

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

Table of contents

Quick start

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

// 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 application

// 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

BasicView

Use case:

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)

How to use:
  • 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
Examples:

An example usage for a simple JQM page:

ConcreteExampleView = BasicView.extend({
    id: "content",
    getSpecificTemplateValues : function(){
        return "something"
    }
});

BasicDialog

Use case:

It will render the page as dialog with or without validation. The previous page will be displayed transparent.

How to use
  • 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;
}
Examples
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)
            }
        });
    });

Validateable

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

Use case

Pages, where validation has to be applied. The validate rules are part of the model under this property this.model.settings.validation.rules

How to use
  • 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;
}
Examples
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()});
            }
        });
    });

Registering handlebars.js templates

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

dynamic scripting and jQuery Mobile

see jQuery Mobile documentation There are two ways to render HTML code (loaded by template) to jQuery Mobile HTML code:

Usage of grunt

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.

Additional Grunt-Contrib tasks

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.

jQuery Mobile Settings

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)

TODO

  • 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
References and similar projects

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 !