Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Backbone.Marionette implementations #284

Closed
wants to merge 34 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4a049b5
committing backbone marionette reference app
Aug 24, 2012
83d113a
Merge branch 'master' of https://github.com/addyosmani/todomvc
Aug 24, 2012
1c358f5
removeCombined:false
Aug 24, 2012
cfe8ab3
using built in index
Aug 24, 2012
6cd7d71
making index default to built file, adding dev index for comparison
Aug 24, 2012
645fad0
naming changes
Aug 24, 2012
fa83d01
build
Aug 24, 2012
b3d3585
cname for local
Aug 24, 2012
3ed88ab
bringing filter upp to app scope
Aug 25, 2012
bfe4245
redundant variable assignment
Aug 25, 2012
143d125
forgot about styling filter anchors
Aug 25, 2012
0c5c4bb
selection managed via app
Aug 25, 2012
b65e95c
changing filter anchor selection trigger
Aug 25, 2012
e01a24f
build
Aug 25, 2012
a9e35c4
jshintignore
Aug 25, 2012
e7329df
removing beautify
Aug 25, 2012
60dcb8b
clarity refactor
Aug 25, 2012
1ae2706
clarity refactor
Aug 25, 2012
e051bdc
getting back in the habit of bindTo
Aug 25, 2012
3e81e5b
build
Aug 25, 2012
0fa7cb6
analytics
Aug 29, 2012
e6f66f5
clearing out dev config
Aug 29, 2012
8b0413a
old habits die hard
Aug 31, 2012
47df8a5
build
Aug 31, 2012
726803b
Merge branch 'master' of git://github.com/addyosmani/todomvc
Sep 5, 2012
f8ee8af
refactoring to remove lines
Sep 5, 2012
98e27f0
build
Sep 5, 2012
682b13c
backbone.marionette reference app
Sep 5, 2012
328cf6a
case idiocy
Sep 5, 2012
50066ee
thanks, osx
Sep 5, 2012
b2bc129
re-worked @jsoverson's Marionette implementation to use Marionette's …
Sep 7, 2012
2ef2482
removed dup'd files
Sep 7, 2012
9feda9c
fixed filtering
Sep 7, 2012
52db7d4
changed the todo item view to be an ItemView
Sep 12, 2012
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 0 additions & 1 deletion CNAME

This file was deleted.

4 changes: 4 additions & 0 deletions labs/architecture-examples/backbone_marionette/.jshintignore
@@ -0,0 +1,4 @@
js/lib/underscore.js
js/lib/backbone.js
js/lib/backbone.marionette.js
js/lib/backbone-localStorage.js
10 changes: 10 additions & 0 deletions labs/architecture-examples/backbone_marionette/css/custom.css
@@ -0,0 +1,10 @@
#todoapp.filter-active #todo-list .completed {
display:none
}
#todoapp.filter-completed #todo-list .active {
display:none
}

#main, #footer {
display : none;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Space between each rule. Space after :, not in front.

97 changes: 97 additions & 0 deletions labs/architecture-examples/backbone_marionette/index.html
@@ -0,0 +1,97 @@
<!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/custom.css">
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be called 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>

<!-- vendor libraries -->
<script src="../../../assets/base.js"></script>
<script src="../../../assets/jquery.min.js"></script>
<script src="js/lib/underscore.js"></script>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use lodash in the asset folder

<script src="js/lib/backbone.js"></script>
<script src="js/lib/backbone-localStorage.js"></script>
<script src="js/lib/backbone.marionette.js"></script>

<!-- application libraries -->
<script src="js/models/Todo.js"></script>
<script src="js/collections/TodoList.js"></script>
<script src="js/Router.js"></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>

<!-- application -->
<script src="js/app.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>

<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<% } %>>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

<% 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>

<script>
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-22728809-1']);
_gaq.push(['_trackPageview']);
(function () {
var ga = document.createElement('script');
ga.type = 'text/javascript';
ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(ga, s);
})();
</script>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove ^

</body>
</html>
11 changes: 11 additions & 0 deletions labs/architecture-examples/backbone_marionette/js/Router.js
@@ -0,0 +1,11 @@

var Router = Backbone.Marionette.AppRouter.extend({
appRoutes : {
'*filter': 'setFilter'
},
controller : {
setFilter : function(param) {
app.vent.trigger('todoList:filter', param.trim() || '');
}
}
});
45 changes: 45 additions & 0 deletions labs/architecture-examples/backbone_marionette/js/app.js
@@ -0,0 +1,45 @@
/*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();
});


@@ -0,0 +1,19 @@

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');
}
});
}());
@@ -0,0 +1,136 @@
/**
* 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]);
};

})();