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>
...@@ -22,8 +22,10 @@ ...@@ -22,8 +22,10 @@
<button id="clear-completed">Clear completed</button> <button id="clear-completed">Clear completed</button>
</footer> </footer>
</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>
\ No newline at end of file
/* /*global jQuery, Handlebars */
( function ( ns ) {
'use strict';
ns.App = function () {
var system;
return {
startup:function () {
system = new dijon.System();
[MIT licensed](http://en.wikipedia.org/wiki/MIT_License) system.mapValue( 'system', system );
(c) [Sindre Sorhus](http://sindresorhus.com) system.mapOutlet( 'system' );
*/ system.injectInto( new ns.Config() );
( function( ns ){
ns.App = function(){
var system;
return {
startup : function(){
system = new dijon.System();
system.mapValue( 'system', system ); system.notify( 'App:startup' );
system.mapOutlet( 'system' ); system.notify( 'App:startupComplete' );
}
system.injectInto( new ns.Config() ); }
}
system.notify( 'App:startup' );
system.notify( 'App:startupComplete' );
}
}
}
}( dijondemo ) ); }( dijondemo ) );
dijondemo.app = new dijondemo.App(); dijondemo.app = new dijondemo.App();
......
...@@ -6,58 +6,53 @@ ...@@ -6,58 +6,53 @@
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;
//values //values
this.system.mapValue( 'enterKey', 13 ); this.system.mapValue( 'enterKey', 13 );
this.system.mapValue( 'uuidUtil', ns.utils.Utils ); this.system.mapValue( 'uuidUtil', ns.utils.Utils );
this.system.mapValue( 'pluralizeUtil', ns.utils.Utils ); this.system.mapValue( 'pluralizeUtil', ns.utils.Utils );
//models //models
this.system.mapSingleton( 'todosModel', ns.models.TodosModel ); this.system.mapSingleton( 'todosModel', ns.models.TodosModel );
//services //services
this.system.mapSingleton( 'storageService', ns.services.LocalStorageService ); this.system.mapSingleton( 'storageService', ns.services.LocalStorageService );
//controllers //views
this.system.mapSingleton( 'todosController', ns.controllers.TodosController ); this.system.mapSingleton( 'footerView', ns.views.FooterView );
//views this.system.mapSingleton( 'formView', ns.views.TodoFormView );
this.system.mapSingleton( 'footerView', ns.views.FooterView );
this.system.mapSingleton( 'listView', ns.views.TodoListView );
this.system.mapSingleton( 'formView', ns.views.TodoFormView );
//handlers
this.system.mapSingleton( 'listView', ns.views.TodoListView ); this.system.mapHandler( 'TodoFormView:addTodo', 'todosModel', 'add' );
this.system.mapHandler( 'TodoListView:toggleDoneOfTodo', 'todosModel', 'toggleDone' );
//handlers this.system.mapHandler( 'TodoListView:setTitleOfTodo', 'todosModel', 'setTitle' );
this.system.mapHandler( 'TodoFormView:addTodo', 'todosModel', 'add' ); this.system.mapHandler( 'TodoListView:removeTodo', 'todosModel', 'remove' );
this.system.mapHandler( 'TodoListView:toggleDoneOfTodo', 'todosModel', 'toggleDone' ); this.system.mapHandler( 'TodoListView:setDoneForAllTodos', 'todosModel', 'setDoneForAll' );
this.system.mapHandler( 'TodoListView:setTitleOfTodo', 'todosModel', 'setTitle' ); this.system.mapHandler( 'TodoListView:removeAllDoneTodos', 'todosModel', 'removeAllDone' );
this.system.mapHandler( 'TodoListView:removeTodo', 'todosModel', 'remove' ); this.system.mapHandler( 'StorageService:retrieveCompleted', 'todosModel', 'setList' );
this.system.mapHandler( 'TodoListView:setDoneForAllTodos', 'todosModel', 'setDoneForAll') this.system.mapHandler( 'TodosModel:todosListUpdated', 'listView', 'render' );
this.system.mapHandler( 'TodoListView:removeAllDoneTodos', 'todosModel', 'removeAllDone' ); this.system.mapHandler( 'TodosModel:todosListUpdated', 'footerView', 'render' );
this.system.mapHandler( 'StorageService:retrieveCompleted', 'todosModel', 'setList' ); this.system.mapHandler( 'TodosModel:todosListUpdated', 'storageService', 'store' );
this.system.mapHandler( 'FooterView:retrieveTodoCounts', 'todosController', 'retrieveCounts' ); this.system.mapHandler( 'App:startup', 'storageService', 'retrieve' );
this.system.mapHandler( 'TodosController:todoCountsRetrieved', 'footerView', 'updateCounts' ); this.system.mapHandler( 'App:startupComplete', 'formView', 'render' );
this.system.mapHandler( 'TodosModel:todosListUpdated', 'listView', 'render' ); this.system.mapHandler( 'App:startupComplete', 'storageService', 'retrieve' );
this.system.mapHandler( 'TodosModel:todosListUpdated', 'footerView', 'render' );
this.system.mapHandler( 'TodosModel:todosListUpdated', 'storageService', 'store' ); }
this.system.mapHandler( 'App:startup', 'storageService', 'retrieve' ); }
this.system.mapHandler( 'App:startupComplete', 'formView', 'render' ); }
this.system.mapHandler( 'App:startupComplete', 'storageService', 'retrieve' );
}
}
}
}( dijondemo ) ); }( dijondemo ) );
\ No newline at end of file
/**
* @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,81 +3,86 @@ ...@@ -3,81 +3,86 @@
* 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(){ },
for( var i = _list.length - 1, n = 0; i >= n; i-- ){ removeAllDone:function () {
if( _list[ i ].done ){ var i,
_list.splice( i, 1 ); n = 0;
} for ( i = _list.length - 1 ; i >= n ; i-- ) {
} if ( _list[ i ].completed ) {
this.notifyOfListUpdate(); _list.splice( i, 1 );
}, }
getNumTotal : function(){ }
return _list.length; this.notifyOfListUpdate();
}, },
getNumActive : function(){ getNumTotal:function () {
var count = 0; return _list.length;
for( var i in _list ){ },
if( ! _list[ i ].done ){ getNumActive:function () {
count++; var count = 0,
} i;
} for ( i in _list ) {
return count; if ( !_list[ i ].completed ) {
} count++;
}
}
return count;
}
} }
} }
}( dijondemo ) ); }( dijondemo ) );
\ No newline at end of file
...@@ -3,18 +3,18 @@ ...@@ -3,18 +3,18 @@
* 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 );
} }
} }
} }
}( dijondemo ) ) }( dijondemo ) )
\ No newline at end of file
...@@ -3,12 +3,15 @@ ...@@ -3,12 +3,15 @@
* 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 count === 1 ? word : word + 's'; return b
} },
}; pluralize:function ( count, word ) {
return count === 1 ? word : word + 's';
}
};
}( dijondemo ) ); }( dijondemo ) );
\ No newline at end of file
...@@ -3,37 +3,40 @@ ...@@ -3,37 +3,40 @@
* 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 {
system : undefined, //inject
pluralizeUtil : undefined, //inject,
setup : function(){
var self = this;
$clearBtn.on( 'click', function() {
self.system.notify( 'TodoListView:removeAllDoneTodos' );
} );
}, return {
render : function(){ system:undefined, //inject
this.system.notify( 'FooterView:retrieveTodoCounts' ); pluralizeUtil:undefined, //inject,
}, todosModel : undefined, //inject
updateCounts : function( numTodosTotal, numTodosActive ){ setup:function () {
var numTodosCompleted = numTodosTotal - numTodosActive; var self = this;
var countTitle = '<b>' + numTodosActive + '</b> ' + this.pluralizeUtil.pluralize( numTodosActive, 'item' ) + ' left'; $clearBtn.on( 'click', function () {
var clearTitle = 'Clear ' + numTodosCompleted + ' completed ' + this.pluralizeUtil.pluralize( numTodosCompleted, 'item' ); self.system.notify( 'TodoListView:removeAllDoneTodos' );
// Only show the footer when there are at least one todo. } );
$footer.toggle( !!numTodosTotal );
// Active todo count },
$count.html( countTitle ); render:function () {
// Toggle clear button and update title this.renderCounts( this.todosModel.getNumTotal(), this.todosModel.getNumActive() );
$clearBtn.text( clearTitle ).toggle( !!numTodosCompleted ); },
} renderCounts:function ( numTodosTotal, numTodosActive ) {
} var numTodosCompleted = numTodosTotal - numTodosActive,
} countTitle = '<b>' + numTodosActive + '</b> ' + this.pluralizeUtil.pluralize( numTodosActive, 'item' ) + ' left',
clearTitle = 'Clear completed (' + numTodosCompleted + ')';
// Only show the footer when there are at least one todo.
$footer.toggle( !!numTodosTotal );
// Active todo count
$count.html( countTitle );
// Toggle clear button and update title
$clearBtn.text( clearTitle ).toggle( !!numTodosCompleted );
}
}
}
}( dijondemo ) ); }( dijondemo ) );
\ No newline at end of file
...@@ -3,37 +3,33 @@ ...@@ -3,37 +3,33 @@
* 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 ),
return; val = $.trim( $input.val() );
} if ( e.which !== self.enterKey || !val ) {
var $input = $(this); return;
var inputVal = $input.val(); }
if ( !inputVal ) { self.system.notify( 'TodoFormView:addTodo', {
return; title:val,
} id:self.uuidUtil.uuid(),
completed:false
} );
self.system.notify( 'TodoFormView:addTodo', { $input.val( '' );
title: inputVal, } );
id: self.uuidUtil.uuid(), },
done: false render:function () {
})
$input.val(''); }
} ); }
}, }
render : function(){
}
}
}
}( dijondemo )) }( dijondemo ))
\ No newline at end of file
...@@ -3,56 +3,62 @@ ...@@ -3,56 +3,62 @@
* 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
var self = this; setup:function () {
$todoList.on( 'change', '.toggle', function() { var self = this;
var id = $( this ).closest('li').data('id'); $todoList.on( 'change', '.toggle', function () {
self.system.notify( 'TodoListView:toggleDoneOfTodo', id ); var id = $( this ).closest( 'li' ).data( 'id' );
} ); self.system.notify( 'TodoListView:toggleDoneOfTodo', id );
$todoList.on( 'dblclick', '.view', function() { } );
$(this) $todoList.on( 'dblclick', '.view', function () {
.closest('li') $( this )
.addClass('editing') .closest( 'li' )
.find('.edit') .addClass( 'editing' )
.focus(); .find( '.edit' )
} ); .focus();
$todoList.on( 'keypress', '.edit', function(e) { } );
if ( e.keyCode === self.enterKey ) { $todoList.on( 'keypress', '.edit', function ( e ) {
console.log( e.target ); if ( e.keyCode === self.enterKey ) {
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() );
self.system.notify( 'TodoListView:setTitleOfTodo', id, val ); if( val ){
} ); self.system.notify( 'TodoListView:setTitleOfTodo', id, val );
$todoList.on( 'click', '.destroy', function() { }else{
var id = $( this ).closest('li').data('id'); self.system.notify( 'TodoListView:removeTodo', id );
self.system.notify( 'TodoListView:removeTodo', id ); }
} ); } );
$todoList.on( 'click', '.destroy', function () {
var id = $( this ).closest( 'li' ).data( '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() );
} }
}
}
}( dijondemo )) }( dijondemo ))
\ No newline at end of file
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