Commit 9b81a25c authored by addyosmani's avatar addyosmani

Dropping the non Marionette module variation of the application, updating index, adding readme.

parent db6e8e70
......@@ -235,9 +235,6 @@
<li>
<a href="labs/architecture-examples/backbone_marionette" data-source="http://marionettejs.com" data-content="Backbone.Marionette is a composite application library for Backbone.js that aims to simplify the construction of large scale JavaScript applications.">MarionetteJS</a>
</li>
<li>
<a href="labs/architecture-examples/backbone_marionette_modules" data-source="http://marionettejs.com" data-content="Backbone.Marionette is a composite application library for Backbone.js that aims to simplify the construction of large scale JavaScript applications.">MarionetteJS (modules)</a>
</li>
<li>
<a href="labs/architecture-examples/thorax" data-source="https://github.com/walmartlabs/thorax" data-content="Thorax is a Backbone superset that integrates deeply with Handlebars to provide easy model and collection binding.">Thorax</a>
</li>
......
Backbone.Marionette is a composite application library for Backbone.js that aims to simplify the construction of large scale JavaScript applications. It is a collection of common design and implementation patterns found in the applications that Derick Bailey has been building with Backbone, and includes various pieces inspired by composite application architectures, such as Microsoft's "Prism" framework.
This implementation of the application uses Marionette's module system. Variations using RequireJS and a more classic approach to JavaScript modules are also [available](https://github.com/marionettejs/backbone.marionette/wiki/Projects-and-websites-using-marionette).
\ No newline at end of file
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Marionette • TodoMVC</title>
<link rel="stylesheet" href="../../../assets/base.css">
<link rel="stylesheet" href="css/app.css">
<!--[if IE]>
<script src="../../../assets/ie.js"></script>
<![endif]-->
</head>
<body>
<section id="todoapp">
<header id="header"></header>
<section id="main"></section>
<footer id="footer"></footer>
</section>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="http://github.com/jsoverson">Jarrod Overson</a></p>
</footer>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Marionette • TodoMVC</title>
<link rel="stylesheet" href="../../../assets/base.css">
<link rel="stylesheet" href="css/app.css">
<!--[if IE]>
<script src="../../../assets/ie.js"></script>
<![endif]-->
<!-- vendor libraries -->
<script src="../../../assets/base.js"></script>
<script src="../../../assets/jquery.min.js"></script>
<script src="../../../assets/lodash.min.js"></script>
<script src="js/lib/backbone.js"></script>
<script src="js/lib/backbone-localStorage.js"></script>
<script src="js/lib/backbone.marionette.js"></script>
<script type="text/html" id="template-footer">
<span id="todo-count"><strong></strong> items left</span>
<ul id="filters">
<li>
<a href="#">All</a>
</li>
<li>
<a href="#active">Active</a>
</li>
<li>
<a href="#completed">Completed</a>
</li>
</ul>
<button id="clear-completed">Clear completed</button>
</script>
<!-- application libraries -->
<script src="js/models/Todo.js"></script>
<script src="js/collections/TodoList.js"></script>
<script src="js/Router.js"></script>
<script type="text/html" id="template-header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?" autofocus>
</script>
<!-- application views -->
<script src="js/views/Footer.js"></script>
<script src="js/views/Header.js"></script>
<script src="js/views/TodoItemView.js"></script>
<script src="js/views/TodoListCompositeView.js"></script>
<script type="text/html" id="template-todoItemView">
<div class="view">
<input class="toggle" type="checkbox" <% if (completed) { %>checked<% } %>>
<label><%= title %></label>
<button class="destroy"></button>
</div>
<input class="edit" value="<%= title %>">
</script>
<!-- application -->
<script src="js/app.js"></script>
<script type="text/html" id="template-todoListCompositeView">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list"></ul>
</script>
<script type="text/html" id="template-footer">
<span id="todo-count"><strong></strong> items left</span>
<ul id="filters">
<li>
<a href="#/">All</a>
</li>
<li>
<a href="#/active">Active</a>
</li>
<li>
<a href="#/completed">Completed</a>
</li>
</ul>
<button id="clear-completed">Clear completed</button>
</script>
</head>
<script type="text/html" id="template-header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?" autofocus>
</script>
<body>
<section id="todoapp">
<header id="header"></header>
<section id="main"></section>
<footer id="footer"></footer>
</section>
<script type="text/html" id="template-todoItemView">
<div class="view">
<input class="toggle" type="checkbox" <% if (completed) { %>checked<% } %>>
<label><%= title %></label>
<button class="destroy"></button>
</div>
<input class="edit" value="<%= title %>">
</script>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>
Created by <a href="http://github.com/jsoverson">Jarrod Overson</a>
and <a href="http://github.com/derickbailey">Derick Bailey</a>,
using <a href="http://marionettejs.com">Backbone.Marionette</a>
</p>
<p>Further variations on the Backbone.Marionette app are also <a href="https://github.com/marionettejs/backbone.marionette/wiki/Projects-and-websites-using-marionette">available</a>.</p>
</footer>
<script type="text/html" id="template-todoListCompositeView">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list"></ul>
</script>
</body>
<!-- vendor libraries -->
<script src="../../../assets/base.js"></script>
<script src="../../../assets/jquery.min.js"></script>
<script src="../../../assets/lodash.min.js"></script>
<script src="js/lib/backbone.js"></script>
<script src="js/lib/backbone-localStorage.js"></script>
<script src="js/lib/backbone.marionette.js"></script>
<!-- application -->
<script src="js/TodoMVC.js"></script>
<script src="js/TodoMVC.Todos.js"></script>
<script src="js/TodoMVC.Layout.js"></script>
<script src="js/TodoMVC.TodoList.Views.js"></script>
<script src="js/TodoMVC.TodoList.js"></script>
<script>
$(function(){
// Start the TodoMVC app (defined in js/TodoMVC.js)
TodoMVC.start();
});
</script>
</body>
</html>
var Router = Backbone.Marionette.AppRouter.extend({
appRoutes : {
'*filter': 'setFilter'
},
controller : {
setFilter : function(param) {
app.vent.trigger('todoList:filter', param.trim() || '');
}
}
});
/*global $*/
var todoList = new TodoList();
var app = new Backbone.Marionette.Application();
app.bindTo(todoList, 'all', function () {
if (todoList.length === 0) {
app.main.$el.hide();
app.footer.$el.hide();
} else {
app.main.$el.show();
app.footer.$el.show();
}
});
app.addRegions({
header : '#header',
main : '#main',
footer : '#footer'
});
app.addInitializer(function(){
app.header.show(new Header());
app.main.show(new TodoListCompositeView({
collection : todoList
}));
app.footer.show(new Footer());
todoList.fetch();
});
app.vent.on('todoList:filter',function(filter) {
filter = filter || 'all';
$('#todoapp').attr('class', 'filter-' + filter);
});
$(function(){
app.start();
new Router();
Backbone.history.start();
});
var TodoList = (function(){
function isCompleted(todo) { return todo.get('completed'); }
return Backbone.Collection.extend({
model: Todo,
localStorage: new Backbone.LocalStorage('todos-backbone'),
getCompleted: function() {
return this.filter(isCompleted);
},
getActive: function() {
return this.reject(isCompleted);
},
comparator: function( todo ) {
return todo.get('created');
}
});
}());
var Todo = Backbone.Model.extend({
localStorage: new Backbone.LocalStorage('todos-backbone'),
defaults: {
title : '',
completed : false,
created : 0
},
initialize : function() {
if (this.isNew()) this.set('created', Date.now());
},
toggle : function() {
return this.set('completed', !this.get('completed'));
}
});
var Footer = Backbone.Marionette.Layout.extend({
template : "#template-footer",
ui : {
count : '#todo-count strong',
filters : '#filters a'
},
events : {
'click #clear-completed' : 'onClearClick'
},
initialize : function() {
this.bindTo(app.vent, 'todoList:filter', this.updateFilterSelection, this);
this.bindTo(todoList, 'all', this.updateCount, this);
},
onRender : function() {
this.updateCount();
},
updateCount : function() {
this.ui.count.html(todoList.getActive().length);
},
updateFilterSelection : function(filter) {
this.ui.filters.removeClass('selected').filter('[href="#/' + filter + '"]').addClass('selected');
},
onClearClick : function() {
function destroy(todo) { todo.destroy(); }
todoList.getCompleted().forEach(destroy);
}
});
var Header = Backbone.Marionette.ItemView.extend({
template : "#template-header",
ui : {
input : '#new-todo'
},
events : {
'keypress #new-todo': 'onInputKeypress'
},
onInputKeypress : function(evt) {
var ENTER_KEY = 13;
var todoText = this.ui.input.val().trim();
if ( evt.which === ENTER_KEY && todoText ) {
todoList.create({
title : todoText
});
this.ui.input.val('');
}
}
});
var TodoItemView = Backbone.Marionette.CompositeView.extend({
tagName : 'li',
template : "#template-todoItemView",
ui : {
edit : '.edit'
},
events : {
'click .destroy' : 'destroy',
'dblclick label' : 'onEditClick',
'keypress .edit' : 'onEditKeypress',
'click .toggle' : 'toggle'
},
initialize : function() {
this.bindTo(this.model, 'change', this.render, this);
},
onRender : function() {
this.$el.removeClass('active completed');
if (this.model.get('completed')) this.$el.addClass('completed');
else this.$el.addClass('active');
},
destroy : function() {
this.model.destroy();
},
toggle : function() {
this.model.toggle().save();
},
onEditClick : function() {
this.$el.addClass('editing');
this.ui.edit.focus();
},
onEditKeypress : function(evt) {
var ENTER_KEY = 13;
var todoText = this.ui.edit.val().trim();
if ( evt.which === ENTER_KEY && todoText ) {
this.model.set('title', todoText).save();
this.$el.removeClass('editing');
}
}
});
var TodoListCompositeView = Backbone.Marionette.CompositeView.extend({
template : "#template-todoListCompositeView",
itemView : TodoItemView,
itemViewContainer : '#todo-list',
ui : {
toggle : '#toggle-all'
},
events : {
'click #toggle-all' : 'onToggleAllClick'
},
initialize : function() {
this.bindTo(this.collection, 'all', this.updateToggleCheckbox, this);
},
onRender : function() {
this.updateToggleCheckbox();
},
updateToggleCheckbox : function() {
function reduceCompleted(left, right) { return left && right.get('completed'); }
var allCompleted = this.collection.reduce(reduceCompleted,true);
this.ui.toggle.prop('checked', allCompleted);
},
onToggleAllClick : function(evt) {
var isChecked = evt.currentTarget.checked;
this.collection.each(function(todo){
todo.save({'completed': isChecked});
});
}
});
js/lib/underscore.js
js/lib/backbone.js
js/lib/backbone.marionette.js
js/lib/backbone-localStorage.js
#todoapp.filter-active #todo-list .completed,
#todoapp.filter-completed #todo-list .active {
display: none;
}
#main,
#footer {
display: none;
}
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Marionette • TodoMVC</title>
<link rel="stylesheet" href="../../../assets/base.css">
<link rel="stylesheet" href="css/app.css">
<!--[if IE]>
<script src="../../../assets/ie.js"></script>
<![endif]-->
<script type="text/html" id="template-footer">
<span id="todo-count"><strong></strong> items left</span>
<ul id="filters">
<li>
<a href="#">All</a>
</li>
<li>
<a href="#active">Active</a>
</li>
<li>
<a href="#completed">Completed</a>
</li>
</ul>
<button id="clear-completed">Clear completed</button>
</script>
<script type="text/html" id="template-header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?" autofocus>
</script>
<script type="text/html" id="template-todoItemView">
<div class="view">
<input class="toggle" type="checkbox" <% if (completed) { %>checked<% } %>>
<label><%= title %></label>
<button class="destroy"></button>
</div>
<input class="edit" value="<%= title %>">
</script>
<script type="text/html" id="template-todoListCompositeView">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list"></ul>
</script>
</head>
<body>
<section id="todoapp">
<header id="header"></header>
<section id="main"></section>
<footer id="footer"></footer>
</section>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>
Created by <a href="http://github.com/jsoverson">Jarrod Overson</a>
and <a href="http://github.com/derickbailey">Derick Bailey</a>,
using <a href="http://marionettejs.com">Backbone.Marionette</a>
</p>
</footer>
<!-- vendor libraries -->
<script src="../../../assets/base.js"></script>
<script src="../../../assets/jquery.min.js"></script>
<script src="../../../assets/lodash.min.js"></script>
<script src="js/lib/backbone.js"></script>
<script src="js/lib/backbone-localStorage.js"></script>
<script src="js/lib/backbone.marionette.js"></script>
<!-- application -->
<script src="js/TodoMVC.js"></script>
<script src="js/TodoMVC.Todos.js"></script>
<script src="js/TodoMVC.Layout.js"></script>
<script src="js/TodoMVC.TodoList.Views.js"></script>
<script src="js/TodoMVC.TodoList.js"></script>
<script>
$(function(){
// Start the TodoMVC app (defined in js/TodoMVC.js)
TodoMVC.start();
});
</script>
</body>
</html>
/**
* Backbone localStorage Adapter
* https://github.com/jeromegn/Backbone.localStorage
*/
(function() {
// A simple module to replace `Backbone.sync` with *localStorage*-based
// persistence. Models are given GUIDS, and saved into a JSON object. Simple
// as that.
// Hold reference to Underscore.js and Backbone.js in the closure in order
// to make things work even if they are removed from the global namespace
var _ = this._;
var Backbone = this.Backbone;
// Generate four random hex digits.
function S4() {
return (((1+Math.random())*0x10000)|0).toString(16).substring(1);
};
// Generate a pseudo-GUID by concatenating random hexadecimal.
function guid() {
return (S4()+S4()+"-"+S4()+"-"+S4()+"-"+S4()+"-"+S4()+S4()+S4());
};
// Our Store is represented by a single JS object in *localStorage*. Create it
// with a meaningful name, like the name you'd give a table.
// window.Store is deprectated, use Backbone.LocalStorage instead
Backbone.LocalStorage = window.Store = function(name) {
this.name = name;
var store = this.localStorage().getItem(this.name);
this.records = (store && store.split(",")) || [];
};
_.extend(Backbone.LocalStorage.prototype, {
// Save the current state of the **Store** to *localStorage*.
save: function() {
this.localStorage().setItem(this.name, this.records.join(","));
},
// Add a model, giving it a (hopefully)-unique GUID, if it doesn't already
// have an id of it's own.
create: function(model) {
if (!model.id) {
model.id = guid();
model.set(model.idAttribute, model.id);
}
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
this.records.push(model.id.toString());
this.save();
return model.toJSON();
},
// Update a model by replacing its copy in `this.data`.
update: function(model) {
this.localStorage().setItem(this.name+"-"+model.id, JSON.stringify(model));
if (!_.include(this.records, model.id.toString())) this.records.push(model.id.toString()); this.save();
return model.toJSON();
},
// Retrieve a model from `this.data` by id.
find: function(model) {
return JSON.parse(this.localStorage().getItem(this.name+"-"+model.id));
},
// Return the array of all models currently in storage.
findAll: function() {
return _(this.records).chain()
.map(function(id){return JSON.parse(this.localStorage().getItem(this.name+"-"+id));}, this)
.compact()
.value();
},
// Delete a model from `this.data`, returning it.
destroy: function(model) {
this.localStorage().removeItem(this.name+"-"+model.id);
this.records = _.reject(this.records, function(record_id){return record_id == model.id.toString();});
this.save();
return model;
},
localStorage: function() {
return localStorage;
}
});
// localSync delegate to the model or collection's
// *localStorage* property, which should be an instance of `Store`.
// window.Store.sync and Backbone.localSync is deprectated, use Backbone.LocalStorage.sync instead
Backbone.LocalStorage.sync = window.Store.sync = Backbone.localSync = function(method, model, options, error) {
var store = model.localStorage || model.collection.localStorage;
// Backwards compatibility with Backbone <= 0.3.3
if (typeof options == 'function') {
options = {
success: options,
error: error
};
}
var resp;
switch (method) {
case "read": resp = model.id != undefined ? store.find(model) : store.findAll(); break;
case "create": resp = store.create(model); break;
case "update": resp = store.update(model); break;
case "delete": resp = store.destroy(model); break;
}
if (resp) {
options.success(resp);
} else {
options.error("Record not found");
}
};
Backbone.ajaxSync = Backbone.sync;
Backbone.getSyncMethod = function(model) {
if(model.localStorage || (model.collection && model.collection.localStorage))
{
return Backbone.localSync;
}
return Backbone.ajaxSync;
};
// Override 'Backbone.sync' to default to localSync,
// the original 'Backbone.sync' is still available in 'Backbone.ajaxSync'
Backbone.sync = function(method, model, options, error) {
return Backbone.getSyncMethod(model).apply(this, [method, model, options, error]);
};
})();
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment