Composite View: Menu
A menu built w/ Marionette
HTML
<script src="http://documentcloud.github.com/underscore/underscore-min.js"></script>
<script src="http://documentcloud.github.com/backbone/backbone-min.js"></script>
<script src="https://raw.github.com/derickbailey/backbone.marionette/master/lib/backbone.marionette.js"></script>
<script src="http://craigsworks.com/projects/qtip2/packages/nightly/jquery.qtip.js"></script>
<link rel="stylesheet" href="http://craigsworks.com/projects/qtip2/packages/nightly/jquery.qtip.css">
<div id="menu">
</div>
<div id="output">
</div>
<div id="option">
<button id="additem">Add Dynamic Menu</button>
</div>
CSS
body {
margin: 100px;
}
#output {
clear: both;
padding-top: 90px;
}
ul.nested {
display: none;
}
.toolbar li {
font-family: arial, sans-serif;
float: left;
-webkit-user-select: none;
cursor: pointer;
outline: 0;
border: 1px solid rgba(0, 0, 0, 0.1);
display: inline-block;
-webkit-transition: border-color .218s;
text-decoration: none !important;
text-shadow: 0 1px 0 #FFFFFF;
color: #666;
background-image: -webkit-linear-gradient(top,#f5f5f5,#f1f1f1);
background-image: -moz-linear-gradient(top,#f5f5f5,#f1f1f1);
background-image: -ms-linear-gradient(top,#f5f5f5,#f1f1f1);
background-image: -o-linear-gradient(top,#f5f5f5,#f1f1f1);
background-image: linear-gradient(top,#f5f5f5,#f1f1f1);
padding: 0 15px;
}
.toolbar li:hover {
background-image: -webkit-linear-gradient(top,#f8f8f8,#f1f1f1);
background-image: -moz-linear-gradient(top,#f8f8f8,#f1f1f1);
background-image: -ms-linear-gradient(top,#f8f8f8,#f1f1f1);
background-image: -o-linear-gradient(top,#f8f8f8,#f1f1f1);
background-image: linear-gradient(top,#f8f8f8,#f1f1f1);
border: 1px solid #939393;
}
.toolbar li:last-child {
-moz-border-radius-topright: 4px;
-webkit-border-top-right-radius: 4px;
border-top-right-radius: 4px;
-moz-border-radius-bottomright: 4px;
-webkit-border-bottom-right-radius: 4px;
border-bottom-right-radius: 4px;
}
.toolbar li:first-child {
-moz-border-radius-topleft: 4px;
-webkit-border-top-left-radius: 4px;
border-top-left-radius: 4px;
-moz-border-radius-bottomleft: 4px;
-webkit-border-bottom-left-radius: 4px;
border-bottom-left-radius: 4px;
}
.ui-tooltip-nav {
min-width: 150px;
max-width: 240px;
}
.ui-tooltip-menu {
-webkit-box-shadow: 0 2px 4px rgba(0,0,0,0.2);
-moz-box-shadow: 0 2px 4px rgba(0,0,0,0.2);
box-shadow: 0 2px 4px rgba(0,0,0,0.2);
-webkit-transition: opacity .218s;
-moz-transition: opacity...
JavaScript
// Created by Anton Vishnyak
// ----------------------------------------------------------------
// Definition of a menu item
//
// Sub-menus can be defined using a "submenu" attribute
// ----------------------------------------------------------------
var MenuItem = Backbone.Model.extend({
defaults: {
// true, false or null/undefined;
disabled: false,
// true, false or null/undefined;
checked: false,
// 'std', 'separator', 'group-header' or null/undefined;
type: "std",
icon: null,
text: "",
// This will be the event that get triggered
action: false
},
initialize: function() {
var nodes = this.get("submenu");
if (nodes) {
this.nodes = new MenuItemCollection(nodes);
this.unset("submenu");
}
}
});
// ----------------------------------------------------------------
// A collection of menu items
// ----------------------------------------------------------------
var MenuItemCollection = Backbone.Collection.extend({
model: MenuItem
});
// ----------------------------------------------------------------
// Menu view renders individual menu items recursively
// ----------------------------------------------------------------
var MenuViewController = Backbone.Marionette.CompositeView.extend({
tagName: "li",
isFirstLevel: false,
itemView: MenuViewController,
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.nodes;
// Bubble up a view refresh to the top
this.on("item:added", function(view) {
this.bindTo(view, 'refresh', this.renderTree, this);
});
},
initialEvents: function() {
// Bind to any changes in the collection and redraw the entire menu chain
if...