Skip to content

Instantly share code, notes, and snippets.

@madsravn
Forked from daffl/app.js
Created December 12, 2013 01:13
Show Gist options
  • Save madsravn/7921644 to your computer and use it in GitHub Desktop.
Save madsravn/7921644 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>Feathers real-time Todos</title>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<style type="text/css">
.done {
text-decoration: line-through;
}
</style>
<div class="container" id="todos">
<h1>Feathers real-time Todos</h1>
<ul class="todos list-unstyled"></ul>
<form role="form" class="create-todo">
<div class="form-group">
<input type="text" class="form-control" name="description" placeholder="Add a new Todo">
</div>
<button type="submit" class="btn btn-info col-md-12">Add Todo</button>
</form>
</div>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect();
var el = $('#todos');
var app = {
addTodo: function(todo) {
var html = '<li class="page-header checkbox" data-id="' + todo.id + '">' +
'<label><input type="checkbox" name="done">' +
todo.description +
'</label><a href="javascript://" class="pull-right delete">' +
'<span class="glyphicon glyphicon-remove"></span>' +
'</a></li>';
el.find('.todos').append(html);
app.updateTodo(todo);
},
removeTodo: function(todo) {
el.find('[data-id="' + todo.id + '"]').remove();
},
updateTodo: function(todo) {
var element = el.find('[data-id="' + todo.id + '"]');
var checkbox = element.find('[name="done"]').removeAttr('disabled');
if(todo.done) {
element.addClass('done');
checkbox.prop('checked', true);
} else {
element.removeClass('done');
checkbox.prop('checked', false);
}
},
errorHandler: function(error) {
if(error) {
alert(error.message);
}
}
};
el.on('submit', 'form', function (ev) {
var field = $(this).find('[name="description"]');
socket.emit('todos::create', {
description: field.val()
}, {}, app.errorHandler);
field.val('');
ev.preventDefault();
}).on('click', '.delete', function (ev) {
var id = $(this).parents('li').data('id');
socket.emit('todos::remove', id, {}, app.errorHandler);
ev.preventDefault();
}).on('click', '[name="done"]', function(ev) {
var id = $(this).parents('li').data('id');
$(this).attr('disabled', 'disabled');
socket.emit('todos::update', id, {
done: $(this).is(':checked')
}, {}, app.errorHandler);
});
socket.on('todos updated', app.updateTodo);
socket.on('todos removed', app.removeTodo);
socket.on('todos created', app.addTodo);
socket.emit('todos::find', {}, function (error, todos) {
todos.forEach(app.addTodo);
});
</script>
</body>
</html>
// To get up and running with this example, download the Gist from
// https://gist.github.com/daffl/6665992/download
// Unpack and in the new folder run
// > npm install feathers
// > node server.js
// Then go to http://localhost:8080
var feathers = require('feathers');
var TodoService = require('./todos');
feathers().configure(feathers.socketio())
.use(feathers.static(__dirname))
.use('/todos', new TodoService())
.listen(8080);
var tagsToReplace = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;'
};
// Escapes HTML so that evil people can't inject mean things into the page
function escapeHtml(str) {
return str.replace(/[&<>]/g, function (tag) {
return tagsToReplace[tag] || tag;
});
}
function TodoStore() {
this.todos = [];
this.lastId = 0;
}
// Returns a Todo by it's id
TodoStore.prototype.getById = function (id) {
var currentTodo;
for (var i = 0; i < this.todos.length; i++) {
currentTodo = this.todos[i];
if (currentTodo.id == id) {
return currentTodo;
}
}
return null;
}
TodoStore.prototype.find = function (params, callback) {
callback(null, this.todos);
}
TodoStore.prototype.get = function (id, params, callback) {
var todo = this.getById(id);
if (todo === null) {
return callback(new Error('Todo not found'));
}
callback(null, todo);
}
TodoStore.prototype.create = function (data, params, callback) {
// Create our actual Todo object so that we only get what we really want
var newTodo = {
id: this.lastId++,
description: escapeHtml(data.description),
done: !!data.done
};
this.todos.push(newTodo);
callback(null, newTodo);
}
TodoStore.prototype.update = function (id, data, params, callback) {
var todo = this.getById(id);
if (todo === null) {
return callback(new Error('Todo does not exist'));
}
// We only want to update the `done` property
// !! is used for sanitization turning everything into a real booelan
todo.done = !!data.done;
callback(null, todo);
}
TodoStore.prototype.remove = function (id, params, callback) {
var todo = this.getById(id);
if (todo === null) {
return callback(new Error('Can not delete Todo'));
}
// Just splice our todo out of the array
this.todos.splice(this.todos.indexOf(todo), 1);
callback(null, todo);
}
module.exports = TodoStore;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment