-
-
Save madsravn/7921644 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!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> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var tagsToReplace = { | |
'&': '&', | |
'<': '<', | |
'>': '>' | |
}; | |
// 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