Skip to content

Instantly share code, notes, and snippets.

@michaeljacobdavis
Created October 31, 2013 23:10
Show Gist options
  • Save michaeljacobdavis/7258709 to your computer and use it in GitHub Desktop.
Save michaeljacobdavis/7258709 to your computer and use it in GitHub Desktop.
Todos
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<link rel="stylesheet" href="http://localtodos.com/todos.css" />
</head>
<body>
<div id="todoapp">
<header>
<h1>Todos</h1>
<input id="new-todo" type="text" placeholder="What needs to be done?">
</header>
<section id="main">
<input id="toggle-all" type="checkbox">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list"></ul>
</section>
<footer>
<a id="A1">Clear completed</a>
<div id="todo-count"></div>
</footer>
</div>
<div id="instructions">
Double-click to edit a todo.
</div>
<div id="credits">
Created by
<br />
<a href="http://jgn.me/">J&eacute;r&ocirc;me Gravel-Niquet</a>.
<br />Rewritten by: <a href="http://addyosmani.github.com/todomvc">TodoMVC</a>.
</div>
<script type="text/template" id="item-template">
<div class="view">
<input class="toggle" type="checkbox" <%= done ? 'checked="checked"' : '' %> />
<label><%- title %></label>
<a class="destroy"></a>
</div>
<input class="edit" type="text" value="<%- title %>" />
</script>
<script type="text/template" id="stats-template">
<% if (done) { %>
<a id="clear-completed">Clear <%= done %> completed <%= done == 1 ? 'item' : 'items' %></a>
<% } %>
<div class="todo-count"><b><%= remaining %></b> <%= remaining == 1 ? 'item' : 'items' %> left</div>
</script>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://underscorejs.org/underscore.js"></script>
<script src="http://backbonejs.org/backbone.js"></script>
<script src="https://rawgithub.com/jeromegn/Backbone.localStorage/master/backbone.localStorage.js"></script>
<script>
$(function () {
var app = (function () {
var Todo = Backbone.Model.extend({
defaults: function () {
return {
title: 'empty todo...',
order: Todos.nextOrder(),
done: false
};
},
toggle: function () {
this.save({ done: !this.get('done') });
}
}),
TodoList = Backbone.Collection.extend({
model: Todo,
localStorage: new Backbone.LocalStorage("todos-backbone"),
done: function () {
return this.where({ done: true });
},
remaining: function () {
return this.where({ done: false });
},
nextOrder: function () {
if (!this.length) return 1;
return this.last().get('order') + 1;
},
comparator: 'order'
}),
Todos = new TodoList,
TodoView = Backbone.View.extend({
tagName: 'li',
template: _.template($('#item-template').html()),
events: {
'click .toggle': 'toggleDone',
'dblclick .view': 'edit',
'click a.destroy': 'clear',
'keypress .edit': 'updateOnEnter',
'blur .edit': 'close'
},
initialize: function () {
this.$el.html(this.template(this.model.toJSON()));
this.$el.toggleClass('done', this.model.get('done'));
this.input = this.$('.edit');
return this;
},
toggleDone: function(){
this.model.toggle();
},
edit: function(){
this.$el.addClass('editing');
this.input.focus();
},
close: function(){
var value = this.input.val();
if(!value){
this.clear();
} else {
this.model.save({title: value});
this.$el.removeClass('editing');
}
},
updateOnEnter: function(e){
if(e.keyCode === 13) this.close();
},
clear: function(){
this.model.destroy();
}
}),
AppView = Backbone.View.extend({
el: $('#todoapp'),
statsTemplate: _.template($('#stats-template').html()),
events: {
'keypress #new-todo': 'createOnEnter',
'click #clear-completed': 'clearCompleted',
'click #toggle-all': 'toggleAllComplete'
},
initialize: function () {
this.input = this.$('#new-todo');
this.allCheckbox = this.$('#toggle-all')[0];
this.listenTo(Todos, 'add', this.addOne);
this.listenTo(Todos, 'reset', this.addAll);
this.listenTo(Todos, 'all', this.render);
this.footer = this.$('footer');
this.main = $('#main');
Todos.fetch();
},
render: function () {
var done = Todos.done().length;
var remaining = Todos.remaining().length;
if (Todos.length) {
this.main.show();
this.footer.show();
this.footer.html(this.statsTemplate({done: done, remaining: remaining}));
} else {
this.main.hide();
this.footer.hide();
}
this.allCheckbox.checked = !remaining;
},
addOne: function(todo){
var view = new TodoView({model: todo});
this.$('#todo-list').append(view.render().el);
},
addAll: function(){
Todos.each(this.addOne, this);
},
createOnEnter: function(e){
if(e.keyCode != 13) return;
if(!this.input.val()) return;
Todos.create({ title: this.input.val()});
this.input.val();
},
toggleAllComplete: function(){
var done = this.allCheckbox.checked;
Todos.each(function(todo){ todo.save({'done': done}); });
}
});
return {
AppView: AppView
};
})();
var appVM = new app.AppView;
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment