Commit 0ee6deb8 authored by Jonas Nicklas's avatar Jonas Nicklas

Added Serenade.js example

parent f9552feb
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Serenade.js • TodoMVC</title>
<link href="../../../assets/base.css" rel="stylesheet">
<!--[if IE]>
<script src="../../../assets/ie.js"></script>
<![endif]-->
<script id="app" type="text/serenade">
section#todoapp
header#header
form[event:submit=newTodo!]
h1 "todos"
input#new-todo[binding:change=@newTitle placeholder="What needs to be done?" autofocus="autofocus"]
- if @allCount
section#main
input#toggle-all[type="checkbox" binding:change=@allCompleted]
label[for="toggle-all"] "Mark all as complete"
ul#todo-list
- collection @filtered
- view "todo"
footer#footer
span#todo-count
strong @activeCount
" "
@label
ul#filters
li
a.all[class:selected=@filterAll href="#/"] "All"
li
a.active[class:selected=@filterActive href="#/active"] "Active"
li
a.completed[class:selected=@filterCompleted href="#/completed"] "Completed"
- if @completedCount
button#clear-completed[event:click=clearCompleted]
"Clear completed (" @completedCount ")"
</script>
<script id="todo" type="text/serenade">
li[class:editing=@edit class:completed=@completed]
form[event:submit=edited!]
input.edit[on:load=loadField event:blur=edited! binding:change=@title]
- unless @edit
input.toggle[type="checkbox" binding:change=@completed]
label[event:dblclick=edit] @title
button.destroy[event:click=removeTodo]
</script>
</head>
<body>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Created by <a href="http://elabs.se">Elabs</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<script src="../../../assets/base.js"></script>
<script src="../../../assets/director.min.js"></script>
<script src="js/lib/serenade.js"></script>
<script src="js/app.js"></script>
</body>
</html>
class Todo extends Serenade.Model
@belongsTo 'app', inverseOf: 'all', as: -> App
@property 'title', serialize: true
@property 'completed', serialize: true
@property 'incomplete',
get: -> not @completed
@property 'edit'
remove: ->
@app.all.delete(this)
class App extends Serenade.Model
@hasMany 'all', inverseOf: 'app', serialize: true, as: -> Todo
@selection 'active', from: 'all', filter: 'incomplete'
@selection 'completed', from: 'all', filter: 'completed'
@property 'label',
get: -> if @activeCount is 1 then 'item left' else 'items left'
@property 'allCompleted',
get: -> @activeCount is 0
set: (value) -> todo.completed = value for todo in @all
@property 'newTitle'
@property 'filter', value: 'all'
@property 'filtered', get: -> @[@filter]
@property 'filterAll', get: -> @filter is 'all'
@property 'filterActive', get: -> @filter is 'active'
@property 'filterCompleted', get: -> @filter is 'completed'
class AppController
constructor: (@app) ->
newTodo: ->
title = @app.newTitle.trim()
@app.all.push(title: title) if title
@app.newTitle = ''
clearCompleted: ->
@app.all = @app.active
class TodoController
constructor: (@todo) ->
removeTodo: ->
@todo.remove()
edit: ->
@todo.edit = true
@field.select()
edited: ->
if @todo.title.trim()
@todo.edit = false if @todo.edit
else
@todo.remove()
@todo.app.changed.trigger()
loadField: (@field) ->
app = new App(JSON.parse(localStorage.getItem('todomvc-serenade')))
app.changed.bind -> localStorage.setItem('todomvc-serenade', app)
router = Router
'/': -> app.filter = 'all'
'/active': -> app.filter = 'active'
'/completed': -> app.filter = 'completed'
router.init()
Serenade.view('app', document.getElementById('app').innerHTML)
Serenade.view('todo', document.getElementById('todo').innerHTML)
Serenade.controller('app', AppController)
Serenade.controller('todo', TodoController)
document.body.insertBefore(Serenade.render('app', app), document.body.children[0])
// Generated by CoffeeScript 1.4.0
(function() {
var App, AppController, Todo, TodoController, app, router,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
Todo = (function(_super) {
__extends(Todo, _super);
function Todo() {
return Todo.__super__.constructor.apply(this, arguments);
}
Todo.belongsTo('app', {
inverseOf: 'all',
as: function() {
return App;
}
});
Todo.property('title', {
serialize: true
});
Todo.property('completed', {
serialize: true
});
Todo.property('incomplete', {
get: function() {
return !this.completed;
}
});
Todo.property('edit');
Todo.prototype.remove = function() {
return this.app.all["delete"](this);
};
return Todo;
})(Serenade.Model);
App = (function(_super) {
__extends(App, _super);
function App() {
return App.__super__.constructor.apply(this, arguments);
}
App.hasMany('all', {
inverseOf: 'app',
serialize: true,
as: function() {
return Todo;
}
});
App.selection('active', {
from: 'all',
filter: 'incomplete'
});
App.selection('completed', {
from: 'all',
filter: 'completed'
});
App.property('label', {
get: function() {
if (this.activeCount === 1) {
return 'item left';
} else {
return 'items left';
}
}
});
App.property('allCompleted', {
get: function() {
return this.activeCount === 0;
},
set: function(value) {
var todo, _i, _len, _ref, _results;
_ref = this.all;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
todo = _ref[_i];
_results.push(todo.completed = value);
}
return _results;
}
});
App.property('newTitle');
App.property('filter', {
value: 'all'
});
App.property('filtered', {
get: function() {
return this[this.filter];
}
});
App.property('filterAll', {
get: function() {
return this.filter === 'all';
}
});
App.property('filterActive', {
get: function() {
return this.filter === 'active';
}
});
App.property('filterCompleted', {
get: function() {
return this.filter === 'completed';
}
});
return App;
})(Serenade.Model);
AppController = (function() {
function AppController(app) {
this.app = app;
}
AppController.prototype.newTodo = function() {
var title;
title = this.app.newTitle.trim();
if (title) {
this.app.all.push({
title: title
});
}
return this.app.newTitle = '';
};
AppController.prototype.clearCompleted = function() {
return this.app.all = this.app.active;
};
return AppController;
})();
TodoController = (function() {
function TodoController(todo) {
this.todo = todo;
}
TodoController.prototype.removeTodo = function() {
return this.todo.remove();
};
TodoController.prototype.edit = function() {
this.todo.edit = true;
return this.field.select();
};
TodoController.prototype.edited = function() {
if (this.todo.title.trim()) {
if (this.todo.edit) {
this.todo.edit = false;
}
} else {
this.todo.remove();
}
return this.todo.app.changed.trigger();
};
TodoController.prototype.loadField = function(field) {
this.field = field;
};
return TodoController;
})();
app = new App(JSON.parse(localStorage.getItem('todomvc-serenade')));
app.changed.bind(function() {
return localStorage.setItem('todomvc-serenade', app);
});
router = Router({
'/': function() {
return app.filter = 'all';
},
'/active': function() {
return app.filter = 'active';
},
'/completed': function() {
return app.filter = 'completed';
}
});
router.init();
Serenade.view('app', document.getElementById('app').innerHTML);
Serenade.view('todo', document.getElementById('todo').innerHTML);
Serenade.controller('app', AppController);
Serenade.controller('todo', TodoController);
document.body.insertBefore(Serenade.render('app', app), document.body.children[0]);
}).call(this);
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment