JSFiddle - React, Tailwind, and code Playground

by heuristocrat

HTML

<script src="http://underscorejs.org/underscore-min.js"></script>
<script src="http://backbonejs.org/backbone-min.js"></script>
<script src="https://raw.github.com/derickbailey/backbone.marionette/master/lib/backbone.marionette.min.js"></script>
<div id="page"></div>
<script id="tab-layout" type="text/template">
    <ul  class="nav nav-tabs"></ul>
    <div class="tab-contents"></div>
</script>
<script id="tab-label" type="text/template">
    <li><%= label %></li>
</script>
<script id="tab-content" type="text/template">
    <div class="tab-pane"><%= content %></div>
</script>
        
<!-- 
The desired mark-up is to match Twitter Bootstrap tab mark-up:
<div class="tabbable">
   <ul class="nav nav-tabs">
      <li>Tab One</li> 
      <li>Tab Two</li> 
   </ul>
   <div class="tab-content">
      <div class="tab-pane">Content One</div>
      <div class="tab-pane">Content Two</div>
   </div>
</div>

But it ends up looking like:
<div class="tabbable">
   <ul class="nav nav-tabs">
      <div>
        <div>
         <li>Tab One</li> 
         <li>Tab Two</li>
        </div>
      </div>
   </ul>
   <div class="tab-content">
      <div>
        <div>
         <div class="tab-pane">Content One</div>
         <div class="tab-pane">Content Two</div>
        </div>
      </div>
   </div>
</div>
-->

CSS

.tabbable {
    border: 1px dotted red;
}

.nav-tabs {
    border: 1px solid blue;
}

.tab-contents {
    border: 1px solid green;
}

.tabbable > ul.tab-labels > li {
    background-color: yellow; /* this won't apply because there are divs in between the ul and li */
}

.tabbable > div.tab-content > div.tab-pane {
    background-color: blue;
}

JavaScript

var TabLayout = Backbone.Marionette.Layout.extend({
    template:  '#tab-layout',
    className: 'tabbable',
    regions: {
        labels: '.nav-tabs',
        panes:  '.tab-contents'
    }
});

var TabModel      = Backbone.Model.extend();
var TabCollection = Backbone.Collection.extend({ model: TabModel });

var TabLabelCollection = Backbone.Marionette.CollectionView.extend({
    itemView: Backbone.Marionette.ItemView.extend({ 
        template: '#tab-label'
    })
});

var TabPaneCollection = Backbone.Marionette.CollectionView.extend({
    itemView: Backbone.Marionette.ItemView.extend({
        template: '#tab-content'
    })
});

var MyApp = new Backbone.Marionette.Application();

MyApp.addRegions({ appRegion: '#page' });

MyApp.addInitializer(function(options) {
    var tabLayout = new TabLayout();
    
    MyApp.appRegion.show(tabLayout);
    
    var tabs = new TabCollection([
        (new TabModel({ label: 'Tab One', content: 'Content One' })),
        (new TabModel({ label: 'Tab Two', content: 'Content Two' }))      
    ]);
    
    var tabLabels   = new TabLabelCollection({   collection: tabs });
    var tabContents = new TabPaneCollection({ collection: tabs });
    
    tabLayout.labels.show(tabLabels);
    tabLayout.panes.show(tabContents);
});

MyApp.start();