Overview
Backbone UI provides a simple way to represent your Backbone Models and Collections as UI components. The need to shuffle data in and out of your UI is replaced with simple data binding techniques. All components are skinnable with CSS, and will render consistently accross browsers. The source is hosted on github with an MIT license.
Philosophy
This framework is written to embrace the DOM rather than fight it. You won't see any messy HTML templates or
innerHTML
references hanging around. What you will see is heavy use of the laconic library to help ease the pain of DOM manipluation so we can happily stay in the context of writing JavaScript.
Not all people will agree with this philosophy, and not all projects will benefit from embracing it. This framework facilitates the creation of highly dynamic front-end clients that request only data from the back-end, not markup. If you have a more traditional application in which your markup is generated before your JavaScript executes, you may still find this framework useful, but keep in mind that it was not designed for such a case.
Another major theme you'll encounter is the concept of data binding. This means that you tell your component which property of the model it's responsible for rendering, and then you forget about shuffling data back and forth. If the model's value changes, the component will re-render. If the user changes the value, the model will be updated. Easy.
Dependencies
Backbone UI depends on Backbone, Underscore, jQuery, and laconic. If you'd like to use the calendar or date picker components, than you'll also need a copy of moment.js.
Components
All components inherit from Backbone.View, and each render method will return a reference to the view itself. Feel free to pass any standard Backbone View option when creating these components. As a convenience, the underscored version of the component's class name will be added to each component's element.
Components can be broken down into four categories:
- Model Bound
- Model Bound with Alternatives
- Collection Bound
- Non-Bound
The following data will be used throughout the examples:
window.regions = new Backbone.Collection([{ name: 'Americas', notes: 'Bright' }, { name: 'Africa', notes: 'Fruity' }]); window.coffee = new Backbone.Model({ roaster: 'Counter Culture', name: 'Baroida', roastedOn: new Date(2012, 2, 28, 6, 30), acidic: true, region: regions.at(0) });
Model-Bound
Model-Bound components are those that interact directly with one property of a single model.
Button
var button = new Backbone.UI.Button({ model: coffee, content: 'roaster' }).render();
Calendar
Checkbox
Date Picker
var picker = new Backbone.UI.DatePicker({ model: coffee, content: 'roastedOn' }).render();
Link
var link = new Backbone.UI.Link({ model: coffee, content: 'roaster' }).render();
Text Area
var area = new Backbone.UI.TextArea({ model: coffee.get('region'), content: 'name' }).render();
Text Field
var field = new Backbone.UI.TextField({ model: coffee, content: 'roaster' }).render();
Time Picker
var picker = new Backbone.UI.TimePicker({ model: coffee, content: 'roastedOn' }).render();
Model-Bound with Alternatives
These components are similar to regular Model-Bound components, but also include a bound collection of alternatives. The
model
and property
options are still used to define the selected value, and following additional options describe the collection of alternatives:Pulldown
var pulldown = new Backbone.UI.Pulldown({ model: coffee, content: 'region', alternatives: regions, altLabelContent: 'name' }).render();
Radio Group
var group = new Backbone.UI.RadioGroup({ model: coffee, content: 'region', alternatives: regions, altLabelContent: 'name' }).render();
Collection-Bound
These components are bound to a Backbone.Collection as opposed to a Model. The rendering of a particular item in the collection is defined by the given itemView implementation.
List View
var Item = Backbone.View.extend({ render: function() { $(this.el).empty(); $.el.div(this.model.get('name')).appendTo(this.el); } }); var list = new Backbone.UI.List({ model: regions, itemView: Item }).render();
- Americas
- Africa
Table View
Table Views are similar to List Views, but allow you to pass a small amount of table meta-data as opposed to writing your own itemView implementation.
var table = new Backbone.UI.TableView({ sortable: true, model: regions, onItemClick: function(model) { alert(model.get('name')); }, columns: [{ title: 'Name', content: 'name' }, { title: 'Notes', width: 100, content: 'notes' }] }).render();
▼
Name
|
Notes
|
---|
Non-Bound
The following components are not meant to be bound to a model or collection, and exist as general-purpose UI elements.
Scroller
var lorem = "Lorem ipsum dolor sit..." var scroller = new Backbone.UI.Scroller({ content: $.el.p({ style: 'height:150px' }, lorem) }).render();
Tab Set
var set = new Backbone.UI.TabSet({ tabs: [{ label: 'Foo', content: "foo's content" }, { label: 'Bar', content: "bar's content" }, { label: 'Baz', content: "baz's content" }] }).render();
foo's content
Glyphs
Many components may be rendered with an optional glyph on the left or right side. A glyph is a 16 x 16 pixel image stored in the
Backbone.UI.GLYPH_DIR
(which defaults to /images/glyphs). Here's some examples:
And here's how you can put them to use:
var button = new Backbone.UI.Button({ content: 'Edit', glyphRight: 'pencil' }).render();
var link = new Backbone.UI.Link({ content: 'Idea', glyph: 'lightbulb' }).render();
var pulldown = new Backbone.UI.Pulldown({ alternatives: [{ name: 'save', glyph: 'disk' }, { name: 'trash', glyph: 'delete' }], altLabelContent: 'name', altGlyph: 'glyph' }).render();
Browser Support
Backbone UI has been tested on most modern browsers, as well as IE8+. If you're using the HTML 5 Doctype, you may need to use the following meta tag to force IE into standards mode:
<meta http-equiv="X-UA-Compatible" value="IE=edge" />
Example Application
What would a framework be these days without an example task list application.
The entirety of this application is listed below:
// create a sorted backbone collection to store our tasks var tasks = new Backbone.Collection([], { comparator: function(task) { return task.get('done') ? 1 : 0; } }); // define how each individual task should render var TaskView = Backbone.View.extend({ render: function() { $(this.el).empty(); // add a link to remove this task from the list this.el.appendChild(new Backbone.UI.Link({ glyph: 'delete', onClick: _(tasks.remove).bind(tasks, this.model) }).render().el); // a checkbox to mark / unmark the done status of this task this.el.appendChild(new Backbone.UI.Checkbox({ model: this.model, labelContent: 'title', content: 'done' }).render().el); } }); // create our list view to render our collection var list = new Backbone.UI.List({ itemView: TaskView, model: tasks}).render(); // create a text field to add new items var newItem = new Backbone.Model; var field = new Backbone.UI.TextField({ model: newItem, content: 'title', placeholder: 'add a new item', onKeyPress: function(e) { if (e.keyCode == 13) { list.options.model.add(newItem.clone()); newItem.set({ title: undefined }); } } }).render(); var appEl = $.el.div(field.el, list.el);
No comments:
Post a Comment