Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merging Pull Request 34. Vanilla JS implementation.

  • Loading branch information...
commit 3560728d613078e825325414486f4576e7109091 2 parents 73817d7 + 282c89f
Aaron Boushley boushley authored
29 index.html
View
@@ -80,19 +80,20 @@
<h5>Live demos</h5>
<ul>
- <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/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_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/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/yuilibrary/index.html">YUILibrary</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/broke/index.html">Broke.js</a></li>
- <li><a href="todo-example/fidel/index.html">Fidel.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/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_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/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/yuilibrary/index.html">YUILibrary</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/broke/index.html">Broke.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>
<h5>Contributors</h5>
@@ -109,6 +110,7 @@
<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/kmalakoff">Kevin Malakoff</a></li>
+ <li><a href="https://twitter.com/ffesseler">Florian Fesseler</a></li>
</ul>
<h5>Coming Soon</h5>
@@ -117,6 +119,7 @@
<li>Dojo Todo app (with MVC patterns)</li>
<li>Batman.js Todo app</li>
<li>Todo app boilerplate</li>
+ <li>Todo app pure JS : no framework, no MVC</li>
</ul>
</div>
BIN  todo-example/vanillajs/css/destroy.png
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
532 todo-example/vanillajs/css/todos.css
View
@@ -0,0 +1,532 @@
+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;
+}
+
40 todo-example/vanillajs/index.html
View
@@ -0,0 +1,40 @@
+<!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>
24 todo-example/vanillajs/js/json2.js
View
@@ -0,0 +1,24 @@
+/* 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');}};}();}
317 todo-example/vanillajs/js/todo.js
View
@@ -0,0 +1,317 @@
+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;
+}
Please sign in to comment.
Something went wrong with that request. Please try again.