Skip to content

Commit

Permalink
Updating to CanJS 1.1.0, adding Mustache views. Closes #330
Browse files Browse the repository at this point in the history
  • Loading branch information
daffl authored and sindresorhus committed Nov 16, 2012
1 parent 5ac3254 commit e19c80f
Show file tree
Hide file tree
Showing 12 changed files with 250 additions and 130 deletions.
30 changes: 17 additions & 13 deletions labs/architecture-examples/canjs/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,22 @@
<![endif]-->
</head>
<body>
<section id="todoapp"></section>
<div id="info">
<p>Double-click to edit a todo</p>
<p>Written by <a href="http://bitovi.com">Bitovi</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</div>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js"></script>
<script src="../../../assets/base.js"></script>
<script src="js/lib/can.jquery-1.0.7.min.js"></script>
<script src="js/lib/can-localstorage.min.js"></script>
<script src="js/models/todo.js"></script>
<script src="js/todos/todos.js"></script>
<script src="js/app.js"></script>
<section id="todoapp">
</section>
<div id="info">
<p>Double-click to edit a todo</p>
<p>Written by <a href="http://bitovi.com">Bitovi</a></p>
<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
</div>

<script src="../../../assets/jquery.min.js"></script>
<script src="../../../assets/base.js"></script>

<script src="js/lib/can.jquery-1.1.0.min.js"></script>
<script src="js/lib/can.mustache.min.js"></script>
<script src="js/lib/can.localstorage.min.js"></script>
<script src="js/models/todo.js"></script>
<script src="js/todos/todos.js"></script>
<script src="js/app.js"></script>
</body>
</html>
17 changes: 15 additions & 2 deletions labs/architecture-examples/canjs/js/app.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
(function() {
$(function() {
can.route(':filter');
// Set up a route that maps to the `filter` attribute
can.route( ':filter' );
// Delay routing until we initialized everything
can.route.ready(false);

// View helper for pluralizing strings
Mustache.registerHelper('plural', function(str, count) {
return str + (count !== 1 ? 's' : '');
});

// Initialize the app
Models.Todo.findAll({}, function(todos) {
new Todos('#todoapp', {
todos: todos,
state: can.route
state : can.route,
view : 'views/todos.mustache'
});
});

// Now we can start routing
can.route.ready(true);
});
})();
52 changes: 0 additions & 52 deletions labs/architecture-examples/canjs/js/lib/can.jquery-1.0.7.min.js

This file was deleted.

64 changes: 64 additions & 0 deletions labs/architecture-examples/canjs/js/lib/can.jquery-1.1.0.min.js

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions labs/architecture-examples/canjs/js/lib/can.mustache.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion labs/architecture-examples/canjs/js/models/todo.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
}, {
// Returns if this instance matches a given filter
// (currently `active` and `complete`)
matches: function(filter) {
matches : function() {
var filter = can.route.attr('filter');
return !filter || (filter === 'active' && !this.attr('complete'))
|| (filter === 'completed' && this.attr('complete'));
}
Expand Down
34 changes: 21 additions & 13 deletions labs/architecture-examples/canjs/js/todos/todos.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@

var ENTER_KEY = 13;
var Todos = can.Control({

// Default options
defaults : {
view : 'views/todos.ejs'
}
}, {
// Initialize the Todos list
init: function() {
// Render the Todos
this.element.append(can.view('todos.ejs', this.options));

// Clear the new todo field
$('#new-todo').val('').focus();
this.element.append(can.view(this.options.view, this.options));
},

// Listen for when a new Todo has been entered
Expand All @@ -22,16 +23,23 @@
text : value,
complete : false
}).save(function () {
el.val('');
});
el.val('');
});
}
},

// Handle a newly created Todo
'{Models.Todo} created': function(list, e, item) {
this.options.todos.push(item);
// Reset the filter so that you always see your new todo
this.options.state.removeAttr('filter');
this.options.state.attr('filter', '');
},

// Listener for when the route changes
'{state} change' : function() {

This comment has been minimized.

Copy link
@justinbmeyer

justinbmeyer Apr 17, 2013

I think this could be done all within the template.

// Remove the `selected` class from the old link and add it to the link for the current location hash
this.element.find('#filters').find('a').removeClass('selected')
.end().find('[href="' + window.location.hash + '"]').addClass('selected');
},

// Listen for editing a Todo
Expand All @@ -46,6 +54,9 @@
var value = can.trim(el.val()),
todo = el.closest('.todo').data('todo');

// If we don't have a todo we don't need to do anything
if(!todo) return;

if (value === '') {
todo.destroy();
} else {
Expand All @@ -62,9 +73,8 @@
this.updateTodo(el);
}
},
'.todo .edit focusout': function(el) {
this.updateTodo(el);
},

'.todo .edit focusout' : "updateTodo",

// Listen for the toggled completion of a Todo
'.todo .toggle click': function(el) {
Expand Down Expand Up @@ -93,8 +103,6 @@
todo.destroy();
}
}
// Reset the filter
this.options.state.removeAttr('filter');
}
});

Expand Down
40 changes: 40 additions & 0 deletions labs/architecture-examples/canjs/readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# CanJS

CanJS is a client-side, JavaScript framework that makes building rich web applications easy. It provides:

- *can.Model* - for connecting to RESTful JSON interfaces
- *can.View* - for template loading and caching
- *can.Observe* - for key-value binding
- *can.EJS* - live binding templates
- *can.Control* - declarative event bindings
- *can.route* - routing support

And works with jQuery, Zepto, YUI, Dojo and Mootools.

## CanJS and JavaScriptMVC

*CanJS* is the extracted, more modern and more library-like MVC parts of [JavaScriptMVC](http://javascriptmvc.com)
(formerly known as *jQueryMX*).

*JavaScriptMVC 3.3* uses CanJS for the MVC structure so this TodoMVC example **applies to JavaScriptMVC** as well.
Additionally JavaScriptMVC contains:

- [CanJS](http://canjs.us) - For the MVC parts
- [jQuery++](http://jquerypp.com) - jQuery's missing utils and special events
- [StealJS](http://javascriptmvc.com/docs.html#!stealjs) - A JavaScript package manager
- [DocumentJS](http://javascriptmvc.com/docs.html#!DocumentJS) - A documentation engine
- [FuncUnit](http://funcunit.com) - jQuery style functional unit testing

## View engines

CanJS supports both live binding [EJS](http://canjs.us/#can_ejs) and [Mustache/Handlebars](http://canjs.us/#can_mustache)
templates. By default the Mustache view will be used but an EJS example is available as well.
You can easily change it by modifying the `view` option in the `js/app.js` file:

Models.Todo.findAll({}, function(todos) {
new Todos('#todoapp', {
todos: todos,
state : can.route,
view : 'views/todos.ejs'
});
});
49 changes: 0 additions & 49 deletions labs/architecture-examples/canjs/todos.ejs

This file was deleted.

40 changes: 40 additions & 0 deletions labs/architecture-examples/canjs/views/todos.ejs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<header id="header">
<h1>todos</h1>
<input id="new-todo" placeholder="What needs to be done?" autofocus>
</header>

<section id="main" class="<%= todos.attr("length") === 0 ? "hidden" : "" %>">
<input id="toggle-all" type="checkbox" <%= todos.allComplete() ? "checked" : "" %>>
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list">
<% todos.each(function( todo ) { %>
<li class="todo
<%= todo.matches(state.attr('filter')) ? '' : 'hidden' %>
<%= todo.attr('complete') ? 'completed' : '' %>
<%= todo.attr('editing') ? 'editing' : '' %>"
<%= (el)-> el.data('todo', todo) %>>
<div class="view">
<input class="toggle" type="checkbox" <%= todo.attr('complete') ? 'checked' : '' %>>
<label><%= todo.attr('text') %></label>
<button class="destroy"></button>
</div>
<input class="edit" value="<%= todo.attr('text') %>">
</li>
<% }) %>
</ul>
</section>
<footer id="footer" class="<%= todos.attr('length') === 0 ? 'hidden' : '' %>">
<span id="todo-count">
<strong><%= todos.remaining() %></strong>
item<%= todos.remaining() == 1 ? "" : "s" %> left
</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" class="<%= todos.completed() === 0 ? 'hidden' : '' %>">
Clear <%= todos.completed() %>
completed item<%= todos.completed() == 1 ? "" : "s" %>
</button>
</footer>
41 changes: 41 additions & 0 deletions labs/architecture-examples/canjs/views/todos.mustache
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<header id="header">
<h1>todos</h1>
<input id="new-todo" {{ (el) -> el.val('').focus() }} placeholder="What needs to be done?" autofocus="">
</header>

<section id="main" class="{{^todos}}hidden{{/todos}}">
<input id="toggle-all" type="checkbox" {{#todos.allComplete}}checked="checked"{{/todos.allComplete}}>
<label for="toggle-all" >Mark all as complete</label>
<ul id="todo-list">
{{#todos}}
<li class="todo {{^matches}}hidden{{/matches}} {{#complete}}completed{{/complete}} {{#editing}}editing{{/editing}}" {{data 'todo'}}>
<div class="view">
<input class="toggle" type="checkbox" {{#complete}}checked="checked"{{/complete}}>
<label>{{text}}</label>
<button class="destroy"></button>
</div>
<input class="edit" type="text" value="{{text}}">
</li>
{{/todos}}
</ul>
</section>

<footer id="footer" class="{{^todos}}hidden{{/todos}}">
<span id="todo-count">
<strong>{{todos.remaining}}</strong> {{plural "item" todos.remaining}} left
</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>
<a href="#!" id="clear-completed" class="{{^todos.completed}}hidden{{/todos.completed}}">
Clear {{todos.completed}} completed {{plural "item" todos.completed}}
</a>
</footer>

0 comments on commit e19c80f

Please sign in to comment.