Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
263 lines (215 sloc) 7.07 KB
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<title>ToDo List</title>
<style>
body { margin:0; padding:0; font-family: Georgia, serif;}
h1, h2 { text-align: center; }
h3 { margin: 0.5em 0; float: left; width: 100%; }
ul { list-style:none; margin:0 0 0.5em 0; padding:0; float: left; width: 100%; }
li { margin: 0; padding: 10px 0; border-bottom: 1px #6F806C solid; cursor: pointer; float:left; width: 100%; font-size: 110%;}
li span { padding-left: 10px; }
form { margin-bottom: 0.5em; }
input { font-size: 110%; margin: 0 auto; width: 100%; min-width: 100px; padding: 5px; font-family: Georgia, serif;}
p { font-size: 75%;}
.template { display: none; visibility: hidden; }
#wrapper { min-height: 100%; position: relative; margin: 0 auto; width: 60%; min-width: 280px; }
.item_actions { display:none; margin: 0 10px; float: right; }
.item_actions a { height: 16px; width: 16px; text-decoration: none; color: #000; }
.item_actions a:visited {color: #000; }
li.task:hover .item_actions { display: block; }
#completed_todos span {text-decoration: line-through;}
</style>
</head>
<body>
<div id="wrapper">
<div class ="content" id="maincontent">
<h1>ToDo List</h1>
<form id="new_entry">
<input type="text" value="" placeholder="Add item"/>
</form>
<h3>Pending</h3>
<ul id="pending_todos" class="list">
<li class="template task">
<span style='float:left'>Dummy Item</span>
<div class="item_actions">
<a href='#' class='remove_item'>✓</a>
</div>
</li>
<p class="empty">No pending items.</p>
</ul>
<h3>Completed</h3>
<ul id="completed_todos" class="list">
<li class="template task">
<span style='float:left'>Dummy Item</span>
<div class="item_actions">
<a href='#' class='remove_item'>×</a>
</div>
</li>
<p class="empty">No completed items.</p>
</ul>
</div>
</div>
<script type="text/javascript" src="../../lib/sugarless.js"></script>
<script type="text/javascript">
/* Shorthands */
var $_ = Sugarless;
var $ = function(sel){ return $_(document.querySelector(sel)) };
/* DOM helpers */
var domReady = function(callback){ document.addEventListener('DOMContentLoaded', callback); }
var createElementFromTemplate = function(template){
var item = template.cloneNode(true);
var classes = item.className.split(" ");
classes.splice(classes.indexOf("template"), 1);
item.className = classes.join(" ");
return item;
};
var prependTo = function(container){
container.insertBefore(this, container.firstChild);
};
var onClick = function(callbacks){
this.addEventListener('click', function(ev){
$_(this)( callbacks );
ev.preventDefault();
});
};
var onSubmit = function(callbacks){
this.addEventListener('submit', function(ev){
$_(this)( callbacks );
ev.preventDefault();
});
};
/* Custom Functions */
var Store = {
polyfill: { data: [], getItem: function(){ return JSON.stringify(this.data); }, setItem: function(){ return this.data.push(arguments[0]) } },
fetch: function(){
return $_(window['localStorage'], { fallback: Store.polyfill })(
$_.invoke, "getItem", this.id
, function(){ return arguments[0] }, "[]" //pass a default value
, JSON.parse
);
},
push: function(item){
var items = Store.fetch.call(this);
items.push(item)
$_(window['localStorage'], { fallback: Store.polyfill })(
$_.invoke, ["setItem", this.id, JSON.stringify(items)]
);
return item;
},
remove: function(item) {
var items = Store.fetch.call(this);
items.splice(items.indexOf(item), 1);
$_(window['localStorage'], { fallback: Store.polyfill })(
$_.invoke, ["setItem", this.id, JSON.stringify(items)]
);
}
};
var EmptyMessage = {
hide: function(){
var empty_message = this.querySelector("p.empty");
empty_message.style.display = "none";
},
show: function(){
if(!this.querySelector(".task:not(.template)")){
var empty_message = this.querySelector("p.empty");
empty_message.style.display = "block";
}
}
};
var List = {
add: function(item){
if(item.length){
EmptyMessage.hide.call(this);
var template = this.querySelector('.template');
var _add = function(name){
$_(createElementFromTemplate(template), {noreturns: true})(
Task.setContent, name
, onClick, (this.id == "pending_todos" ? [Task.complete] : [Task.remove])
, prependTo, this
);
};
//check whether the given item is an array
if(Array.isArray(item)){
item.forEach(_add, this);
}
else {
_add.call(this, item);
}
}
},
remove: function(item){
this.removeChild(item);
}
};
var Task = {
complete: function(){
var element = this;
var name = element.querySelector('span').innerHTML
// remove task from pending list
$("#pending_todos")(
Store.remove, name
, List.remove, element
, EmptyMessage.show
);
// add task to completed list
$("#completed_todos")(
Store.push, name
, List.add
);
},
remove: function(){
var element = this;
var name = element.querySelector('span').innerHTML
// remove task from completed list
$("#completed_todos")(
Store.remove, name
, List.remove, element
, EmptyMessage.show
);
},
save: function(name){
$("#pending_todos")(
Store.push, name
, List.add
);
},
setContent: function(content){
this.querySelector('span').innerHTML = content;
}
};
var Form = {
captureInput: function(){
var input = this.querySelector('input[type=text]').value
if(input.length){
return input;
}
else {
alert("Task can't be empty");
$_(this).clear(); //clears the remaining functions queue
}
},
reset: function(){
this.querySelector('input[type=text]').value = "";
}
};
/* Behaviour calls */
domReady(function() {
$("#pending_todos")(
Store.fetch
, List.add
);
$("#completed_todos")(
Store.fetch
, List.add
);
$("#new_entry")(
onSubmit, [ Form.captureInput, Task.save, Form.reset ]
);
});
</script>
</body>
</html>