A few weeks weeks ago, I posted a first Backbone.js and Twitter Bootstrap sample application. While interesting, “Employee Directory” is a read-only application. As such, it doesn’t show off the full power of Backbone’s models or the coolness of some of Bootstrap’s data entry features such as forms, validation, etc.
To demonstrate these features, I decided to revisit my wine cellar application, which was in need of a serious UI makeover.
You can run the application here.

This online version uses an in-memory datastore: all your changes will be lost the next time you start the application or hit your browser’s refresh button. The image upload feature is also disabled, but you can still drag an image from your file system and drop it in the Wine Form, which is pretty cool (see the note about browser support below). The source code available on GitHub includes a persistent back-end (in addition to the in-memory datastore), and a fully functional implementation of the file upload feature.
Code Highlights
Template Loader
This application features a template loader that now uses jQuery “deferreds” to load the HTML templates more efficiently.
Drag-and-Drop File Upload and HTML 5 File API
To upload an image file for a Wine, drag a file from your file system and drop it in the image box inside the Wine Form: The image is automatically displayed inside the img tag. This is done using the HTML 5 File API and doesn’t require a server roundtrip.
NOTE: This feature only works in Chrome at this time. I will implement an alternative implementation in a future version of the application to provide a consistent behavior across browsers.
The image is uploaded to the server using Ajax (XHR) when you save the form: no page refresh or iframe hack.
Twitter Bootstrap provides easy markup and styles to create paginated lists. In this application, the Bootstrap markup and styles are “componentized” or “widgetized” into a Backbone View (Paginator), which adds the appropriate pagination behavior. NOTE: In the current implementation of this application, the entire data set is always retrieved from the server and paging is provided for a cosmetic/layout reason. You could easily replace this implementation with a true paging strategy where pages are lazy-loaded from the server as needed. Backbone Cellar also uses Twitter Bootstrap’s forms, which greatly help with form layouts (see WineView). Twitter Bootstrap also provides simple markup and styles to highlight validation errors in forms. In Backbone Cellar, Bootstrap’s validation markup and styles are wired with validation rules defined in the Backbone model. Note that at this time, the application doesn’t use the Backbone model’s default validate() method, but custom validateItem() and validateAll() methods instead. The application also uses other Twitter Bootstrap features including thumbnails, dropdowns, alerts, etc. The source code is available in the bootstrap folder of the backbone-cellar repository on GitHub. This is a sample application, not a production application. Some trade-offs were made to keep the code generic, simple and readable. In a real-life application, you should consider implementing a namespacing scheme to keep the global namespace clean, and other optimization techniques such as view and/or data caching.Forms
Validation
Source Code
Disclaimer

wonderful and useful examples
thx
Mani
Thanks. Really really useful.
great great great thanks!
Great work! A quick note: the content is obscured by the header on an iPad.
yahooooooooooooooooooooooooooooooooooooooooo !! Perfect, thank you so much.
Perfect. Perfect. Perfect. Thanks a lot.
Dream comes true
As usual all posts from you are very helpful. Just picked up Backbone.js 1hr back and i already know everything about it. Thank You.
Hi. Have you implemented modal windows with backbone.js yet? I can’t seem to get it working.
Other than that, great example!
What webserver are you using? I’m trying to run a similar app using lighttpd on ubuntu but I can’t seem to figure out how to configure lighttpd to work properly with Slim in a subdirectory. Any insights?
Thanks for the tutorial by the way. It’s very helpful.
You’ll have to set up virtual host in lighttpd.conf
assuming you’ve created cellar folder in lighttpd/cellar/
$HTTP["host"] =~ “cellar” {
server.document-root = “/home/lighttpd/cellar/http”
}
For localhost.cellar or cellar.localhost
$HTTP["host"] =~ “(^|\.)cellar\.localhost$” {
server.document-root = “/home/lighttpd/cellar/http”
}
Forgot to add that you need to have the api folder in root for this work and slim inside the folder.
Thank Mr Coenraets. This sample’s very helpful.
Great work Mr Coenraets.
This is exactly the framework I was looking for when developing my proof of concept. There is one issue I can’t get around though. I can’t connect to mysql to pull records from. I have rechecked my api/index.php several times but still no luck. I removed .
”
To use the app with a persistent RESTful back-end (provided in the GitHub repo), simply comment out the line below.
”
Do I need to implement anything else???
Any suggestions as I’m running out of ideas.
Thanks
Great Tutorial, Thank you!
I have found 2 small things:
1. The tagName for the WineListItemView is set to ‘li. But your template for the items also contains the so that you end up with two for every element.
2. The code in the description is not the same as the code in the example.
in the example i found the el: $(‘#wineList’) – not in the description.
Thanks for the great tutorial, however this works with 1 model only. It would be greate if you could make a tutorial on how to use nested views (when top view switches pages and nested view displays the items).
Hi Christophe
Great App!
I Have one question:
Why when I try to add a wine the framework said: “Success! Wine saved successfully”. However when I check my database on wine don’t appear the new resource.
Thanks!!
I believed you forgot to uncomment the “” line in index.html.
I forgot to remove the script tags. What I meant to say was you did not uncomment the line where “script src=”js/memorystore.js” can be found.
Hi
I’m a beginner so I read your post with great interest. About the paginator, I think it would be more interesting for performance to create a variable with a list of pages to be displayed and then injecting it into the DOM. Something like:
window.Paginator = Backbone.View.extend({
className: “pagination pagination-centered”,
initialize:function () {
this.model.bind(“reset”, this.render, this);
this.render();
},
render:function () {
var items = this.model.models;
var len = items.length;
var pageCount = Math.ceil(len / 8);
$(this.el).html(”);
var pages = ”;
for (var i=0; i < pageCount; i++) {
pages += "” + (i+1) + ““;
};
$(‘ul’, this.el).append(pages);
return this;
}
});
thanks for such amazing tutorials!
i am a beginer with Bootstrap and I am having the following issue:
-the nav bar won’t show in the browser :(
what could be the problem? when running the app in Dreamweaver I can see all of it!
thanks again
When I try to add new model to database using slim.php, it is showing “Error An error occurred while trying to add this item”. But when I am trying to fetch, update, delete its working good. Why it is showing error only on adding ?
bootstrap/js/views/winedetails.js
Great tutorial and demo. I have learned backbone by following ur simple demos. I have forked this project to include require.js for AMD support.
https://github.com/phillycoder/backbone-require-cellar
Thanks
Great Tutorial.
I m able to get the pagination work. I have two problems which may be very silly.
a) How do i make the pagination limited to only 5 pages. Say i got 100 pages. I show only the 2 previous and 2 next pages along with next, previous link.
b) I find in Network Tab that on each page click collection is being reloaded. I want to avoid that. Just load the collection once and then show the result.
Thanks once again.
Great tutorial.
I got problem when trying to change the picture. Tested with Chrome(win7)
How to upload image file using the the framework.
very blog good
Great!
I was looking such tutorial for long time.
thanks for sharing. keep it up.
There are many global variables which may be conflict which other library. I think it should be wrap it in single object.
http://stackoverflow.com/questions/15876225/layout-similar-to-google-chrome-application-tab
I tried running the project locally and the local datastore only loads in Safari, not Chrome or Firefox. Any ideas?
It is really a good and useful piece of information. I’m satisfied that you simply shared this useful information with us. Please stay us informed like this. Thanks for sharing.
fantastic problems altogether, you simply received a new reader. What would you recommend in regards to your submit that you simply simply produced some days in the past? Any certain?
good app
i’m beginner and taking ur app as a starting point.
questions. the drop in functionality doesnt work.
and also how can i add a select drop down to the view.
thanks