Skip to content

Instantly share code, notes, and snippets.

@clarle
Created September 20, 2012 16:18
Show Gist options
  • Save clarle/3756875 to your computer and use it in GitHub Desktop.
Save clarle/3756875 to your computer and use it in GitHub Desktop.
YUI TodoMVC and CoffeeScript???
YUI.add "todo-app", ((Y) ->
"use strict"
# Dependencies from MVC namespace.
TodoList = Y.TodoMVC.TodoList
TodoView = Y.TodoMVC.TodoView
TodoApp = undefined
# -- Main Application --------------
TodoApp = Y.Base.create("todoApp", Y.App, [],
# Set container to bind to the existing '#todoapp' element
containerTemplate: "#todoapp"
# Compile statistics template with Handlebars.
template: Y.Handlebars.compile(Y.one("#stats-template").getHTML())
# DOM events for creating new Todos and clearing out old ones.
events:
"#new-todo":
keypress: "enterCreate"
"#clear-completed":
click: "clearCompleted"
"#toggle-all":
click: "completeAll"
# Initialize our TodoList, and bind any events that occur
# when new Todos are added, changed, or removed within it.
# Also, fetch any Todos that are found within localStorage.
initializer: ->
@set "todoList", new TodoList()
list = @get("todoList")
Y.Handlebars.registerHelper "pluralize", (context, word) ->
(if (context is 1) then word else word + "s")
list.after ["add", "remove", "reset", "todo:completedChange"], @render, this
list.load()
# Keep our filters on refresh by immediately dispatching route.
@once "ready", (e) ->
@dispatch() if @hasRoute(@getPath())
# Render our application with the statistics from our TodoList,
# and various other stylistic elements.
render: ->
todoList = @get("todoList")
completed = todoList.completed().size()
remaining = todoList.remaining().size()
container = @get("container")
main = @get("main")
footer = @get("footer")
# If we have Todos in our TodoList, show them with statistics.
if todoList.size()
main.show()
footer.show()
footer.setHTML @template(
completed: completed
remaining: remaining
)
# Highlights for filters at the bottom of our Todo application.
container.one("#filters li a").removeClass "selected"
container.all("#filters li a").filter("[href=\"#/" + (@get("filter") or "") + "\"]").addClass "selected"
else
main.hide()
footer.hide()
# Set the checkbox only if all Todos have been completed.
@get("allCheckbox").set "checked", not remaining
@addViews()
# Add Todo views to the DOM simultaneously, triggered when
# the application initially loads, or we switch filters.
addViews: ->
fragment = Y.one(Y.config.doc.createDocumentFragment())
todoList = @get("todoList")
models = undefined
# An Array of models is passed through when the 'reset'
# event is triggered through syncing through load().
switch @get("filter")
when "active"
models = todoList.remaining()
when "completed"
models = todoList.completed()
else
models = todoList
# Iterate through the (filtered) ModelList.
models.each (model) ->
view = new TodoView(model: model)
fragment.append view.render().get("container")
@get("container").one("#todo-list").setContent fragment
# Create and save a new Todo from the inputted value when the
# Enter key is pressed down.
enterCreate: (e) ->
ENTER_KEY = 13
todoList = @get("todoList")
inputNode = @get("inputNode")
value = Y.Escape.html(Y.Lang.trim(inputNode.get("value")))
return if e.keyCode isnt ENTER_KEY or not value
todoList.create title: value
inputNode.set "value", ""
# Clear all completed Todos from the TodoList. This removes the models
# from the list, as well as deletes them from localStorage.
clearCompleted: (e) ->
todoList = @get("todoList")
completed = todoList.completed()
todoList.remove completed
completed.each (todo) ->
todo.clear()
# Complete all non-complete Todos, or reset them all if they are
# all already complete.
completeAll: ->
todoList = @get("todoList")
allCheckbox = @get("allCheckbox")
completed = allCheckbox.get("checked")
Y.Array.each todoList.toArray(), (todo) ->
todo.save completed: completed
# Set the filter for our application from the route that is passed
# in (see below).
handleFilter: (req) ->
@set "filter", req.params.filter
@get("todoList").load()
,
ATTRS:
# Significant DOM elements that relate to our application that
# we would like to keep as attributes.
container:
valueFn: ->
Y.one "#todoapp"
inputNode:
valueFn: ->
Y.one "#new-todo"
allCheckbox:
valueFn: ->
Y.one "#toggle-all"
main:
valueFn: ->
Y.one "#main"
footer:
valueFn: ->
Y.one "#footer"
# This can be set to fall back on server-side routing when
# HTML5 pushState is not available. For this application,
# we are only using hash-based URLs though.
serverRouting:
value: false
# Our initial filter for the application.
filter:
value: null
# Routing for the application, to determine the filter.
# The callback takes a request object, Express-style.
routes:
value: [
path: "/:filter"
callback: "handleFilter"
]
)
# Namespace this application under our custom Y.MVC namespace.
Y.namespace("TodoMVC").TodoApp = TodoApp
), "@VERSION@",
requires: ["app", "todo-list", "todo-view", "node", "event-focus"]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment