Using jQuery's UI Slider For Page Sizes

Posted by: Malcolm Sheridan , on 10/23/2009, in Category jQuery and ASP.NET
Views: 42414
Abstract: The following article demonstrates how to use jQuery’s UI Slider widget to determine the number of records to show in a grid.
Using jQuery's UI Slider For Page Sizes
 
Recently I did an article on Efficient Server Side Paging With ASP.NET and jQuery where I explained how jQuery’s Ajax functionality could be used to eliminate the need to use page heavy server controls such as the GridView, and prevent bloating your page with tonnes of ViewState. 

I thought it might be an idea to build on this article and incorporate the jQuery UI Slider widget to give the user the power to change how many records are displayed per page by sliding the control. The end result will show you how to create a slider to set the number of rows displayed per page. The end result will look something like this:


10RecordsPerPage
Before we get started, this example uses the latest version of jQuery which is 1.3.2. That can be downloaded from here. You’ll also need the jQuery UI Core Slider Widget and the Slider’s CSS files which can be downloaded from here. You’ll also need a copy of the Northwind database. If you don’t have a copy of the Northwind database, you can go here to download it. Finally you’ll need to download a copy of jTemplates
The Slider has a number of different options available. Some of the ones I’ll work with in this article are:
  • max – the maximum number of the slider
  • min – the minimum number of the slider
  • orientation – horizontal or vertical
  • value – determines the value of the slider
  • step - determines the size or amount of each interval or step the slider takes between min and max
 The two events I’m working with are:
  • slide - this event is triggered on every mouse move during slide
  • change - this event is triggered on slide stop, or if the value is changed programmatically (by the value method)
Let’s get started! Open Visual Studio 2008 and create a new Web Application. To begin with add a new LINQ to SQL Classes file to your project and call it Northwind. Add the customer table to the design surface:
Customer
Save and build your project. Now that is done I’m going to create a custom class to return to the client. I’m creating it this way because the method needs to return not only a list of customers, but it also needs to return the total customer count for the paging to function correctly. Add a new class to your web application and call it CustomerData. Add the following code:
C#
public class CustomerData
{
public List<Customer> Customers { get; set; }
      public int TotalRecords { get; set; }
}
VB.NET
Public Class CustomerData
Private privateCustomers As List(Of Customer)
Public Property Customers() As List(Of Customer)
      Get
            Return privateCustomers
      End Get
      Set(ByVal value As List(Of Customer))
            privateCustomers = value
      End Set
End Property
       Private privateTotalRecords As Integer
       Public Property TotalRecords() As Integer
             Get
                   Return privateTotalRecords
             End Get
             Set(ByVal value As Integer)
                   privateTotalRecords = value
             End Set
       End Property
End Class
The CustomerData class has two properties. The Customers property will contain the list of customers, and TotalRecords will hold the total number of records. Now we need to add one method to the default page to retrieve the data. This needs to be decorated with the WebMethod attribute so it can be consumed by jQuery’s Ajax function. Add the following method to fetch the customer data.
C#
[WebMethod]
public static CustomerData FetchCustomers(int skip, int take)
{
var data = new CustomerData();
      using (var dc = new NorthwindDataContext())
      {
            var query = (from p in dc.Customers
                            select p)
                            .Skip(skip)
                            .Take(take)                           
                            .ToList();
            data.Customers = query;
            data.TotalRecords = (from p in dc.Customers
                                     select p).Count();
}
return data;
}
VB.NET
<WebMethod> _
Public Shared Function FetchCustomers(ByVal skip As Integer, ByVal take As Integer) As CustomerData
Dim data = New CustomerData()
       Using dc = New NorthwindDataContext()
             Dim query = ( _
                  From p In dc.Customers _
                  Select p).Skip(skip).Take(take).ToList()
                  data.Customers = query
                  data.TotalRecords = ( _
                      From p In dc.Customers _
                      Select p).Count()
       End Using
Return data
End Function
In the code above the method acceps two parameters, skip and take which are integer values that will be used to run the IQueryable Take and Skip methods. These methods create an SQL statement that only returns records between the rows starting at the Take value, and then skipping all the rows in the Skip value instead of the whole table. That’s the server code done! The next step is to add the JavaScript. Open the Default.aspx page and add the following jQuery code to the <head> section of the page. Ideally JavaScript should go to a separate .js file, however for this example; I’ll keep it in the same page:
<script language="javascript" type="text/javascript" src="jquery-1.3.2.js"></script>
    <script language="javascript" type="text/javascript" src="jquery-ui-1.7.2.custom.min.js"></script>
    <script language="javascript" type="text/javascript" src="http://jtemplates.tpython.com/jTemplates/jquery-jtemplates.js"></script>
    <script language="javascript" type="text/javascript">
        $(document).ready(function() {
            var $slide = $("#slider");
            $slide.slider({
                orientation: "horizontal",
                range: "min",
                min: 0,
                max: 20,
                value: 10,
                step: 1,
                slide: function(event, ui) {
                    printRecordsPerPage(ui.value);
                },
                change: function(event, ui) {
                    fetchCustomer(1);
                }
            });
            printRecordsPerPage($slide.slider("option", "value"));
            fetchCustomer(1);
        });
 
        function fetchCustomer(skip) {             
            var $slide = $("#slider");
            var take = $slide.slider("option", "value");           
            var skippy = skip == 1 ? 0 : (skip * take) - take;
            $.ajax({
                type: "POST",
                url: "Default.aspx/FetchCustomers",
                data: "{skip:" + skippy + ",take:" + take + "}",
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                async: true,
               cache: false,
                success: function(msg) {                   
                    var total = msg.d.TotalRecords;
                    if (total > 0) {
                        printCustomer(msg.d.Customers);
                        $("#paging").text("");
                        $("#paging").die("click");
                        // Get the page count by dividing the total records
                        // by the page size. This has to be rounded up
                        // otherwise you might not get the last page
                        var pageTotal = Math.ceil(total / take);
                        for (var i = 0; i < pageTotal; i++) {                           
                            var newId = "anchor" + i;
                            var pageNo = parseInt(i + 1);
                            $("#paging").append("<a href=\"#pagedData\" id=" + newId + ">" + pageNo + "</a>&nbsp;");
                            $("#paging a[id$=" + newId + "]").live("click", function() {
                                fetchCustomer($(this).text());
                            });
                        }
                    }
                },
                error: function(XMLHttpRequest, textStatus, errorThrown) {
                    alert(textStatus);
                }
            });
        }
 
        // Display the number of rows per page
        function printRecordsPerPage(count) {
            $("#recordsPerPage").text(count + " records per page");
        }
       
        // This function accepts a customer object
        // and prints the results to the div element.
        function printCustomer(msg) {           
            $("#result").setTemplateURL("Template.htm");
            $("#result").processTemplate(msg);
        }
    </script>
There’s allot going on in the code above, so I’ll break it down into smaller pieces. In the code above, the first thing that is executed is the $(document).ready event. In this event I’m creating the slider, setting default values for the orientation, min, max, value and step options. I have also created event handlers for the slide and change event:
$(document).ready(function() {
            var $slide = $("#slider");
            $slide.slider({
                orientation: "horizontal",
                range: "min",
                min: 0,
                max: 20,
                value: 10,
                step: 1,
                slide: function(event, ui) {
                    printRecordsPerPage(ui.value);
                },
                change: function(event, ui) {
                    fetchCustomer(1);
                }
            });
            printRecordsPerPage($slide.slider("option", "value"));
            fetchCustomer(1);
        });
When the user runs the application, the default page size is set by the value option. When they slide the slider to display more/less records, the slide event is triggered. This calls the printRecordsPerPage function which updates the current value of the slider. When the user stops sliding, the change event is triggered. That calls fetchCustomers and sets the current page back to the beginning. fetchCustomers uses jQuery’s Ajax functionality to retrieve the data from the server via the WebMethod. The WebMethod takes two parameters, skip and take. The skip value is determined by what page the user is on, but the take value gets the current value of the slider and uses that to determine the page size:
var take = $slide.slider("option", "value");           
var skippy = skip == 1 ? 0 : (skip * take) - take;
 
This function also calls printCustomer which renders the results to the browser by using jTemplatesjTemplates is a free plug-in that allows you to create templates that accept JSON and output the result as standard HTML. This allows you to separate your UI from your JavaScript code.
 function printCustomer(msg) {            
$("#result").setTemplateURL("Template.htm");
      $("#result").processTemplate(msg);
}
<table style="border:solid 1px #000000;">
 <thead>
    <tr>
      <th>ID</th>
      <th>Company Name</th>
      <th>City</th>
    </tr>
 </thead>
 <tbody>
    {#foreach $T as data}
    <tr>
      <td>{$T.data.CustomerID}</td>
      <td>{$T.data.CompanyName}</td>
      <td>{$T.data.City}</td>
    </tr>
    {#/for}
 </tbody>
</table>
If you run the code you’ll see the records are displayed ten at a time. If you slide the slider down, you’ll decrease the amount of records displayed per page:
4RecordsPerPage
And if you increase the value of the slider, you’ll display more rows per page:
15RecordsPerPage.png

I hope reading this article makes you think of different ways to interact with your users. The entire source code of this article can be downloaded over here

This article has been editorially reviewed by Suprotim Agarwal.

Absolutely Awesome Book on C# and .NET

C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.

We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).

Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.

Click here to Explore the Table of Contents or Download Sample Chapters!

What Others Are Reading!
Was this article worth reading? Share it with fellow developers too. Thanks!
Share on LinkedIn
Share on Google+

Author
Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @malcolmsheridan


Page copy protected against web site content infringement 	by Copyscape




Feedback - Leave us some adulation, criticism and everything in between!
Comment posted by Jace Worthing on Tuesday, October 27, 2009 10:16 AM
I really hate the password protection on the source code.  Requiring registration is frustrating and more than most people (including me) are willing to endure.  I'm taking the time to write this comment in the hopes that you'll reconsider this action which puts an additional and unwelcome step between your users and your content.
Comment posted by Admin on Wednesday, October 28, 2009 9:36 AM
Jace: Thanks for your comment. The registration is a one time process and ensures that only registered users download the code. It also helps us track the number of downloads per user and helps us keep a check on the bandwidth. Anyways we are working out an alternative to way to replace this process and we hope to do it soon.

Thanks.
Comment posted by EtienneT on Saturday, October 31, 2009 9:11 AM
An online demo should be mandatory on any jQuery article. ;)
Comment posted by Malcolm Sheridan on Sunday, November 1, 2009 2:15 AM
@EtienneT
That is a very good suggestion :)
Comment posted by Tom on Sunday, February 28, 2010 12:56 PM
Hello Sir,
I started the project as an asp.net website.I exactly followed your code.I am getting the slider in the UI,but not getting the data populated. :(
What could be wrong? I rarely work on web application projects.I prefer website projects.Your source code works pretty well.What are the basic changes to be made while converting a web application project to a website project?
Thanks in advance.
Comment posted by Malcolm Sheridan on Friday, March 5, 2010 6:56 AM
@Tom
Sorry to hear it's not working. I'm not too familiar with web sites, but if you're not getting the data, then it's not hitting the data layer.  Throw some break points on to see what's happening.

Categories

JOIN OUR COMMUNITY

POPULAR ARTICLES

C# .NET BOOK

C# Book for Building Concepts and Interviews

Tags

JQUERY COOKBOOK

jQuery CookBook