I have recently been looking at the knockoutjs library and what it can be used for. I started off writing a post on knockout grids. It was getting a little long so I have decided to break it up into a number of posts so they will be shorter and hopefully clearer.
In this first part we are going to take a look at a paged SimpleGird similar to this Paged Grid sample on the KO site.
The current knockout library is at version 3.0 and can be found here or via an easy to install nuget package. The paged grid sample uses an additional library called knockout.simpleGrid.3.0.js available here. It is not necessary, but I have local copies of the files and configured a bundle
bundles.Add(new ScriptBundle("~/bundles/knockoutjs").Include(
"~/scripts/knockout-{version}.js",
"~/scripts/knockout.simpleGrid.3.0.js"));
Paged Grid
The amount of code needed on the page to create a grid with paging abilities is not much as the code below demonstrates. Obviously the data would not usually be hard coded in the page, data would usually be retrieved from a database.
@{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<div data-bind='simpleGrid: gridViewModel'></div>
@section Scripts {
@Scripts.Render("~/bundles/knockoutjs")
<script type="text/javascript">
var PagedGridModel = function (items) {
this.items = ko.observableArray(items);
this.gridViewModel = new ko.simpleGrid.viewModel({
data: this.items,
columns: [
{ headerText: "Person ID", rowText: "employeeid" },
{ headerText: "Title", rowText: "title" },
{ headerText: "Forename", rowText: "forename" },
{ headerText: "Surname", rowText: "surname" },
{ headerText: "Start Date", rowText: "startdate" }
],
pageSize: 3
});
}
var gridData = [
{ employeeid: 1000, title: "Mr", forename: "Fred", surname: "Flinstone", startdate: "12 May 1953" },
{ employeeid: 1001, title: "Mr", forename: "Barney", surname: "Rubble", startdate: "20 Jun 1978" },
{ employeeid: 1002, title: "Ms", forename: "Belinda", surname: "Mason", startdate: "11 Nov 2004" },
{ employeeid: 1003, title: "Mrs", forename: "Mary", surname: "Moore", startdate: "5 Aug 1999" },
{ employeeid: 1004, title: "Mr", forename: "Harry", surname: "Hill", startdate: "1 Mar 1995" },
{ employeeid: 1005, title: "Dr", forename: "Carl", surname: "Flowers", startdate: "11 Sep 1988" },
{ employeeid: 1006, title: "Miss", forename: "Jenna", surname: "Pray", startdate: "5 Dec 2010" }
];
ko.applyBindings(new PagedGridModel(gridData));
</script>
}
The page size is set to 3, although it could be set to anything as appropriate. With a size of 3 I could keep the demo data to a minimum.
Because the grid is dynamically created you will not see the html markup of the table when viewing the page source, right-click and View source in IE or View page source in Chrome. Though if you inspect the page via the Developer Tool of you browser you can see how knockout has constructed the table.
<div data-bind="simpleGrid: gridViewModel">
<table class="ko-grid" cellspacing="0">
<thead>
<tr data-bind="foreach: columns">
<th data-bind=" text: headerText">Person ID</th>
<th data-bind=" text: headerText">Title</th>
<th data-bind=" text: headerText">Forename</th>
<th data-bind=" text: headerText">Surname</th>
<th data-bind=" text: headerText">Start Date</th>
</tr>
</thead>
<tbody data-bind=" foreach: itemsOnCurrentPage">
<tr data-bind=" foreach: $parent.columns">
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">1000</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Mr</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Fred</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Flinstone</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">12 May 1953</td>
</tr>
<tr data-bind=" foreach: $parent.columns">
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">1001</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Mr</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Barney</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Rubble</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">20 Jun 1978</td>
</tr>
<tr data-bind=" foreach: $parent.columns">
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">1002</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Ms</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Belinda</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Mason</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">11 Nov 2004</td>
</tr>
<tr data-bind=" foreach: $parent.columns">
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">1003</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Mrs</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Mary</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">Moore</td>
<td data-bind=" text: typeof rowText == 'function' ? rowText($parent) : $parent[rowText]">5 Aug 1999</td>
</tr>
</tbody>
</table>
<div class="ko-grid-pageLinks"><span>Page:</span>
<!-- ko foreach: ko.utils.range(0, maxPageIndex) -->
<a class="selected" href="#" data-bind=" text: $data + 1, click: function () { $root.currentPageIndex($data) }, css: { selected: $data == $root.currentPageIndex() }">1</a> <a href="#" data-bind=" text: $data + 1, click: function () { $root.currentPageIndex($data) }, css: { selected: $data == $root.currentPageIndex() }">2</a> <a href="#" data-bind=" text: $data + 1, click: function () { $root.currentPageIndex($data) }, css: { selected: $data == $root.currentPageIndex() }">3</a>
<!-- /ko -->
</div>
</div>
The bottom div with a class of ko-grid-pageLinks contains the pager.
We will see code like this again when looking at custom grid templates later.





You must be logged in to post a comment.