Knockout - jQuery UI, dialogs, binding handlers
by johnpapa
HTML
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="https://github.com/downloads/SteveSanderson/knockout/knockout-2.0.0.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.8.16/jquery-ui.min.js"></script>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/themes/base/jquery-ui.css">
<script src="https://github.com/SteveSanderson/knockout.mapping/raw/master/build/output/knockout.mapping-latest.js"></script>
<div data-bind="template: {name: 'foldersTemplate' , foreach: folders}"></div>
<script type="text/html" id="foldersTemplate">
<div>
<h2 data-bind='click: $parent.SelUnsel'>
<a href="#" data-bind='text: folderName'></a>
</h2>
<div>
<a href="#" data-bind="click: function() { $root.editFolder($data) }" >edit Folder</a>
</div>
<div data-bind="if: $parent.selectedFolder()">
<div data-bind="if: $parent.selectedFolder().folderName == folderName">
<ul data-bind=" template: {name: 'linksTemplate' , foreach: links } " ></ul>
</div>
</div>
</div>
</script>
<script type="text/html" id="linksTemplate">
<div>
<li><a href="#" data-bind='text: name' ></a></li>
<li><a href="#" data-bind='text: url' ></a></li>
</div>
<div>
<a href="#" data-bind="click: function() { $root.editLink($data) }" >edit Link</a>
</div>
</script>
<div id="details" data-bind="template: { name: 'editTmpl', if:selectedLink, data: selectedLink }, openDialog: selectedLink">
</div>
<script id="editTmpl" type="text/html">
<p>
<label>Name: </label>
<input data-bind="value: name, valueUpdate: 'afterkeydown' "/>
<label>URL: </label>
<textarea data-bind="value: url, valueUpdate: 'afterkeydown' "/>
</p>
</script>
<div id="folderdetails" data-bind="template: { name:...
CSS
#dialog-confirm { visibility: hidden; }
JavaScript
function Folder(id, name, isNew) {
this.id = ko.observable(id);
this.name = ko.observable(name);
this.isNew = isNew;
this.editId = ko.observable(id);
this.editName = ko.observable(name);
//persist edits to real values on accept
this.accept = function() {
this.id(this.editId()).name(this.editName());
}.bind(this);
//reset to originals on cancel
this.cancel = function() {
this.editId(this.id()).editName(this.name());
}.bind(this);
}
$(function() {
//set up dialog
$("#details").dialog({
autoOpen: false,
resizable: false,
modal: true,
buttons: {
"Accept": function() {
foldersModel.accept();
$(this).dialog("close");
},
Cancel: function() {
foldersModel.cancel();
$(this).dialog("close");
}
}
});
});
$(function() {
//set up dialog
$("#folderdetails").dialog({
autoOpen: false,
resizable: false,
modal: true,
buttons: {
"Accept": function() {
foldersModel.acceptFolder();
$(this).dialog("close");
},
Cancel: function() {
foldersModel.cancelFolder();
$(this).dialog("close");
}
}
});
});
var FoldersModel = function(folders) {
var self = this;
self.folders = ko.mapping.fromJS(folders);
// self.folders = ko.observableArray(ko.utils.arrayMap(folders, function(folder) {
// return { folderName: folder.name, links: ko.observableArray(folder.links) };
// }));
self.folderToEdit = ko.observable();
self.selectedFolder = ko.observable();
self.selectedLink = ko.observable();
self.SelUnsel = function(e) {
if (self.selectedFolder() == null || self.selectedFolder().folderName != e.folderName)
self.selectedFolder(e);
...