Skip to content

Instantly share code, notes, and snippets.

@ksafranski
Created February 23, 2014 02:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ksafranski/9165623 to your computer and use it in GitHub Desktop.
Save ksafranski/9165623 to your computer and use it in GitHub Desktop.
Demo UI for DozerJS TodoList App Tutorial
<!DOCTYPE html>
<html>
<head>
<title>DozerJS TodoList</title>
<link rel="stylesheet" href="screen.css">
</head>
<body>
<ul id="todos"></ul>
<input id="new-todo" placeholder="Create New Item...">
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script src="todos.js"></script>
<script>
var todos = new Todos();
</script>
</body>
</html>
html, body {
background: #e7e7e7;
}
body {
width: 500px;
margin: 5% auto 0 auto;
font: normal 22px Arial, Helvetica, sans-serif;
font-weight: bold;
color: #666;
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.8)
}
#todos {
margin: 0;
padding: 0;
}
#todos li, input#new-todo {
display: block;
width: 100%;
background: #ededed;
border: 1px solid #666;
border-radius: 5px;
list-style: none;
padding: 5px 15px;
margin: 3px 0;
box-shadow: 1px 1px 2px 0 rgba(255,255,255,0.8);
cursor: pointer;
}
#todos li[data-complete="true"] {
text-decoration: line-through;
font-style: italic;
color: #999;
}
#todos li span {
display: block;
}
#todos i {
display: block;
float: right;
margin: 0 0 0 15px;
color: #666;
font-style: normal;
transition: .3s color;
}
#todos i:before {
content: 'x';
}
#todos i:hover {
color: #ff0000;
}
input#new-todo {
cursor: text;
background: #fff;
font: normal 22px Arial, Helvetica, sans-serif;
}
var Todos = function (el) {
// Set primary element
this.$el = $('#todos');
// Set new item field
this.$newItem = $('#new-todo');
// Set api
this.api = '/api/todos/';
// Initialize
this.init();
};
// This is what kicks off initial load
Todos.prototype.init = function () {
// Expose this as self
var self = this;
// Make a request to the server, get initial list
var request = $.ajax({
url: this.api,
type: 'GET'
});
// Deffered to handle a succesfull response
request.done(function (res) {
// Make sure it returned data
if (res.data.length) {
// Reverse it to maintain chronological display
res.data.reverse();
// Loop through the items in data
for (var i = 0, z = res.data.length; i < z; i++) {
// Send it to append
self.appendTodo(res.data[i]);
}
}
});
// Binds item click to change 'complete' value
self.$el.on('click', 'li>span', function (e) {
e.stopPropagation();
self.changeComplete($(this).parent('li'));
});
// Binds create new field enter press to create method
self.$newItem.on('keypress', function (e) {
// Check for enter key
if (e.keyCode === 13) {
self.createItem($(this));
}
});
// Binds delete button
self.$el.on('click', 'li>i', function (e) {
// Prevent it from triggering the li click event
e.stopPropagation();
self.deleteItem($(this).parent('li'));
});
};
Todos.prototype.appendTodo = function (todo) {
// Add a new element to the list
this.$el.append('<li data-complete="'+todo.complete+'" data-id="'+todo._id+'"><i></i><span>'+todo.item+'</span></li>');
};
Todos.prototype.createItem = function ($field) {
// Expose this
var self = this;
// Get value
var item = $field.val();
// Make sure it's not empty
if (item.length) {
var request = $.ajax({
url: this.api,
type: 'POST',
data: { item: item, complete: false }
});
// When the request is finished...
request.done(function (res) {
// Create new element from response data
self.appendTodo(res.data);
// Clear the field
$field.val('').focus();
});
}
};
Todos.prototype.deleteItem = function ($item) {
// Get id
var id = $item.attr('data-id');
// Make request
var request = $.ajax({
url: this.api + id,
type: 'DELETE'
});
// On success, delete the element
request.done(function () {
$item.remove();
});
};
// Handles click event to change 'complete' state
Todos.prototype.changeComplete = function ($item) {
// Get id from data-attr
var id = $item.attr('data-id');
// Get state from data-attr
var state = $item.attr('data-complete');
// Get text
var text = $item.find('span').text();
// Set state to opposite
state = (state === 'true') ? false : true;
// Make request
var request = $.ajax({
url: this.api + id,
type: 'PUT',
data: { item: text, complete: state }
});
// Process request on success
request.done(function () {
// Change data attribute
$item.attr('data-complete', state.toString());
});
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment