Commit 7d7de006 authored by Camille Reynders's avatar Camille Reynders Committed by Sindre Sorhus

Close #85: Dijon app

parent 55483ef9
# Dijon • [TodoMVC](http://todomvc.com)
## Credit
Created by [Camille Reynders](http://www.creynders.be)
Largely based on the jQuery example by [Sindre Sorhus](https://github.com/sindresorhus)
\ No newline at end of file
html,
body {
margin: 0;
padding: 0;
}
body {
font: 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eeeeee;
color: #333333;
width: 520px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
}
#todoapp {
background: #fff;
padding: 20px;
margin-bottom: 40px;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
-webkit-border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-ms-border-radius: 0 0 5px 5px;
-o-border-radius: 0 0 5px 5px;
border-radius: 0 0 5px 5px;
}
#todoapp h1 {
font-size: 36px;
font-weight: bold;
text-align: center;
padding: 0 0 10px 0;
}
#todoapp input[type="text"] {
width: 466px;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
padding: 6px;
border: 1px solid #999999;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
}
#todoapp input::-webkit-input-placeholder {
font-style: italic;
}
#main {
display: none;
}
#todo-list {
margin: 10px 0;
padding: 0;
list-style: none;
}
#todo-list li {
padding: 18px 20px 18px 0;
position: relative;
font-size: 24px;
border-bottom: 1px solid #cccccc;
}
#todo-list li:last-child {
border-bottom: none;
}
#todo-list li.done label {
color: #777777;
text-decoration: line-through;
}
#todo-list li .destroy {
display: none;
position: absolute;
top: 20px;
right: 10px;
cursor: pointer;
width: 20px;
height: 20px;
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUBAMAAAB/pwA+AAAABGdBTUEAALGPC/xhBQAAACdQTFRFzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMAAAA////zMzMhnu0WAAAAAt0Uk5T5u3pqtV3jFQEKAC0bVelAAAAfUlEQVQI12NYtWpFsc8R865VqxhWrZpyBgg8QcylZ8AgCsjMgTCPrWJYfgYKqhjWwJgaDDVnzpw+c2bPmTPHGWzOnNm95/TuM2cOM/AARXfvBooeZAAp270bRCIz4QoOIGtDMqwJZoUEQzvCYrhzuhhWtUKYEahOX7UK6iEA3A6NUGwCTZIAAAAASUVORK5CYII=') no-repeat center center;
}
#todo-list li:hover .destroy {
display: block;
}
#todo-list li.editing {
border-bottom: none;
margin-top: -1px;
padding: 0;
}
#todo-list li.editing:last-child {
margin-bottom: -1px;
}
#todo-list li.editing .edit {
display: block;
width: 444px;
padding: 13px 15px 14px 20px;
margin: 0;
}
#todo-list li.editing .view {
display: none;
}
#todo-list li .view label {
word-break: break-word;
}
#todo-list li .edit {
display: none;
}
#todoapp footer {
display: none;
margin: 0 -20px -20px -20px;
overflow: hidden;
color: #555555;
background: #f4fce8;
border-top: 1px solid #ededed;
padding: 0 20px;
line-height: 37px;
-webkit-border-radius: 0 0 5px 5px;
-moz-border-radius: 0 0 5px 5px;
-ms-border-radius: 0 0 5px 5px;
-o-border-radius: 0 0 5px 5px;
border-radius: 0 0 5px 5px;
}
#clear-completed {
display: none;
float: right;
line-height: 20px;
text-decoration: none;
background: rgba(0, 0, 0, 0.1);
color: #555555;
font-size: 11px;
margin-top: 8px;
margin-bottom: 8px;
padding: 0 10px 1px;
cursor: pointer;
-webkit-border-radius: 12px;
-moz-border-radius: 12px;
-ms-border-radius: 12px;
-o-border-radius: 12px;
border-radius: 12px;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
-ms-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
}
#clear-completed:hover {
background: rgba(0, 0, 0, 0.15);
-webkit-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
-moz-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
-ms-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
-o-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
}
#clear-completed:active {
position: relative;
top: 1px;
}
#todo-count span {
font-weight: bold;
}
#instructions {
margin: 10px auto;
color: #777777;
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
text-align: center;
}
#instructions a {
color: #336699;
}
#credits {
margin: 30px auto;
color: #999;
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
text-align: center;
}
#credits a {
color: #888;
}
\ No newline at end of file
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>jQuery • TodoMVC</title> <title>Dijon • TodoMVC</title>
<link rel="stylesheet" href="../../../assets/base.css"> <link rel="stylesheet" href="../../../assets/base.css">
</head> </head>
<body> <body>
...@@ -24,6 +24,8 @@ ...@@ -24,6 +24,8 @@
</section> </section>
<footer id="info"> <footer id="info">
<p>Double-click to edit a todo</p> <p>Double-click to edit a todo</p>
<p>Based on app and template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p>
<p>Created by <a href="http://www.creynders.be">Camille Reynders</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p> <p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer> </footer>
<script type="text/x-handlebars-template" id="todo-template"> <script type="text/x-handlebars-template" id="todo-template">
...@@ -38,17 +40,16 @@ ...@@ -38,17 +40,16 @@
</li> </li>
{{/this}} {{/this}}
</script> </script>
<script src="js/libs/json2.js"></script> <script src="../../../assets/jquery.min.js"></script>
<script src="js/libs/jquery-1.7.1.min.js"></script> <script src="../../../assets/handlebars.min.js"></script>
<script src="js/libs/handlebars-1.0.0.beta.6.js"></script> <script src="http://creynders.github.com/dijon-framework/bin/dijon-0.5.3.min.js"></script>
<script src="js/libs/dijon-0.5.1.min.js"></script>
<script src="js/config.js"></script> <script src="js/config.js"></script>
<script src="js/models/TodosModel.js"></script> <script src="js/models/TodosModel.js"></script>
<script src="js/services/LocalStorageService.js"></script> <script src="js/services/LocalStorageService.js"></script>
<script src="js/controllers/TodosController.js"></script>
<script src="js/utils/Utils.js"></script> <script src="js/utils/Utils.js"></script>
<script src="js/views/FooterView.js"></script> <script src="js/views/FooterView.js"></script>
<script src="js/views/TodoFormView.js"></script> <script src="js/views/TodoFormView.js"></script>
<script src="js/views/TodoListView.js"></script> <script src="js/views/TodoListView.js"></script>
<script src="js/app.js"></script>
</body> </body>
</html> </html>
/* /*global jQuery, Handlebars */
( function ( ns ) {
[MIT licensed](http://en.wikipedia.org/wiki/MIT_License) 'use strict';
(c) [Sindre Sorhus](http://sindresorhus.com) ns.App = function () {
*/
( function( ns ){
ns.App = function(){
var system; var system;
return { return {
startup : function(){ startup:function () {
system = new dijon.System(); system = new dijon.System();
system.mapValue( 'system', system ); system.mapValue( 'system', system );
......
...@@ -6,16 +6,16 @@ ...@@ -6,16 +6,16 @@
var dijondemo = {}; var dijondemo = {};
( function( ns ){ ( function ( ns ) {
ns.views = {}; ns.views = {};
ns.models = {}; ns.models = {};
ns.controllers = {}; ns.controllers = {};
ns.services = {}; ns.services = {};
ns.utils = {}; ns.utils = {};
ns.Config = function(){ ns.Config = function () {
return{ return{
system : undefined, //inject system:undefined, //inject
setup : function(){ setup:function () {
this.system.autoMapOutlets = true; this.system.autoMapOutlets = true;
...@@ -30,9 +30,6 @@ var dijondemo = {}; ...@@ -30,9 +30,6 @@ var dijondemo = {};
//services //services
this.system.mapSingleton( 'storageService', ns.services.LocalStorageService ); this.system.mapSingleton( 'storageService', ns.services.LocalStorageService );
//controllers
this.system.mapSingleton( 'todosController', ns.controllers.TodosController );
//views //views
this.system.mapSingleton( 'footerView', ns.views.FooterView ); this.system.mapSingleton( 'footerView', ns.views.FooterView );
...@@ -45,11 +42,9 @@ var dijondemo = {}; ...@@ -45,11 +42,9 @@ var dijondemo = {};
this.system.mapHandler( 'TodoListView:toggleDoneOfTodo', 'todosModel', 'toggleDone' ); this.system.mapHandler( 'TodoListView:toggleDoneOfTodo', 'todosModel', 'toggleDone' );
this.system.mapHandler( 'TodoListView:setTitleOfTodo', 'todosModel', 'setTitle' ); this.system.mapHandler( 'TodoListView:setTitleOfTodo', 'todosModel', 'setTitle' );
this.system.mapHandler( 'TodoListView:removeTodo', 'todosModel', 'remove' ); this.system.mapHandler( 'TodoListView:removeTodo', 'todosModel', 'remove' );
this.system.mapHandler( 'TodoListView:setDoneForAllTodos', 'todosModel', 'setDoneForAll') this.system.mapHandler( 'TodoListView:setDoneForAllTodos', 'todosModel', 'setDoneForAll' );
this.system.mapHandler( 'TodoListView:removeAllDoneTodos', 'todosModel', 'removeAllDone' ); this.system.mapHandler( 'TodoListView:removeAllDoneTodos', 'todosModel', 'removeAllDone' );
this.system.mapHandler( 'StorageService:retrieveCompleted', 'todosModel', 'setList' ); this.system.mapHandler( 'StorageService:retrieveCompleted', 'todosModel', 'setList' );
this.system.mapHandler( 'FooterView:retrieveTodoCounts', 'todosController', 'retrieveCounts' );
this.system.mapHandler( 'TodosController:todoCountsRetrieved', 'footerView', 'updateCounts' );
this.system.mapHandler( 'TodosModel:todosListUpdated', 'listView', 'render' ); this.system.mapHandler( 'TodosModel:todosListUpdated', 'listView', 'render' );
this.system.mapHandler( 'TodosModel:todosListUpdated', 'footerView', 'render' ); this.system.mapHandler( 'TodosModel:todosListUpdated', 'footerView', 'render' );
this.system.mapHandler( 'TodosModel:todosListUpdated', 'storageService', 'store' ); this.system.mapHandler( 'TodosModel:todosListUpdated', 'storageService', 'store' );
......
/**
* @author Camille Reynders
* Date: 03/02/12
* Time: 14:36
*/
( function( ns ){
ns.controllers.TodosController = function(){
return {
system : undefined, //inject
todosModel : undefined, //inject
retrieveCounts : function(){
this.system.notify( 'TodosController:todoCountsRetrieved', this.todosModel.getNumTotal(), this.todosModel.getNumActive() );
}
}
}
}( dijondemo ) );
\ No newline at end of file
var dijon={VERSION:"0.5.0"};dijon.System=function(){this._mappings={};this._outlets={};this._handlers={};this.strictInjections=true;this.autoMapOutlets=false};dijon.System.prototype={_createAndSetupInstance:function(c,b){var a=new b();this.injectInto(a,c);return a},_retrieveFromCacheOrCreate:function(d,c){if(c==undefined){c=false}if(this._mappings.hasOwnProperty(d)){var b=this._mappings[d];var a=null;if(!c&&b.isSingleton){if(b.object==null){b.object=this._createAndSetupInstance(d,b.clazz)}a=b.object}else{if(b.clazz){a=this._createAndSetupInstance(d,b.clazz)}else{}}}else{throw new Error(1020)}return a},mapOutlet:function(c,b,a){if(c==undefined){throw new Error(1010)}if(b==undefined){b="global"}if(a==undefined){a=c}if(!this._outlets.hasOwnProperty(b)){this._outlets[b]={}}this._outlets[b][a]=c;return this},getObject:function(a){if(a==undefined){throw new Error(1010)}return this._retrieveFromCacheOrCreate(a)},mapValue:function(a,b){if(a==undefined){throw new Error(1010)}this._mappings[a]={clazz:null,object:b,isSingleton:true};if(this.autoMapOutlets){this.mapOutlet(a)}return this},hasMapping:function(a){if(a==undefined){throw new Error(1010)}return this._mappings.hasOwnProperty(a)},mapClass:function(b,a){if(b==undefined){throw new Error(1010)}if(b==undefined){throw new Error(1010)}this._mappings[b]={clazz:a,object:null,isSingleton:false};if(this.autoMapOutlets){this.mapOutlet(b)}return this},mapSingleton:function(b,a){if(b==undefined){throw new Error(1010)}if(a==undefined){throw new Error(1010)}this._mappings[b]={clazz:a,object:null,isSingleton:true};if(this.autoMapOutlets){this.mapOutlet(b)}return this},instantiate:function(a){if(a==undefined){throw new Error(1010)}return this._retrieveFromCacheOrCreate(a,true)},injectInto:function(a,d){if(a==undefined){throw new Error(1010)}var g=[];if(this._outlets.hasOwnProperty("global")){g.push(this._outlets.global)}if(d!=undefined&&this._outlets.hasOwnProperty(d)){g.push(this._outlets[d])}for(var c in g){var b=g[c];for(var f in b){var e=b[f];if(!this.strictInjections||f in a){a[f]=this.getObject(e)}}}if("setup" in a){a.setup.call(a)}return this},unmap:function(a){if(a==undefined){throw new Error(1010)}delete this._mappings[a];return this},unmapOutlet:function(b,a){if(b==undefined){throw new Error(1010)}if(a==undefined){throw new Error(1010)}delete this._outlets[b][a];return this},mapHandler:function(b,c,d,e,a){if(b==undefined){throw new Error(1010)}if(c==undefined){c="global"}if(d==undefined){d=b}if(e==undefined){e=false}if(a==undefined){a=false}if(!this._handlers.hasOwnProperty(b)){this._handlers[b]={}}if(!this._handlers[b].hasOwnProperty(c)){this._handlers[b][c]=[]}this._handlers[b][c].push({handler:d,oneShot:e,passEvent:a});return this},unmapHandler:function(b,e,f){if(b==undefined){throw new Error(1010)}if(e==undefined){e="global"}if(f==undefined){f=b}if(this._handlers.hasOwnProperty(b)&&this._handlers[b].hasOwnProperty(e)){var a=this._handlers[b][e];for(var d in a){var c=a[d];if(c.handler==f){a.splice(d,1);break}}}return this},notify:function(g){var j=Array.prototype.slice.call(arguments);var c=j.slice(1);if(this._handlers.hasOwnProperty(g)){var d=this._handlers[g];for(var k in d){var h=d[k];var l;if(k!="global"){l=this.getObject(k)}var f=[];for(var e=0,b=h.length;e<b;e++){var m;var a=h[e];if(l&&typeof a.handler=="string"){m=l[a.handler]}else{m=a.handler}if(a.oneShot){f.unshift(e)}if(a.passEvent){m.apply(l,j)}else{m.apply(l,c)}}for(var e=0,b=f.length;e<b;e++){h.splice(f[e],1)}}}return this}};
\ No newline at end of file
This diff is collapsed.
...@@ -3,75 +3,80 @@ ...@@ -3,75 +3,80 @@
* Date: 03/02/12 * Date: 03/02/12
* Time: 14:39 * Time: 14:39
*/ */
( function( ns ){ ( function ( ns ) {
ns.models.TodosModel = function(){ ns.models.TodosModel = function () {
var _list = []; var _list = [];
return { return {
system : undefined, //inject, system:undefined, //inject,
getTodo : function( id ){ getTodo:function ( id ) {
return _list[ this.getIndex( id ) ]; return _list[ this.getIndex( id ) ];
}, },
getIndex : function( id ){ getIndex:function ( id ) {
var list = _list; var list = _list,
for( var i in _list ){ todo;
for ( var i in _list ) {
var todo = _list[ i ]; todo = _list[ i ];
if( todo.id == id ) { if ( todo.id == id ) {
return i; return i;
} }
} }
return -1; return -1;
}, },
notifyOfListUpdate : function(){ notifyOfListUpdate:function () {
var list = this.getList(); var list = this.getList();
this.system.notify( 'TodosModel:todosListUpdated', list ); this.system.notify( 'TodosModel:todosListUpdated', list );
}, },
setList : function( list ){ setList:function ( list ) {
_list = list || []; _list = list || [];
this.system.notify( 'TodosModel:todosListUpdated', list ); this.system.notify( 'TodosModel:todosListUpdated', list );
}, },
getList : function(){ getList:function () {
return _list; return _list;
}, },
add : function( vo ){ add:function ( vo ) {
_list.push( vo ); _list.push( vo );
this.notifyOfListUpdate(); this.notifyOfListUpdate();
}, },
toggleDone : function( id ){ toggleDone:function ( id ) {
var todo = this.getTodo( id ); var todo = this.getTodo( id );
todo.done = ! todo.done; todo.completed = !todo.completed;
this.notifyOfListUpdate(); this.notifyOfListUpdate();
}, },
setTitle : function( id, title ){ setTitle:function ( id, title ) {
this.getTodo( id ).title = title; this.getTodo( id ).title = title;
this.notifyOfListUpdate(); this.notifyOfListUpdate();
}, },
remove : function( id ){ remove:function ( id ) {
_list.splice( this.getIndex( id ), 1 ); _list.splice( this.getIndex( id ), 1 );
this. notifyOfListUpdate(); this.notifyOfListUpdate();
}, },
setDoneForAll : function( done ){ setDoneForAll:function ( completed ) {
for( var i in _list ){ var i;
_list[ i ].done = done; for ( i in _list ) {
_list[ i ].completed = completed;
} }
this.notifyOfListUpdate(); this.notifyOfListUpdate();
}, },
removeAllDone : function(){ removeAllDone:function () {
for( var i = _list.length - 1, n = 0; i >= n; i-- ){ var i,
if( _list[ i ].done ){ n = 0;
for ( i = _list.length - 1 ; i >= n ; i-- ) {
if ( _list[ i ].completed ) {
_list.splice( i, 1 ); _list.splice( i, 1 );
} }
} }
this.notifyOfListUpdate(); this.notifyOfListUpdate();
}, },
getNumTotal : function(){ getNumTotal:function () {
return _list.length; return _list.length;
}, },
getNumActive : function(){ getNumActive:function () {
var count = 0; var count = 0,
for( var i in _list ){ i;
if( ! _list[ i ].done ){ for ( i in _list ) {
if ( !_list[ i ].completed ) {
count++; count++;
} }
} }
......
...@@ -3,16 +3,16 @@ ...@@ -3,16 +3,16 @@
* Date: 03/02/12 * Date: 03/02/12
* Time: 13:27 * Time: 13:27
*/ */
( function( ns ){ ( function ( ns ) {
dijondemo.services.LocalStorageService = function(){ dijondemo.services.LocalStorageService = function () {
return { return {
system : undefined, //inject system:undefined, //inject
store : function( data ){ store:function ( data ) {
return localStorage.setItem( 'todo-jquery', JSON.stringify( data ) ); return localStorage.setItem( 'todos-dijon', JSON.stringify( data ) );
}, },
retrieve : function(){ retrieve:function () {
var data = localStorage.getItem('todo-jquery'); var data = localStorage.getItem( 'todos-dijon' ),
var output = ( data && JSON.parse( data ) ) || []; output = ( data && JSON.parse( data ) ) || [];
this.system.notify( 'StorageService:retrieveCompleted', output ); this.system.notify( 'StorageService:retrieveCompleted', output );
} }
} }
......
...@@ -3,11 +3,14 @@ ...@@ -3,11 +3,14 @@
* Date: 03/02/12 * Date: 03/02/12
* Time: 14:34 * Time: 14:34
*/ */
( function( ns ){ ( function ( ns ) {
ns.utils.Utils = { ns.utils.Utils = {
// https://gist.github.com/1308368 // https://gist.github.com/1308368
uuid: function(a,b){for(b=a='';a++<36;b+=a*51&52?(a^15?8^Math.random()*(a^20?16:4):4).toString(16):'_');return b}, uuid:function ( a, b ) {
pluralize: function( count, word ) { for ( b = a = '' ; a++ < 36 ; b += a * 51 & 52 ? (a ^ 15 ? 8 ^ Math.random() * (a ^ 20 ? 16 : 4) : 4).toString( 16 ) : '_' );
return b
},
pluralize:function ( count, word ) {
return count === 1 ? word : word + 's'; return count === 1 ? word : word + 's';
} }
}; };
......
...@@ -3,28 +3,31 @@ ...@@ -3,28 +3,31 @@
* Date: 03/02/12 * Date: 03/02/12
* Time: 14:20 * Time: 14:20
*/ */
( function( ns ){ ( function ( ns ) {
ns.views.FooterView = function(){ ns.views.FooterView = function () {
var $count = $('#todo-count'); var $count = $( '#todo-count' ),
var $clearBtn = $('#clear-completed'); $clearBtn = $( '#clear-completed' ),
var $footer = $('#todoapp').find('footer'); $footer = $( '#todoapp' ).find( 'footer' );
return { return {
system : undefined, //inject system:undefined, //inject
pluralizeUtil : undefined, //inject, pluralizeUtil:undefined, //inject,
setup : function(){ todosModel : undefined, //inject
setup:function () {
var self = this; var self = this;
$clearBtn.on( 'click', function() { $clearBtn.on( 'click', function () {
self.system.notify( 'TodoListView:removeAllDoneTodos' ); self.system.notify( 'TodoListView:removeAllDoneTodos' );
} ); } );
}, },
render : function(){ render:function () {
this.system.notify( 'FooterView:retrieveTodoCounts' );
this.renderCounts( this.todosModel.getNumTotal(), this.todosModel.getNumActive() );
}, },
updateCounts : function( numTodosTotal, numTodosActive ){ renderCounts:function ( numTodosTotal, numTodosActive ) {
var numTodosCompleted = numTodosTotal - numTodosActive; var numTodosCompleted = numTodosTotal - numTodosActive,
var countTitle = '<b>' + numTodosActive + '</b> ' + this.pluralizeUtil.pluralize( numTodosActive, 'item' ) + ' left'; countTitle = '<b>' + numTodosActive + '</b> ' + this.pluralizeUtil.pluralize( numTodosActive, 'item' ) + ' left',
var clearTitle = 'Clear ' + numTodosCompleted + ' completed ' + this.pluralizeUtil.pluralize( numTodosCompleted, 'item' ); clearTitle = 'Clear completed (' + numTodosCompleted + ')';
// Only show the footer when there are at least one todo. // Only show the footer when there are at least one todo.
$footer.toggle( !!numTodosTotal ); $footer.toggle( !!numTodosTotal );
......
...@@ -3,35 +3,31 @@ ...@@ -3,35 +3,31 @@
* Date: 03/02/12 * Date: 03/02/12
* Time: 13:38 * Time: 13:38
*/ */
( function(ns){ ( function ( ns ) {
ns.views.TodoFormView = function(){ ns.views.TodoFormView = function () {
var $newTodo = $('#new-todo'); var $newTodo = $( '#new-todo' );
return { return {
system : undefined, //inject system:undefined, //inject
enterKey : undefined, //inject enterKey:undefined, //inject
uuidUtil : undefined, //inject uuidUtil:undefined, //inject
setup : function(){ setup:function () {
var self = this; var self = this;
$newTodo.on( 'keyup', function(e) { $newTodo.on( 'keyup', function ( e ) {
if ( e.which !== self.enterKey ) { var $input = $( this ),
val = $.trim( $input.val() );
if ( e.which !== self.enterKey || !val ) {
return; return;
} }
var $input = $(this);
var inputVal = $input.val();
if ( !inputVal ) {
return;
}
self.system.notify( 'TodoFormView:addTodo', { self.system.notify( 'TodoFormView:addTodo', {
title: inputVal, title:val,
id: self.uuidUtil.uuid(), id:self.uuidUtil.uuid(),
done: false completed:false
}) } );
$input.val(''); $input.val( '' );
} ); } );
}, },
render : function(){ render:function () {
} }
} }
......
...@@ -3,55 +3,61 @@ ...@@ -3,55 +3,61 @@
* Date: 03/02/12 * Date: 03/02/12
* Time: 13:39 * Time: 13:39
*/ */
( function(ns){ ( function ( ns ) {
ns.views.TodoListView = function(){ ns.views.TodoListView = function () {
var _template = Handlebars.compile( $('#todo-template').html() ); var _template = Handlebars.compile( $( '#todo-template' ).html() );
var $toggleAll = $('#toggle-all'); var $toggleAll = $( '#toggle-all' );
var $todoList = $('#todo-list'); var $todoList = $( '#todo-list' );
var $main = $('#main'); var $main = $( '#main' );
var $count = $('#todo-count'); var $count = $( '#todo-count' );
return { return {
system : undefined, //inject system:undefined, //inject
enterKey : undefined, enterKey:undefined,
setup : function(){ todosModel : undefined, //inject
setup:function () {
var self = this; var self = this;
$todoList.on( 'change', '.toggle', function() { $todoList.on( 'change', '.toggle', function () {
var id = $( this ).closest('li').data('id'); var id = $( this ).closest( 'li' ).data( 'id' );
self.system.notify( 'TodoListView:toggleDoneOfTodo', id ); self.system.notify( 'TodoListView:toggleDoneOfTodo', id );
} ); } );
$todoList.on( 'dblclick', '.view', function() { $todoList.on( 'dblclick', '.view', function () {
$(this) $( this )
.closest('li') .closest( 'li' )
.addClass('editing') .addClass( 'editing' )
.find('.edit') .find( '.edit' )
.focus(); .focus();
} ); } );
$todoList.on( 'keypress', '.edit', function(e) { $todoList.on( 'keypress', '.edit', function ( e ) {
if ( e.keyCode === self.enterKey ) { if ( e.keyCode === self.enterKey ) {
console.log( e.target );
e.target.blur(); e.target.blur();
} }
} ); } );
$todoList.on( 'blur', '.edit', function() { $todoList.on( 'blur', '.edit', function () {
var id = $( this ).closest('li').data('id'); var id = $( this ).closest( 'li' ).data( 'id' ),
var val = $(this).removeClass('editing').val(); val = $.trim( $( this ).removeClass( 'editing' ).val() );
if( val ){
self.system.notify( 'TodoListView:setTitleOfTodo', id, val ); self.system.notify( 'TodoListView:setTitleOfTodo', id, val );
}else{
self.system.notify( 'TodoListView:removeTodo', id );
}
} ); } );
$todoList.on( 'click', '.destroy', function() { $todoList.on( 'click', '.destroy', function () {
var id = $( this ).closest('li').data('id'); var id = $( this ).closest( 'li' ).data( 'id' );
self.system.notify( 'TodoListView:removeTodo', id ); self.system.notify( 'TodoListView:removeTodo', id );
} ); } );
$toggleAll.on( 'change', function() { $toggleAll.on( 'change', function () {
var isChecked = !!$(this).attr('checked'); var isChecked = !!$( this ).attr( 'checked' );
self.system.notify( 'TodoListView:setDoneForAllTodos', isChecked ); self.system.notify( 'TodoListView:setDoneForAllTodos', isChecked );
} ); } );
}, },
render : function( todosList ){ render:function () {
$todoList.html( _template( todosList ) ); var todoList = this.todosModel.getList();
$main.toggle( !!todosList.length ); $todoList.html( _template( todoList ) );
$main.toggle( !!todoList.length );
$toggleAll.prop( 'checked', !this.todosModel.getNumActive() );
} }
} }
} }
......
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