Knockout SPA
http://learn.knockoutjs.com/#/?tutorial=webmail
by WizKid81
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-3.2.0.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<body>
<!-- Folders -->
<ul class="folders" data-bind="foreach: searches">
<li data-bind="text: $data,
css: { selected: $data == $root.chosenSearchId() },
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.searches = ['Queue', 'Active', 'Completed'];
self.chosenFolderId = ko.observable();
self.chosenSearchId = 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('#:search', function() {
var search = this.params.search;
//self.chosenFolderId(folder);
self.chosenSearchId(search);
self.chosenMailData(null);
///This is a dummy ajax call that just returns the same JSON data passed to it. Then the success function is called to process that JSON to load the data for display. In real application, would make a call to a Search web service to get the real data back
$.ajax({
type: 'POST',
url: '/echo/json/',
data: {
json: JSON.stringify({
search: search
}),
delay: 0
},
success: function(data) {
console.log("data: ", data);
self.chosenFolderData({
mails: fakeData["Inbox"]
});
}
});
});
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() {
...