JSFiddle - React, Tailwind, and code Playground
by arhari
HTML
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/themes/blitzer/jquery-ui.css">
<script src="https://github.com/jquery/jquery-tmpl/raw/master/jquery.tmpl.js"></script>
<script src="https://github.com/SteveSanderson/knockout/raw/master/build/output/knockout-latest.debug.js"></script>
<table>
<tr>
<th>Id</th>
<th>Name</th>
<th></th>
<th></th>
</tr>
<tbody data-bind="foreach: productList">
<tr>
<td data-bind="text: id"></td>
<td data-bind="text: name"></td>
<td>
<button data-bind="click: $root.editProduct">Edit</button>
</td>
<td>
<button data-bind="click: $root.removeProduct">Delete</button>
</td>
</tr>
</tbody>
</table>
<button data-bind="click: addProduct">Add Product</button>
<hr />
<div id="details" data-bind="jqDialog: { autoOpen: false, resizable: false, modal: true }, template: { name: 'editTmpl', data: selectedProduct }, openDialog: selectedProduct, onCloseDialog: onCloseDialog">
</div>
<script id="editTmpl" type="text/html">
<p>
<label>ID: </label>
<input data-bind="value: editId" />
</p>
<p>
<label>Name: </label>
<input data-bind="value: editName" />
</p>
<button data-bind="jqButton: {}, click: $root.accept">Accept</button>
<button data-bind="jqButton: {}, click: $root.cancel">Cancel</button>
</script>
CSS
td { padding: 5px; }
input { width: 100px; margin: 10px; }
label: { width: 100px; }
JavaScript
//custom binding to initialize a jQuery UI dialog
ko.bindingHandlers.jqDialog = {
init: function(element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()) || {};
//handle disposal
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).dialog("destroy");
});
$(element).dialog(options);
}
};
ko.bindingHandlers.onCloseDialog = {
init: function(element, valueAccessor) {
var listener = ko.utils.unwrapObservable(valueAccessor());
$(element).dialog({ close: listener });
}
};
//custom binding handler that opens/closes the dialog
ko.bindingHandlers.openDialog = {
update: function(element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
if (value) {
$(element).dialog("open");
} else {
$(element).dialog("close");
}
}
}
//custom binding to initialize a jQuery UI button
ko.bindingHandlers.jqButton = {
init: function(element, valueAccessor) {
var options = ko.utils.unwrapObservable(valueAccessor()) || {};
//handle disposal
ko.utils.domNodeDisposal.addDisposeCallback(element, function() {
$(element).button("destroy");
});
$(element).button(options);
}
};
var Product = function(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);
}
var ViewModel = function() {
var self = this;
this.productList = ko.observableArray([
...