Commit 47c8ab0a authored by Mikael Karon's avatar Mikael Karon Committed by Sindre Sorhus

Close GH-120: Example using TroopJS.

parent c7f05d38
@import url("../../../../assets/base.css");
/* base.css overrides */
#todo-list li .prepare {
#footer, #main {
display: none;
position: absolute;
top: 20px;
right: 35px;
cursor: pointer;
width: 20px;
height: 20px;
background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2RpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo3ODkwNzY1QzM1QUVFMDExOUI0MDg3MzJEODFDNjBGNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpEODdBM0JBQ0I3MDAxMUUwQjBBMUMzMUU4NTAwRDVFRSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpEODdBM0JBQkI3MDAxMUUwQjBBMUMzMUU4NTAwRDVFRSIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoxQTFDMDFENjAwQjdFMDExQTVFMUI2QkYyMkQyMTM0OSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo3ODkwNzY1QzM1QUVFMDExOUI0MDg3MzJEODFDNjBGNyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PstLE0sAAAD3SURBVHjanNLBCgFBHMdxO22urh6AB1BSHkAJ7UE2OeDg6kr2CSgHt5WLA6VwIhd3LyFOrh5AKeU39d+apml2Zv/1qTW7vu0244RhmEowJ6jR9RUaboLICjzhdx0uzDKSg65ivWoT4oEX/wz4SPcc09AUNnCEmyJ2YIaRCV17itgaOq5FJCXFfCjAnS8yy4gYa0cRXUgX4TOHrbjAEkRmMJYXWYJIoLohhkp0Vr62ETk0pAd9RUwbEUNZKMMOzlIsNsInOkd9WMIP0pCBN+1MYHL0Gf1xAE8YwQMq0DSNRG/Ugjws6LgX6W2sxqXd6sFes2Ox8xdgAFvzNQf5podzAAAAAElFTkSuQmCC') no-repeat center center;
}
#todo-list li:hover .prepare {
display: block;
}
#todo-list li {
padding-right: 60px;
.filter-active .completed,
.filter-completed .active {
display: none;
}
......@@ -2,36 +2,55 @@
<html lang="en">
<head>
<meta charset="utf-8">
<title>Troop.js</title>
<link rel="stylesheet" href="css/app.css" type="text/css" media="screen" charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title>Troop.js • TodoMVC</title>
<link rel="stylesheet" href="../../../assets/base.css">
<!-- CSS overrides - remove if you don't need it -->
<link rel="stylesheet" href="css/app.css">
<!--[if IE]>
<script src="../../../assets/ie.js"></script>
<![endif]-->
</head>
<body>
<div id="todoapp">
<header>
<h1>Todos</h1>
<input id="new-todo" type="text" placeholder="What needs to be done?" data-weave="widget/create">
<section id="todoapp">
<header id="header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?" autofocus data-weave="widget/create">
</header>
<!-- this section is hidden by default and you be shown when there are todos and hidden when not -->
<!-- This section should be hidden by default and shown when there are todos -->
<section id="main" data-weave="widget/display">
<input id="toggle-all" type="checkbox" data-weave="widget/mark">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list" data-weave="widget/list"></ul>
</section>
<!-- This footer should hidden by default and shown when there are todos -->
<footer id="footer" data-weave="widget/display">
<div id="todo-count" data-weave="widget/count"></div>
<a id="clear-completed" data-weave="widget/clear">Clear completed</a>
<!-- This should be `0 items left` by default -->
<span id="todo-count" data-weave="widget/count"><strong>0</strong> items left</span>
<!-- Remove this if you don't implement routing -->
<ul id="filters" data-weave="widget/filters">
<li>
<a href="#/">All</a>
</li>
<li>
<a href="#/active">Active</a>
</li>
<li>
<a href="#/completed">Completed</a>
</li>
</ul>
<button id="clear-completed" data-weave="widget/clear">Clear completed (0)</button>
</footer>
</div>
<div id="instructions">
Double click to edit a todo.
</div>
<div id="credits">
<p>Created by <a href="http://troopjs.com/">Mikael Karon</a>.</p>
<p>Part of <a href="http://todomvc.com/">TodoMVC</a>.</p>
</div>
<!-- scripts here -->
<script type="text/javascript" data-main="js/app.js" src="js/lib/require.js"></script>
</section>
<footer id="info">
<p>Double-click to edit a todo</p>
<p>Template by <a href="http://github.com/sindresorhus">Sindre Sorhus</a></p>
<!-- Change this out with your name and url ↓ -->
<p>Created by <a href="http://github.com/mikaelkaron">Mikael Karon</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</footer>
<!-- Scripts here. Don't remove this ↓ -->
<script src="../../../assets/base.js"></script>
<script type="text/javascript" data-main="js/app.js" src="../../../assets/require.min.js"></script>
</body>
</html>
require({
"baseUrl" : "js",
"paths" : {
"jquery" : "lib/jquery",
"troopjs-bundle" : "lib/troopjs-bundle"
"jquery" : "../../../../assets/jquery.min",
"troopjs-bundle" : "lib/troopjs-bundle.min"
},
"priority": [ "jquery", "config", "troopjs-bundle" ]
}, [ "jquery" ], function App(jQuery) {
}, [ "require", "jquery", "troopjs-bundle" ], function Deps(parentRequire, jQuery) {
// Application and plug-ins
parentRequire([
"widget/application",
"troopjs-jquery/weave",
"troopjs-jquery/destroy",
"troopjs-jquery/hashchange",
"troopjs-jquery/action" ], function App(Application) {
// Hook ready
jQuery(document).ready(function ready($) {
$(this.body).find("[data-weave]").weave();
Application($(this.body), "app/todos").start();
});
});
});
This diff is collapsed.
This diff is collapsed.
define( [ "troopjs-core/widget/application", "troopjs-core/route/router", "jquery" ], function ApplicationModule(Application, Router, $) {
function forward(signal, deferred) {
var services = $.map(this.services, function map(service, index) {
return $.Deferred(function deferredSignal(deferSignal) {
service.signal(signal, deferSignal);
});
});
if (deferred) {
$.when.apply($, services).then(deferred.resolve, deferred.reject);
}
}
return Application.extend({
"sig/initialize" : forward,
"sig/finalize" : forward,
"sig/start" : forward,
"sif/stop" : forward,
services : [ Router($(window)) ]
});
});
......@@ -5,20 +5,10 @@ define( [ "troopjs-core/component/widget", "jquery" ], function ClearModule(Widg
}
return Widget.extend({
"hub/todos/change" : function onChange(topic, items) {
"hub:memory/todos/change" : function onChange(topic, items) {
var count = $.grep(items, filter, true).length;
var $element = this.$element;
if (count > 0) {
$element
.text("Clear " + count + (count > 1 ? " completed items" : " completed item"))
.show();
}
else {
$element
.text("Clear no completed items")
.hide();
}
this.$element.text("Clear completed (" + count + ")")[count > 0 ? "show" : "hide"]();
},
"dom/click" : function onClear(topic, $event) {
......
......@@ -5,16 +5,10 @@ define( [ "troopjs-core/component/widget", "jquery" ], function CountModule(Widg
}
return Widget.extend({
"hub/todos/change" : function onChange(topic, items) {
"hub:memory/todos/change" : function onChange(topic, items) {
var count = $.grep(items, filter, true).length;
var $element = this.$element;
if (count > 0) {
$element.text(count + (count > 1 ? " items left" : " item left"));
}
else {
$element.text("No items left");
}
this.$element.html("<strong>" + count + "</strong> " + (count === 1 ? "item" : "items") + " left");
}
});
});
define( [ "troopjs-core/component/widget" ], function CreateModule(Widget) {
var ENTER_KEY = 13;
return Widget.extend({
"dom/keyup" : function onKeyUp(topic, $event) {
var self = this;
var $element = self.$element;
var value;
switch($event.keyCode) {
case 13:
self.publish("todos/add", $element.val());
case ENTER_KEY:
value = $element.val().trim();
if (value !== "") {
self.publish("todos/add", value);
$element.val("");
}
}
}
});
});
......@@ -5,8 +5,8 @@ define( [ "troopjs-core/component/widget", "jquery" ], function DisplayModule(Wi
}
return Widget.extend({
"hub/todos/change": function onChange(topic, items) {
this.$element[$.grep(items, filter, true).length > 0 ? "show" : "hide"]("fast");
"hub:memory/todos/change": function onChange(topic, items) {
this.$element[$.grep(items, filter, true).length > 0 ? "show" : "hide"]();
}
});
});
define( [ "troopjs-core/component/widget", "jquery" ], function FiltersModule(Widget, $) {
return Widget.extend({
"hub:memory/route" : function onRoute(topic, uri) {
this.publish("todos/filter", uri.source);
},
"hub:memory/todos/filter" : function onFilter(topic, filter) {
filter = filter || "/";
// Update UI
$("a[href^='#']")
.removeClass("selected")
.filter("[href='#" + filter + "']")
.addClass("selected");
}
});
});
<%
var i = data.i;
var item = data.item;
if (item.completed) { %>
<li class="done">
<div class="view">
<input class="toggle" type="checkbox" data-action="status(<%= i %>)" checked>
<label data-action="prepare.dblclick(<%= i %>)"><%= item.text %></label>
<a class="destroy" data-action="delete(<%= i %>)"></a>
<a class="prepare" data-action="prepare.click(<%= i %>)"></a>
var completed = item.completed;
%>
<li class="<%= (completed ? 'completed' : 'active') %>">
<div class="view" data-action="prepare(<%= i %>)">
<input class="toggle" type="checkbox" <%= (completed ? 'checked' : '') %> data-action="status(<%= i %>)">
<label><%= item.title %></label>
<button class="destroy" data-action="delete(<%= i %>)"></button>
</div>
<input class="edit" type="text" data-action="update(<%= i %>)">
<input class="edit" data-action="commit(<%= i %>)">
</li>
\ No newline at end of file
<% } else { %>
<li>
<div class="view">
<input class="toggle" type="checkbox" data-action="status(<%= i %>)">
<label data-action="prepare.dblclick(<%= i %>)"><%= item.text %></label>
<a class="destroy" data-action="delete(<%= i %>)"></a>
<a class="prepare" data-action="prepare.click(<%= i %>)"></a>
</div>
<input class="edit" type="text" data-action="update(<%= i %>)">
</li>
<% } %>
\ No newline at end of file
define( [ "troopjs-core/component/widget" ], function MarkModule(Widget) {
var INDETERMINATE = "indeterminate";
var CHECKED = "checked";
return Widget.extend({
"hub/todos/change" : function onChange(topic, items) {
"hub:memory/todos/change" : function onChange(topic, items) {
var total = 0;
var count = 0;
var $element = this.$element;
......@@ -22,18 +20,18 @@ define( [ "troopjs-core/component/widget" ], function MarkModule(Widget) {
if (count === 0) {
$element
.prop(INDETERMINATE, false)
.prop(CHECKED, false);
.prop("indeterminate", false)
.prop("checked", false);
}
else if (count === total) {
$element
.prop(INDETERMINATE, false)
.prop(CHECKED, true);
.prop("indeterminate", false)
.prop("checked", true);
}
else {
$element
.prop(INDETERMINATE, true)
.prop(CHECKED, false);
.prop("indeterminate", true)
.prop("checked", false);
}
},
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment