Task manager using Reactive Coffee
HTML
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.4.4/underscore-min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.string/2.3.0/underscore.string.min.js"></script>
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/normalize/2.1.0/normalize.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/reactive-coffee/0.0.3/reactive-coffee.min.js"></script>
SCSS
html, body { margin: 20px; padding: 0; }
body {
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
line-height: 1.4em;
background: #eaeaea;
color: #4d4d4d;
width: 550px;
margin: 0 auto;
-webkit-font-smoothing: antialiased;
-moz-font-smoothing: antialiased;
-ms-font-smoothing: antialiased;
-o-font-smoothing: antialiased;
font-smoothing: antialiased;
}
ul { list-style: none; padding: 0; }
label { display: inline-block; width: 100px; }
.descrip { margin: 10px; }
.task a { font-size: smaller; }
.task-selected { margin-bottom: 2px; background: rgba(0,0,0,.1); }
.task-unselected { margin-bottom: 2px; }
CoffeeScript
bind = rx.bind
rxt.importTags()
# This is our application's core data model, an array of Task objects.
# `cell` and `array` are our primitive reactive data structures. You can
# listen for (and react to) changes to their values.
class Task
constructor: (descrip, priority, isDone) ->
@descrip = rx.cell(descrip)
@priority = rx.cell(priority)
@isDone = rx.cell(isDone)
tasks = rx.array([
new Task('Get milk', 'important', false)
new Task('Play with Reactive Coffee', 'critical', false)
new Task('Walk the dog', 'meh', false)
])
# Our main view: a checklist of tasks, a button to add a new task, and a
# task editor component (defined further down).
#
# `bind` (and `array.map`) are the central mechanisms by which you can
# declare cells that are always bound to the current value of some
# expression over other cells. `z = bind -> x.get() + y.get()` says `z`
# should always reflect the sum even as `x` and `y` change. Subscription
# management is handled automatically.
main = ->
currentTask = rx.cell(tasks.at(0)) # "View model" of currently selected task
$('body').append(
div {class: 'task-manager'}, [
h1 bind -> "#{tasks.length()} task(s) for today"
ul {class: 'tasks'}, tasks.map (task) ->
li {class: bind -> "task-#{if task == currentTask.get() then 'selected' else 'unselected'}"}, [
input {type: 'checkbox', click: -> task.isDone.set(@is(':checked')); true}
span {class: 'descrip'}, bind ->
"#{task.descrip.get()} (#{task.priority.get()})"
a {href: 'javascript: void 0', click: -> currentTask.set(task)}, 'Edit'
]
button {click: -> tasks.push(new Task('Task', 'none', false))}, 'Add new task'
taskEditor {
task: bind -> currentTask.get()
onSubmit: (descrip, priority) ->
currentTask.get().descrip.set(descrip)
currentTask.get().priority.set(priority)
}
]
)
# The task editor demonstrates how to define a simple...