<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<style>
*{
margin: 0;
padding: 0;
}
body{
background-color: #eaeaea;
font: 14px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
}
header,section,footer{
display: block;
}
#todo{
width: 500px;
margin: 0 auto;
background-color: white;
padding: 20px;
border-radius: 0 0 8px 8px;
-webkit-box-shadow: 0px 1px 4px 2px #bababa;
}
header>h1{
text-align: center;
margin: 10px 0 20px 0;
}
header>input{
/*display: block;*/
line-height: 28px;
font-size: 25px;
font-style: italic;
padding: 6px;
margin-bottom: 5px;
width: 100%;
box-sizing: border-box;
outline: none;
}
.views{
display: none;
}
.views>p{
height: 25px;
line-height: 25px;
margin-bottom: 10px;
}
.views>p>*{
vertical-align: middle;
}
#select-all{
margin-right: 5px;
}
.todoList>li{
list-style-type: none;
position: relative;
padding: 10px 0;
font-size: 24px;
}
.todoList>li>.view>*{
vertical-align: middle;
height: 30px;
line-height: 30px;
}
.edit{
display: none;
position: absolute;
top: 0px;
left: 0px;
padding: 0 20px;
width: 460px;
font-size: 25px;
height: 50px;
line-height: 40px;
outline: none;
}
.todoList>li:hover>.view .destroy{
display: block;
}
.todoList>li>.view .destroy{
float: right;
width: 16px;
height: 16px;
margin-top: 12px;
line-height: 16px;
text-align: center;
border-radius: 10px;
background-color: #d1d1d1;
color: white;
font-size: 12px;
display: none;
}
.todoList>li .destroy:hover{
cursor: pointer;
background-color: #b1b1b1;
}
.select label{
text-decoration: line-through;
color: #a1a1a1;
}
footer{
background-color: #f4fce8;
margin: 0 -20px;
margin-bottom: -20px;
margin-top: 20px;
padding: 10px 20px 10px 20px;
display: none;
border-radius: 0 0 8px 8px;;
}
#clear-complete{
float: right;
font-size: 12px;
padding: 2px 10px;
border-radius: 10px;
background-color: #d1d1d1;
}
#clear-complete:hover{
cursor: pointer;
background-color: #a1a1a1;
}
</style>
</head>
<body>
<div id="todo">
<header>
<h1>Todos</h1>
<input type="text" id="new-todo" placeholder="What needs to be done?"/>
</header>
<section>
<p><input type="checkbox" id="select-all"/><label for="select-all">Mark all as complete</label></p>
<ul>
</ul>
</section>
<footer></footer>
</div>
<script src="jquery-1.11.2.min.js"></script>
<script src="handlebars-v3.0.0.js"></script>
<script src="json2.js"></script>
<script src="underscore.js"></script>
<script src="backbone.js"></script>
<script type="text/x-handlebars-template" id="todo-template">
<div>
<input type="checkbox"{{#if done}} checked {{else}} '' {{/if}}/>
<label for="">{{title}}</label>
<a>X</a>
</div>
<input type="text" value="{{title}}"/>
</script>
<script type="text/x-handlebars-template" id="footer-template">
{{#if done}}
<a id="clear-complete">
Clear <b>{{done}}</b> completed
</a>
{{/if}}
<div id="todo-count">
<strong>{{remaining}}</strong> items left
</div>
</script>
<script>
var Todo = Backbone.Model.extend({
defaults: {
title: "empty title",
done: false
},
toggle: function(){
this.set('done', !this.get('done'));
}
})
var TodoS = Backbone.Collection.extend({
model: Todo,
done: function(){
return this.where({done: true}).length;
},
initialize: function(){
},
remaining: function(){
return this.where({done: false}).length;
},
destroyView: function(model){
this.remove(model);
}
})
var todoS = new TodoS;
var TodoView = Backbone.View.extend({
tagName: 'li',
template: Handlebars.compile($('#todo-template').html()),
initialize: function(){
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'remove', this.destroyView);
},
events: {
"click .toggle": "toggleDown",
"click .destroy": "destroyView",
"dblclick .view": "edit",
"blur .edit": "saveEdit",
"keypress .edit": "saveEdit"
},
render: function(){
this.$el.html(this.template(this.model.toJSON()));
if(this.model.get('done')){
this.$el.addClass('select');
}else{
this.$el.removeClass('select');
}
return this;
},
toggleDown: function(){
this.model.toggle();
},
destroyView: function(){
this.remove();
todoS.destroyView(this.model);
},
edit: function(){
this.$('.edit').show();
this.$('.edit').focus();
},
saveEdit: function(e){
if(e.charCode == 13 || !e.charCode){
this.model.set('title', this.$('.edit').val());
this.$('.edit').hide();
}
if(this.$('.edit').val() == ""){
todoS.remove(this.model);
}
}
})
var AppView = Backbone.View.extend({
el: $('#todo'),
footerTemplate: Handlebars.compile($('#footer-template').html()),
initialize: function(){
this.input = this.$("#new-todo");
this.listenTo(todoS, 'add', this.addNewView);
this.listenTo(todoS, 'all', this.render);
this.footer = this.$('footer');
this.views = this.$('.views');
this.toggleAll = this.$('#select-all');
this.firstRender();
},
events: {
"keypress #new-todo": "createEnter",
"click #select-all": "toggleAllComplete",
"click #clear-complete": "removeSelect"
},
addNewView: function(model){
var todoView = new TodoView({model: model});
this.$('.todoList').append(todoView.render().$el)
},
render: function(){
if(todoS.length){
this.views.show();
this.footer.html(this.footerTemplate({done: todoS.done(), remaining: todoS.remaining()}));
this.footer.show();
}else{
this.views.hide();
this.footer.hide();
}
var flag = true;
todoS.each(function(model){
if(!model.get('done')){
flag = false;
}
})
this.toggleAll[0].checked = flag;
localStorage.setItem('todoS', JSON.stringify(todoS));
},
createEnter: function(e){
if(e.keyCode != 13) return 1;
if(this.input.val()==null || this.input.val().match(/^\s*$/)) return 1;
todoS.add({title: this.input.val()});
this.input.val('');
},
toggleAllComplete: function(){
var done = this.toggleAll[0].checked;
todoS.each(function(model){
model.set('done', done);
})
},
removeSelect: function(){
var len = todoS.models.length;
while(len){
if(todoS.models[len-1].get('done')){
todoS.destroyView(todoS.models[len-1]);
}
len--;
}
},
firstRender: function(){
var todoArr = JSON.parse(localStorage.getItem('todoS'));
todoArr.forEach(function(todo){
todoS.add(todo);
})
if(todoArr >= 1){
todoArr.each(function(todo){
console.log(todo)
todoS.add(todo);
})
}
console.log(todoS)
}
})
var appView = new AppView;
</script>
</body>
</html>