Nested Question List

by hoffmanc

HTML

<script src="http://documentcloud.github.com/underscore/underscore.js"></script>
<script src="https://github.com/downloads/wycats/handlebars.js/handlebars-1.0.0.beta.6.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone.js"></script>
<script src="https://raw.github.com/derickbailey/backbone.marionette/master/src/backbone.marionette.js"></script>
            <div id='questions'></div>

    <script type='text/template' id="question-template">
        <li>{{defaultText}}</li>
    </script>

CSS

ul {
  list-style: disc;
  margin: 10px;
  padding-left: 10px;    
}

JavaScript

// customizations
// http://derickbailey.github.com/backbone.marionette/#backbone-marionette-renderer/caching-pre-compiled-templates
Backbone.Marionette.TemplateCache.loadTemplate = function(template, callback){
  // pre-compile the template and store that in the cache.
  var compiledTemplate = Handlebars.compile($(template).html());
  callback.call(this, compiledTemplate);
};

Backbone.Marionette.Renderer.renderTemplate = function(template, data){
  // because `template` is the pre-compiled template object,
  // we only need to execute the template with the data
  return template(data);
}

// MODELS
var QuestionTreeNode = Backbone.Model.extend({
    initialize: function(){
        var questions = this.get("questions");
        if (questions){
            this.questions = new QuestionTreeNodeCollection(questions);
            this.unset("questions");
        }
    }        
});

// COLLECTIONS
var QuestionTreeNodeCollection = Backbone.Collection.extend({
    model: QuestionTreeNode
});

// VIEWS

// The recursive tree view
var QuestionTreeView = Backbone.Marionette.CompositeView.extend({
    template: "#question-template",
    tagName: "ul",
    initialize: function(){
        // grab the child collection from the parent model
        // so that we can render the collection as children
        // of this parent node
        this.collection = this.model.questions;
    },
    appendHtml: function(collectionView, itemView){
        // ensure we nest the child list inside of 
        // the current list item
        collectionView.$("li:first").append(itemView.el);
    }
});

// The tree's root: a simple collection view that renders 
// a recursive tree structure for each item in the collection
var QuestionTreeRoot = Backbone.Marionette.CollectionView.extend({
    
    questionIdx: null,
    
    itemView: QuestionTreeView,
    onRender: function() {
        this.$el.sortable({
            items: 'li',
            placeholder: 'ui-state-hover'            
       ...