Last active
November 3, 2021 16:27
-
-
Save jaigouk/7389699 to your computer and use it in GitHub Desktop.
Riot.js Todo MVC in coffeescript https://github.com/moot/riotjs
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
DB = (key) -> | |
store = window.localStorage | |
get: -> | |
JSON.parse store[key] or "{}" | |
put: (data) -> | |
store[key] = JSON.stringify(data) |
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
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<title>Riot! JS | The 1kb framework</title> | |
<link rel="stylesheet" href="../bower_components/todomvc-common/base.css"> | |
</head> | |
<script type="html/todo"> | |
<li id="{id}"> | |
<div class="view"> | |
<input class="toggle" type="checkbox"> | |
<label>{name}</label> | |
<button class="destroy"/> | |
</div> | |
<input class="edit" value="{name}"> | |
</li> | |
</script> | |
<body> | |
<section id="todoapp"> | |
<header id="header"> | |
<h1>todos</h1> | |
<input id="new-todo" placeholder="What needs to be done?" autofocus> | |
</header> | |
<section id="main"> | |
<input id="toggle-all" type="checkbox"> | |
<label for="toggle-all">Mark all as complete</label> | |
<ul id="todo-list"></ul> | |
</section> | |
<footer id="footer"> | |
<span id="todo-count"></span> | |
<ul id="filters"> | |
<li> | |
<a class="selected" href="#/">All</a> | |
</li> | |
<li> | |
<a href="#/active">Active</a> | |
</li> | |
<li> | |
<a href="#/completed">Completed</a> | |
</li> | |
</ul> | |
<button id="clear-completed"></button> | |
</footer> | |
</section> | |
<footer id="info"> | |
<p>Double-click to edit a todo</p> | |
<p>Template by <a href="https://moot.it/blog">Tero Piirainen • Moot</a></p> | |
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p> | |
</footer> | |
<script src="../bower_components/todomvc-common/base.js"></script> | |
<script src="../bower_components/jquery/jquery.min.js"></script> | |
<script src="../jquery.riot.js"></script> | |
<script src="../ext/render.js"></script> | |
<script src="store.js"></script> | |
<script src="api.js"></script> | |
<script src="app.js"></script> | |
</body> | |
</html> |
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
# The model | |
Todo = (db) -> | |
db = db or DB("todo-riot") | |
self = $.observable(this) | |
items = db.get() | |
self.add = (name) -> | |
item = | |
id: "_" + ("" + Math.random()).slice(2) | |
name: name | |
items[item.id] = item | |
self.trigger "add", item | |
self.edit = (item) -> | |
items[item.id] = item | |
self.trigger "edit", item | |
self.remove = (filter) -> | |
els = self.items(filter) | |
$.each els, -> | |
delete items[@id] | |
self.trigger "remove", els | |
self.toggle = (id) -> | |
item = items[id] | |
item.done = not item.done | |
self.trigger "toggle", item | |
# @param filter: <empty>, id, "active", "completed" | |
self.items = (filter) -> | |
ret = [] | |
$.each items, (id, item) -> | |
ret.push item if not filter or filter is id or filter is ((if item.done then "completed" else "active")) | |
ret | |
# sync database | |
self.on "add remove toggle edit", -> | |
db.put items |
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
# The presenter | |
(-> | |
# | |
# A Model instance exposed to global space so you can | |
# use the Todo APi from the console. For example: | |
# | |
# todo.add("My task"); | |
# | |
# HTML for a single todo item | |
# Listen to user events | |
# Listen to model events | |
# counts | |
# Routing | |
# clear list and add new ones | |
# selected class | |
# update counts | |
# Private functions | |
toggle = (el, flag) -> | |
el.toggleClass "completed", flag | |
$(":checkbox", el).prop "checked", flag | |
add = (item) -> | |
blur = -> | |
el.removeClass "editing" | |
item = this if @id | |
el = $($.render(template, item)).appendTo(root) | |
input = $(".edit", el) | |
$(".toggle", el).click -> | |
todo.toggle item.id | |
toggle el, !!item.done | |
# edit | |
input.blur(blur).keydown (e) -> | |
val = $.trim(@value) | |
if e.which is 13 and val | |
item.name = val | |
todo.edit item | |
blur() if e.which is 27 | |
$("label", el).dblclick -> | |
el.addClass "editing" | |
input.focus()[0].select() | |
# remove | |
$(".destroy", el).click -> | |
todo.remove item.id | |
counts = -> | |
active = todo.items("active").length | |
done = todo.items("completed").length | |
$("#todo-count").html "<strong>" + active + "</strong> item" + ((if active is 1 then "" else "s")) + " left" | |
$("#clear-completed").toggle(done > 0).text "Clear completed (" + done + ")" | |
$("#footer").toggle active + done > 0 | |
"use strict" | |
window.todo = new Todo() | |
template = $("[type='html/todo']").html() | |
root = $("#todo-list") | |
nav = $("#filters a") | |
$("#new-todo").keyup (e) -> | |
val = $.trim(@value) | |
if e.which is 13 and val | |
todo.add val | |
@value = "" | |
$("#toggle-all").click -> | |
$("li", root).each -> | |
todo.toggle @id | |
$("#clear-completed").click -> | |
todo.remove "completed" | |
todo.on("add", add).on("remove", (items) -> | |
$.each items, -> | |
$("#" + @id).remove() | |
).on("toggle", (item) -> | |
toggle $("#" + item.id), !!item.done | |
).on("edit", (item) -> | |
el = $("#" + item.id) | |
el.removeClass "editing" | |
$("label, .edit", el).text(item.name).val item.name | |
).on "add remove toggle", counts | |
nav.click -> | |
$.route $(this).attr("href") | |
$.route (hash) -> | |
root.empty() and $.each(todo.items(hash.slice(2)), add) | |
nav.removeClass("selected").filter("[href='" + hash + "']").addClass "selected" | |
counts() | |
)() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment