Created
February 5, 2015 20:25
-
-
Save daffl/c52e1dc2b3798811bfb7 to your computer and use it in GitHub Desktop.
Isomorphic web-components
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 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 | |
| }); | |
| }); |
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 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> |
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
| <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> |
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
| 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