1 | <!DOCTYPE html>
|
2 | <html>
|
3 | <head>
|
4 | <title>Alfred: Batman's Todos</title>
|
5 | <meta http-equiv="X-UA-Compatible" content="IE=Edge" />
|
6 |
|
7 | <link href='http://fonts.googleapis.com/css?family=Lobster' rel='stylesheet' type='text/css'>
|
8 | <link rel="stylesheet" href="resources/alfred.css" type="text/css">
|
9 |
|
10 | <script type="text/javascript" src="../lib/es5-shim.js"></script>
|
11 | <script type="text/javascript" src="../lib/batman.js"></script>
|
12 | <script type="text/javascript" src="../lib/batman.solo.js"></script>
|
13 | <script type="text/javascript" src="../lib/coffee-script.js"></script>
|
14 | </head>
|
15 |
|
16 | <body>
|
17 | <div id="container">
|
18 | <h1>Alfred</h1>
|
19 | <form data-formfor-todo="controllers.todos.emptyTodo" data-event-submit="controllers.todos.create">
|
20 | <input class="new-item" placeholder="add a todo item" data-bind="todo.body" />
|
21 | </form>
|
22 |
|
23 | <ul id="items">
|
24 | <li data-foreach-todo="Todo.all" data-mixin="animation">
|
25 | <input type="checkbox" data-bind="todo.isDone" data-event-change="todo.save" />
|
26 | <label data-bind="todo.body" data-addclass-done="todo.isDone" data-mixin="editable"></label>
|
27 | <a data-event-click="todo.destroy">delete</a>
|
28 | </li>
|
29 | <li><span data-bind="Todo.all.length"></span> <span data-bind="'item' | pluralize Todo.all.length"></span></li>
|
30 | </ul>
|
31 | </div>
|
32 |
|
33 | <script type="text/coffeescript">
|
34 | # Create our application and namespace.
|
35 | class Alfred extends Batman.App
|
36 | @global yes
|
37 |
|
38 | # setup our root route. When the app starts up, it will automatically call TodosController::index
|
39 | @root 'todos#index'
|
40 |
|
41 |
|
42 | # Define the principal Todo model with `body` and `isDone` attributes, and tell it to persist itself using Local Storage.
|
43 | class Alfred.Todo extends Batman.Model
|
44 | # @global exposes this class on the global object, so you can access `Todo` directly.
|
45 | @global yes
|
46 |
|
47 | # @persist tells a model which storage mechanism it should use to load and save. Batman.LocalStorage is the simplest, simply persisting your records to the browser storage.
|
48 | @persist Batman.LocalStorage
|
49 |
|
50 | # @encode tells the persistence mechanism which fields to archive. You can also setup specific encoder and decoder functions to handle specific types of data.
|
51 | @encode 'body', 'isDone'
|
52 |
|
53 | # just some defaults, but these are optional
|
54 | body: ''
|
55 | isDone: false
|
56 |
|
57 | class Alfred.TodosController extends Batman.Controller
|
58 | emptyTodo: null
|
59 |
|
60 | index: ->
|
61 | @set 'emptyTodo', new Todo
|
62 |
|
63 | # add some example todos to show off.
|
64 | Todo.load (error, todos) ->
|
65 | # you always want to make sure you handle errors (more elegantly than this) when writing connection code
|
66 | throw error if error
|
67 | unless todos and todos.length
|
68 | callback = (error) -> throw error if error
|
69 | new Todo(body: 'joker escaped arkham again', isDone: true).save(callback)
|
70 | new Todo(body: 'riddler sent riemann hypothesis').save(callback)
|
71 | new Todo(body: 'bane wants to meet, not worried').save(callback)
|
72 |
|
73 | # prevent the implicit render of views/todos/index.html
|
74 | @render false
|
75 |
|
76 | create: =>
|
77 | @emptyTodo.save (error, record) =>
|
78 | throw error if error
|
79 |
|
80 | # we use set so that our form will automatically update with the new Todo instance
|
81 | @set 'emptyTodo', new Todo
|
82 |
|
83 | # since this isn't actually a route action, nothing will be rendered here.
|
84 |
|
85 |
|
86 | # Start the app. This will start up the dispatcher and a number of other mechanisms.
|
87 | Alfred.run()
|
88 | </script>
|
89 | </body>
|
90 | </html>
|
91 |
|