Commit 74d16714 authored by Burke Holland's avatar Burke Holland Committed by Sindre Sorhus

Close GH-810: Update to use Bower and new Kendo UI Router.

parent 101f4661
......@@ -3,6 +3,7 @@
"version": "0.0.0",
"dependencies": {
"todomvc-common": "~0.1.6",
"jquery": "~2.0.0"
"jquery": "~2.1.0",
"kendo-ui": "~2013.3.1119"
}
}
......@@ -9,15 +9,15 @@
<section id="todoapp">
<header id="header">
<h1>todos</h1>
<input id="new-todo" data-bind="enter: saveTodo"
<input id="new-todo" data-bind="enter: saveTodo, value: newTodo"
placeholder="What needs to be done?" autofocus>
</header>
<section id="main" data-bind="visible: isVisible">
<input id="toggle-all" type="checkbox" data-bind="click: toggleAll, checked: allCompleted">
<section id="main" data-bind="attr: { class : isVisible }">
<input id="toggle-all" type="checkbox" data-bind="events: { click: toggleAll }, checked: allCompleted">
<label for="toggle-all">Mark all as complete</label>
<ul id="todo-list" data-role="listview" data-template="item-template" data-bind="source: todos"></ul>
<ul id="todo-list" data-template="item-template" data-bind="source: todos"></ul>
</section>
<footer id="footer" data-bind="visible: isVisible">
<footer id="footer" class="hidden" data-bind="attr: { class: isVisible }">
<span id="todo-count">
<strong data-bind="text: activeCount"></strong>
<span data-bind="text: activeCountText"></span> left
......@@ -53,12 +53,15 @@
<button class="destroy" data-bind="click: destroy">
</button>
</div>
<input class="edit" data-bind="value: title, events: { change: endEdit, blur: endEdit }, enter: endEdit">
<input class="edit" data-bind="value: title, events: { blur: endEdit, change: endEdit }, enter: endEdit, escape: cancelEdit">
</li>
</script>
<script src="bower_components/todomvc-common/base.js"></script>
<script src="bower_components/jquery/jquery.js"></script>
<script src="js/lib/kendo.web.js"></script>
<script src="bower_components/kendo-ui/src/js/kendo.core.js"></script>
<script src="bower_components/kendo-ui/src/js/kendo.data.js"></script>
<script src="bower_components/kendo-ui/src/js/kendo.binder.js"></script>
<script src="bower_components/kendo-ui/src/js/kendo.router.js"></script>
<script src="js/lib/kendo.bindings.custom.js"></script>
<script src="js/lib/kendo.data.localstoragedatasource.js"></script>
<script src="js/app.js"></script>
......
......@@ -10,22 +10,24 @@ var app = app || {};
};
// Route object to manage filtering the todo item list
var routes = {
'/': function () {
app.todoData.filter({});
app.todoViewModel.set('filter', '');
},
'/active': function () {
filterBase.value = false;
app.todoData.filter(filterBase);
app.todoViewModel.set('filter', 'active');
},
'/completed': function () {
filterBase.value = true;
app.todoData.filter(filterBase);
app.todoViewModel.set('filter', 'completed');
}
};
var router = new kendo.Router();
router.route('/', function () {
app.todoData.filter({});
app.todoViewModel.set('filter', '');
});
router.route('/active', function () {
filterBase.value = false;
app.todoData.filter(filterBase);
app.todoViewModel.set('filter', 'active');
});
router.route('/completed', function () {
filterBase.value = true;
app.todoData.filter(filterBase);
app.todoViewModel.set('filter', 'completed');
});
// Todo Model Object
app.Todo = kendo.data.Model.define({
......@@ -46,6 +48,13 @@ var app = app || {};
itemBase: 'todos-kendo',
schema: {
model: app.Todo
},
change: function () {
var completed = $.grep(this.data(), function (el) {
return el.get('completed');
});
app.todoViewModel.set('allCompleted', completed.length === this.data().length);
}
});
......@@ -54,63 +63,71 @@ var app = app || {};
todos: app.todoData,
filter: null,
// Handle route changes and direct to the appropriate handler in our
// local routes object.
routeChanged: function (url) {
routes[url || '/'].call(this);
},
// Main element visibility handler
isVisible: function () {
return this.get('todos').data().length;
return this.get('todos').data().length ? '' : 'hidden';
},
// new todo value
newTodo: null,
// Core CRUD Methods
saveTodo: function () {
var todos = this.get('todos');
var newTodo = $('#new-todo');
var newTodo = this.get('newTodo');
var todo = new app.Todo({
title: newTodo.val().trim(),
title: newTodo.trim(),
completed: false,
edit: false
});
todos.add(todo);
todos.sync();
newTodo.val('');
this.set('newTodo', null);
},
toggleAll: function () {
var completed = this.completedTodos().length === this.get('todos').data().length;
$.grep(this.get('todos').data(), function (el) {
el.set('completed', !completed);
});
},
startEdit: function (e) {
e.data.set('edit', true);
$('li[data-uid=' + e.data.uid + ']').find('input').focus();
this.set('titleCache', e.data.get('title'));
$(e.target).closest('li').find('input').focus();
},
endEdit: function (e) {
var editData = e;
var editData = e,
title;
if (e.data) {
editData = e.data;
title = e.data.get('title');
// If the todo has a title, set it's edit property
// to false. Otherwise, delete it.
if (editData.title.trim()) {
editData.set('edit', false);
editData.set('title', title.trim());
} else {
this.destroy(e);
}
}
this.todos.sync();
editData.set('edit', false);
},
cancelEdit: function (e) {
e.set('title', this.get('titleCache'));
e.set('edit', false);
this.todos.sync();
},
sync: function () {
this.todos.sync();
this.get('todos').sync();
},
destroy: function (e) {
this.todos.remove(e.data);
......@@ -140,9 +157,8 @@ var app = app || {};
completedCount: function () {
return this.completedTodos().length;
},
allCompleted: function () {
return this.completedTodos().length === this.get('todos').data().length;
},
allCompleted: false,
// Text value bound methods
activeCountText: function () {
......@@ -172,18 +188,9 @@ var app = app || {};
});
// Kendo History object for capturing hash changes and triggering
// our route-changed handler
kendo.history.start({
ready: function (e) {
app.todoViewModel.routeChanged(e.url);
},
change: function (e) {
app.todoViewModel.routeChanged(e.url);
}
});
// Bind the ViewModel to the todoapp DOM element
kendo.bind($('#todoapp'), app.todoViewModel);
router.start();
}($, kendo));
......@@ -26,4 +26,29 @@
refresh: function () {}
});
var ESCAPE_KEY = 27;
// Create a custom "enter" binding by extending the kendo.data.Binder
// object with a custom init function that binds to the keyup event and,
// if the enter key is pressed, will call a bound function.
kendo.data.binders.escape = kendo.data.Binder.extend({
init: function (widget, bindings, options) {
// Call the "base" init method
kendo.data.Binder.fn.init.call(this, widget, bindings, options);
$(this.element).bind('keyup', function (e) {
// If the keypressed is not the escape key, return
if (e.which !== ESCAPE_KEY) {
return;
}
// Otherwise, call the function specified in the enter binding
this.bindings['escape'].get();
}.bind(this));
},
// The refresh function must be specified in a custom binding,
// even when empty.
refresh: function () {}
});
})($, kendo);
\ No newline at end of file
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