MarionetteJS Stack View Controller

Adding views to a stack, using a sliding transition.

by Jon Beebe

HTML

<script src="http://underscorejs.org/underscore.js"></script>
<script src="http://backbonejs.org/backbone.js"></script>
<script src="https://raw.github.com/marionettejs/backbone.marionette/bb099/lib/backbone.marionette.js"></script>
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap.css">
<link rel="stylesheet" href="http://twitter.github.com/bootstrap/assets/css/bootstrap-responsive.css">
<script src="http://twitter.github.com/bootstrap/assets/js/bootstrap.js"></script>
<link rel="stylesheet" href="http://daneden.me/animate/animate.css">
<header>
<h1>A Marionette Playground</h1>
</header>

<br />

<button id="add">Add New Item</button>
<br />
<br />
<button id="remove">Remove Item</button>

<div id="stackView">
    <div class="stacks">
        <div class="stack-item">one</div>
        <div class="stack-item">two</div>
        <div class="stack-item">three</div>
    </div>
</div>

CSS

body, html {
    background: #eee;
}

#stackView {
    width: 300px;
    height: 500px;
    position: absolute;
    right: 30px;
    top: 60px;
    background: white;
}

.stacks {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    overflow: hidden;
}

.stack-item {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: white;
    box-shadow: 0 0 15px 0 #999;
}

.stack-item.red {
    background: red;
}

.stack-item.gray { 
 	background: #999;   
}

.stack-item.light { 
 	background: #ccc;   
}

@-webkit-keyframes slideInFromRight {
  0% {
    -webkit-transform: translateX(100%);
  }
  100% {
    -webkit-transform: translateX(0%);
  }
}

.slideInFromRight {
  -webkit-animation-name: slideInFromRight;
}

@-webkit-keyframes slideOutToRight {
  0% {
    -webkit-transform: translateX(0%);
  }
  100% {
    -webkit-transform: translateX(100%);
  }
}

.slideOutToRight {
  -webkit-animation-name: slideOutToRight;
}

JavaScript

// Define the app and a region to show content
// -------------------------------------------

var App = new Marionette.Application();

App.addRegions({
    "mainRegion": "#stackView" 
});

// Create a module to contain some functionality
// ---------------------------------------------

App.module("SampleModule", function(Mod, App, Backbone, Marionette, $, _){
    
    // The Stack Manager View
    // ----------------------
   
    var StackView = Marionette.View.extend({
        
        hasRootView: false,
        
        // Define options for transitioning views in and out
        defaults: {
            inTransitionClass: 'animated slideInFromRight',
            outTransitionClass: 'animated slideOutToRight',
            transitionDelay: 1000,
            'class': 'stacks',
            itemClass: 'stack-item'
        },
        
        initialize: function(options) {
            this.views = [];
            options = options || {};
            this.options = _.defaults({}, this.defaults, options);
        },
        
        setRootView: function(view) {
            this.hasRootView = true;
        	this.views.push(view);
            view.render();
            view.$el.addClass(this.options.itemClass);
            this.$el.append(view.$el);
        },
        
        render: function() {
            this.$el.addClass(this.options['class']);
            return this;
        },
        
        // Pop the top-most view off of the stack.
        pop: function() {
            var self = this;
            if(this.views.length > (this.hasRootView ? 1 : 0)) {
                var view = this.views.pop();
                this.transitionViewOut(view);
            }
        },
        
        // Push a new view onto the stack.
        // The itemClass will be auto-added to the parent element.
        push: function(view) {
            this.views.push(view);
            view.render();
            view.$el.addClass(this.options.itemClass);
           ...