JSFiddle - React, Tailwind, and code Playground

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>
<h1>Survey Designer</h1>
<p>This page is a testing ground for building a new survey designer interface, using Backbone.js</p>

<div id='questions'></div>

    <script type='text/template' id="question-template">
        <span class='handle'>↕</span>
        {{defaultText}}
        <ul data-id='{{id}}'></ul>
    </script>

CSS

ul {
  list-style: none;
  margin: 10px;    
}

span.handle{
  cursor: move;
  margin-right: 10px;
}

h1 {
    font-size: 18pt;
}

.ui-state-hover {
    background-color: #990;
    height: 1em;
}

JavaScript

SDApp = new Backbone.Marionette.Application();

// 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) {
            n = this;
            this.questions = new QuestionTreeNodeCollection(
                _.map(questions, function(q) { return _.extend(q, {parent: n}); })
            );
            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: "li",
    events: {
        'question:move': 'moveQuestion'
    },
    moveQuestion: function(event, parentId, pos) {
        this.$el.trigger('question:move:approved', [this.model, parentId, pos]);
    },
    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(cv, iv) {
        // ensure we nest the child list inside of 
        // the current list item
        cv.$("ul:first").append(iv.el);
    },
    onRender: function() {
        if (_.isUndefined(this.collection))...