Knockout master-detail
by smichelotti
HTML
<script src="http://cloud.github.com/downloads/SteveSanderson/knockout/knockout-1.3.0beta.debug.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/redmond/jquery-ui.css">
<div class="master ui-widget-content ui-corner-all">
<h3 class="title ui-widget-header">Tags</h3>
<input id="newTag" type="text" placeholder="Add New Tag" data-bind="value: itemToAdd, valueUpdate: 'afterkeydown', event: { keypress: checkAdd }" />
<button type="submit" data-bind="click: addTag">Add</button>
<table>
<tbody data-bind='template: {name:"tagsTemplate", foreach:tags}'></tbody>
</table>
<script type="text/html" id="tagsTemplate">
<tr>
<td><span data-bind="text: Name"/></td>
<td><button class="edit-item">Edit</button></td>
<td><button class="remove-item">Remove</button></td>
<td><button class="drills">Drills</button></td>
</tr>
</script>
</div>
<div class="detail ui-widget-content ui-corner-all">
<h3 class="title ui-widget-header">Drills</h3>
<table>
<tr>
<th>Name</th>
<th>Description</th>
</tr>
<tbody data-bind='template: {name:"drillsTemplate", foreach:currentTagDrills}'></tbody>
</table>
<script type="text/hml" id="drillsTemplate">
<tr>
<td><span data-bind="text: Name"/></td>
<td><span data-bind="text: Description"/></td>
</tr>
</script>
</div>
<div id="tagDialog" />
JavaScript
$(function() {
var viewModel = {
// Data
itemToAdd: ko.observable(""),
tags: ko.observableArray(fakeData.Tags),
selectedTag: ko.observable(fakeData.Tags[1]),
currentTagDrills: ko.observableArray([]),
// Behaviors
selectTag: function(tag) {
this.selectedTag(tag);
},
addTag: function() {
this.tags.push({
Name: this.itemToAdd()
});
this.itemToAdd("");
},
checkAdd: function(event) {
if (event.charCode === 13) {
this.addTag();
return false;
}
return true;
}
}; // end viewModel
var tagDialog = $("#tagDialog").dialog({
autoOpen: false
});
$(".remove-item").live("click", function() {
viewModel.tags.remove(ko.dataFor(this));
});
$(".edit-item").live("click", function() {
tagDialog.dialog("open");
});
$(".drills").live("click", function() {
console.log("in drills click");
viewModel.selectTag(ko.dataFor(this));
});
ko.applyBindings(viewModel);
ko.dependentObservable(function() {
console.log("in dep observable: ");
console.log(this.selectedTag().Name);
this.currentTagDrills(fakeData[this.selectedTag().Name]);
}, viewModel);
});
//Fake data for jsFiddle echo AJAX requests
var fakeData = {};
fakeData.Tags = [{
"Id": 1,
"Name": "Transition"},
{
"Id": 2,
"Name": "Passing"},
{
"Id": 3,
"Name": "Ball Handling"},
{
"Id": 4,
"Name": "Shooting"},
{
"Id": 5,
"Name": "Team Offense"},
{
"Id": 6,
"Name": "Team Defense"},
{
"Id": 7,
"Name": "Rebounding"},
{
"Id": 8,
"Name": "Defense"}];
fakeData.Transition = [{
"Id": 2,
"Name": "Perfection",
"Description": null,
"TagId": 2,
"Tag": null},
{
"Id": 3,
"Name": "3-man Weave",
...