This is a simple app that we'll build together at CharlotteJS meetup on June 20, 2013. The library app uses localStorage for our store.
Bit.ly URL to this repo: http://bit.ly/cjs-backbone
If you want to work off of the build-out branch to try and build the app yourself, here are steps you'll need to follow for each piece. Consult the Backbone Docs if you need refreshers on some of the methods.
- Make sure new model instances of default values:
titleStringauthorStringimgString Can useplaceholder.gifcompletedBoolean
 - Create a 
toggleStatusmethod- This method should toggle the value of the 
completedproperty and usesaveto save your method. - Your 
savecall should also include asuccesscallback handler that triggers thevisibleevent on the model. 
 - This method should toggle the value of the 
 
- Create your collection class using 
Bookfor your modelBookis the variable passed in to our module definition using RequireJS. This is a reference to the new model class we created in the first step.
 - Set up a new store, since this is just specific to our storage here is the code you will need to use:
localStorage: new Store( "anidentifier" )- This just sets up our collection to use Backbone.localStorage
 
 - Set up your 
comparatorproperty to sort the collection bycompleted. 
- Use an 
lias the view element and make sure its class attribute containsbook span4 - Create your template property and use Underscore's 
templatemethod usingtplas the content.tplis a variable defined in our module definition. This is a reference to our template in/templates/book.htmlif you want to reference the code.
 - Set up your events object to manage the view's DOM events. The list below is in an "event selector : callbackName" format.
"click .togglestatus" : "toggleStatus""click .destroy": "removeBook"
 - Create your 
initializemethod and inside set up listeners for model events. The list below is in "modelevent : methodName" format.change : renderdestroy : removevisible : toggleVisible
 - Create your 
rendermethod. In this method you'll need to use your template method to hand off your model's attributes and append them to the view element. - Create a 
toggleStatusmethod ( it should accept one argument for the event object )- First off, 
preventDefaulton the event (if there was a fallback URL we want to make sure we prevent it from loading). - Now, call our model's 
toggleStatusmethod. 
 - First off, 
 
- Create a 
removeBookmethod. In this method, we simply need to destroy the model. 
- Use the existing 
.bookshelfelement for your view element - Create your 
initializemethod and set up your collection event listeners and fetch the collection ( remember to pass{ reset: true }tofetchso that theresetevent fires )- Set up your collection event listeners (list is in "collectionevent : methodName" format):
add : renderreset : addBooks
 - Call 
fetchon your collection 
 - Set up your collection event listeners (list is in "collectionevent : methodName" format):
 - Create your 
rendermethod (hint: you'll need to passmodelin as a parameter)- Inside of 
rendercreate a newBookViewinstance and render it.BookViewis a variable defined in our module definition that references our model view that we created.
 - Append your new view instance element to the collection view element.
 
 - Inside of 
 - Create an 
addBooksmethod- In this method, you'll need to empty the current view element's HTML
 - You'll also need to utilize one of Underscore's proxied methods to iterate over our collection list. On each model in the collection, call our 
rendermethod. (hint: if you useforEachdon't forget to pass yourthiscontext) 
 
- Use the existing 
.appelement for your view element - Set up your events object to manage the view's DOM events. The list below is in an "event selector : callbackName" format.
"click a" : "filterBooks""click li.add a" : "showForm"submit: "createBook"
 - Create your 
initializemethod and do the following:- Go ahead and set up a couple cached jQuery objects that you can use throughout your view:
this.$filterBar- Should cache a jQuery collection for.nav-pills.this.$addForm- Should cache a jQuery collection for.addForm.- Remember, you can use 
$elto execute scoped jQuery object methods. 
 - Set up a collection event listener that will listen for the 
filterevent and call ourfilterBooksmethod. 
 - Go ahead and set up a couple cached jQuery objects that you can use throughout your view:
 renderis already created and filled out. This will keep track of our filter bar state as we step through the app to ensure that it matches current state.- Create the 
filterBooksmethod and do the following:- Use one of Underscore's proxied methods to iterate over the collection. On each model, trigger the 
visibleevent (hint: don't forget to pass yourthiscontext if you useforEach) - At the end of your method, call 
render(to make sure our filter bar is in active state) 
 - Use one of Underscore's proxied methods to iterate over the collection. On each model, trigger the 
 - Create the 
createBookmethod that will be used when the "Add Book" form is submitted. Do the following in your function body:- First off prevent the default form submission.
 - Then use 
createconvenience function to create a new model instance. To get the object of attributes to use for your new instance, you can callthis.newAttrs()which is set up already for you. - On the very last line of your method, call 
this.$addForm.modal( "hide" ). This is simply to hide our add a book form. 
 - There are a couple more methods that are already in the app view file, here's a brief explanation of both:
showForm- This is just going to show our modal to add a new book when the "Add a book" link is clicked.newAttrs- This is a convenience function to get all the form data being submitted in our new book form.
 
Now we want to set up our Application constructor. The constructor function is already defined in the file, we just need to create a few properties that each instance of our application will share.
Below where the steps mention to create a new instance, the variable reference is what we've defined in our RequireJS definition function. These names relate to the collection and views that we've required as a dependency in our app.
- Create a 
this.collections.booksproperty and create a newBookscollection instance. - Create a 
this.views.booksproperty and create a newBooksViewview instance (don't forget to pass our new collection above to our new view instance). - Create a 
this.views.appproperty and create a newAppViewview instance (don't forget to pass our new collection above to our new view instance). - Create a 
this.common.bookFilterproperty and assign it the value of an empty string for now. This is what we'll use to keep track of filter state across our app. - The last step is inside of the piece that is already filled out for you about localStorage. Inside that snippet you'll see 
"youridentifier". Just replace that string with whatever identifier name you chose when creating your new store on your collection. 
- Create your Router class.
 - Add a routes object that has 3 routes:
""that will be used as our main route that should callmain":type(/)"that will be used for our filter and should callsetFilter"*path"to see how we can use a catch all route.
 - Create our methods that we'll use when the routes above are matched:
main- Set 
window.library.common.bookFilterto an empty string.- You may be wondering where 
window.librarycomes from. We'll define that in our next step, but it simply refers to the newAppinstance that we create. We'll store it as a global so that we can reference it throughout our application. 
 - You may be wondering where 
 - Trigger 
filteron the collection (you'll access the collection atwindow.library.collections.books) 
- Set 
 setFilter- This method should accept a parameter that matches what our route matched.
 - Set 
window.library.common.bookFilterto equal the argument passed in to the method. - Trigger 
filteron the collection (you'll access the collection atwindow.library.collections.books) 
catchAll- This method is just to show what the catch-all route path looks like when using a *splat.
console.logthe path argument that gets passed in to the method
 
- This method is just to show what the catch-all route path looks like when using a *splat.
 
 
Down to the last step and just a few things to do here. At the top of this file is the RequireJS configuration for our app.  You'll want to scroll down to where you see the comment // Kick off our app and that's where you'll do your work. The snippet below shows where your code will go.
	// Kick off our app
	require( [
		"app",
		"router"
	],
	function( App, Router ) {
		// YOUR CODE WILL GO HERE
	});
There are 3 final steps that we need to do:
- Create a new 
Appinstance onwindow.library - Create a new 
Routerinstance onwindow.library.router - Tell Backbone.History to 
startwatching for changes. 
You should now be able to load your app in a browser and have a fully functional app that can add new books, delete books, and toggle the read status.
That doesn't mean you have to be done though! Extend the app more. Maybe enable the books to be edited? Perhaps drag-and-drop ordering? You're in control now. This could be the greatest library (you know one that catalogs books) that anyone has ever seen.