KnockoutJS Paged Editable Grid
Paging a Knockout Observable Array
by mrrodd
HTML
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.1/css/bootstrap-combined.min.css">
<script src="//cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.js"></script>
<div id="grid" class="container">
<div class="row">
<div class="col-md-6">
<table class="table table-condensed table-striped">
<thead>
<tr>
<th><label class="control-label">Row</label></th>
<th><label class="control-label">City</label></th>
<th><label class="control-label">Zip</label></th>
</tr>
</thead>
<tbody data-bind="foreach: pagedItems">
<tr>
<td><span data-bind="text: $parent.pagedIndex($index() + 1)"></span></td>
<td><input class="form-control" data-bind="value: city" /> </td>
<td><input class="form-control" data-bind="value: zip" /> </td>
</tr>
</tbody>
</table>
<ul class="pager">
<li data-bind="css: {'disabled': !previousPageEnabled()}">
<a href="#" data-bind="click: previousPage">Previous</a>
</li>
<li data-bind="css: {'disabled': !nextPageEnabled()}">
<a href="#" data-bind="click: nextPage">Next</a>
</li>
</ul>
</div>
<div class="col-md-6">
<table class="table table-condensed table-striped">
<thead>
<tr>
<th><label class="control-label">Row</label></th>
<th><label class="control-label">City</label></th>
<th><label class="control-label">Zip</label></th>
</tr>
</thead>
<tbody...
JavaScript
var data = [
{ city: "Fort Dodge", zip: "34889" },
{ city: "Fitchburg", zip: "83366" },
{ city: "Menomonee Falls", zip: "52534" },
{ city: "Norfolk", zip: "02232" },
{ city: "Dearborn", zip: "55899" },
{ city: "Pomona", zip: "90483" },
{ city: "Port Orford", zip: "02565" },
{ city: "Clovis", zip: "98500" },
{ city: "Sister Bay", zip: "20285" },
{ city: "Bethlehem", zip: "57757" },
{ city: "Broken Arrow", zip: "18820" },
{ city: "Idabel", zip: "65964" },
{ city: "Macomb", zip: "43974" },
{ city: "Dearborn", zip: "03451" },
{ city: "Corinth", zip: "93401" },
{ city: "El Paso", zip: "26282" },
{ city: "Cortland", zip: "67010" },
{ city: "Barre", zip: "52555" },
{ city: "Aspen", zip: "62155" },
{ city: "New Brunswick", zip: "68095" },
{ city: "Garland", zip: "85242" },
{ city: "Gloucester", zip: "33586" },
{ city: "Beacon", zip: "21493" },
{ city: "New Rochelle", zip: "82251" },
{ city: "Fairbanks", zip: "66241" },
{ city: "Lewiston", zip: "38572" },
{ city: "Bismarck", zip: "91912" },
{ city: "Hammond", zip: "69642" },
{ city: "Uniontown", zip: "31508" },
{ city: "Rolla", zip: "92430" }
];
var PagedDataset = (function(data) {
// Convert the data
//var items = ko.observableArray(data); // Converts the data array to an ObserveableArray, but does nothing to the data properties.
var items = ko.mapping.fromJS(data); // Converts the data array to an ObserveableArray and the data properties to Observables
// Setup the pager and related functions
var currentPage = ko.observable(1),
perPage = 10,
pagedItems = ko.computed(function() {
var page = currentPage(),
start = perPage * (page - 1),
end = start + perPage;
return items().slice(start, end);
}),
pagedIndex = function(index) {
return currentPage() == 1 ? index : (perPage *...