learn.knockoutjs.com - single page applications
http://learn.knockoutjs.com/#/?tutorial=webmail
by Shobhit Sharma
HTML
<link rel="stylesheet" href="http://learn.knockoutjs.com/Content/App/coderunner.css">
<link rel="stylesheet" href="http://learn.knockoutjs.com/Content/TutorialSpecific/webmail.css">
<script src="http://learn.knockoutjs.com/scripts/lib/sammy.js"></script>
<script src="http://knockoutjs.com/downloads/knockout-2.2.1.js"></script>
<body>
<!-- Folders -->
<ul class="folders" data-bind="foreach: folders">
<li data-bind="text: $data,
css: { selected: $data == $root.chosenFolderId() },
click: $root.goToFolder"></li>
</ul>
<!-- Mails grid -->
<table class="mails" data-bind="with: chosenFolderData">
<thead><tr><th>From</th><th>To</th><th>Subject</th><th>Date</th></tr></thead>
<tbody data-bind="foreach: mails">
<tr data-bind="click: $root.goToMail">
<td data-bind="text: from"></td>
<td data-bind="text: to"></td>
<td data-bind="text: subject"></td>
<td data-bind="text: date"></td>
</tr>
</tbody>
</table>
<!-- Chosen mail -->
<div class="viewMail" data-bind="with: chosenMailData">
<div class="mailInfo">
<h1 data-bind="text: subject"></h1>
<p><label>From</label>: <span data-bind="text: from"></span></p>
<p><label>To</label>: <span data-bind="text: to"></span></p>
<p><label>Date</label>: <span data-bind="text: date"></span></p>
</div>
<p class="message" data-bind="html: messageContent" />
</div>
</body>
JavaScript
function WebmailViewModel() {
// Data
var self = this;
self.folders = ['Inbox', 'Archive', 'Sent', 'Spam'];
self.chosenFolderId = ko.observable();
self.chosenFolderData = ko.observable();
self.chosenMailData = ko.observable();
// Behaviours
self.goToFolder = function(folder) { location.hash = folder };
self.goToMail = function(mail) { location.hash = mail.folder + '/' + mail.id };
// Client-side routes
Sammy(function() {
this.get('#:folder', function() {
var folder = this.params.folder;
self.chosenFolderId(folder);
self.chosenMailData(null);
$.ajax({
type: 'POST',
url: '/echo/json/',
data: {
json: JSON.stringify({ folder: folder }),
delay: 0
},
success: function(data) {
self.chosenFolderData({ mails: fakeData[folder] });
}
});
});
this.get('#:folder/:mailId', function() {
var folder = this.params.folder,
mailId = this.params.mailId;
self.chosenFolderId(folder);
self.chosenFolderData(null);
$.ajax({
type: 'POST',
url: '/echo/json/',
data: {
json: JSON.stringify({ mailId: mailId }),
delay: 0
},
success: function(data) {
self.chosenMailData(ko.utils.arrayFirst(fakeData[folder], function(item) {
return item.id == mailId;
}));
}
});
});
this.get('', function() { this.app.runRoute('get', '#Inbox') });
}).run();
};
ko.applyBindings(new WebmailViewModel());
//Fake data for jsFiddle...