Skip to content

Instantly share code, notes, and snippets.

@bloodyowl
Created November 12, 2012 14:00
Show Gist options
  • Save bloodyowl/4059550 to your computer and use it in GitHub Desktop.
Save bloodyowl/4059550 to your computer and use it in GitHub Desktop.
Todo List using Craft.js and localStorage
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Todo List</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>Todo List</h1>
<input type="text" value="" id="add" placeholder="Add a new item and hit enter" name="add">
<ul id="todo"></ul>
<a id="items" href="#">Clear checked items</a>
<script type="text/javascript" src="http://raw.github.com/mlbli/craft/master/craft-min.js"></script>
<script type="text/javascript" src="todo.js"></script>
</body>
</html>
html,
body {
background: #eee;
padding: 0;
margin: 0;
}
body {
width: 30em;
margin: 1em auto;
padding: 1em;
background: #fff;
font: 1em/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
border: 1px #bbb solid;
box-shadow: 0 0.3em 0.6em rgba(0,0,0,0.1);
}
h1 {
text-align: center;
font: 400 2.4em Georgia, "Times New Roman", Times, serif;
color: #666;
margin: 0;
padding: 0.2em 0;
}
#add {
display: block;
width: 100%;
font-family: inherit;
font-size: 1em;
text-align: center;
padding: 1em 0;
position: relative;
left: -1px;
border: 1px #ccc solid;
border-radius: 0.3em;
box-shadow: 0 0.1em 0.3em rgba(0,0,0,0.1);
font-weight: 300;
}
#todo {
list-style-type: none;
padding: 0;
}
#todo li {
border-bottom: 1px #bbb dotted;
padding: 0.5em;
position: relative;
}
#todo li .edit-text {
font-size: 1.4em;
font-weight: 300;
padding: 0 0.7em;
line-height: 2;
display: inline;
font-family: inherit;
border: none;
width: 15em;
border-radius: 0.1em;
}
#todo li .edit-text:focus {
outline: none;
box-shadow: 0 0 0.3em #079;
}
#todo li .edit,
#todo li .delete {
display: none;
}
#todo li .edit.visible,
#todo li .delete.visible {
display: block;
}
#todo li .delete {
position: absolute;
right: 1em;
font-size: 2em;
top: 50%;
margin-top: -0.4em;
line-height: 0.6;
text-align: center;
text-decoration: none;
color: #fff;
background: #ccc;
height: 0.8em;
width: 0.8em;
border-radius: 0.8em;
}
#todo li .delete:hover,
#todo li .delete:focus {
background: #c33;
}
#todo li.deactivated input {
color: #999;
}
#items {
display: block;
text-align: center;
font-family: Georgia, "Times New Roman", Times, serif;
text-decoration: none;
color: #333;
}
#items:hover,
#items:focus {
color: #666;
text-decoration: underline;
}
#items:active {
color: #000;
}
Element.ready(function(){
var list = $("todo")
, addInput = $("add")
, STORAGE = "localStorage" in window
function Storage(operation, key, value, done){
if(!STORAGE) return;
if(operation == "remove") localStorage.removeItem(key)
if(operation == "set") localStorage.setItem(key, (done ? "::done::" : "") + value )
}
function addItem(text, key, isDone){
if(text.indexOf("::done::") == 0) {
text = text.replace("::done::", "")
isDone = true
}
var id = key || +new Date()
, checkbox = Element.create("input", { type : "checkbox", value : "done", name : "done"})
.listen("click", function(){
if(checkbox.getValue() == "done") {
a.getParent().remove().addClass("deactivated").appendTo(list)
Storage("set", id, text, true)
}
else {
a.getParent().remove().removeClass("deactivated").prependTo(list)
Storage("set", id, text)
}
})
, input = Element.create("input", { type : "text", className : "edit-text", value : text })
.listen("keypress blur", function(e){
if(e.keyCode && e.keyCode != 13) return;
input.blur()
if(checkbox.getValue() == "done") {
Storage("set", id, input.getValue(), true)
}
else {
Storage("set", id, input.getValue())
}
})
, a = Element.create("a", { href : "#", className : "delete", innerHTML : "&times;" })
.listen("click", function(e){
Event.stop(e)
a.getParent().remove()
Storage("remove", id)
})
, item = Element.create("li").listen("mouseover", function(){ a.addClass("visible")}).listen("mouseout",function(){ a.removeClass("visible") })
item.insert({ top : checkbox,
bottom : input
}).insert(a).prependTo(list)
if(isDone) checkbox.click()
Storage("set", id, text, isDone)
}
addInput.listen("keypress", function(e){
var value
if(e.keyCode != 13 || !(value = addInput.getValue())) return;
addItem(value)
$("add").setValue("")
})
if(STORAGE && localStorage.length) {
Hash(localStorage).forEach(function(item, index){
if(index == "length") return;
addItem(item, index)
})
} else {
addItem("hello, this is your first item")
}
$("items").listen("click", function(e){
Event.stop(e)
Element.getByClass("deactivated").invoke("getByTag", "a").group().forEach(function(item){
item.click()
})
})
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment