JSFiddle - React, Tailwind, and code Playground

by milosdakic

HTML

<script src="https://raw.github.com/documentcloud/underscore/master/underscore-min.js"></script>
<script src="https://raw.github.com/documentcloud/backbone/0.9.2/backbone-min.js"></script>
<ul id="tabs" class="tabs">

</ul>

<input id="change-name" />
<button id="add-tab">Add Tab</button>

<script id="tab-template"><a href="#"><%= title %></a></script>

CSS

.tabs {
    font: 11px 'Lucida Grande';
    border: 1px solid #dedede;
    margin: 5px;
    border-radius: 3px 3px 0 0;
    display: block;
    clear: both;
    height: auto;
}
.tabs:after {
    content: '.';
    display: block;
    clear: both;
    height: 0;
    visibility: hidden;
}
.tab {
    float: left;
}
.tab a {
    display: block;
    min-width: 50px;
    text-align: center;
    padding: 6px;
    background: #f1f1f1;
    border-right: 1px solid #dedede;
    text-decoration: none;
    color: #333;
    opacity: 0.8;
}
.tab.selected a {
    background: #D5E10B;
}
.tab a:hover {
    opacity: 1;
}

JavaScript

var Tabs = Backbone.View.extend({
    el: '#tabs',
    initialize: function(options) {
        if (options.tabs) this.tabs = options.tabs || [];
        _.each(this.tabs, this.append, this);
        
        _.bindAll(this, 'onSelect');
        
        this.bindTabs();
    },
    bindTabs: function() {
        var root = this;
        _.each(this.tabs, function(tab) {
            tab.off('select');
            tab.on('select', root.onSelect, root);
        });
    },
    addTab: function(tab) {
        this.tabs.push(tab);
        this.bindTabs();
    },
    append: function(view) {
        this.$el.append(view.render().$el);
    },
    render: function() {
        _.each(this.tabs, this.append, this);
    },
    onSelect: function(tab) {
        console.log(tab, this.active);
        this.$el.find('.selected').removeClass('selected');
        if (this.active !== 'undefined' && this.active !== tab) {
            this.active = tab;
            this.active.$el.addClass('selected');
            $('#change-name').val(this.active.options.title);
        } else {
            this.active = undefined;
            $('#change-name').val('');
        }        
    }
});

var Tab = Backbone.View.extend({
    tagName: 'li',
    className: 'tab',
    events: {
        'click a': 'selected'
    },
    initialize: function(options) {
        if (options.template) this.template = $(options.template).html();
        else this.template = $('#tab-template').html();        
    },
    render: function() {
        this.$el.html(_.template(this.template, this.options));
        return this;
    },
    selected: function() {
        this.trigger('select', this);
    },
    changeTitle: function(title) {
        this.options.title = title;
    }
});

// Tabs Implementation
var left = new Tabs({
    el: '#tabs',
    tabs: [
        new Tab({title: 'One'}),
        new Tab({title: 'Two'})
    ]
});

$('#change-name').keyup(function() {
    if (left.active !== undefined)...