Knockout Table Paging Binding
Using Knockout to do table Paging
by cjgaudin
HTML
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.14/themes/base/jquery-ui.css">
<script src="https://raw.github.com/SteveSanderson/knockout.mapping/master/build/output/knockout.mapping-latest.debug.js"></script>
<script src="https://raw.github.com/SteveSanderson/knockout/master/build/output/knockout-latest.debug.js"></script>
<div id="messageLog">
</div>
<div id="filterPanel">
<h3><a href="#">Filter Panel</a> </h3>
<div id="filterContainer">
<div class="first">
<span>Job#:</span>
<input type="text" data-bind="value: selectedJobNumber" maxlength="8"/>
</div>
<div>
<span>Title:</span>
<input type="text" data-bind="value: selectedTitle"/>
</div>
<div class="first">
<span>Categories:</span>
<select data-bind="options: categoryLookups,
optionsCaption: ' ',
optionsText: 'Name',
value: selectedCategory"></select>
</div>
<div>
<span>Types:</span>
<select data-bind="options: typeLookups,
optionsCaption: ' ',
optionsText: 'Type',
value: selectedType"></select>
</div>
<div>
<span>Status:</span>
<select data-bind="options: statusLookups,
optionsCaption: ' ',
optionsText: 'Status',
value: selectedStatus"></select>
</div>
<input id="clearFilterButton" type="button" value="clear" />
<input id="filterButton" type="button" value="filter" />
</div>
</div>
<div id="projectList">
<table class="work-table" >
<thead>
<tr>
<th><a href="#" data-sort-field="JobNumber" data-sort-direction="Desc"...
CSS
/* Table Styling*/
table.work-table {
border-collapse:collapse;
border: 1px solid black;
width: 100%;
}
table.work-table th {
background-color:lightgray;
color: black;
font-weight: bold;
font-size: 0.8em;
border: 1px solid black;
text-align: center;
}
table.work-table tr:nth-child(even) {
background-color: rgb(240, 240, 240);
}
table.work-table tr:nth-child(odd) {
background-color: white;
}
table.work-table tr td {
border: 1px solid rgb(134, 134, 134);
text-align: center;
}
table.work-table td.justify-left {
text-align: left;
}
table.work-table tr.highlightRow {
cursor: pointer;
}
table.work-table tr.tableDataRow td {
padding: 3px;
}
table.work-table tr.highlightRow:hover {
background-color: rgb(241, 255, 219);
}
table.work-table tr.task-complete-row {
background-color: rgb(241, 255, 219);
}
table.work-table tr.task-complete-row > td {
border: 1px solid yellowgreen;
}
table.work-table tr.task-incomplete-row {
background-color: rgb(255, 227, 227);
}
table.work-table tr.task-incomplete-row > td {
border: 1px solid red;
}
table.work-table tr.assigned-work-request-row {
background-color: rgb(252, 240, 231);
}
td > span.tableDescriptionColumn {
font-style:italic;
font-size: 0.9em;
padding-left: 20px;
}
td > span.tableDataColumn, a.edit-comment, a.edit-equipment, a.edit-task {
font-size: 1.0em;
}
div.pagingContent {
padding: 10px;
width: 100px;
margin: 0 auto;
text-align: center;
}
div.pagingContent > a {
padding: 3px;
font-weight: bold;
color:rgb(149, 149, 149);
}
a.metro-button {
font-variant:small-caps;
font-size: 1.0em;
font-family: Verdana,Arial,sans-serif/*{ffDefault}*/;
border:1px solid black;
padding: 3px;
font-weight: bold;
width: 150px;
text-align:center;
border-radius: 5px;
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
display: block;
color: black;
line-height:...
JavaScript
var main = (function (main, $, undefined) {
var viewModel = main.searchViewModel = main.searchViewModel || {};
//Default options for this view model
var options = {
filterPanelSelector: '#filterPanel',
filterButtonSelector: '#filterButton',
clearButtonSelector: '#clearFilterButton',
messageSelector: '#messageLog',
dialogSelector: '#selectedProjectContainer',
baseSearchUrl: null,
baseLookupUrl: null,
baseWorkUrl: null
};
//---------------PUBLIC FUNCTIONS--------------------
viewModel.initialize = function (serverModel) {
viewModel.searchItems = ko.observableArray();
viewModel.typeLookups = serverModel.Types;
viewModel.statusLookups = serverModel.Statuses;
viewModel.categoryLookups = serverModel.Categories;
viewModel.selectedWorkItem = ko.observable(null);
viewModel.selectedCategory = ko.observable(null);
viewModel.selectedStatus = ko.observable(null);
viewModel.selectedType = ko.observable(null);
viewModel.selectedJobNumber = ko.observable('');
viewModel.selectedTitle = ko.observable('');
//Url binders for the action menu
viewModel.viewWorkUrl = ko.observable('#');
viewModel.editWorkUrl = ko.observable('#');
//Paging Table bindings
viewModel.pageSize = ko.observable(10);
viewModel.pageIndex = ko.observable(0);
viewModel.previousPage = function () {
viewModel.pageIndex(viewModel.pageIndex() - 1);
};
viewModel.nextPage = function () {
viewModel.pageIndex(viewModel.pageIndex() + 1);
};
viewModel.maxPageIndex = ko.computed(function () {
return Math.ceil(this.searchItems().length / this.pageSize()) - 1;
}, viewModel);
viewModel.pagedItems = ko.computed(function () {
var size = this.pageSize();
var start = this.pageIndex() * size;
...