KnockoutJS & jQuery Datatable custom binding (jQueryUI)
a custom knockout binding
HTML
<script src="//cdn.datatables.net/1.10.7/js/jquery.dataTables.min.js"></script>
<script src="//code.jquery.com/ui/1.11.3/jquery-ui.min.js"></script>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css">
<script src="https://rawgit.com/zachpainter77/zach-knockout.js/master/zach-knockout.debug.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.3.5/knockout.mapping.js"></script>
<script src="https://cdn.rawgit.com/zachpainter77/DatatablesForEach-Custom-Knockout-Binding/master/DatatablesForEach.js"></script>
<button data-bind="click: add">ADD</button> Toggle Editing Mode <span data-bind="text: getEditMode"></span>
<input type="checkbox" data-bind="checked: inline" />
<br />
<br/>
<button data-bind="click: removeAll">Remove All</button>
<br />
<br />
<div id="wrapper">
<table id="example" style="width:100%" class="table table-striped table-bordered dataTable">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
<th>Remove</th>
<th>Edit</th>
</tr>
</thead>
<tbody data-bind="DataTablesForEach: {data: people, options: { jQueryUI: true,
scrollY: 250, paging: true, dom: 'rtip', columns:[{width: '30px'},{width: '100px'},{width: '100px'},{width: '100px'},{width:'100px'}] }}">
<tr style="height:50px;">
<td><span data-bind="text: id" />
</td>
<td style="width:50px;"> <span data-bind="text: first, visible:!isEdit()"></span>
<input class="form-control input-sm" data-bind="textInput: first, visible: isEdit()" style="width:95%" />
</td>
<td> <span data-bind="text: age, visible:!isEdit()"></span>
<input class="form-control input-sm" data-bind="textInput: age, visible: isEdit()" style="width:95%"...
CSS
.ui-buttonset .ui-button {
margin-left: 0;
margin-right: 0;
}
JavaScript
// this is the worst.
// Person ViewModel
var Person = function (data, parent) {
var that = this;
this.id = data.id;
this.isEdit = ko.observable(false);
this.first = ko.observable(data.first);
this.last = ko.observable(data.last);
this.age = ko.observable(data.age);
this.editButtonText = ko.computed(function () {
return that.isEdit() ? 'Save' : 'Edit';
});
this.full = ko.computed(function () {
return this.first() + " " + this.last();
}, this);
// Subscribe a listener to the observable properties for the table
// and invalidate the DataTables row when they change so it will redraw
};
//Main ViewModel
var ViewModel = new function () {
var that = this;
this.people = ko.mapping.fromJS([]);
this.inline = ko.observable(true);
this.add = function () {
$('#dialog').dialog('open');
};
this.getEditMode = ko.computed(function () {
return that.inline() ? '(Inline)' : '(Dialog)';
});
this.remove = function (person, event) {
that.people.remove(person);
};
this.removeAll = function(person, event){
that.people.removeAll();
};
this.edit = function (person, event) {
if (that.inline()) {
if (person.isEdit()){
person.isEdit(false);
}
else{
that.people().forEach(function(p){
if(p.isEdit()){
p.isEdit(false);
}
});
person.isEdit(true);
}
} else {
$('#editdialog').data('id', person.id);
$('#editName').val(person.first());
$('#editLast').val(person.last());
$('#editAge').val(person.age());
...