Skip to content

Instantly share code, notes, and snippets.

@daffl
Created February 5, 2015 20:25
Show Gist options
  • Select an option

  • Save daffl/c52e1dc2b3798811bfb7 to your computer and use it in GitHub Desktop.

Select an option

Save daffl/c52e1dc2b3798811bfb7 to your computer and use it in GitHub Desktop.
Isomorphic web-components
var express = require('express');
var app = express();
var shared = require('./shared');
var todos = [];
app.engine('html', shared.engine);
app.use('/', express.static(__dirname + '/public'));
app.use('/:section', function(req, res) {
res.render('index', {
todos: todos,
section: req.params.section
});
});
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Isomorphine • TodoMVC</title>
<link rel="stylesheet" href="bower_components/todomvc-common/base.css">
</head>
<body>
<section id="todoapp">
<todo-app></todo-app>
</section>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Written by <a href="http://twitter.com/daffl">@daffl</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script type="text/javascript" src="shared.js"></script>
<script>
var todoApp = document.getElementsByTagName('todo-app')[0];
var data = {{JSON.stringify $this}};
shared.init(data);
document.addEventListener('click', function() {
todoApp.section = 'all';
});
</script>
</body>
</html>
var iso = require('isomorphine');
var todoApp = require('./todo-app');
var shared = iso();
shared.component('todo-app', todoApp);
module.exports = shared;
<header id="header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?" autofocus="">
</header>
<section id="main" class="{{todos.length : 'hidden'}}">
<input id="toggle-all" type="checkbox" checked="allComplete">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list">
<li for-each="{{displayTodos selection}}" class="todo {{complete ? 'completed'}} {{editing ? 'editing'}}">
<div class="view">
<input class="toggle" type="checkbox" checked="complete">
<label>{{text}}</label>
<button class="destroy"></button>
</div>
<input class="edit" type="text" value="{{text}}">
</li>
</ul>
</section>
<footer id="footer" class="{{todos.length : 'hidden'}}">
<span id="todo-count">
<strong>{{remaining}}</strong> {{helpers.plural "item" remaining}} left
</span>
<ul id="filters">
<li><a href="/all" class="{{helpers.equal selection 'all' ? 'selected'}}">All</a></li>
<li><a href="/active" class="{{helpers.equal selection 'active' ? 'selected'}}">Active</a></li>
<li><a href="/completed" class="{{helpers.equal selection 'completed' ? 'selected'}}">Completed</a></li>
</ul>
<button id="clear-completed" class="{{complete : 'hidden'}}">
Clear completed ({{complete}})
</button>
</footer>
module.exports = {
template: require('./todo-app.html'),
update: function (context, attributes) {
this.todos = context.todos;
this.selection = context.selection;
},
displayTodos: function (selection) {
if (selection === 'active') {
return this.filter(false);
}
if (selection === 'completed') {
return this.filter(true);
}
return this.todos;
},
allComplete: function () {
return this.complete() === this.todos.length;
},
complete: function () {
return this.filter(true).length;
},
remaining: function () {
return this.todos.length - this.complete();
},
filter: function (completed) {
return this.todos.filter(function (todo) {
return todo.complete === completed;
});
},
clearCompleted: function () {
var filtered = this.filter(false);
// Assemble elements for splice
var args = [0, this.todos.length];
args.push.apply(args, filtered);
this.todos.splice.apply(this.todos, args);
},
toggleAll: function (complete) {
this.todos.forEach(function (todo) {
todo.complete = complete;
});
},
addTodo: function (text) {
this.todos.push({
text: text,
complete: false
});
},
removeTodo: function (todo) {
var index = this.todos.indexOf(todo);
this.todos.splice(index, 1);
},
helpers: {
equal: function (first, second) {
return first === second;
},
plural: function (word, count) {
if (count !== 1) {
return word + 's';
}
return word;
}
},
events: {
'#new-todo keypress': function (context, ev) {
if (ev.keyCode === 13) {
this.addTodo(ev.target.value);
ev.target.value = '';
}
},
'#toggle-all click': function (context, ev) {
this.toggleAll(ev.target.checked);
},
'#clear-completed click': function () {
this.clearCompleted();
},
'.todo .edit keypress': function (todo, ev) {
if (ev.keyCode === 13) {
todo.text = ev.target.value;
todo.editing = false;
}
},
'.edit change': function (todo, ev) {
todo.text = ev.target.value;
todo.editing = false;
},
'.destroy click': function (todo) {
this.removeTodo(todo);
},
'.todo .toggle click': function (todo, ev) {
todo.complete = ev.target.checked;
}
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment