learn.knockoutjs.com - single page applications
http://learn.knockoutjs.com/#/?tutorial=webmail
by gurkavcu
HTML
<script src="http://learn.knockoutjs.com/Scripts/Lib/jquery.tmpl.js"></script>
<script src="http://learn.knockoutjs.com/Scripts/Lib/jquery.address.js"></script>
<script src="http://learn.knockoutjs.com/Scripts/Lib/knockout-1.3.0.latest.js"></script>
<link rel="stylesheet" href="http://learn.knockoutjs.com/Content/App/coderunner.css">
<script src="http://learn.knockoutjs.com/scripts/lib/knockout.address.js"></script>
<link rel="stylesheet" href="http://learn.knockoutjs.com/Content/TutorialSpecific/webmail.css">
<body>
<!-- Folders -->
<ul class="folders" data-bind="template: { name: 'folderTemplate', foreach: folders }"></ul>
<script type="text/html" id="folderTemplate">
<li data-bind="css: { selected: $data == mailViewModel.selectedFolder() },
click: function() { mailViewModel.selectFolder($data) }">
${$data}
</li>
</script>
<!-- Mails grid -->
<table class="mails" data-bind="visible: !selectedMail()">
<thead><tr><th>From</th><th>To</th><th>Subject</th><th>Date</th></tr></thead>
<tbody data-bind="template: { name: 'mailsGridRow', foreach: currentPageMails }"></tbody>
</table>
<script type="text/html" id="mailsGridRow">
<tr data-bind="click: function() { mailViewModel.selectedMailId(id) }">
<td>${from}</td>
<td>${to}</td>
<td>${subject}</td>
<td>${date}</td>
</tr>
</script>
<!-- Selected mail -->
<div class="viewMail" data-bind="template: { name: 'mailTemplate', data: selectedMail }"></div>
<script type="text/html" id="mailTemplate">
<div class="mailInfo">
<h1>${subject}</h1>
<p><label>From</label>: ${from}</p>
<p><label>To</label>: ${to}</p>
<p><label>Date</label>: ${date}</p>
</div>
<p class="message" data-bind="html: messageContent" />
</script>
</body>
JavaScript
$(function() {
var viewModel = {
// Data
folders: ['Inbox', 'Archive', 'Sent', 'Spam'],
selectedFolder: ko.observable('Inbox'),
selectedMailId: ko.observable(),
currentPageMails: ko.observableArray([]),
// Behaviours
selectFolder: function(folder) {
this.selectedMailId(null);
this.selectedFolder(folder);
}
};
viewModel.selectedMail = ko.dependentObservable(function() {
var mailIdToFind = this.selectedMailId();
return ko.utils.arrayFirst(viewModel.currentPageMails(), function(item) {
return item.id == mailIdToFind
});
}, viewModel);
window.mailViewModel = viewModel;
ko.applyBindings(viewModel);
ko.linkObservableToUrl(viewModel.selectedFolder, "folder" /* hash param name */ , "Inbox" /* default value */ );
ko.linkObservableToUrl(viewModel.selectedMailId, "mailId" /* hash param name */ );
ko.dependentObservable(function() {
if (this.lastMailRequest) this.lastMailRequest.abort(); // Prevent concurrent requests
// Get folder data from JSON web service and feed output into currentPageMails
//this.lastMailRequest = $.get("/mail/foldercontents", {
// folder: this.selectedFolder()
//}, this.currentPageMails);
this.lastMailRequest = $.ajax({
type: 'POST',
url: '/echo/json/',
data: {
json: JSON.stringify({ folder: this.selectedFolder() }),
delay: 0
},
context: this,
success: function(data) {
this.currentPageMails(fakeData[data.folder]);
}
});
}, viewModel);
});
//Fake data for jsFiddle echo AJAX requests
var fakeData = {};
fakeData.Inbox =
[{"id":1,"from":"Abbot \[email protected]\u003e","to":"[email protected]","date":"May 25, 2011","subject":"Booking confirmation...