Small Town Coder

sharing code samples for desktop, web, and mobile

BBUI ActionBar using Backbone and jQuery

I will admit that creating web and app UIs is not an strength that I can brag about. Fortunately, the work being put into UI frameworks such as jQuery Mobile, Sencha, and even BBUI for BlackBerry 10 allow me to focus more on the back end of my apps instead of the presentation.

At this point, I'm spending most of my time trying to learn as much about each of these UI frameworks along with other app frameworks such as Backbone.js. In this example, I've used Backbone.js, jQuery, and BBUI together to create and render a BBUI ActionBar into a BBUI screen.

The sample uses the following JavaScript, CSS, and HTML files:

  • jquery-1.8.2.min.js
  • underscore-min.js
  • backbone-min.js
  • bbui.js
  • app.js (sample javascript file containing application logic)
  • bbui-min.css
  • index.html (file referenced in WebWorks config as the content source)
  • main.html (BBUI screen html fragment file)

The index.html file looks like this:

<!DOCTYPE html>
<html>
  <head>
    <title>BBUI ActionBar using Backbone and jQuery</title>
	<link rel="stylesheet" type="text/css" href="resources/css/bbui-min.css"/>
	<script type="text/javascript" src="resources/js/jquery-1.8.2.min.js"></script>
	<script type="text/javascript" src="resources/js/underscore-min.js"></script>
	<script type="text/javascript" src="resources/js/backbone-min.js"></script>
	<script type="text/javascript" src="resources/js/bbui.js"></script>
	<script type="text/javascript" src="resources/js/app.js"></script>
  </head>
  <body>

  </body>
</html>

The main.html file looks like this:

<div id="mainscreen" data-bb-type="screen">
	<!-- container for content rendered with Backbone -->
	<div id="content">

	</div>
</div>

The "content" div is merely a container for additional Backbone Views that are not part of this example.

My app.js file contains event handlers for initializing BBUI as well as the Backbone Views that will be rendered into the main screen.

var TabBar;

function changePage(url) {
	bb.pushScreen(url);
}

$(document).bind('webworksready', function() {
	bb.init({
		onscreenready: function(e) {
			TabBar = new ActionBar();
			$(TabBar.el).appendTo(e);
		},
		ondomready: function(e) {
			bb.actionBar.apply(TabBar.el);
		}
	});
	bb.pushScreen('main.html', 'mainscreen');
});

var ActionBar = Backbone.View.extend({
	tagName: 'div',
	attributes: {
		'data-bb-type': 'action-bar'
	},
	initialize: function() {
		this.collection = new Backbone.Collection([
			{'style': 'tab', 'overflow':false, 'icon':'resources/images/actionbar/document.png', 'caption':'Documents', 'url':'documents'},
			{'style': 'tab', 'overflow':false, 'icon':'resources/images/actionbar/photo.png', 'caption':'Photos', 'url':'photos'},
			{'style': 'tab', 'overflow':false, 'icon':'resources/images/actionbar/movie.png', 'caption':'Vidoes', 'url':'videos'},
			{'style': 'tab', 'overflow':false, 'icon':'resources/images/actionbar/music.png', 'caption':'Music', 'url':'music'}
		]);
		this.render();
	},
	render: function() {
		for (var i = 0; i < this.collection.length; i++) {
			$(this.el).append(new ActionBarItem({ model: this.collection.at(i) }).el);
		}
		return this;
	}
});

var ActionBarItem = Backbone.View.extend({
	tagName: 'div',
	attributes: {
		'data-bb-type': 'action'
	},
	initialize: function() {
		this.render();
	},
	events: {
		'click': 'onclick'
	},
	render: function() {
		$(this.el).attr('data-bb-style', this.model.get('style'));
		$(this.el).attr('data-bb-overflow', this.model.get('overflow'));
		$(this.el).attr('data-bb-img', this.model.get('icon'));
		$(this.el).text(this.model.get('caption'));
		return this;
	},
	onclick: function() {
		alert(this.model.get('url'));
	}
});

Code Breakdown

A requirement of BBUI is that it must be initialized within the "webworksready" event by calling bb.init(). Within bb.init, I attach handlers to the "onscreenready" and "ondomready" events in order to create and render my ActionBar view. BBUI fires the "onscreenready" event whenever the html screen fragment file has been loaded but not yet inserted into the dom. The "ondomready" event fires after the html screen fragment has been inserted into the dom.

ActionBar View

The ActionBar view is responsibile for rendering the BBUI ActionBar container as well as holding the ActionBar item configurations in a Backbone collection. In the "render" function, each ActionBar item in the collection is passed to a new instance of the ActionBarItem view which is responsible for rendering the individual items. The JSON model data in the collection determines the attributes of each individual item.

ActionBarItem View

The ActionBarItem view is responsible for rendering either a tab or a button within the ActionBar depending on the model data as well as handle the click event for the item. The render function adds the appropriate attributes to the element using the values contained within the model. The onclick event map function queries the url attribute from the model which could be a reference to a html screen fragment (passed into bb.pushScreen) or a key to another Backbone view that can be rendered into the current screen fragment (remember the "content" div).

Summary

This example has been successfully tested using the Ripple extension in Google Chrome. I have not tested on an actual BB10 device since it hasn't been released yet (at the time of this post) and I also don't have a Dev Alpha (sigh) to work with.

As always, I gladly accept comments on my work. I'm learning from other examples out there and hope that by sharing, I've helped you too.