Single Page Binding with Kendo UI ListView

If you’ve looked at the demos on the Kendo UI site, you’ll notice the ListView and DataSource combination are a pretty capable combination. The ListView gives you full control over the user interface, while supporting common functionality like paging, sorting, and more. The DataSource provides read and update functionality to a local or remote data source, even giving you full control over these processes (for instance, you can use JQuery directly for AJAX communication). The pager natively pages through the contents of the listview automatically for you. The three widgets offer great functionality for the developer.

While the combination works well, I personally ran into a snag using the Kendo UI core version (open source). With the pager component natively paging the content, the data source required a complete dataset downloaded from the server. If your ListView will be presenting 30 records, all 30 must be retrieved from the server; if 3,000, all 3,000 must be retrieved from the server. Now natively the data source control supports server paging, most examples illustrated using the Telerik MVC wrappers for handling the server-side processing, and as such, I wasn’t sure whether it was supported. If it works, I would recommend using the kendo pager as it offers the smoothest navigation; but if not, this workaround worked just as well, with some added effort. In order to get around this, I ended up using the Bootstrap Paginator plugin.

The bootstrap paginator allows you control over the number of pages to show, and provide delegation on user interaction, with the example below.

            currentPage: 1,
            totalPages: 10,
            onPageClicked: function(e, evt, type, page){
                //Reload the listview - listview uses custom AJAX option

The currentPage option sets the current page in the list, within the range of total pages. It’s possible to preload these from an MVC model, especially when you factor in postbacks (the pager needs reinitialized on postbacks), as in the following:

   currentPage: @Model.CurrentPage,
   totalPages: @Model.TotalPages

When the user clicks on a page, it fires the onPageClicked callback handler, which subsequently triggers an AJAX action back to the server. We’ll need the new page index from the event handler; we can get it directly from the plugin, or store the current index in a hidden variable. Either way, this piece of information needs passed back to the server.
If you looked in the example online, it has a custom AJAX action as shown below.

    dataSource: {
       transport: {
           read: function(o) {
              var index = // Get index from hidden variable or wherever

                  type: "post",
                  url: "@Url.Action("Action", "Controller"),
                  data: { index: index, otherParams: "OTHER PARAMS" },
                  success: function(d) { o.success(d); },
                  error: function(d) { o.error(d); }

Here we trigger the postback to the server, and pass in the list of form data values, as well as the currently selected page index. Since the items per page is hard-coded in this scenario (at say 10, for example), we can quickly calculate the starting index and ending index of the current page.

There are many ways to implement this solution; this is one quick, simple way to introduce paging with large lists of data, where each page is dynamically loaded at paging time.


Resolving an Uncommon Eclipse Startup Error

I recently downloaded the Android development tools for Windows 8, using the Eclipse environment for app developmen. In the latest download, the Android developer tools already come with Eclipse, the popular tool for Android and Java development. After some time, though, I got the following error below. It’s rather large so I’ll cut to the chase now. The fix for me was to run the eclipse.exe -clean command. Note, if you are running a virtual environment, such as using Hyper-V or VirtualBox, you may need to run the command as an administrator.

!SESSION 2013-02-16 21:58:12.331 ———————————————–
java.vendor=Oracle Corporation
BootLoader constants: OS=win32, ARCH=x86_64, WS=win32, NL=en_US
Framework arguments: -product
Command-line arguments: -os win32 -ws win32 -arch x86_64 -product

!ENTRY org.eclipse.osgi 4 0 2013-02-16 21:58:13.223
!MESSAGE FrameworkEvent ERROR
org.osgi.framework.BundleException: Exception in org.eclipse.osgi.framework.internal.core.SystemBundleActivator.start() of bundle org.eclipse.osgi.
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.start(
at org.eclipse.osgi.framework.internal.core.InternalSystemBundle.resume(
at org.eclipse.osgi.framework.internal.core.Framework.launch(
at org.eclipse.core.runtime.adaptor.EclipseStarter.startup(
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.eclipse.equinox.launcher.Main.invokeFramework(
at org.eclipse.equinox.launcher.Main.basicRun(
at org.eclipse.equinox.launcher.Main.main(
Caused by: java.lang.IllegalStateException: Expected to find an object at table index: 357
at org.eclipse.osgi.internal.resolver.StateReader.getFromObjectTable(
at org.eclipse.osgi.internal.resolver.StateReader.readGenericDescription(
at org.eclipse.osgi.internal.resolver.StateReader.readBundleDescriptionLazyData(
at org.eclipse.osgi.internal.resolver.StateReader.fullyLoad(
at org.eclipse.osgi.internal.resolver.BundleDescriptionImpl.loadLazyData(
at org.eclipse.osgi.internal.resolver.BundleDescriptionImpl.getExportPackages(
at org.eclipse.osgi.framework.internal.core.PackageAdminImpl.setFrameworkVersion(
at org.eclipse.osgi.framework.internal.core.PackageAdminImpl.setResolvedBundles(
at org.eclipse.osgi.framework.internal.core.SystemBundleActivator.start(
at org.eclipse.osgi.framework.internal.core.BundleContextImpl$
at Method)
at org.eclipse.osgi.framework.internal.core.BundleContextImpl.startActivator(