Permalink
Fetching contributors…
Cannot retrieve contributors at this time
156 lines (139 sloc) 4.43 KB
<!DOCTYPE html>
<!--Sample inspired by Backbone Todos sample: http://documentcloud.github.com/backbone/examples/todos/index.html -->
<html>
<head>
<title>JsViews Demo: Todos</title>
<script src="//code.jquery.com/jquery-1.11.2.js" type="text/javascript"></script>
<script src="../../jsrender.js" type="text/javascript"></script>
<script src="../../jquery.observable.js" type="text/javascript"></script>
<script src="../../jquery.views.js" type="text/javascript"></script>
<link href="../resources/todos.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="todoapp">
<div class="nav"><a href="../demos.html">JsViews Demos</a></div>
<h1>Todos</h1>
<input id="new-todo" placeholder="What needs to be done?" />
<ul id="todo-list"></ul>
<div id="todo-stats">
<span data-link="~remainingMessage(remaining)"></span>
<a href="#" data-link="{:~completedMessage(completed)}" class="todo-clear"></a>
</div>
</div>
<ul id="instructions">
<li>Todos: enter to add, double-click to edit...</li>
</ul>
<!-- Templates -->
<script id="item-template" type="text/x-jsrender">
<li>
<input name="{{:#index}}" data-link="done" class="check" type="checkbox" />
<div data-link="{:content || 'empty todo...'} css-text-decoration{:done ? 'line-through' : ''}"
class="todo-content"></div>
<span class="todo-destroy"></span>
</li>
</script>
<script id="edit-template" type="text/x-jsrender">
<li class="editing">
<input data-link="content" class="todo-input" />
</li>
</script>
<script>
(function(){
// Initialize app
var editing = null,
useStorage = window.JSON && window.localStorage,
todos = {
items: useStorage && $.parseJSON( localStorage.getItem( "JsViewsTodos" )) || [], // Intialize from local storage
edit: function( view ) {
editing = view;
view.tmpl = $.templates.editTemplate;
view.refresh();
$( view.contents(true, 'input')).focus();
},
removeItem: function( index, item ) {
$.observable( this.items ).remove( index );
this.doneChanged( item.done ? -1 : 0 );
},
clearCompleted: function( index ) {
var l = this.items.length;
while ( l-- ) {
if ( this.items[ l ].done ) {
this.removeItem( l, this.items[ l ]);
}
}
},
doneChanged: function( incr ) {
var completed = this.completed + incr;
$.observable( this ).setProperty({
remaining: this.items.length - completed,
completed: completed
});
},
contentChanged: function( view ) {
view.tmpl = $.templates.itemTemplate;
view.refresh();
}
}
todos.completed = $( todos.items ).filter( function( index, val ) { return val.done; }).length;
todos.remaining = todos.items.length - todos.completed;
// Helper functions
$.views.helpers({
remainingMessage: function( remaining ) {
return remaining ? ( remaining + " item" + ( remaining > 1 ? "s" : "" ) + " left" ) : "";
},
completedMessage: function( completed ) {
return completed ? ( "Clear " + completed + " completed item" + ( completed > 1 ? "s" : "" )) : "";
},
// Provide afterChange handler for datalinking. (In this case it will be on the top view, so available to all views)
onAfterChange: function( ev ) {
switch( ev.type ) {
case "change":
var view = this.view;
switch(ev.target.className) {
case "check":
todos.doneChanged( view.data.done ? 1 : -1 );
break;
case "todo-input":
todos.contentChanged( view );
}
break;
case "arrayChange":
if ( useStorage ) {
localStorage.setItem( "JsViewsTodos", JSON.stringify( todos.items ));
}
}
}
});
// Compile template
$.templates({
itemTemplate: "#item-template",
editTemplate: "#edit-template"
});
// UI Event bindings
$( "#new-todo" ).keypress( function( ev ) {
if ( ev.keyCode === 13 ) {
$.observable( todos.items ).insert({ content: this.value, done: false });
todos.doneChanged( 0 );
this.value = "";
}
});
$( ".todo-clear" ).on( "click", function() { todos.clearCompleted(); });
// Link UI, and handle changes to 'done' and 'content' properties of Todo items
$( "#todo-stats" ).link( true, todos );
$.link.itemTemplate( "#todo-list", todos.items )
.on( "click", ".todo-destroy", function() {
var view = $.view( this );
todos.removeItem( view.index, view.data );
})
.on( "dblclick", "li", function( ev ) {
todos.edit( $.view( this ));
})
.on( "keypress", "input", function( ev ) {
if ( ev.keyCode === 13 ) {
this.blur();
}
});
})();
</script>
</body>
</html>