Created
September 20, 2012 16:18
-
-
Save clarle/3756875 to your computer and use it in GitHub Desktop.
YUI TodoMVC and CoffeeScript???
This file contains 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
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