Commit 3560728d authored by Aaron Boushley's avatar Aaron Boushley

Merging Pull Request 34. Vanilla JS implementation.

parents 73817d73 282c89f2
...@@ -80,19 +80,20 @@ ...@@ -80,19 +80,20 @@
<h5>Live demos</h5> <h5>Live demos</h5>
<ul> <ul>
<li><a href="todo-example/emberjs/index.html">Ember.js</a></li> <li><a href="todo-example/emberjs/index.html">Ember.js</a></li>
<li><a href="todo-example/javascriptmvc/todo/todo/index.html">JavaScriptMVC</a></li> <li><a href="todo-example/javascriptmvc/todo/todo/index.html">JavaScriptMVC</a></li>
<li><a href="todo-example/spine/index.html">Spine.js</a></li> <li><a href="todo-example/spine/index.html">Spine.js</a></li>
<li><a href="todo-example/backbone/index.html">Backbone.js</a></li> <li><a href="todo-example/backbone/index.html">Backbone.js</a></li>
<li><a href="todo-example/backbone_require/index.html">Backbone.js + RequireJS</a></li> <li><a href="todo-example/backbone_require/index.html">Backbone.js + RequireJS</a></li>
<li><a href="todo-example/sammyjs/index.html">Sammy.js</a></li> <li><a href="todo-example/sammyjs/index.html">Sammy.js</a></li>
<li><a href="todo-example/knockback/todos-classic/index.html">Knockback.js</a></li> <li><a href="todo-example/knockback/todos-classic/index.html">Knockback.js</a></li>
<li><a href="todo-example/knockoutjs/index.html">KnockoutJS (MVVM)</a></li> <li><a href="todo-example/knockoutjs/index.html">KnockoutJS (MVVM)</a></li>
<li><a href="todo-example/yuilibrary/index.html">YUILibrary</a></li> <li><a href="todo-example/yuilibrary/index.html">YUILibrary</a></li>
<li><a href="todo-example/angularjs/main/index.html">AngularJS</a></li> <li><a href="todo-example/angularjs/main/index.html">AngularJS</a></li>
<li><a href="todo-example/angularjs/persistencejs/index.html">Angular + PersistenceJS</a></li> <li><a href="todo-example/angularjs/persistencejs/index.html">Angular + PersistenceJS</a></li>
<li><a href="todo-example/broke/index.html">Broke.js</a></li> <li><a href="todo-example/broke/index.html">Broke.js</a></li>
<li><a href="todo-example/fidel/index.html">Fidel.js</a></li> <li><a href="todo-example/fidel/index.html">Fidel.js</a></li>
<li><a href="todo-example/vanillajs/index.html">Vanilla JS</a></li>
</ul> </ul>
<h5>Contributors</h5> <h5>Contributors</h5>
...@@ -109,6 +110,7 @@ ...@@ -109,6 +110,7 @@
<li><a href="https://github.com/jacobmumm">Jacob Mumm</a></li> <li><a href="https://github.com/jacobmumm">Jacob Mumm</a></li>
<li><a href="https://github.com/brokenseal">Davide Callegari</a></li> <li><a href="https://github.com/brokenseal">Davide Callegari</a></li>
<li><a href="https://github.com/kmalakoff">Kevin Malakoff</a></li> <li><a href="https://github.com/kmalakoff">Kevin Malakoff</a></li>
<li><a href="https://twitter.com/ffesseler">Florian Fesseler</a></li>
</ul> </ul>
<h5>Coming Soon</h5> <h5>Coming Soon</h5>
...@@ -117,6 +119,7 @@ ...@@ -117,6 +119,7 @@
<li>Dojo Todo app (with MVC patterns)</li> <li>Dojo Todo app (with MVC patterns)</li>
<li>Batman.js Todo app</li> <li>Batman.js Todo app</li>
<li>Todo app boilerplate</li> <li>Todo app boilerplate</li>
<li>Todo app pure JS : no framework, no MVC</li>
</ul> </ul>
</div> </div>
......
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, font, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-weight: inherit;
font-style: inherit;
font-size: 100%;
font-family: inherit;
vertical-align: baseline;
}
body {
line-height: 1;
color: black;
background: white;
}
ol, ul {
list-style: none;
}
a img {
border: none;
}
html {
background: #eeeeee;
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: 14px;
line-height: 1.4em;
background: #eeeeee;
color: #333333;
}
#todoapp {
width: 480px;
margin: 0 auto 40px;
background: white;
padding: 20px;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
-webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
-o-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0;
}
#todoapp h1 {
font-size: 36px;
font-weight: bold;
text-align: center;
padding: 20px 0 30px 0;
line-height: 1;
}
#create-todo {
position: relative;
}
#create-todo input {
width: 466px;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
padding: 6px;
border: 1px solid #999999;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-webkit-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;
}
#create-todo span {
position: absolute;
z-index: 999;
width: 170px;
left: 50%;
margin-left: -85px;
}
#todo-list {
margin-top: 10px;
}
#todo-list li {
padding: 12px 20px 11px 0;
position: relative;
font-size: 24px;
line-height: 1.1em;
border-bottom: 1px solid #cccccc;
}
#todo-list li:after {
content: "\0020";
display: block;
height: 0;
clear: both;
overflow: hidden;
visibility: hidden;
}
#todo-list li.editing {
padding: 0;
border-bottom: 0;
}
#todo-list .editing .display,
#todo-list .edit {
display: none;
}
#todo-list .editing .edit {
display: block;
}
#todo-list .editing input {
width: 444px;
font-size: 24px;
font-family: inherit;
margin: 0;
line-height: 1.6em;
border: 0;
outline: none;
padding: 10px 7px 0px 27px;
border: 1px solid #999999;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-webkit-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;
}
#todo-list .check {
position: relative;
top: 9px;
margin: 0 10px 0 7px;
float: left;
}
#todo-list .done .todo-content {
text-decoration: line-through;
color: #777777;
}
#todo-list .todo-destroy {
position: absolute;
right: 5px;
top: 14px;
display: none;
cursor: pointer;
width: 20px;
height: 20px;
background: url(../../TodoMVC/todo-example/backbone/css/destroy.png) no-repeat 0 0;
}
#todo-list li:hover .todo-destroy {
display: block;
}
#todo-list .todo-destroy:hover {
background-position: 0 -20px;
}
#todo-stats {
*zoom: 1;
margin-top: 10px;
color: #777777;
}
#todo-stats:after {
content: "\0020";
display: block;
height: 0;
clear: both;
overflow: hidden;
visibility: hidden;
}
#todo-stats .todo-count {
float: left;
}
#todo-stats .todo-count .number {
font-weight: bold;
color: #333333;
}
#todo-stats .todo-clear {
float: right;
}
#todo-stats .todo-clear a {
color: #777777;
font-size: 12px;
}
#todo-stats .todo-clear a:visited {
color: #777777;
}
#todo-stats .todo-clear a:hover {
color: #336699;
}
#instructions {
width: 520px;
margin: 10px auto;
color: #777777;
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
text-align: center;
}
#instructions a {
color: #336699;
}
#credits {
width: 520px;
margin: 30px auto;
color: #999;
text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0;
text-align: center;
}
#credits a {
color: #888;
}
/*
* François 'cahnory' Germain
*/
.ui-tooltip, .ui-tooltip-top, .ui-tooltip-right, .ui-tooltip-bottom, .ui-tooltip-left {
color:#ffffff;
cursor:normal;
display:-moz-inline-stack;
display:inline-block;
font-size:12px;
font-family:arial;
padding:.5em 1em;
position:relative;
text-align:center;
text-shadow:0 -1px 1px #111111;
-webkit-border-top-left-radius:4px ;
-webkit-border-top-right-radius:4px ;
-webkit-border-bottom-right-radius:4px ;
-webkit-border-bottom-left-radius:4px ;
-khtml-border-top-left-radius:4px ;
-khtml-border-top-right-radius:4px ;
-khtml-border-bottom-right-radius:4px ;
-khtml-border-bottom-left-radius:4px ;
-moz-border-radius-topleft:4px ;
-moz-border-radius-topright:4px ;
-moz-border-radius-bottomright:4px ;
-moz-border-radius-bottomleft:4px ;
border-top-left-radius:4px ;
border-top-right-radius:4px ;
border-bottom-right-radius:4px ;
border-bottom-left-radius:4px ;
-o-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
-moz-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
-khtml-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
-webkit-box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
box-shadow:0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444;
background-color:#3b3b3b;
background-image:-moz-linear-gradient(top,#555555,#222222);
background-image:-webkit-gradient(linear,left top,left bottom,color-stop(0,#555555),color-stop(1,#222222));
filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#555555,EndColorStr=#222222);
-ms-filter:progid:DXImageTransform.Microsoft.gradient(startColorStr=#555555,EndColorStr=#222222);
}
.ui-tooltip:after, .ui-tooltip-top:after, .ui-tooltip-right:after, .ui-tooltip-bottom:after, .ui-tooltip-left:after {
content:"\25B8";
display:block;
font-size:2em;
height:0;
line-height:0;
position:absolute;
}
.ui-tooltip:after, .ui-tooltip-bottom:after {
color:#2a2a2a;
bottom:0;
left:1px;
text-align:center;
text-shadow:1px 0 2px #000000;
-o-transform:rotate(90deg);
-moz-transform:rotate(90deg);
-khtml-transform:rotate(90deg);
-webkit-transform:rotate(90deg);
width:100%;
}
.ui-tooltip-top:after {
bottom:auto;
color:#4f4f4f;
left:-2px;
top:0;
text-align:center;
text-shadow:none;
-o-transform:rotate(-90deg);
-moz-transform:rotate(-90deg);
-khtml-transform:rotate(-90deg);
-webkit-transform:rotate(-90deg);
width:100%;
}
.ui-tooltip-right:after {
color:#222222;
right:-0.375em;
top:50%;
margin-top:-.05em;
text-shadow:0 1px 2px #000000;
-o-transform:rotate(0);
-moz-transform:rotate(0);
-khtml-transform:rotate(0);
-webkit-transform:rotate(0);
}
.ui-tooltip-left:after {
color:#222222;
left:-0.375em;
top:50%;
margin-top:.1em;
text-shadow:0 -1px 2px #000000;
-o-transform:rotate(180deg);
-moz-transform:rotate(180deg);
-khtml-transform:rotate(180deg);
-webkit-transform:rotate(180deg);
}
/*the following changes require some cleanup and integration with the above.**/
/* line 9 */
/* line 17 */
#todoapp {
background: white;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 2px 6px 0;
-webkit-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;
-moz-border-radius-bottomleft: 5px;
-webkit-border-bottom-left-radius: 5px;
-o-border-bottom-left-radius: 5px;
-ms-border-bottom-left-radius: 5px;
-khtml-border-bottom-left-radius: 5px;
border-bottom-left-radius: 5px;
-moz-border-radius-bottomright: 5px;
-webkit-border-bottom-right-radius: 5px;
-o-border-bottom-right-radius: 5px;
-ms-border-bottom-right-radius: 5px;
-khtml-border-bottom-right-radius: 5px;
border-bottom-right-radius: 5px;
}
/* line 24 */
/* line 32 */
#todoapp .content #create-todo {
position: relative;
}
/* line 34 */
#todoapp .content #create-todo input {
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
padding: 6px;
border: 1px solid #999999;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-webkit-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;
}
/* line 47 */
#todoapp .content #create-todo span {
position: absolute;
z-index: 999;
width: 170px;
left: 50%;
margin-left: -85px;
opacity: 0;
}
/* line 55 */
#todoapp .content ul#todo-list {
margin-top: 10px;
}
/* line 57 */
#todoapp .content ul#todo-list li {
padding: 15px 20px 15px 0;
position: relative;
font-size: 24px;
border-bottom: 1px solid #cccccc;
*zoom: 1;
cursor: move;
}
/* line 22, /opt/ree/lib/ruby/gems/1.8/gems/compass-0.10.5/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
#todoapp .content ul#todo-list li:after {
content: "\0020";
display: block;
height: 0;
clear: both;
overflow: hidden;
visibility: hidden;
}
/* line 64 */
#todoapp .content ul#todo-list li.editing {
padding: 0;
border-bottom: 0;
}
/* line 67 */
#todoapp .content ul#todo-list li.editing .todo-input {
display: block;
width: 466px;
font-size: 24px;
font-family: inherit;
line-height: 1.4em;
border: 0;
outline: none;
padding: 6px;
border: 1px solid #999999;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset;
-webkit-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;
}
/* line 79 */
#todoapp .content ul#todo-list li.editing .todo-content {
display: none;
}
/* line 81 */
#todoapp .content ul#todo-list li.editing .todo-check {
display: none;
}
/* line 83 */
#todoapp .content ul#todo-list li.editing .todo-destroy {
display: none !important;
}
/* line 85 */
#todoapp .content ul#todo-list li .todo-input {
display: none;
}
/* line 87 */
#todoapp .content ul#todo-list li .todo-check {
position: relative;
top: 6px;
margin: 0 10px 0 7px;
float: left;
}
/* line 93 */
#todoapp .content ul#todo-list li.done .todo-content {
text-decoration: line-through;
color: #777777;
}
/* line 96 */
#todoapp .content ul#todo-list li .todo-destroy {
position: absolute;
right: 0px;
top: 16px;
display: none;
cursor: pointer;
width: 20px;
height: 20px;
}
/* line 106 */
#todoapp .content ul#todo-list li:hover .todo-destroy {
display: block;
}
/* line 109 */
#todoapp #todo-stats {
*zoom: 1;
margin-top: 10px;
color: #555555;
-moz-border-radius-bottomleft: 5px;
-webkit-border-bottom-left-radius: 5px;
-o-border-bottom-left-radius: 5px;
-ms-border-bottom-left-radius: 5px;
-khtml-border-bottom-left-radius: 5px;
border-bottom-left-radius: 5px;
-moz-border-radius-bottomright: 5px;
-webkit-border-bottom-right-radius: 5px;
-o-border-bottom-right-radius: 5px;
-ms-border-bottom-right-radius: 5px;
-khtml-border-bottom-right-radius: 5px;
border-bottom-right-radius: 5px;
background: #f4fce8;
border-top: 1px solid #ededed;
padding: 0 20px;
line-height: 36px;
}
/* line 22, /opt/ree/lib/ruby/gems/1.8/gems/compass-0.10.5/frameworks/compass/stylesheets/compass/utilities/general/_clearfix.scss */
#todoapp #todo-stats:after {
content: "\0020";
display: block;
height: 0;
clear: both;
overflow: hidden;
visibility: hidden;
}
/* line 118 */
#todoapp #todo-stats .todo-count {
float: left;
}
/* line 120 */
#todoapp #todo-stats .todo-count .number {
font-weight: bold;
color: #555555;
}
/* line 123 */
#todoapp #todo-stats .todo-clear {
float: right;
}
/* line 125 */
#todoapp #todo-stats .todo-clear a {
display: block;
line-height: 20px;
text-decoration: none;
-moz-border-radius: 12px;
-webkit-border-radius: 12px;
-o-border-radius: 12px;
-ms-border-radius: 12px;
-khtml-border-radius: 12px;
border-radius: 12px;
background: rgba(0, 0, 0, 0.1);
color: #555555;
font-size: 11px;
margin-top: 8px;
padding: 0 10px 1px;
-moz-box-shadow: rgba(0, 0, 0, 0.2) 0 -1px 0 0;
-webkit-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;
}
/* line 136 */
#todoapp #todo-stats .todo-clear a:hover {
background: rgba(0, 0, 0, 0.15);
-moz-box-shadow: rgba(0, 0, 0, 0.3) 0 -1px 0 0;
-webkit-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;
}
/* line 139 */
#todoapp #todo-stats .todo-clear a:active {
position: relative;
top: 1px;
}
<!DOCTYPE html>
<html>
<head>
<link href="css/todos.css" rel="stylesheet" type="text/css">
<script src="js/todo.js"></script>
<script src="js/json2.js"></script>
</head>
<body onload="bodyLoadHandler()">
<div id="todoapp">
<div class="title">
<h1>Todos</h1>
</div>
<div class="content">
<div id="create-todo">
<input id="new-todo" placeholder="What needs to be done?" onkeypress="newTodoKeyPressHandler(event)">
<span class="ui-tooltip-top" style="display:none;">Press Enter to save this task</span>
</div>
<div id="todos">
<ul id="todo-list">
</ul>
</div>
<div id="todo-stats">
</div>
</div>
</div>
</body>
</html>
\ No newline at end of file
/* json2.js
* 2008-01-17
* Public Domain
* No warranty expressed or implied. Use at your own risk.
* See http://www.JSON.org/js.html
*/
if(!this.JSON){JSON=function(){function f(n){return n<10?'0'+n:n;}
Date.prototype.toJSON=function(){return this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z';};var m={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'};function stringify(value,whitelist){var a,i,k,l,r=/["\\\x00-\x1f\x7f-\x9f]/g,v;switch(typeof value){case'string':return r.test(value)?'"'+value.replace(r,function(a){var c=m[a];if(c){return c;}
c=a.charCodeAt();return'\\u00'+Math.floor(c/16).toString(16)+
(c%16).toString(16);})+'"':'"'+value+'"';case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
if(typeof value.toJSON==='function'){return stringify(value.toJSON());}
a=[];if(typeof value.length==='number'&&!(value.propertyIsEnumerable('length'))){l=value.length;for(i=0;i<l;i+=1){a.push(stringify(value[i],whitelist)||'null');}
return'['+a.join(',')+']';}
if(whitelist){l=whitelist.length;for(i=0;i<l;i+=1){k=whitelist[i];if(typeof k==='string'){v=stringify(value[k],whitelist);if(v){a.push(stringify(k)+':'+v);}}}}else{for(k in value){if(typeof k==='string'){v=stringify(value[k],whitelist);if(v){a.push(stringify(k)+':'+v);}}}}
return'{'+a.join(',')+'}';}}
return{stringify:stringify,parse:function(text,filter){var j;function walk(k,v){var i,n;if(v&&typeof v==='object'){for(i in v){if(Object.prototype.hasOwnProperty.apply(v,[i])){n=walk(i,v[i]);if(n!==undefined){v[i]=n;}}}}
return filter(k,v);}
if(/^[\],:{}\s]*$/.test(text.replace(/\\./g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof filter==='function'?walk('',j):j;}
throw new SyntaxError('parseJSON');}};}();}
\ No newline at end of file
var tasks = [];
var stat;
/**************************/
/* MODEL /
/**************************/
function Todo(name, done) {
this.id = uuid();
this.name = name;
this.done = done;
}
function Stat() {
this.todoLeft = 0;
this.todoCompleted = 0;
this.totalTodo = 0;
}
/**************************/
/* EVENT HANDLERS /
/**************************/
function bodyLoadHandler() {
loadTasks();
refreshData();
}
function inputEditTodoKeyPressHandler(event) {
var inputEditTodo = event.target;
var taskId = event.target.id.slice(6);
if (event.keyCode === 13) {
editTask(taskId, inputEditTodo.value);
}
}
function newTodoKeyPressHandler(event) {
if (event.keyCode === 13) {
addTask(document.getElementById("new-todo").value);
}
}
function spanDeleteClickHandler(event) {
removeTaskById(event.target.id);
refreshData();
}
function hrefClearClickHandler() {
removeTasksDone();
refreshData();
}
function todoContentHandler(event) {
var taskId = event.target.id;
var div = document.getElementById("li_"+taskId);
div.className = "editing";
var inputEditTodo = document.getElementById("input_"+taskId);
inputEditTodo.focus();
}
function checkboxChangeHandler(event) {
var checkbox = event.target;
var todo = getTodoById(checkbox.id);
todo.done = checkbox.checked;
refreshData();
}
/**************************/
/* ACTIONS /
/**************************/
function loadTasks() {
if (!localStorage.todo) {
localStorage.todo = JSON.stringify([]);
}
tasks = JSON.parse(localStorage['todo']);
}
function addTask(text) {
var todo = new Todo(text, false);
tasks.push(todo);
refreshData();
}
function editTask(taskId, text) {
for (var i=0; i < tasks.length; i++) {
if (tasks[i].id === taskId) {
tasks[i].name = text;
}
}
refreshData();
}
function removeTaskById(id) {
for (var i=0; i < tasks.length; i++) {
if (tasks[i].id === id) {
tasks.splice(i, 1);
}
}
}
function removeTasksDone() {
for (var i=tasks.length-1; i >= 0; --i) {
if (tasks[i].done) {
tasks.splice(i, 1);
}
}
}
function getTodoById(id) {
for (var i=0; i < tasks.length; i++) {
if (tasks[i].id === id) {
return tasks[i];
}
}
}
function refreshData() {
saveTasks();
computeStats();
redrawTasksUI();
redrawStatsUI();
}
function saveTasks() {
localStorage['todo'] = JSON.stringify(tasks);
}
function computeStats() {
stat = new Stat();
stat.totalTodo = tasks.length;
for (var i=0; i < tasks.length; i++) {
if (tasks[i].done) {
stat.todoCompleted += 1;
}
}
stat.todoLeft = stat.totalTodo - stat.todoCompleted;
}
/**************************/
/* DRAWING /
/**************************/
function redrawTasksUI() {
var ul = document.getElementById("todo-list");
var todo;
removeChildren(ul);
document.getElementById("new-todo").value = "";
for (var i= 0; i < tasks.length; i++) {
todo = tasks[i];
//create checkbox
var checkbox = document.createElement("input");
checkbox.className = "check";
checkbox.id = todo.id;
checkbox.type = "checkbox";
checkbox.addEventListener("change", checkboxChangeHandler);
//create div text
var divText = document.createElement("div");
divText.className = "todo-content";
divText.id = todo.id;
divText.appendChild(document.createTextNode(todo.name));
divText.addEventListener("dblclick", todoContentHandler);
//create delete button
var spanDelete = document.createElement("span");
spanDelete.className = "todo-destroy";
spanDelete.id = todo.id;
spanDelete.addEventListener("click", spanDeleteClickHandler);
//create divDisplay
var divDisplay = document.createElement("div");
divDisplay.className = "display";
divDisplay.appendChild(checkbox);
divDisplay.appendChild(divText);
divDisplay.appendChild(spanDelete);
//create div todo
var divTodo = document.createElement("div");
divTodo.className = "todo ";
divTodo.appendChild(divDisplay);
//create todo input
var inputEditTodo = document.createElement("input");
inputEditTodo.id = "input_" + todo.id;
inputEditTodo.type = "text";
inputEditTodo.className = "todo-input";
inputEditTodo.value = todo.name;
inputEditTodo.addEventListener("keypress", inputEditTodoKeyPressHandler);
//create div edit
var divEdit = document.createElement("div");
divEdit.className = "edit";
divEdit.appendChild(inputEditTodo);
//create li
var li = document.createElement("li");
li.id = "li_" + todo.id;
li.appendChild(divTodo);
li.appendChild(divEdit);
if (todo.done)
{
divTodo.className += "done";
checkbox.checked = true;
}
ul.appendChild(li);
}
}
function redrawStatsUI() {
removeChildren(document.getElementById("todo-stats"))
if (stat.totalTodo > 0) {
drawTodoCount();
}
if (stat.todoCompleted > 0) {
drawTodoClear();
}
}
function drawTodoCount() {
//create span number
var spanNumber = document.createElement("span");
spanNumber.className = "number";
spanNumber.innerHTML = stat.todoLeft;
//create span word
var spanWord = document.createElement("span");
spanWord.className = "word";
spanWord.innerHTML = " item";
if (stat.todoLeft > 1) {
spanWord.innerHTML += "s";
}
var spanTodoCount = document.createElement("span");
spanTodoCount.className = "todo-count";
spanTodoCount.appendChild(spanNumber);
spanTodoCount.appendChild(spanWord);
spanTodoCount.innerHTML += " left.";
document.getElementById("todo-stats").appendChild(spanTodoCount);
}
function drawTodoClear() {
//create a href
var hrefClear = document.createElement("a");
hrefClear.href = "#";
hrefClear.addEventListener("click", hrefClearClickHandler);
hrefClear.innerHTML = "Clear ";
//create span number done
var spanNumberDone = document.createElement("span");
spanNumberDone.className = "number-done";
spanNumberDone.innerHTML = stat.todoCompleted;
hrefClear.appendChild(spanNumberDone);
hrefClear.innerHTML += " completed ";
//create span word
var spanWordDone = document.createElement("span");
spanWordDone.className = "word-done";
spanWordDone.innerHTML = " item";
if (stat.todoCompleted > 1) {
spanWordDone.innerHTML += "s";
}
hrefClear.appendChild(spanWordDone);
var spanTodoClear = document.createElement("span");
spanTodoClear.className = "todo-clear";
spanTodoClear.appendChild(hrefClear);
document.getElementById("todo-stats").appendChild(spanTodoClear);
}
function removeChildren(node) {
while (node.hasChildNodes()) {
node.removeChild(node.firstChild);
}
}
/**************************/
/* UTILS /
/**************************/
function uuid() {
var uuid = "", i, random;
for (i = 0; i < 32; i++) {
random = Math.random() * 16 | 0;
if (i == 8 || i == 12 || i == 16 || i == 20) {
uuid += "-"
}
uuid += (i == 12 ? 4 : (i == 16 ? (random & 3 | 8) : random)).toString(16);
}
return uuid;
}
\ 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